Mark room as fully read when user goes back to the room list. (#2687)

* Remove not helping warning.

* Add and improve tests

* Send the `m.fully_read` read marker when the user navigates back to the room list, to mark the room as read.
This commit is contained in:
Benoit Marty 2025-06-04 16:14:29 +02:00 committed by GitHub
parent 7a3db35ccb
commit 525870f30d
10 changed files with 232 additions and 56 deletions

View file

@ -0,0 +1,37 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.messages.impl.timeline
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.timeline.ReceiptType
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
interface MarkAsFullyRead {
operator fun invoke(roomId: RoomId)
}
@ContributesBinding(SessionScope::class)
class DefaultMarkAsFullyRead @Inject constructor(
private val matrixClient: MatrixClient,
) : MarkAsFullyRead {
override fun invoke(roomId: RoomId) {
matrixClient.sessionCoroutineScope.launch {
matrixClient.getRoom(roomId)?.use { room ->
room.markAsRead(receiptType = ReceiptType.FULLY_READ)
.onFailure {
Timber.e("Failed to mark room $roomId as fully read", it)
}
}
}
}
}

View file

@ -8,6 +8,7 @@
package io.element.android.features.messages.impl.timeline
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
@ -76,6 +77,7 @@ class TimelinePresenter @AssistedInject constructor(
private val resolveVerifiedUserSendFailurePresenter: Presenter<ResolveVerifiedUserSendFailureState>,
private val typingNotificationPresenter: Presenter<TypingNotificationState>,
private val roomCallStatePresenter: Presenter<RoomCallState>,
private val markAsFullyRead: MarkAsFullyRead,
) : Presenter<TimelineState> {
@AssistedFactory
interface Factory {
@ -177,6 +179,12 @@ class TimelinePresenter @AssistedInject constructor(
}
}
DisposableEffect(Unit) {
onDispose {
markAsFullyRead(room.roomId)
}
}
LaunchedEffect(Unit) {
timelineItemsFactory.timelineItems
.onEach { newTimelineItems ->