From d0b4a21cfe05ee73dbdf80dc1218de9fc705032b Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 15 Jul 2026 15:01:35 +0200 Subject: [PATCH 1/3] Fix timelines not loading after marking a room as read from notification when app was killed (#7202) This can only happen when the app was killed by the OS and then you received some notification. This notification action creates a new `DefaultSessionPreferencesStore` when trying to fetch `isSendPublicReadReceiptsEnabled`, which would contain a different session coroutine scope than the one created when instantiating the navigation graph (`@SessionCoroutineScope`), resulting in flows that never emit any items and close automatically as 'completed'. This in turn prevented the timeline items subscription in `TimelinePresenter` from progressing, since we're also checking `isRenderReadReceiptsEnabled` there, which is closed and in turn closes the timeline items flow. --- .../android/x/di/DefaultSessionGraphFactory.kt | 2 +- .../NotificationBroadcastReceiverHandler.kt | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/io/element/android/x/di/DefaultSessionGraphFactory.kt b/app/src/main/kotlin/io/element/android/x/di/DefaultSessionGraphFactory.kt index 9631713bb6..5bfe082ffe 100644 --- a/app/src/main/kotlin/io/element/android/x/di/DefaultSessionGraphFactory.kt +++ b/app/src/main/kotlin/io/element/android/x/di/DefaultSessionGraphFactory.kt @@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.MatrixClient @ContributesBinding(AppScope::class) class DefaultSessionGraphFactory( - private val appGraph: AppGraph + private val appGraph: AppGraph, ) : SessionGraphFactory { override fun create(client: MatrixClient): Any { return appGraph.sessionGraphFactory.create(client) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt index cb9ef8c82d..8dedb3325c 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt @@ -105,13 +105,21 @@ class NotificationBroadcastReceiverHandler( @Suppress("unused") private fun handleMarkAsRead(sessionId: SessionId, roomId: RoomId, threadId: ThreadId?) = appCoroutineScope.launch { val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return@launch - val isSendPublicReadReceiptsEnabled = sessionPreferencesStore.get(sessionId, this).isSendPublicReadReceiptsEnabled().first() + val isSendPublicReadReceiptsEnabled = sessionPreferencesStore.get( + sessionId = sessionId, + // Make sure `sessionCoroutineScope` is used here, otherwise we'll have several instances using different coroutines, + // and it will not work as expected. + sessionCoroutineScope = client.sessionCoroutineScope, + ).isSendPublicReadReceiptsEnabled().first() val receiptType = if (isSendPublicReadReceiptsEnabled) { ReceiptType.READ } else { ReceiptType.READ_PRIVATE } - val room = client.getJoinedRoom(roomId) ?: return@launch + + val (room, needsDestroy) = activeRoomsHolder.getActiveRoomMatching(sessionId, roomId)?.let { it to false } + ?: client.getJoinedRoom(roomId)?.let { it to true } + ?: return@launch val timeline = if (threadId != null) { room.createTimeline(CreateTimelineParams.Threaded(threadId)).getOrNull() } else { @@ -131,6 +139,10 @@ class NotificationBroadcastReceiverHandler( if (timeline?.mode != Timeline.Mode.Live) { timeline?.close() } + + if (needsDestroy) { + room.destroy() + } } private fun handleSmartReply( From d732f043dc3fcdda1df39aa62fa445bf55ccb018 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:38:20 +0200 Subject: [PATCH 2/3] Update dependency org.matrix.rustcomponents:sdk-android to v26.07.15 (#7216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependency org.matrix.rustcomponents:sdk-android to v26.07.15 * Fix API breaks: add `status` and `call` parameters to `aRustRoomMember` helper --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jorge Martín --- gradle/libs.versions.toml | 2 +- .../libraries/matrix/impl/fixtures/factories/RoomMember.kt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9debb63d59..2c725427d2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -185,7 +185,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.07.13" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.07.15" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt index 6b4f958d84..e4ea392197 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt @@ -12,6 +12,8 @@ import io.element.android.libraries.matrix.api.core.UserId import org.matrix.rustcomponents.sdk.MembershipState import org.matrix.rustcomponents.sdk.PowerLevel import org.matrix.rustcomponents.sdk.RoomMember +import org.matrix.rustcomponents.sdk.UserCall +import org.matrix.rustcomponents.sdk.UserStatus import uniffi.matrix_sdk.RoomMemberRole internal fun aRustRoomMember( @@ -25,6 +27,8 @@ internal fun aRustRoomMember( role: RoomMemberRole = RoomMemberRole.USER, membershipChangeReason: String? = null, isServiceMember: Boolean = false, + status: UserStatus? = null, + call: UserCall? = null, ) = RoomMember( userId = userId.value, displayName = displayName, @@ -36,4 +40,6 @@ internal fun aRustRoomMember( suggestedRoleForPowerLevel = role, membershipChangeReason = membershipChangeReason, isServiceMember = isServiceMember, + status = status, + call = call, ) From 8de8826b1f72471b5a888ffc33056eff5cbbf243 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:53:26 +0200 Subject: [PATCH 3/3] Merge pull request #7188 from element-hq/renovate/roborazzi Update roborazzi to v1.67.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2c725427d2..52f59e898c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,7 +32,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" -roborazzi = "1.64.0" +roborazzi = "1.67.0" # Jetbrain datetime = "0.8.0"