Browse Source

Fix pinned events banner reappearing when loading (#3519)

* Fix pinned events banner reappearing when loading.

Make the `RustTimelineItem.timelineItems` property a `SharedFlow` so we don't always incorrectly load an empty state by default.
pull/3525/head
Jorge Martin Espinosa 4 weeks ago committed by GitHub
parent
commit
16d5be3ed5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/banner/PinnedMessagesBannerPresenter.kt
  2. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt
  3. 12
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt
  4. 8
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt

3
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/banner/PinnedMessagesBannerPresenter.kt

@ -24,7 +24,6 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom @@ -24,7 +24,6 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
@ -106,7 +105,7 @@ class PinnedMessagesBannerPresenter @Inject constructor( @@ -106,7 +105,7 @@ class PinnedMessagesBannerPresenter @Inject constructor(
}
}
@OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class)
@OptIn(ExperimentalCoroutinesApi::class)
@Composable
private fun PinnedMessagesBannerItemsEffect(
onItemsChange: (AsyncData<ImmutableList<PinnedMessagesBannerItem>>) -> Unit,

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt

@ -41,7 +41,6 @@ import io.element.android.libraries.matrix.api.room.roomMembers @@ -41,7 +41,6 @@ import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
@ -161,7 +160,6 @@ class PinnedMessagesListPresenter @AssistedInject constructor( @@ -161,7 +160,6 @@ class PinnedMessagesListPresenter @AssistedInject constructor(
}
}
@OptIn(FlowPreview::class)
@Composable
private fun PinnedMessagesListEffect(onItemsChange: (AsyncData<ImmutableList<TimelineItem>>) -> Unit) {
val updatedOnItemsChange by rememberUpdatedState(onItemsChange)

12
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt

@ -11,7 +11,7 @@ import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem @@ -11,7 +11,7 @@ import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.matrix.rustcomponents.sdk.TimelineChange
@ -20,7 +20,7 @@ import org.matrix.rustcomponents.sdk.TimelineItem @@ -20,7 +20,7 @@ import org.matrix.rustcomponents.sdk.TimelineItem
import timber.log.Timber
internal class MatrixTimelineDiffProcessor(
private val timelineItems: MutableStateFlow<List<MatrixTimelineItem>>,
private val timelineItems: MutableSharedFlow<List<MatrixTimelineItem>>,
private val timelineItemFactory: MatrixTimelineItemMapper,
) {
private val mutex = Mutex()
@ -47,9 +47,13 @@ internal class MatrixTimelineDiffProcessor( @@ -47,9 +47,13 @@ internal class MatrixTimelineDiffProcessor(
private suspend fun updateTimelineItems(block: MutableList<MatrixTimelineItem>.() -> Unit) =
mutex.withLock {
val mutableTimelineItems = timelineItems.value.toMutableList()
val mutableTimelineItems = if (timelineItems.replayCache.isNotEmpty()) {
timelineItems.first().toMutableList()
} else {
mutableListOf()
}
block(mutableTimelineItems)
timelineItems.value = mutableTimelineItems
timelineItems.tryEmit(mutableTimelineItems)
}
private fun MutableList<MatrixTimelineItem>.applyDiff(diff: TimelineDiff) {

8
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt

@ -49,10 +49,12 @@ import kotlinx.coroutines.CoroutineScope @@ -49,10 +49,12 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.getAndUpdate
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
@ -88,8 +90,8 @@ class RustTimeline( @@ -88,8 +90,8 @@ class RustTimeline(
private val initLatch = CompletableDeferred<Unit>()
private val isTimelineInitialized = MutableStateFlow(false)
private val _timelineItems: MutableStateFlow<List<MatrixTimelineItem>> =
MutableStateFlow(emptyList())
private val _timelineItems: MutableSharedFlow<List<MatrixTimelineItem>> =
MutableSharedFlow(replay = 1, extraBufferCapacity = Int.MAX_VALUE)
private val timelineEventContentMapper = TimelineEventContentMapper()
private val inReplyToMapper = InReplyToMapper(timelineEventContentMapper)
@ -522,7 +524,7 @@ class RustTimeline( @@ -522,7 +524,7 @@ class RustTimeline(
}
override suspend fun loadReplyDetails(eventId: EventId): InReplyTo = withContext(dispatcher) {
val timelineItem = _timelineItems.value.firstOrNull { timelineItem ->
val timelineItem = _timelineItems.first().firstOrNull { timelineItem ->
timelineItem is MatrixTimelineItem.Event && timelineItem.eventId == eventId
} as? MatrixTimelineItem.Event

Loading…
Cancel
Save