Fixed scrolling up to original message from reply when it's not in the currently loaded history + hide keyboard when displaying message long press menu

This commit is contained in:
Sylvain Berfini 2024-08-13 16:27:12 +02:00
parent 2021c5e102
commit a855c569fb
2 changed files with 67 additions and 33 deletions

View file

@ -216,7 +216,12 @@ open class ConversationFragment : SlidingPaneChildFragment() {
} else if (adapter.itemCount != itemCount) {
if (viewModel.searchInProgress.value == true) {
val recyclerView = binding.eventsList
recyclerView.scrollToPosition(viewModel.itemToScrollTo.value ?: 0)
var indexToScrollTo = viewModel.itemToScrollTo.value ?: 0
if (indexToScrollTo < 0) indexToScrollTo = 0
Log.i(
"$TAG User has loaded more history to go to a specific message, scrolling to index [$indexToScrollTo]"
)
recyclerView.scrollToPosition(indexToScrollTo)
viewModel.searchInProgress.postValue(false)
}
}
@ -516,18 +521,21 @@ open class ConversationFragment : SlidingPaneChildFragment() {
val repliedMessageId = model.replyToMessageId
if (repliedMessageId.isNullOrEmpty()) {
Log.w("$TAG Message [${model.id}] doesn't have a reply to ID!")
return@consume
}
val originalMessage = adapter.currentList.find { eventLog ->
!eventLog.isEvent && (eventLog.model as MessageModel).id == repliedMessageId
}
if (originalMessage != null) {
val position = adapter.currentList.indexOf(originalMessage)
Log.i("$TAG Scrolling to position [$position]")
binding.eventsList.scrollToPosition(position)
} else {
val originalMessage = adapter.currentList.find { eventLog ->
!eventLog.isEvent && (eventLog.model as MessageModel).id == repliedMessageId
}
if (originalMessage != null) {
val position = adapter.currentList.indexOf(originalMessage)
Log.i("$TAG Scrolling to position [$position]")
binding.eventsList.scrollToPosition(position)
} else {
Log.w("$TAG Failed to find matching message in adapter's items!")
// TODO FIXME: load original message & messages in between, then scroll to it
}
Log.w(
"$TAG Failed to find message with ID [$repliedMessageId] in already loaded history, loading missing items"
)
viewModel.loadDataUpUntilToMessageId(model.replyToMessageId)
}
}
}
@ -1096,6 +1104,7 @@ open class ConversationFragment : SlidingPaneChildFragment() {
@UiThread
private fun showChatMessageLongPressMenu(chatMessageModel: MessageModel) {
binding.sendArea.messageToSend.hideKeyboard()
Compatibility.setBlurRenderEffect(binding.coordinatorLayout)
messageLongPressViewModel.setMessage(chatMessageModel)
chatMessageModel.dismissLongPressMenuEvent.observe(viewLifecycleOwner) {

View file

@ -560,6 +560,25 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
}
}
@UiThread
fun loadDataUpUntilToMessageId(messageId: String?) {
messageId ?: return
coreContext.postOnCoreThread {
searchInProgress.postValue(true)
val eventLog = chatRoom.findEventLog(messageId)
if (eventLog != null) {
Log.i("$TAG Found event log [$eventLog] with message ID [$messageId]")
loadMessagesUpTo(eventLog)
} else {
Log.e(
"$TAG Failed to find event log with message ID [$messageId] in chat room history!"
)
searchInProgress.postValue(false)
}
}
}
@WorkerThread
private fun configureChatRoom() {
scrollingPosition = SCROLLING_POSITION_NOT_SET
@ -872,6 +891,30 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
}
}
@WorkerThread
private fun loadMessagesUpTo(targetEvent: EventLog) {
val historyToAdd = chatRoom.getHistoryRangeBetween(
targetEvent,
eventsList[0].eventLog,
HistoryFilter.None.toInt()
)
Log.i(
"$TAG Loaded [${historyToAdd.size}] items from history to go to event log [$targetEvent]"
)
Log.i("$TAG Loading [$ITEMS_TO_LOAD_BEFORE_SEARCH_RESULT] items before the target")
val previousMessages = chatRoom.getHistoryRangeNear(
ITEMS_TO_LOAD_BEFORE_SEARCH_RESULT,
0,
targetEvent,
HistoryFilter.None.toInt()
)
itemToScrollTo.postValue(previousMessages.size - 2) // To go to the item before the target event
val toAdd = previousMessages.plus(historyToAdd)
prependEvents(toAdd)
}
@WorkerThread
private fun searchChatMessage(direction: SearchDirection) {
searchInProgress.postValue(true)
@ -904,26 +947,7 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
}
if (found == null) {
Log.i("$TAG Found result isn't in currently loaded history, loading missing events")
val historyToAdd = chatRoom.getHistoryRangeBetween(
latestMatch,
eventsList[0].eventLog,
HistoryFilter.None.toInt()
)
Log.i("$TAG Loaded [${historyToAdd.size}] items from history")
Log.i(
"$TAG Also loading [$ITEMS_TO_LOAD_BEFORE_SEARCH_RESULT] items before the match"
)
val previousMessages = chatRoom.getHistoryRangeNear(
ITEMS_TO_LOAD_BEFORE_SEARCH_RESULT,
0,
match,
HistoryFilter.None.toInt()
)
itemToScrollTo.postValue(previousMessages.size - 1)
val toAdd = previousMessages.plus(historyToAdd)
prependEvents(toAdd)
loadMessagesUpTo(match)
} else {
Log.i("$TAG Found result is already in history, no need to load more history")
(found.model as? MessageModel)?.highlightText(textToSearch)
@ -932,7 +956,8 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
// Go to next message to prevent the message we are looking for to be behind the scroll to bottom button
itemToScrollTo.postValue(index + 1)
} else {
itemToScrollTo.postValue(index)
// Go to previous message so target message won't be displayed stuck to the top
itemToScrollTo.postValue(index - 1)
}
searchInProgress.postValue(false)
}