From 1275a9d7e1669f7d7e73f91bc91811098bba4ffc Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 22 Feb 2018 12:34:36 +0100
Subject: [PATCH] Improved buffer activity tracking

- cleaned up code
- clicking a buffer now properly dimisses activity in it
---
 .../chat/buffers/BufferViewConfigFragment.kt  |  43 +++--
 .../ui/chat/messages/MessageListFragment.kt   |  21 ++-
 .../ui/viewmodel/QuasselViewModel.kt          | 156 +++++++++---------
 3 files changed, 113 insertions(+), 107 deletions(-)

diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt
index 7feb5e9e1..1c60b03d9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt
@@ -78,32 +78,31 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
     chatList.adapter = BufferListAdapter(
       this,
       viewModel.bufferList.zip(database.filtered().listen(accountId)).map {
-        val (list, activityList) = it
+        val (data, activityList) = it
+        val (config, list) = data ?: Pair(null, emptyList())
+        val minimumActivity = config?.minimumActivity() ?: Buffer_Activity.NONE
         val activities = activityList.map { it.bufferId to it.filtered }.toMap()
-        list
-          ?.map {
-            val activity = it.activity - (activities[it.info.bufferId] ?: 0)
-            it.bufferActivity to it.copy(
-              description = ircFormatDeserializer?.formatString(
-                it.description.toString(), appearanceSettings.colorizeMirc
-              ) ?: it.description,
-              activity = activity,
-              bufferActivity = Buffer_Activity.of(
-                when {
-                  it.highlights > 0                     -> Buffer_Activity.Highlight
-                  activity.hasFlag(Message_Type.Plain) ||
-                  activity.hasFlag(Message_Type.Notice) ||
-                  activity.hasFlag(Message_Type.Action) -> Buffer_Activity.NewMessage
-                  activity.isNotEmpty()                 -> Buffer_Activity.OtherActivity
-                  else                                  -> Buffer_Activity.NoActivity
-                }
-              )
+        list.map {
+          val activity = it.activity - (activities[it.info.bufferId] ?: 0)
+          it.copy(
+            description = ircFormatDeserializer?.formatString(
+              it.description.toString(), appearanceSettings.colorizeMirc
+            ) ?: it.description,
+            activity = activity,
+            bufferActivity = Buffer_Activity.of(
+              when {
+                it.highlights > 0                     -> Buffer_Activity.Highlight
+                activity.hasFlag(Message_Type.Plain) ||
+                activity.hasFlag(Message_Type.Notice) ||
+                activity.hasFlag(Message_Type.Action) -> Buffer_Activity.NewMessage
+                activity.isNotEmpty()                 -> Buffer_Activity.OtherActivity
+                else                                  -> Buffer_Activity.NoActivity
+              }
             )
-          }?.filter { (minimumActivity, props) ->
+          )
+        }.filter { props ->
             minimumActivity.toInt() <= props.bufferActivity.toInt() ||
             props.info.type.hasFlag(Buffer_Type.StatusBuffer)
-          }?.map { (_, props) ->
-            props
           }
       },
       handlerThread::post,
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt
index f3a923a63..7784cb0a9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt
@@ -110,8 +110,11 @@ class MessageListFragment : ServiceBoundFragment() {
           val session = it?.first
           val buffer = it?.second
           val bufferSyncer = session?.bufferSyncer
-          if (buffer != null && bufferSyncer != null && buffer != previous) {
-            onBufferChange(previous, buffer, messageId, bufferSyncer)
+          if (buffer != null && bufferSyncer != null) {
+            markAsRead(bufferSyncer, buffer, messageId)
+            if (buffer != previous) {
+              onBufferChange(previous, buffer, messageId, bufferSyncer)
+            }
             lastBuffer = buffer
           }
         }
@@ -147,14 +150,16 @@ class MessageListFragment : ServiceBoundFragment() {
     return view
   }
 
+  private fun markAsRead(bufferSyncer: BufferSyncer, buffer: BufferId, lastMessageId: MsgId?) {
+    bufferSyncer.requestMarkBufferAsRead(buffer)
+    if (lastMessageId != null)
+      bufferSyncer.requestSetLastSeenMsg(buffer, lastMessageId)
+  }
+
   private fun onBufferChange(previous: BufferId?, current: BufferId, lastMessageId: MsgId?,
                              bufferSyncer: BufferSyncer) {
-    if (lastMessageId != null) {
-      bufferSyncer.requestMarkBufferAsRead(current)
-      bufferSyncer.requestSetLastSeenMsg(current, lastMessageId)
-      if (previous != null) {
-        bufferSyncer.requestSetMarkerLine(previous, lastMessageId)
-      }
+    if (previous != null && lastMessageId != null) {
+      bufferSyncer.requestSetMarkerLine(previous, lastMessageId)
     }
     // Try loading messages when switching to isEmpty buffer
     if (database.message().bufferSize(current) == 0) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt
index bd37272ed..7bedb147c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt
@@ -206,7 +206,9 @@ class QuasselViewModel : ViewModel() {
     }
   }
 
-  val bufferList = session.zip(bufferViewConfig).switchMapRx { (session, config) ->
+  val bufferList: LiveData<Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>?> = session.zip(
+    bufferViewConfig
+  ).switchMapRx { (session, config) ->
     val bufferSyncer = session?.bufferSyncer
     if (bufferSyncer != null && config != null) {
       config.live_config.debounce(16, TimeUnit.MILLISECONDS).switchMap { currentConfig ->
@@ -216,108 +218,108 @@ class QuasselViewModel : ViewModel() {
               ids.mapNotNull { id ->
                 bufferSyncer.bufferInfo(id)
               }.filter {
-                currentConfig.networkId() <= 0 || currentConfig.networkId() == it.networkId
-              }.filter {
-                (currentConfig.allowedBufferTypes() and it.type).isNotEmpty() ||
-                it.type.hasFlag(Buffer_Type.StatusBuffer)
-              }.mapNotNull {
-                val network = session.networks[it.networkId]
-                if (network == null) {
-                  null
-                } else {
-                  it to network
-                }
-              }.map { (info, network) ->
-                bufferSyncer.liveActivity(info.bufferId).switchMap { activity ->
-                  bufferSyncer.liveHighlightCount(info.bufferId).map { highlights ->
-                    activity to highlights
+                  currentConfig.networkId() <= 0 || currentConfig.networkId() == it.networkId
+                }.filter {
+                  (currentConfig.allowedBufferTypes() and it.type).isNotEmpty() ||
+                  it.type.hasFlag(Buffer_Type.StatusBuffer)
+                }.mapNotNull {
+                  val network = session.networks[it.networkId]
+                  if (network == null) {
+                    null
+                  } else {
+                    it to network
                   }
-                }.switchMap { (activity, highlights) ->
-                  when (info.type.toInt()) {
-                    BufferInfo.Type.QueryBuffer.toInt()   -> {
-                      network.liveIrcUser(info.bufferName).switchMap { user ->
-                        user.live_away.switchMap { away ->
-                          user.live_realName.map { realName ->
+                }.map { (info, network) ->
+                  bufferSyncer.liveActivity(info.bufferId).switchMap { activity ->
+                    bufferSyncer.liveHighlightCount(info.bufferId).map { highlights ->
+                      activity to highlights
+                    }
+                  }.switchMap { (activity, highlights) ->
+                      when (info.type.toInt()) {
+                        BufferInfo.Type.QueryBuffer.toInt() -> {
+                          network.liveIrcUser(info.bufferName).switchMap { user ->
+                            user.live_away.switchMap { away ->
+                              user.live_realName.map { realName ->
+                                BufferListAdapter.BufferProps(
+                                  info = info,
+                                  network = network.networkInfo(),
+                                  bufferStatus = when {
+                                    user == IrcUser.NULL -> BufferListAdapter.BufferStatus.OFFLINE
+                                    away                 -> BufferListAdapter.BufferStatus.AWAY
+                                    else                 -> BufferListAdapter.BufferStatus.ONLINE
+                                  },
+                                  description = realName,
+                                  activity = activity,
+                                  highlights = highlights
+                                )
+                              }
+                            }
+                          }
+                        }
+                        BufferInfo.Type.ChannelBuffer.toInt() -> {
+                          network.liveIrcChannel(
+                            info.bufferName
+                          ).switchMap { channel ->
+                            channel.live_topic.map { topic ->
+                              BufferListAdapter.BufferProps(
+                                info = info,
+                                network = network.networkInfo(),
+                                bufferStatus = when (channel) {
+                                  IrcChannel.NULL -> BufferListAdapter.BufferStatus.OFFLINE
+                                  else            -> BufferListAdapter.BufferStatus.ONLINE
+                                },
+                                description = topic,
+                                activity = activity,
+                                highlights = highlights
+                              )
+                            }
+                          }
+                        }
+                        BufferInfo.Type.StatusBuffer.toInt() -> {
+                          network.liveConnectionState.map {
                             BufferListAdapter.BufferProps(
                               info = info,
                               network = network.networkInfo(),
-                              bufferStatus = when {
-                                user == IrcUser.NULL -> BufferListAdapter.BufferStatus.OFFLINE
-                                away                 -> BufferListAdapter.BufferStatus.AWAY
-                                else                 -> BufferListAdapter.BufferStatus.ONLINE
-                              },
-                              description = realName,
+                              bufferStatus = BufferListAdapter.BufferStatus.OFFLINE,
+                              description = "",
                               activity = activity,
-                              highlights = highlights,
-                              bufferActivity = config.minimumActivity()
+                              highlights = highlights
                             )
                           }
                         }
-                      }
-                    }
-                    BufferInfo.Type.ChannelBuffer.toInt() -> {
-                      network.liveIrcChannel(
-                        info.bufferName
-                      ).switchMap { channel ->
-                        channel.live_topic.map { topic ->
+                        else -> Observable.just(
                           BufferListAdapter.BufferProps(
                             info = info,
                             network = network.networkInfo(),
-                            bufferStatus = when (channel) {
-                              IrcChannel.NULL -> BufferListAdapter.BufferStatus.OFFLINE
-                              else            -> BufferListAdapter.BufferStatus.ONLINE
-                            },
-                            description = topic,
+                            bufferStatus = BufferListAdapter.BufferStatus.OFFLINE,
+                            description = "",
                             activity = activity,
-                            highlights = highlights,
-                            bufferActivity = config.minimumActivity()
+                            highlights = highlights
                           )
-                        }
-                      }
-                    }
-                    BufferInfo.Type.StatusBuffer.toInt()  -> {
-                      network.liveConnectionState.map {
-                        BufferListAdapter.BufferProps(
-                          info = info,
-                          network = network.networkInfo(),
-                          bufferStatus = BufferListAdapter.BufferStatus.OFFLINE,
-                          description = "",
-                          activity = activity,
-                          highlights = highlights,
-                          bufferActivity = config.minimumActivity()
                         )
                       }
                     }
-                    else                                  -> Observable.just(
-                      BufferListAdapter.BufferProps(
-                        info = info,
-                        network = network.networkInfo(),
-                        bufferStatus = BufferListAdapter.BufferStatus.OFFLINE,
-                        description = "",
-                        activity = activity,
-                        highlights = highlights,
-                        bufferActivity = config.minimumActivity()
-                      )
-                    )
-                  }
-                }
-              }, object : Function<Array<Any>, List<BufferListAdapter.BufferProps>> {
+                }, object : Function<Array<Any>, List<BufferListAdapter.BufferProps>> {
               override fun apply(objects: Array<Any>): List<BufferListAdapter.BufferProps> {
                 return objects.toList() as List<BufferListAdapter.BufferProps>
               }
             }
             ).map { list ->
-              list.filter {
-                (!config.hideInactiveBuffers()) ||
-                it.bufferStatus != BufferListAdapter.BufferStatus.OFFLINE ||
-                it.info.type.hasFlag(Buffer_Type.StatusBuffer)
-              }
+              Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>(
+                config,
+                list.filter {
+                  (!config.hideInactiveBuffers()) ||
+                  it.bufferStatus != BufferListAdapter.BufferStatus.OFFLINE ||
+                  it.info.type.hasFlag(Buffer_Type.StatusBuffer)
+                })
             }
           }
         }
       }
     } else {
-      Observable.just(emptyList())
+      Observable.just(
+        Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>(null, emptyList())
+      )
     }
   }
 }
\ No newline at end of file
-- 
GitLab