Split notifications for messages in threads (#5595)

* Separate thread notifications into their own notifications when the feature flag is enabled.

Otherwise, set the `threadId` to null so it'll behave as usual. It's done this way to avoid having to inject `FeatureFlagService` in several places.

* Add permalink navigation to threads from notifications, focusing on the latest event in the list of messages of the notification tapped

* Fix redactions in threads

* Clear notifications for a thread when visiting it

* Fix opening a thread happening twice, first because of the `openThreadId` value, then because of the `focusedEventId` one

* Make opening a room through a notification also focus on the latest event

* Add helper `NotificationCreator.messageTag` function

* Remove unused `ROOM_CALL_NOTIFICATION_ID`: `FOREGROUND_SERVICE_NOTIFICATION_ID`+ `ForegroundServiceType` is used instead

* Simplify `DefaultDeepLinkCreator`

* Make sure the main timeline focuses on the thread root id too when navigating to a thread

* Handle "Mark as read" action for thread notification, using `timeline.markAsRead`

* Log failures to mark rooms as read using the notification action

---------

Co-authored-by: Benoit Marty <benoit@matrix.org>
This commit is contained in:
Jorge Martin Espinosa 2025-10-30 16:15:00 +01:00 committed by GitHub
parent e8b7db22cd
commit 7facc40771
55 changed files with 702 additions and 284 deletions

View file

@ -15,6 +15,7 @@ import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import kotlinx.parcelize.Parcelize
@ -22,7 +23,9 @@ import kotlinx.parcelize.Parcelize
interface MessagesEntryPoint : FeatureEntryPoint {
sealed interface InitialTarget : Parcelable {
@Parcelize
data class Messages(val focusedEventId: EventId?) : InitialTarget
data class Messages(
val focusedEventId: EventId?,
) : InitialTarget
@Parcelize
data object PinnedMessages : InitialTarget
@ -46,3 +49,7 @@ interface MessagesEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder
}
interface MessagesEntryPointNode {
suspend fun attachThread(threadId: ThreadId, focusedEventId: EventId?)
}