Merge pull request #5049 from nextcloud/issue-5041-jump-to-coversation

Preserve Conversation List position
This commit is contained in:
Marcel Hibbe 2025-07-16 16:46:47 +02:00 committed by GitHub
commit 1b2d419351
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 45 additions and 2 deletions

View File

@ -59,6 +59,7 @@ class ConversationItem(
IFilterable<String?> { IFilterable<String?> {
private var header: GenericTextHeaderItem? = null private var header: GenericTextHeaderItem? = null
private val chatMessage = model.lastMessage?.asModel() private val chatMessage = model.lastMessage?.asModel()
var mHolder: ConversationItemViewHolder? = null
constructor( constructor(
conversation: ConversationModel, conversation: ConversationModel,
@ -97,6 +98,7 @@ class ConversationItem(
position: Int, position: Int,
payloads: List<Any> payloads: List<Any>
) { ) {
mHolder = holder
val appContext = sharedApplication!!.applicationContext val appContext = sharedApplication!!.applicationContext
holder.binding.dialogName.setTextColor( holder.binding.dialogName.setTextColor(
ResourcesCompat.getColor( ResourcesCompat.getColor(

View File

@ -392,7 +392,6 @@ class ChatActivity :
private val onBackPressedCallback = object : OnBackPressedCallback(true) { private val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
val intent = Intent(this@ChatActivity, ConversationsListActivity::class.java) val intent = Intent(this@ChatActivity, ConversationsListActivity::class.java)
intent.putExtras(Bundle())
startActivity(intent) startActivity(intent)
} }
} }

View File

@ -345,6 +345,16 @@ class ConversationsListActivity :
showSearchOrToolbar() showSearchOrToolbar()
} }
override fun onPause() {
super.onPause()
val firstVisible = layoutManager?.findFirstVisibleItemPosition() ?: 0
val firstItem = adapter?.getItem(firstVisible)
val firstTop = (firstItem as ConversationItem).mHolder?.itemView?.top
val firstOffset = firstTop?.minus(CONVERSATION_ITEM_HEIGHT) ?: 0
appPreferences.setConversationListPositionAndOffset(firstVisible, firstOffset)
}
// if edge to edge is used, add an empty item at the bottom of the list // if edge to edge is used, add an empty item at the bottom of the list
@Suppress("MagicNumber") @Suppress("MagicNumber")
private fun addEmptyItemForEdgeToEdgeIfNecessary() { private fun addEmptyItemForEdgeToEdgeIfNecessary() {
@ -426,6 +436,9 @@ class ConversationsListActivity :
.firstOrNull { ConversationUtils.isNoteToSelfConversation(it) } .firstOrNull { ConversationUtils.isNoteToSelfConversation(it) }
val isNoteToSelfAvailable = noteToSelf != null val isNoteToSelfAvailable = noteToSelf != null
handleNoteToSelfShortcut(isNoteToSelfAvailable, noteToSelf?.token ?: "") handleNoteToSelfShortcut(isNoteToSelfAvailable, noteToSelf?.token ?: "")
val pair = appPreferences.conversationListPositionAndOffset
layoutManager?.scrollToPositionWithOffset(pair.first, pair.second)
}.collect() }.collect()
} }
@ -1873,7 +1886,6 @@ class ConversationsListActivity :
val bundle = Bundle() val bundle = Bundle()
bundle.putString(KEY_ROOM_TOKEN, selectedConversation!!.token) bundle.putString(KEY_ROOM_TOKEN, selectedConversation!!.token)
// bundle.putString(KEY_ROOM_ID, selectedConversation!!.roomId)
bundle.putString(KEY_SHARED_TEXT, textToPaste) bundle.putString(KEY_SHARED_TEXT, textToPaste)
if (selectedMessageId != null) { if (selectedMessageId != null) {
bundle.putString(BundleKeys.KEY_MESSAGE_ID, selectedMessageId) bundle.putString(BundleKeys.KEY_MESSAGE_ID, selectedMessageId)
@ -2221,5 +2233,6 @@ class ConversationsListActivity :
private const val SIXTEEN_HOURS_IN_SECONDS: Long = 57600 private const val SIXTEEN_HOURS_IN_SECONDS: Long = 57600
const val LONG_1000: Long = 1000 const val LONG_1000: Long = 1000
private const val NOTE_TO_SELF_SHORTCUT_ID = "NOTE_TO_SELF_SHORTCUT_ID" private const val NOTE_TO_SELF_SHORTCUT_ID = "NOTE_TO_SELF_SHORTCUT_ID"
private const val CONVERSATION_ITEM_HEIGHT = 44
} }
} }

View File

@ -13,6 +13,8 @@ import android.annotation.SuppressLint;
import com.nextcloud.talk.ui.PlaybackSpeed; import com.nextcloud.talk.ui.PlaybackSpeed;
import kotlin.Pair;
@SuppressLint("NonConstantResourceId") @SuppressLint("NonConstantResourceId")
public interface AppPreferences { public interface AppPreferences {
@ -181,5 +183,9 @@ public interface AppPreferences {
void setShowRegularNotificationWarning(boolean value); void setShowRegularNotificationWarning(boolean value);
void setConversationListPositionAndOffset(int position, int offset);
Pair<Integer, Integer> getConversationListPositionAndOffset();
void clear(); void clear();
} }

View File

@ -400,6 +400,28 @@ class AppPreferencesImpl(val context: Context) : AppPreferences {
} }
} }
override fun setConversationListPositionAndOffset(position: Int, offset: Int) {
runBlocking<Unit> {
async {
writeString(CONVERSATION_LIST_POSITION_OFFSET, "$position,$offset")
}
}
}
override fun getConversationListPositionAndOffset(): Pair<Int, Int> {
val pairString = runBlocking {
async { readString(CONVERSATION_LIST_POSITION_OFFSET).first() }
}.getCompleted()
if (pairString.isEmpty()) return Pair(0, 0)
val pairArr = pairString.split(',')
val position = pairArr[0].toInt()
val offset = pairArr[1].toInt()
return Pair(position, offset)
}
override fun setPhoneBookIntegrationLastRun(currentTimeMillis: Long) = override fun setPhoneBookIntegrationLastRun(currentTimeMillis: Long) =
runBlocking<Unit> { runBlocking<Unit> {
async { async {
@ -614,6 +636,7 @@ class AppPreferencesImpl(val context: Context) : AppPreferences {
const val VOICE_MESSAGE_PLAYBACK_SPEEDS = "voice_message_playback_speeds" const val VOICE_MESSAGE_PLAYBACK_SPEEDS = "voice_message_playback_speeds"
const val SHOW_REGULAR_NOTIFICATION_WARNING = "show_regular_notification_warning" const val SHOW_REGULAR_NOTIFICATION_WARNING = "show_regular_notification_warning"
const val LAST_NOTIFICATION_WARNING = "last_notification_warning" const val LAST_NOTIFICATION_WARNING = "last_notification_warning"
const val CONVERSATION_LIST_POSITION_OFFSET = "CONVERSATION_LIST_POSITION_OFFSET"
private fun String.convertStringToArray(): Array<Float> { private fun String.convertStringToArray(): Array<Float> {
var varString = this var varString = this
val floatList = mutableListOf<Float>() val floatList = mutableListOf<Float>()