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 651d79a3db1f5e8b7f0f12fd02706faf8540a541..34ab9c155d4cc767bb33aa2634fa108598956297 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