From a9861cb2197b8eb3bc20669252f2b7c279814b76 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Wed, 2 May 2018 00:10:58 +0200
Subject: [PATCH] Implement long message ids

Signed-off-by: Janne Koschinski <janne@kuschku.de>
---
 .../quasseldroid/service/QuasselService.kt    |  4 +-
 .../ui/chat/messages/MessageListFragment.kt   |  2 +-
 .../de/kuschku/libquassel/protocol/Message.kt |  2 +-
 .../de/kuschku/libquassel/protocol/QType.kt   |  2 +-
 .../de/kuschku/libquassel/protocol/QTypes.kt  | 11 +++--
 .../primitive/serializer/MessageSerializer.kt |  4 +-
 .../serializer/SignedId64Serializer.kt        | 42 +++++++++++++++++++
 .../libquassel/quassel/ExtendedFeature.kt     |  4 +-
 .../quassel/syncables/BufferSyncer.kt         |  4 +-
 .../libquassel/session/NotificationManager.kt |  2 +-
 .../persistence/QuasselDatabase.kt            |  4 +-
 .../viewmodel/data/FormattedMessage.kt        |  3 +-
 12 files changed, 66 insertions(+), 18 deletions(-)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/SignedId64Serializer.kt

diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
index eeb654979..ee1778e9a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
@@ -179,8 +179,8 @@ class QuasselService : DaggerLifecycleService(),
       }
     }
 
-    val clearMessageId = intent.getIntExtra("mark_read_message", -1)
-    if (bufferId != -1 && clearMessageId != -1) {
+    val clearMessageId = intent.getLongExtra("mark_read_message", -1)
+    if (bufferId != -1 && clearMessageId != -1L) {
       sessionManager.session.value?.bufferSyncer?.requestSetLastSeenMsg(bufferId, clearMessageId)
       sessionManager.session.value?.bufferSyncer?.requestMarkBufferAsRead(bufferId)
     }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
index 53884fc0d..89bcbe7cb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
@@ -313,7 +313,7 @@ class MessageListFragment : ServiceBoundFragment() {
       swipeRefreshLayout.isEnabled = (bufferId != null || bufferId != -1)
     })
 
-    var previousVisible = -1
+    var previousVisible = -1L
     viewModel.buffer.toFlowable(BackpressureStrategy.LATEST).switchMap { buffer ->
       database.filtered().listenRx(accountId, buffer).switchMap { filtered ->
         database.message().firstMsgId(buffer).map {
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
index 38e62fb9c..f7e535378 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
@@ -25,7 +25,7 @@ import de.kuschku.libquassel.util.flag.Flags
 import org.threeten.bp.Instant
 
 class Message(
-  val messageId: Int,
+  val messageId: MsgId,
   val time: Instant,
   val type: Message_Types,
   val flag: Message_Flags,
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt
index 723f54f2b..419081905 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt
@@ -33,7 +33,7 @@ enum class QType(val typeName: String, val serializer: Serializer<*>,
   Identity("Identity", VariantMapSerializer),
   IdentityId("IdentityId", IntSerializer),
   Message("Message", MessageSerializer),
-  MsgId("MsgId", IntSerializer),
+  MsgId("MsgId", SignedId64Serializer),
   NetworkId("NetworkId", IntSerializer),
   NetworkInfo("NetworkInfo", VariantMapSerializer),
   Network_Server("Network::Server", VariantMapSerializer),
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
index 1a3adf171..79a5070cf 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
@@ -35,10 +35,13 @@ typealias QVariant_ = QVariant<*>
 typealias QVariantMap = Map<String, QVariant_>
 typealias QVariantList = List<QVariant_>
 
-typealias IdentityId = Int
-typealias BufferId = Int
-typealias MsgId = Int
-typealias NetworkId = Int
+typealias SignedId = Int
+typealias SignedId64 = Long
+
+typealias IdentityId = SignedId
+typealias BufferId = SignedId
+typealias MsgId = SignedId64
+typealias NetworkId = SignedId
 
 typealias Message_Type = Message.MessageType
 typealias Message_Types = Flags<Message_Type>
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
index ff3170291..9b3381170 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
@@ -28,7 +28,7 @@ import java.nio.ByteBuffer
 
 object MessageSerializer : Serializer<Message> {
   override fun serialize(buffer: ChainedByteBuffer, data: Message, features: QuasselFeatures) {
-    IntSerializer.serialize(buffer, data.messageId, features)
+    SignedId64Serializer.serialize(buffer, data.messageId, features)
     if (features.hasFeature(ExtendedFeature.LongMessageTime))
       LongSerializer.serialize(buffer, data.time.toEpochMilli(), features)
     else
@@ -48,7 +48,7 @@ object MessageSerializer : Serializer<Message> {
 
   override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Message {
     return Message(
-      messageId = IntSerializer.deserialize(buffer, features),
+      messageId = SignedId64Serializer.deserialize(buffer, features),
       time = if (features.hasFeature(ExtendedFeature.LongMessageTime))
         Instant.ofEpochMilli(LongSerializer.deserialize(buffer, features))
       else
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/SignedId64Serializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/SignedId64Serializer.kt
new file mode 100644
index 000000000..bc8c21aad
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/SignedId64Serializer.kt
@@ -0,0 +1,42 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2018 Janne Koschinski
+ * Copyright (c) 2018 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.primitive.serializer
+
+import de.kuschku.libquassel.protocol.SignedId64
+import de.kuschku.libquassel.quassel.ExtendedFeature
+import de.kuschku.libquassel.quassel.QuasselFeatures
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
+import java.nio.ByteBuffer
+
+object SignedId64Serializer : Serializer<SignedId64> {
+  override fun serialize(buffer: ChainedByteBuffer, data: SignedId64, features: QuasselFeatures) {
+    if (features.hasFeature(ExtendedFeature.LongMessageId))
+      buffer.putLong(data)
+    else
+      buffer.putInt(data.toInt())
+  }
+
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): SignedId64 {
+    return if (features.hasFeature(ExtendedFeature.LongMessageId))
+      buffer.long
+    else
+      buffer.int.toLong()
+  }
+}
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/ExtendedFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/ExtendedFeature.kt
index 1464beb49..92af6d3ce 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/ExtendedFeature.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/ExtendedFeature.kt
@@ -49,7 +49,9 @@ enum class ExtendedFeature {
   /** Serialize message time as 64-bit */
   LongMessageTime,
   /** Real Name and Avatar URL in backlog */
-  RichMessages;
+  RichMessages,
+  /** 64-bit IDs for messages */
+  LongMessageId;
 
   companion object {
     private val map = values().associateBy(ExtendedFeature::name)
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
index 6a83d3481..c819cb2ca 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
@@ -141,7 +141,7 @@ class BufferSyncer constructor(
 
   override fun initSetLastSeenMsg(data: QVariantList) {
     (0 until data.size step 2).map {
-      data[it].value(0) to data[it + 1].value(0)
+      data[it].value(0) to data[it + 1].value(0L)
     }.forEach { (buffer, msgId) ->
       setLastSeenMsg(buffer, msgId)
     }
@@ -150,7 +150,7 @@ class BufferSyncer constructor(
 
   override fun initSetMarkerLines(data: QVariantList) {
     (0 until data.size step 2).map {
-      data[it].value(0) to data[it + 1].value(0)
+      data[it].value(0) to data[it + 1].value(0L)
     }.forEach { (buffer, msgId) ->
       setMarkerLine(buffer, msgId)
     }
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/NotificationManager.kt b/lib/src/main/java/de/kuschku/libquassel/session/NotificationManager.kt
index b6e4f4085..982505d80 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/NotificationManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/NotificationManager.kt
@@ -26,5 +26,5 @@ import de.kuschku.libquassel.protocol.MsgId
 interface NotificationManager {
   fun init(session: Session)
   fun processMessages(session: Session, vararg messages: Message)
-  fun clear(buffer: BufferId, lastRead: MsgId = Int.MAX_VALUE)
+  fun clear(buffer: BufferId, lastRead: MsgId = MsgId.MAX_VALUE)
 }
diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt
index 69078084e..7f4f76c22 100644
--- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt
+++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt
@@ -69,7 +69,7 @@ abstract class QuasselDatabase : RoomDatabase() {
 
   @Entity(tableName = "message", indices = [Index("bufferId"), Index("ignored")])
   data class MessageData(
-    @PrimaryKey var messageId: Int,
+    @PrimaryKey var messageId: MsgId,
     var time: Instant,
     var type: Message_Types,
     var flag: Message_Flags,
@@ -223,7 +223,7 @@ abstract class QuasselDatabase : RoomDatabase() {
 
   @Entity(tableName = "notification", indices = [Index("bufferId")])
   data class NotificationData(
-    @PrimaryKey var messageId: Int,
+    @PrimaryKey var messageId: MsgId,
     var time: Instant,
     var type: Message_Types,
     var flag: Message_Flags,
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt
index b31304934..6eda804f1 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/FormattedMessage.kt
@@ -20,9 +20,10 @@
 package de.kuschku.quasseldroid.viewmodel.data
 
 import android.graphics.drawable.Drawable
+import de.kuschku.libquassel.protocol.MsgId
 
 class FormattedMessage(
-  val id: Int,
+  val id: MsgId,
   val time: CharSequence,
   val name: CharSequence? = null,
   val content: CharSequence? = null,
-- 
GitLab