From f799da78cfa7ccff00735a7d3230061a1f03bd2b Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Wed, 21 Feb 2018 18:54:33 +0100
Subject: [PATCH] Fixes several markerline bugs

---
 .../ui/chat/MessageListFragment.kt            | 133 +++++++-----------
 1 file changed, 53 insertions(+), 80 deletions(-)

diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageListFragment.kt
index 651d79a3d..34ab9c155 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageListFragment.kt
@@ -1,6 +1,5 @@
 package de.kuschku.quasseldroid_ng.ui.chat
 
-import android.arch.lifecycle.LiveData
 import android.arch.lifecycle.Observer
 import android.arch.lifecycle.ViewModelProviders
 import android.arch.paging.LivePagedListBuilder
@@ -15,8 +14,8 @@ import android.view.ViewGroup
 import butterknife.BindView
 import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.BufferId
-import de.kuschku.libquassel.session.Backend
-import de.kuschku.libquassel.session.SessionManager
+import de.kuschku.libquassel.protocol.MsgId
+import de.kuschku.libquassel.quassel.syncables.BufferSyncer
 import de.kuschku.quasseldroid_ng.R
 import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
 import de.kuschku.quasseldroid_ng.ui.viewmodel.QuasselViewModel
@@ -25,11 +24,13 @@ import de.kuschku.quasseldroid_ng.util.helper.*
 import de.kuschku.quasseldroid_ng.util.service.ServiceBoundFragment
 
 class MessageListFragment : ServiceBoundFragment() {
-  private lateinit var viewModel: QuasselViewModel
+  @BindView(R.id.messages)
+  lateinit var messageList: RecyclerView
 
-  private val sessionManager: LiveData<SessionManager?> = backend.map(Backend::sessionManager)
+  @BindView(R.id.scrollDown)
+  lateinit var scrollDown: FloatingActionButton
 
-  private var lastBuffer: BufferId? = null
+  private lateinit var viewModel: QuasselViewModel
 
   private val handler = AndroidHandlerThread("Chat")
 
@@ -38,43 +39,34 @@ class MessageListFragment : ServiceBoundFragment() {
   private lateinit var linearLayoutManager: LinearLayoutManager
   private lateinit var adapter: MessageAdapter
 
-  @BindView(R.id.messages)
-  lateinit var messageList: RecyclerView
-
-  @BindView(R.id.scrollDown)
-  lateinit var scrollDown: FloatingActionButton
+  private var lastBuffer: BufferId? = null
 
   override fun onCreate(savedInstanceState: Bundle?) {
     handler.onCreate()
     super.onCreate(savedInstanceState)
-
     viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
     setHasOptionsMenu(true)
   }
 
   private val boundaryCallback = object :
     PagedList.BoundaryCallback<QuasselDatabase.DatabaseMessage>() {
-    override fun onItemAtFrontLoaded(itemAtFront: QuasselDatabase.DatabaseMessage)
-      = Unit
-
-    override fun onItemAtEndLoaded(itemAtEnd: QuasselDatabase.DatabaseMessage)
-      = loadMore()
+    override fun onItemAtFrontLoaded(itemAtFront: QuasselDatabase.DatabaseMessage) = Unit
+    override fun onItemAtEndLoaded(itemAtEnd: QuasselDatabase.DatabaseMessage) = loadMore()
   }
 
-  override fun onCreateView(inflater: LayoutInflater,
-                            container: ViewGroup?,
+  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.fragment_messages, container, false)
     ButterKnife.bind(this, view)
 
-    adapter = MessageAdapter(context!!)
-    messageList.adapter = adapter
     linearLayoutManager = LinearLayoutManager(context)
     linearLayoutManager.reverseLayout = true
+
+    adapter = MessageAdapter(context!!)
+    messageList.adapter = adapter
     messageList.layoutManager = linearLayoutManager
     messageList.itemAnimator = null
     messageList.setItemViewCacheSize(20)
-
     messageList.addOnScrollListener(
       object : RecyclerView.OnScrollListener() {
         override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
@@ -97,27 +89,22 @@ class MessageListFragment : ServiceBoundFragment() {
           .setInitialLoadSizeHint(20)
           .setEnablePlaceholders(true)
           .build()
-      )
-        .setBoundaryCallback(boundaryCallback)
-        .build()
+      ).setBoundaryCallback(boundaryCallback).build()
     }
 
     handler.post {
-      val database = QuasselDatabase.Creator.init(this.context!!)
-      sessionManager.zip(viewModel.getBuffer(), data).observe(
+      viewModel.sessionManager.zip(viewModel.getBuffer(), data).observe(
         this, Observer {
+        val previous = lastBuffer ?: -1
+        val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
+        val messageId = adapter[firstVisibleItemPosition]?.messageId
         handler.post {
           val session = it?.first
           val buffer = it?.second
           val bufferSyncer = session?.bufferSyncer
-
-          if (buffer != null && bufferSyncer != null) {
-            val lastMessage = database.message().findLastByBufferId(buffer)
-
-            if (lastMessage != null) {
-              bufferSyncer.requestMarkBufferAsRead(buffer)
-              bufferSyncer.requestSetLastSeenMsg(buffer, lastMessage.messageId)
-            }
+          if (buffer != null && bufferSyncer != null && buffer != previous) {
+            onBufferChange(previous, buffer, messageId, bufferSyncer)
+            lastBuffer = buffer
           }
         }
       }
@@ -131,76 +118,62 @@ class MessageListFragment : ServiceBoundFragment() {
     }
     )
 
+    var lastBuffer = -1
     data.observe(
       this, Observer { list ->
       val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
+      val buffer = viewModel.getBuffer().value ?: -1
+      if (buffer != lastBuffer) {
+        lastBuffer = buffer
+        adapter.clearCache()
+      }
       adapter.setList(list)
       if (firstVisibleItemPosition < 2) {
-        activity?.runOnUiThread {
-          messageList.scrollToPosition(0)
-        }
-        handler.postDelayed(
-          {
-            activity?.runOnUiThread {
-              messageList.scrollToPosition(0)
-            }
-          }, 16
-        )
+        activity?.runOnUiThread { messageList.scrollToPosition(0) }
+        handler.postDelayed({ activity?.runOnUiThread { messageList.scrollToPosition(0) } }, 16)
       }
     }
     )
+    scrollDown.hide()
+    scrollDown.setOnClickListener { messageList.scrollToPosition(0) }
+    return view
+  }
 
-    viewModel.getBuffer().observe(
-      this, Observer {
-      val previous = lastBuffer
-      val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
-      val messageId = adapter[firstVisibleItemPosition]?.messageId
-
-      handler.post {
-        val bufferSyncer = sessionManager.value?.bufferSyncer
-        if (previous != null && messageId != null)
-          bufferSyncer?.requestSetMarkerLine(previous, messageId)
-
-        // Try loading messages when switching to isEmpty buffer
-        if (it != null) {
-          if (database.message().bufferSize(it) == 0) {
-            loadMore()
-          }
-          activity?.runOnUiThread {
-            messageList.scrollToPosition(0)
-          }
-
-          lastBuffer = it
-        }
+  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)
       }
     }
-    )
-
-    scrollDown.hide()
-    scrollDown.setOnClickListener {
-      messageList.scrollToPosition(0)
+    // Try loading messages when switching to isEmpty buffer
+    if (database.message().bufferSize(current) == 0) {
+      loadMore()
     }
-
-    return view
+    activity?.runOnUiThread { messageList.scrollToPosition(0) }
   }
 
   override fun onPause() {
     val previous = lastBuffer
     val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
     val messageId = adapter[firstVisibleItemPosition]?.messageId
-    val bufferSyncer = sessionManager.value?.bufferSyncer
-    if (previous != null && messageId != null)
+    val bufferSyncer = viewModel.sessionManager.value?.bufferSyncer
+    if (previous != null && messageId != null) {
       bufferSyncer?.requestSetMarkerLine(previous, messageId)
-
+    }
     super.onPause()
   }
 
   private fun loadMore() {
     handler.post {
       viewModel.getBuffer().let { bufferId ->
-        backend()?.sessionManager()?.backlogManager?.requestBacklog(
+        viewModel.sessionManager()?.backlogManager?.requestBacklog(
           bufferId = bufferId,
-          last = database.message().findFirstByBufferId(bufferId)?.messageId ?: -1,
+          last = database.message().findFirstByBufferId(
+            bufferId
+          )?.messageId ?: -1,
           limit = 20
         )
       }
@@ -211,4 +184,4 @@ class MessageListFragment : ServiceBoundFragment() {
     handler.onDestroy()
     super.onDestroy()
   }
-}
+}
\ No newline at end of file
-- 
GitLab