fix: fetch older messages as needed before jumping to searched message (#557)
Refs: https://github.com/FossifyOrg/Messages/issues/350
This commit is contained in:
parent
3303fc7c07
commit
93a2907fce
5 changed files with 149 additions and 117 deletions
|
|
@ -216,7 +216,7 @@ class ThreadActivity : SimpleActivity() {
|
|||
private var capturedImageUri: Uri? = null
|
||||
private var loadingOlderMessages = false
|
||||
private var allMessagesFetched = false
|
||||
private var oldestMessageDate = -1
|
||||
private var isJumpingToMessage = false
|
||||
private var isRecycleBin = false
|
||||
private var isLaunchedFromShortcut = false
|
||||
|
||||
|
|
@ -463,7 +463,7 @@ class ThreadActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun setupThread() {
|
||||
private fun setupThread(callback: () -> Unit) {
|
||||
if (conversation == null && isLaunchedFromShortcut) {
|
||||
if (isTaskRoot) {
|
||||
Intent(this, MainActivity::class.java).apply {
|
||||
|
|
@ -494,6 +494,7 @@ class ThreadActivity : SimpleActivity() {
|
|||
try {
|
||||
if (participants.isNotEmpty() && messages.hashCode() == cachedMessagesCode && !hasParticipantWithoutName) {
|
||||
setupAdapter()
|
||||
runOnUiThread { callback() }
|
||||
return@ensureBackgroundThread
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
|
|
@ -553,6 +554,7 @@ class ThreadActivity : SimpleActivity() {
|
|||
runOnUiThread {
|
||||
setupThreadTitle()
|
||||
setupSIMSelector()
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -717,7 +719,44 @@ class ThreadActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun jumpToMessage(messageId: Long) {
|
||||
if (messages.any { it.id == messageId }) {
|
||||
val index = threadItems.indexOfFirst { (it as? Message)?.id == messageId }
|
||||
if (index != -1) binding.threadMessagesList.smoothScrollToPosition(index)
|
||||
return
|
||||
}
|
||||
|
||||
ensureBackgroundThread {
|
||||
if (loadingOlderMessages) return@ensureBackgroundThread
|
||||
loadingOlderMessages = true
|
||||
isJumpingToMessage = true
|
||||
|
||||
var cutoff = messages.firstOrNull()?.date ?: Int.MAX_VALUE
|
||||
var found = false
|
||||
var loops = 0
|
||||
|
||||
// not the best solution, but this will do for now.
|
||||
while (!found && !allMessagesFetched) {
|
||||
if (fetchOlderMessages(cutoff).isEmpty() || loops >= 1000) break
|
||||
cutoff = messages.first().date
|
||||
found = messages.any { it.id == messageId }
|
||||
loops++
|
||||
}
|
||||
|
||||
threadItems = getThreadItems()
|
||||
runOnUiThread {
|
||||
loadingOlderMessages = false
|
||||
val index = threadItems.indexOfFirst { (it as? Message)?.id == messageId }
|
||||
getOrCreateThreadAdapter().updateMessages(
|
||||
newMessages = threadItems, scrollPosition = index, smoothScroll = true
|
||||
)
|
||||
isJumpingToMessage = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryLoadMoreMessages() {
|
||||
if (isJumpingToMessage) return
|
||||
val layoutManager = binding.threadMessagesList.layoutManager as LinearLayoutManager
|
||||
if (layoutManager.findFirstVisibleItemPosition() <= PREFETCH_THRESHOLD) {
|
||||
loadMoreMessages()
|
||||
|
|
@ -726,21 +765,11 @@ class ThreadActivity : SimpleActivity() {
|
|||
|
||||
private fun loadMoreMessages() {
|
||||
if (messages.isEmpty() || allMessagesFetched || loadingOlderMessages) return
|
||||
|
||||
val firstItem = messages.first()
|
||||
val dateOfFirstItem = firstItem.date
|
||||
|
||||
oldestMessageDate = dateOfFirstItem
|
||||
loadingOlderMessages = true
|
||||
|
||||
val cutoff = messages.first().date
|
||||
ensureBackgroundThread {
|
||||
val olderMessages = getMessages(threadId, oldestMessageDate)
|
||||
.filterNotInByKey(messages) { it.getStableId() }
|
||||
|
||||
messages.addAll(0, olderMessages)
|
||||
allMessagesFetched = olderMessages.isEmpty()
|
||||
fetchOlderMessages(cutoff)
|
||||
threadItems = getThreadItems()
|
||||
|
||||
runOnUiThread {
|
||||
loadingOlderMessages = false
|
||||
getOrCreateThreadAdapter().updateMessages(threadItems)
|
||||
|
|
@ -748,23 +777,32 @@ class ThreadActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun fetchOlderMessages(cutoff: Int): List<Message> {
|
||||
val older = getMessages(threadId, cutoff)
|
||||
.filterNotInByKey(messages) { it.getStableId() }
|
||||
|
||||
if (older.isEmpty()) {
|
||||
allMessagesFetched = true
|
||||
return older
|
||||
}
|
||||
|
||||
messages.addAll(0, older)
|
||||
return older
|
||||
}
|
||||
|
||||
private fun loadConversation() {
|
||||
handlePermission(PERMISSION_READ_PHONE_STATE) { granted ->
|
||||
if (granted) {
|
||||
setupButtons()
|
||||
setupConversation()
|
||||
setupCachedMessages {
|
||||
val searchedMessageId = intent.getLongExtra(SEARCHED_MESSAGE_ID, -1L)
|
||||
intent.removeExtra(SEARCHED_MESSAGE_ID)
|
||||
if (searchedMessageId != -1L) {
|
||||
val index =
|
||||
threadItems.indexOfFirst { (it as? Message)?.id == searchedMessageId }
|
||||
if (index != -1) {
|
||||
binding.threadMessagesList.smoothScrollToPosition(index)
|
||||
setupThread {
|
||||
val searchedMessageId = intent.getLongExtra(SEARCHED_MESSAGE_ID, -1L)
|
||||
intent.removeExtra(SEARCHED_MESSAGE_ID)
|
||||
if (searchedMessageId != -1L) {
|
||||
jumpToMessage(searchedMessageId)
|
||||
}
|
||||
}
|
||||
|
||||
setupThread()
|
||||
setupScrollListener()
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1712,14 +1750,13 @@ class ThreadActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.ASYNC)
|
||||
fun refreshMessages(event: Events.RefreshMessages) {
|
||||
fun refreshMessages(@Suppress("unused") event: Events.RefreshMessages) {
|
||||
if (isRecycleBin) {
|
||||
return
|
||||
}
|
||||
|
||||
refreshedSinceSent = true
|
||||
allMessagesFetched = false
|
||||
oldestMessageDate = -1
|
||||
|
||||
if (isActivityVisible) {
|
||||
notificationManager.cancel(threadId.hashCode())
|
||||
|
|
|
|||
|
|
@ -328,11 +328,19 @@ class ThreadAdapter(
|
|||
|
||||
private fun isThreadDateTime(position: Int) = currentList.getOrNull(position) is ThreadDateTime
|
||||
|
||||
fun updateMessages(newMessages: ArrayList<ThreadItem>, scrollPosition: Int = -1) {
|
||||
fun updateMessages(
|
||||
newMessages: ArrayList<ThreadItem>,
|
||||
scrollPosition: Int = -1,
|
||||
smoothScroll: Boolean = false
|
||||
) {
|
||||
val latestMessages = newMessages.toMutableList()
|
||||
submitList(latestMessages) {
|
||||
if (scrollPosition != -1) {
|
||||
recyclerView.scrollToPosition(scrollPosition)
|
||||
if (smoothScroll) {
|
||||
recyclerView.smoothScrollToPosition(scrollPosition)
|
||||
} else {
|
||||
recyclerView.scrollToPosition(scrollPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue