Fix marking a room as read re-instantiates its timeline (#5628)

* Add `Timeline.markAsRead` to avoid reinstantiating the timeline using `Room.markAsRead`

* Mark as read when exiting the room screen, destroy the timeline when fully closed

* Ensure `MarkAsFullyReadAndExit` event can only be processed once

* Fix `DelayedVisibility` not being displayed in previews
This commit is contained in:
Jorge Martin Espinosa 2025-10-30 08:39:06 +01:00 committed by GitHub
parent bb61126c96
commit 6c3b280ecd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 281 additions and 89 deletions

View file

@ -0,0 +1,46 @@
/*
* 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.libraries.designsystem.utils
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalInspectionMode
import kotlinx.coroutines.delay
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
/**
* Displays the content of [block] after a delay of [duration].
*/
@Composable
fun DelayedVisibility(
duration: Duration = 300.milliseconds,
block: @Composable () -> Unit,
) {
// Technically this shouldn't be needed because `LocalInspectionMode` won't change, but let's make the linter happy
val movableBlock = remember { movableContentOf { block() } }
if (LocalInspectionMode.current) {
// Just allow the contents to be displayed in the previews/screenshot tests
movableBlock()
} else {
var shouldDisplay by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
delay(duration)
shouldDisplay = true
}
AnimatedVisibility(shouldDisplay) {
movableBlock()
}
}
}