From 2a06904d76a7e0a3531fceab9ed5fed312fb9636 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Fri, 25 Jun 2021 09:38:26 +1000 Subject: [PATCH] Scroll to first unread message upon opening a conversation --- .../conversation/v2/ConversationActivityV2.kt | 7 +++++++ .../conversation/v2/ConversationAdapter.kt | 15 +++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 7ee907dc3b..4a72070c6d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -125,6 +125,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe getLatestOpenGroupInfoIfNeeded() setUpBlockedBanner() setUpLinkPreviewObserver() + scrollToFirstUnreadMessage() } private fun setUpRecyclerView() { @@ -237,6 +238,12 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe }) } + private fun scrollToFirstUnreadMessage() { + val lastSeenTimestamp = DatabaseFactory.getThreadDatabase(this).getLastSeenAndHasSent(threadID).first() + val lastSeenItemPosition = adapter.findLastSeenItemPosition(lastSeenTimestamp) ?: return + conversationRecyclerView.scrollToPosition(lastSeenItemPosition) + } + override fun onPrepareOptionsMenu(menu: Menu): Boolean { ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) } super.onPrepareOptionsMenu(menu) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt index 04723aa87a..63306b0c4f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt @@ -2,20 +2,16 @@ package org.thoughtcrime.securesms.conversation.v2 import android.content.Context import android.database.Cursor -import android.graphics.drawable.ColorDrawable import android.view.ViewGroup import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView.ViewHolder import kotlinx.android.synthetic.main.view_visible_message.view.* -import network.loki.messenger.R import org.thoughtcrime.securesms.conversation.v2.messages.ControlMessageView import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageView import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.MessageRecord -import org.thoughtcrime.securesms.loki.utilities.getColorWithID import org.thoughtcrime.securesms.mms.GlideRequests -import java.lang.IllegalStateException class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPress: (MessageRecord, Int, VisibleMessageView) -> Unit, private val onItemSwipeToReply: (MessageRecord, Int) -> Unit, private val onItemLongPress: (MessageRecord, Int) -> Unit, @@ -110,4 +106,15 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPr if (selectedItems.contains(message)) selectedItems.remove(message) else selectedItems.add(message) notifyItemChanged(position) } + + fun findLastSeenItemPosition(lastSeenTimestamp: Long): Int? { + val cursor = this.cursor + if (lastSeenTimestamp <= 0L || cursor == null || !isActiveCursor) return null + for (i in 0 until itemCount) { + cursor.moveToPosition(i) + val messageRecord = messageDB.readerFor(cursor).current + if (messageRecord.isOutgoing || messageRecord.dateReceived <= lastSeenTimestamp) { return i } + } + return null + } } \ No newline at end of file