diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowRoom.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowRoom.kt index 1e239069ad..826f584f6a 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowRoom.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowRoom.kt @@ -109,9 +109,9 @@ class FlowRoom(private val room: Room) { } fun liveLocalUnreadThreadList(): Flow> { - return room.getNumberOfLocalThreadNotificationsLive().asFlow() + return room.getMarkedThreadNotificationsLive().asFlow() .startWith(room.coroutineDispatchers.io) { - room.getNumberOfLocalThreadNotifications() + room.getMarkedThreadNotifications() } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/threads/ThreadsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/threads/ThreadsService.kt index 34a50a8951..e4d1d979e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/threads/ThreadsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/threads/ThreadsService.kt @@ -20,33 +20,30 @@ import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent /** - * This interface defines methods to interact with threads related features. It's implemented at the room level within the main timeline. + * This interface defines methods to interact with threads related features. + * It's implemented at the room level within the main timeline. */ interface ThreadsService { /** - * Get a live list of all the TimelineEvents which have thread replies for the specified roomId - * @return the [LiveData] of [TimelineEvent] + * Returns a [LiveData] list of all the thread root TimelineEvents that exists at the room level */ fun getAllThreadsLive(): LiveData> /** - * Get a list of all the TimelineEvents which have thread replies for the specified roomId - * @return the [LiveData] of [TimelineEvent] + * Returns a list of all the thread root TimelineEvents that exists at the room level */ fun getAllThreads(): List /** - * Get a live list of all the local unread threads for the specified roomId - * @return the [LiveData] of [TimelineEvent] + * Returns a [LiveData] list of all the marked unread threads that exists at the room level */ - fun getNumberOfLocalThreadNotificationsLive(): LiveData> + fun getMarkedThreadNotificationsLive(): LiveData> /** - * Get a list of all the local unread threads for the specified roomId - * @return the [LiveData] of [TimelineEvent] + * Returns a list of all the marked unread threads that exists at the room level */ - fun getNumberOfLocalThreadNotifications(): List + fun getMarkedThreadNotifications(): List /** * Returns whether or not the current user is participating in the thread @@ -55,14 +52,16 @@ interface ThreadsService { fun isUserParticipatingInThread(rootThreadEventId: String): Boolean /** - * Enhance the thread list with the edited events if needed - * @return the [LiveData] of [TimelineEvent] + * Enhance the provided root thread TimelineEvent [List] by adding the latest + * message edition for that thread + * @return the enhanced [List] with edited updates */ fun mapEventsWithEdition(threads: List): List /** - * Marks the current thread as read. This is a local implementation - * @param rootThreadEventId the eventId of the current thread + * Marks the current thread as read in local DB. + * note: read receipts within threads are not yet supported with the API + * @param rootThreadEventId the root eventId of the current thread */ suspend fun markThreadAsRead(rootThreadEventId: String) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt index afc090604a..f703bfaf82 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt @@ -159,7 +159,7 @@ internal fun TimelineEventEntity.Companion.findAllThreadsForRoomId(realm: Realm, .sort("${TimelineEventEntityFields.ROOT.THREAD_SUMMARY_LATEST_MESSAGE}.${TimelineEventEntityFields.ROOT.ORIGIN_SERVER_TS}", Sort.DESCENDING) /** - * Map each timelineEvent with the equivalent decrypted text edition/replacement for root threads + * Map each root thread TimelineEvent with the equivalent decrypted text edition/replacement */ internal fun List.mapEventsWithEdition(realm: Realm, roomId: String): List = this.map { @@ -180,8 +180,8 @@ internal fun List.mapEventsWithEdition(realm: Realm, roomId: Stri } /** - * Find the number of all the local notifications for the specified room - * @param roomId The room that the number of notifications will be returned + * Returns a list of all the marked unread threads that exists for the specified room + * @param roomId The roomId that the user is currently in */ internal fun TimelineEventEntity.Companion.findAllLocalThreadNotificationsForRoomId(realm: Realm, roomId: String): RealmQuery = TimelineEventEntity diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt index e6fe5e6a8b..5967ae8d2e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt @@ -49,14 +49,14 @@ internal class DefaultThreadsService @AssistedInject constructor( fun create(roomId: String): DefaultThreadsService } - override fun getNumberOfLocalThreadNotificationsLive(): LiveData> { + override fun getMarkedThreadNotificationsLive(): LiveData> { return monarchy.findAllMappedWithChanges( { TimelineEventEntity.findAllLocalThreadNotificationsForRoomId(it, roomId = roomId) }, { timelineEventMapper.map(it) } ) } - override fun getNumberOfLocalThreadNotifications(): List { + override fun getMarkedThreadNotifications(): List { return monarchy.fetchAllMappedSync( { TimelineEventEntity.findAllLocalThreadNotificationsForRoomId(it, roomId = roomId) }, { timelineEventMapper.map(it) } diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index 81ac0b3c72..b8bef506b1 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -417,14 +417,13 @@ class CommandParser @Inject constructor() { * @return The command that is not supported */ private fun getNotSupportedByThreads(isInThreadTimeline: Boolean, slashCommand: String): Command? { - if (isInThreadTimeline) { + return if (isInThreadTimeline) { notSupportedThreadsCommands.firstOrNull { it.command == slashCommand - }?.let { - return it } + } else { + null } - return null } private fun trimParts(message: CharSequence, messageParts: List): String? { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index afbe641c93..1deed976bb 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1924,17 +1924,16 @@ class TimelineFragment @Inject constructor( timelineViewModel.handle(action) } is EncryptedEventContent -> { - if (isRootThreadEvent) { - onThreadSummaryClicked(informationData.eventId, isRootThreadEvent) - } else { timelineViewModel.handle(RoomDetailAction.TapOnFailedToDecrypt(informationData.eventId)) - } } is MessageLocationContent -> { handleShowLocationPreview(messageContent, informationData.senderId) } else -> { - onThreadSummaryClicked(informationData.eventId, isRootThreadEvent) + val handled = onThreadSummaryClicked(informationData.eventId, isRootThreadEvent) + if (!handled) { + Timber.d("No click action defined for this message content") + } } } } @@ -1966,9 +1965,12 @@ class TimelineFragment @Inject constructor( } } - override fun onThreadSummaryClicked(eventId: String, isRootThreadEvent: Boolean) { - if (vectorPreferences.areThreadMessagesEnabled() && isRootThreadEvent && !isThreadTimeLine()) { + override fun onThreadSummaryClicked(eventId: String, isRootThreadEvent: Boolean): Boolean { + return if (vectorPreferences.areThreadMessagesEnabled() && isRootThreadEvent && !isThreadTimeLine()) { navigateToThreadTimeline(eventId) + true + } else { + false } } @@ -2361,7 +2363,7 @@ class TimelineFragment @Inject constructor( } } -// VectorInviteView.Callback + // VectorInviteView.Callback override fun onAcceptInvite() { notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) } timelineViewModel.handle(RoomDetailAction.AcceptInvite) @@ -2381,7 +2383,7 @@ class TimelineFragment @Inject constructor( } } -// AttachmentTypeSelectorView.Callback + // AttachmentTypeSelectorView.Callback private val typeSelectedActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> if (allGranted) { val pendingType = attachmentsHelper.pendingType @@ -2431,7 +2433,7 @@ class TimelineFragment @Inject constructor( }.exhaustive } -// AttachmentsHelper.Callback + // AttachmentsHelper.Callback override fun onContentAttachmentsReady(attachments: List) { val grouped = attachments.toGroupedContentAttachmentData() if (grouped.notPreviewables.isNotEmpty()) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index 8851f187e0..eaa2ae9453 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -156,7 +156,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec } interface ThreadCallback { - fun onThreadSummaryClicked(eventId: String, isRootThreadEvent: Boolean) + fun onThreadSummaryClicked(eventId: String, isRootThreadEvent: Boolean) : Boolean } interface ReadReceiptsCallback {