From e98ccdc58042c40d7b567ddd4b07a646bb6b5f96 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 Jan 2024 13:45:03 +0100 Subject: [PATCH] Improved how chat room mark as read is handled --- .../NotificationBroadcastReceiver.kt | 9 +++---- .../notifications/NotificationsManager.kt | 4 ++-- .../chat/fragment/ConversationFragment.kt | 24 ++++++++++++------- .../chat/viewmodel/ConversationViewModel.kt | 21 ++++++++++++++-- .../res/layout/assistant_login_fragment.xml | 1 + 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt index e2661351e..c353ecb88 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt @@ -97,7 +97,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { val remoteAddress = core.interpretUrl(remoteSipAddress, false) if (remoteAddress == null) { Log.e( - "$TAG Couldn't interpret remote address $remoteSipAddress" + "$TAG Couldn't interpret remote address [$remoteSipAddress]" ) return@postOnCoreThread } @@ -105,7 +105,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { val localAddress = core.interpretUrl(localIdentity, false) if (localAddress == null) { Log.e( - "$TAG Couldn't interpret local address $localIdentity" + "$TAG Couldn't interpret local address [$localIdentity]" ) return@postOnCoreThread } @@ -113,7 +113,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { val room = core.searchChatRoom(null, localAddress, remoteAddress, arrayOfNulls(0)) if (room == null) { Log.e( - "$TAG Couldn't find conversation for remote address $remoteSipAddress and local address $localIdentity" + "$TAG Couldn't find conversation for remote address [$remoteSipAddress] and local address [$localIdentity]" ) return@postOnCoreThread } @@ -123,8 +123,9 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { msg.userData = notificationId msg.addListener(coreContext.notificationsManager.chatListener) msg.send() - Log.i("$TAG Reply sent for notif id $notificationId") + Log.i("$TAG Reply sent for notif id [$notificationId]") } else if (intent.action == NotificationsManager.INTENT_MARK_MESSAGE_AS_READ_NOTIF_ACTION) { + Log.i("$TAG Marking chat room from notification id [$notificationId] as read") room.markAsRead() if (!coreContext.notificationsManager.dismissChatNotification(room)) { Log.w( diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 4a415e5be..099c873cb 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -335,7 +335,7 @@ class NotificationsManager @MainThread constructor(private val context: Context) } } - @AnyThread + @WorkerThread fun setCurrentlyDisplayedChatRoomId(id: String) { Log.i( "$TAG Currently displayed conversation is [$id], messages received in it won't be notified" @@ -343,7 +343,7 @@ class NotificationsManager @MainThread constructor(private val context: Context) currentlyDisplayedChatRoomId = id } - @AnyThread + @WorkerThread fun resetCurrentlyDisplayedChatRoomId() { currentlyDisplayedChatRoomId = "" Log.i("$TAG Reset currently displayed conversation") diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt index 65bc8ecee..ca232e6a8 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt @@ -84,7 +84,6 @@ import org.linphone.ui.main.chat.viewmodel.SendMessageInConversationViewModel import org.linphone.ui.main.fragment.SlidingPaneChildFragment import org.linphone.utils.Event import org.linphone.utils.FileUtils -import org.linphone.utils.LinphoneUtils import org.linphone.utils.RecyclerViewSwipeUtils import org.linphone.utils.RecyclerViewSwipeUtilsCallback import org.linphone.utils.TimestampUtils @@ -178,6 +177,13 @@ class ConversationFragment : SlidingPaneChildFragment() { private val dataObserver = object : AdapterDataObserver() { override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { + if (viewModel.isUserScrollingUp.value == true) { + Log.i( + "$TAG [$itemCount] events have been loaded but user was scrolling up in conversation, do not scroll" + ) + return + } + if (positionStart == 0 && adapter.itemCount == itemCount) { // First time we fill the list with messages Log.i( @@ -616,7 +622,13 @@ class ConversationFragment : SlidingPaneChildFragment() { binding.eventsList.addOnScrollListener(object : OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { val layoutManager = binding.eventsList.layoutManager as LinearLayoutManager - viewModel.isUserScrollingUp.value = layoutManager.findLastCompletelyVisibleItemPosition() != adapter.itemCount - 1 + val scrollingUp = layoutManager.findLastCompletelyVisibleItemPosition() != adapter.itemCount - 1 + viewModel.isUserScrollingUp.value = scrollingUp + + if (!scrollingUp) { + Log.i("$TAG Last message is visible, considering conversation as read") + viewModel.markAsRead() + } } }) } @@ -624,11 +636,7 @@ class ConversationFragment : SlidingPaneChildFragment() { override fun onResume() { super.onResume() - val id = LinphoneUtils.getChatRoomId(args.localSipUri, args.remoteSipUri) - Log.i( - "$TAG Asking notifications manager not to notify messages for conversation [$id]" - ) - coreContext.notificationsManager.setCurrentlyDisplayedChatRoomId(id) + viewModel.updateCurrentlyDisplayedConversation() if (viewModel.scrollingPosition != SCROLLING_POSITION_NOT_SET) { binding.eventsList.scrollToPosition(viewModel.scrollingPosition) @@ -650,6 +658,7 @@ class ConversationFragment : SlidingPaneChildFragment() { coreContext.postOnCoreThread { bottomSheetReactionsModel?.destroy() bottomSheetDeliveryModel?.destroy() + coreContext.notificationsManager.resetCurrentlyDisplayedChatRoomId() } if (viewModel.isGroup.value == true) { @@ -661,7 +670,6 @@ class ConversationFragment : SlidingPaneChildFragment() { } catch (e: IllegalStateException) { Log.e("$TAG Failed to unregister data observer to adapter: $e") } - coreContext.notificationsManager.resetCurrentlyDisplayedChatRoomId() val layoutManager = binding.eventsList.layoutManager as LinearLayoutManager viewModel.scrollingPosition = layoutManager.findFirstCompletelyVisibleItemPosition() diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt index bd011a2cb..b346f54ce 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt @@ -116,7 +116,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { @WorkerThread override fun onChatMessageSending(chatRoom: ChatRoom, eventLog: EventLog) { val message = eventLog.chatMessage - Log.i("$TAG Message [$message] is being sent") + Log.i("$TAG Message [$message] is being sent, marking conversation as read") // Prevents auto scroll to go to latest received message chatRoom.markAsRead() @@ -183,7 +183,6 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { list.addAll(newList) events.postValue(list) - chatRoom.markAsRead() } @WorkerThread @@ -398,6 +397,23 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { } } + @UiThread + fun markAsRead() { + coreContext.postOnCoreThread { + Log.i("$TAG Marking chat room as read") + chatRoom.markAsRead() + } + } + + @UiThread + fun updateCurrentlyDisplayedConversation() { + coreContext.postOnCoreThread { + val id = LinphoneUtils.getChatRoomId(chatRoom) + Log.i("$TAG Asking notifications manager not to notify messages for conversation [$id]") + coreContext.notificationsManager.setCurrentlyDisplayedChatRoomId(id) + } + } + @WorkerThread private fun configureChatRoom() { scrollingPosition = SCROLLING_POSITION_NOT_SET @@ -414,6 +430,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { computeEvents() chatRoom.markAsRead() + Log.i("$TAG Conversation was marked as read") } @WorkerThread diff --git a/app/src/main/res/layout/assistant_login_fragment.xml b/app/src/main/res/layout/assistant_login_fragment.xml index a61971bf0..70526579d 100644 --- a/app/src/main/res/layout/assistant_login_fragment.xml +++ b/app/src/main/res/layout/assistant_login_fragment.xml @@ -234,6 +234,7 @@ android:paddingStart="20dp" android:paddingEnd="20dp" android:text="@string/assistant_login_using_single_sign_on" + android:visibility="gone" app:layout_constraintWidth_max="@dimen/button_max_width" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"