Pinned events : start displaying actions in timeline

This commit is contained in:
ganfra 2024-08-28 21:59:10 +02:00
parent 3bcd76d271
commit 3cc749dd0a
24 changed files with 474 additions and 86 deletions

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.core.coroutine
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/**
* A [StateFlow] that derives its value from a [Flow].
* Useful when you want to apply transformations to a [Flow] and expose it as a [StateFlow].
*/
class DerivedStateFlow<T>(
private val getValue: () -> T,
private val flow: Flow<T>
) : StateFlow<T> {
override val replayCache: List<T>
get() = listOf(value)
override val value: T
get() = getValue()
override suspend fun collect(collector: FlowCollector<T>): Nothing {
coroutineScope { flow.distinctUntilChanged().stateIn(this).collect(collector) }
}
}
/**
* Maps the value of a [StateFlow] to a new value and returns a new [StateFlow] with the mapped value.
*/
fun <T1, R> StateFlow<T1>.mapState(transform: (a: T1) -> R): StateFlow<R> {
return DerivedStateFlow(
getValue = { transform(this.value) },
flow = this.map { a -> transform(a) }
)
}

View file

@ -42,6 +42,7 @@ dependencies {
implementation(libs.serialization.json)
api(projects.libraries.sessionStorage.api)
implementation(libs.coroutines.core)
api(projects.libraries.architecture)
testImplementation(libs.test.junit)
testImplementation(libs.test.truth)

View file

@ -17,14 +17,16 @@
package io.element.android.libraries.matrix.api.timeline
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
/**
* This interface defines a way to get the active timeline.
* It could be the current room timeline, or a timeline for a specific event.
* It could be the live timeline, a pinned timeline or a detached timeline.
* By default, the active timeline is the live timeline.
*/
interface TimelineProvider {
fun activeTimelineFlow(): StateFlow<Timeline>
fun activeTimelineFlow(): StateFlow<Timeline?>
}
suspend fun TimelineProvider.getActiveTimeline(): Timeline = activeTimelineFlow().first()
suspend fun TimelineProvider.getActiveTimeline(): Timeline = activeTimelineFlow().filterNotNull().first()