Update rust-sdk (from maven)
This commit is contained in:
parent
8d4d8e96bd
commit
247f6d2188
12 changed files with 86 additions and 96 deletions
|
|
@ -28,8 +28,6 @@ import io.element.android.features.messages.timeline.factories.TimelineItemsFact
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.matrix.core.EventId
|
import io.element.android.libraries.matrix.core.EventId
|
||||||
import io.element.android.libraries.matrix.room.MatrixRoom
|
import io.element.android.libraries.matrix.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.timeline.MatrixTimeline
|
|
||||||
import io.element.android.libraries.matrix.timeline.MatrixTimelineItem
|
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
|
@ -47,17 +45,6 @@ class TimelinePresenter @Inject constructor(
|
||||||
|
|
||||||
private val timeline = room.timeline()
|
private val timeline = room.timeline()
|
||||||
|
|
||||||
private class TimelineCallback(
|
|
||||||
private val coroutineScope: CoroutineScope,
|
|
||||||
private val timelineItemsFactory: TimelineItemsFactory,
|
|
||||||
) : MatrixTimeline.Callback {
|
|
||||||
override fun onPushedTimelineItem(timelineItem: MatrixTimelineItem) {
|
|
||||||
coroutineScope.launch {
|
|
||||||
timelineItemsFactory.pushItem(timelineItem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): TimelineState {
|
override fun present(): TimelineState {
|
||||||
val localCoroutineScope = rememberCoroutineScope()
|
val localCoroutineScope = rememberCoroutineScope()
|
||||||
|
|
@ -83,10 +70,8 @@ class TimelinePresenter @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
DisposableEffect(Unit) {
|
DisposableEffect(Unit) {
|
||||||
timeline.callback = TimelineCallback(localCoroutineScope, timelineItemsFactory)
|
|
||||||
timeline.initialize()
|
timeline.initialize()
|
||||||
onDispose {
|
onDispose {
|
||||||
timeline.callback = null
|
|
||||||
timeline.dispose()
|
timeline.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import io.element.android.features.messages.timeline.diff.MatrixTimelineItemsDif
|
||||||
import io.element.android.features.messages.timeline.factories.event.TimelineItemEventFactory
|
import io.element.android.features.messages.timeline.factories.event.TimelineItemEventFactory
|
||||||
import io.element.android.features.messages.timeline.factories.virtual.TimelineItemVirtualFactory
|
import io.element.android.features.messages.timeline.factories.virtual.TimelineItemVirtualFactory
|
||||||
import io.element.android.features.messages.timeline.model.TimelineItem
|
import io.element.android.features.messages.timeline.model.TimelineItem
|
||||||
import io.element.android.features.messages.timeline.util.invalidateLast
|
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.matrix.timeline.MatrixTimelineItem
|
import io.element.android.libraries.matrix.timeline.MatrixTimelineItem
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
@ -61,18 +60,6 @@ class TimelineItemsFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun pushItem(
|
|
||||||
timelineItem: MatrixTimelineItem,
|
|
||||||
) = withContext(dispatchers.computation) {
|
|
||||||
lock.withLock {
|
|
||||||
// Makes sure to invalidate last as we need to recompute some data (like groupPosition)
|
|
||||||
timelineItemsCache.invalidateLast()
|
|
||||||
timelineItemsCache.add(null)
|
|
||||||
matrixTimelineItems = matrixTimelineItems + timelineItem
|
|
||||||
buildAndEmitTimelineItemStates(matrixTimelineItems)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun buildAndEmitTimelineItemStates(timelineItems: List<MatrixTimelineItem>) {
|
private suspend fun buildAndEmitTimelineItemStates(timelineItems: List<MatrixTimelineItem>) {
|
||||||
val newTimelineItemStates = ArrayList<TimelineItem>()
|
val newTimelineItemStates = ArrayList<TimelineItem>()
|
||||||
for (index in timelineItemsCache.indices.reversed()) {
|
for (index in timelineItemsCache.indices.reversed()) {
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
|
||||||
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
||||||
molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" }
|
molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" }
|
||||||
timber = "com.jakewharton.timber:timber:5.0.1"
|
timber = "com.jakewharton.timber:timber:5.0.1"
|
||||||
|
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.2"
|
||||||
|
|
||||||
# Di
|
# Di
|
||||||
inject = "javax.inject:javax.inject:1"
|
inject = "javax.inject:javax.inject:1"
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ anvil {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.libraries.rustsdk)
|
//api(projects.libraries.rustsdk)
|
||||||
|
api(libs.matrix.sdk)
|
||||||
implementation(projects.libraries.di)
|
implementation(projects.libraries.di)
|
||||||
implementation(libs.dagger)
|
implementation(libs.dagger)
|
||||||
implementation(projects.libraries.core)
|
implementation(projects.libraries.core)
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ import org.matrix.rustcomponents.sdk.RequiredState
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncMode
|
import org.matrix.rustcomponents.sdk.SlidingSyncMode
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncRequestListFilters
|
import org.matrix.rustcomponents.sdk.SlidingSyncRequestListFilters
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncViewBuilder
|
import org.matrix.rustcomponents.sdk.SlidingSyncViewBuilder
|
||||||
import org.matrix.rustcomponents.sdk.StoppableSpawn
|
import org.matrix.rustcomponents.sdk.TaskHandle
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
@ -114,7 +114,7 @@ class RustMatrixClient constructor(
|
||||||
dispatchers,
|
dispatchers,
|
||||||
::onRestartSync
|
::onRestartSync
|
||||||
)
|
)
|
||||||
private var slidingSyncObserverToken: StoppableSpawn? = null
|
private var slidingSyncObserverToken: TaskHandle? = null
|
||||||
|
|
||||||
private val mediaResolver = RustMediaResolver(this)
|
private val mediaResolver = RustMediaResolver(this)
|
||||||
private val isSyncing = AtomicBoolean(false)
|
private val isSyncing = AtomicBoolean(false)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ import org.matrix.rustcomponents.sdk.SlidingSyncViewRoomsListDiff
|
||||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
import org.matrix.rustcomponents.sdk.UpdateSummary
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.util.Collections
|
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
interface RoomSummaryDataSource {
|
interface RoomSummaryDataSource {
|
||||||
|
|
@ -128,30 +127,40 @@ internal class RustRoomSummaryDataSource(
|
||||||
}
|
}
|
||||||
Timber.v("ApplyDiff: $diff for list with size: $size")
|
Timber.v("ApplyDiff: $diff for list with size: $size")
|
||||||
when (diff) {
|
when (diff) {
|
||||||
is SlidingSyncViewRoomsListDiff.Push -> {
|
is SlidingSyncViewRoomsListDiff.Append -> {
|
||||||
|
val roomSummaries = diff.values.map {
|
||||||
|
buildSummaryForRoomListEntry(it)
|
||||||
|
}
|
||||||
|
addAll(roomSummaries)
|
||||||
|
}
|
||||||
|
is SlidingSyncViewRoomsListDiff.PushBack -> {
|
||||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
||||||
add(roomSummary)
|
add(roomSummary)
|
||||||
}
|
}
|
||||||
is SlidingSyncViewRoomsListDiff.UpdateAt -> {
|
is SlidingSyncViewRoomsListDiff.PushFront -> {
|
||||||
|
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
||||||
|
add(0, roomSummary)
|
||||||
|
}
|
||||||
|
is SlidingSyncViewRoomsListDiff.Set -> {
|
||||||
fillUntil(diff.index.toInt())
|
fillUntil(diff.index.toInt())
|
||||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
||||||
set(diff.index.toInt(), roomSummary)
|
set(diff.index.toInt(), roomSummary)
|
||||||
}
|
}
|
||||||
is SlidingSyncViewRoomsListDiff.InsertAt -> {
|
is SlidingSyncViewRoomsListDiff.Insert -> {
|
||||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
||||||
add(diff.index.toInt(), roomSummary)
|
add(diff.index.toInt(), roomSummary)
|
||||||
}
|
}
|
||||||
is SlidingSyncViewRoomsListDiff.Move -> {
|
is SlidingSyncViewRoomsListDiff.Remove -> {
|
||||||
Collections.swap(this, diff.oldIndex.toInt(), diff.newIndex.toInt())
|
|
||||||
}
|
|
||||||
is SlidingSyncViewRoomsListDiff.RemoveAt -> {
|
|
||||||
removeAt(diff.index.toInt())
|
removeAt(diff.index.toInt())
|
||||||
}
|
}
|
||||||
is SlidingSyncViewRoomsListDiff.Replace -> {
|
is SlidingSyncViewRoomsListDiff.Reset -> {
|
||||||
clear()
|
clear()
|
||||||
addAll(diff.values.map { buildSummaryForRoomListEntry(it) })
|
addAll(diff.values.map { buildSummaryForRoomListEntry(it) })
|
||||||
}
|
}
|
||||||
SlidingSyncViewRoomsListDiff.Pop -> {
|
SlidingSyncViewRoomsListDiff.PopBack -> {
|
||||||
|
removeFirstOrNull()
|
||||||
|
}
|
||||||
|
SlidingSyncViewRoomsListDiff.PopFront -> {
|
||||||
removeLastOrNull()
|
removeLastOrNull()
|
||||||
}
|
}
|
||||||
SlidingSyncViewRoomsListDiff.Clear -> {
|
SlidingSyncViewRoomsListDiff.Clear -> {
|
||||||
|
|
@ -185,13 +194,4 @@ internal class RustRoomSummaryDataSource(
|
||||||
block(mutableRoomSummaries)
|
block(mutableRoomSummaries)
|
||||||
roomSummaries.value = mutableRoomSummaries
|
roomSummaries.value = mutableRoomSummaries
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SlidingSyncViewRoomsListDiff.isInvalidation(): Boolean {
|
|
||||||
return when (this) {
|
|
||||||
is SlidingSyncViewRoomsListDiff.InsertAt -> this.value is RoomListEntry.Invalidated
|
|
||||||
is SlidingSyncViewRoomsListDiff.UpdateAt -> this.value is RoomListEntry.Invalidated
|
|
||||||
is SlidingSyncViewRoomsListDiff.Push -> this.value is RoomListEntry.Invalidated
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,16 +21,9 @@ import kotlinx.coroutines.flow.Flow
|
||||||
import org.matrix.rustcomponents.sdk.TimelineListener
|
import org.matrix.rustcomponents.sdk.TimelineListener
|
||||||
|
|
||||||
interface MatrixTimeline {
|
interface MatrixTimeline {
|
||||||
var callback: Callback?
|
|
||||||
|
|
||||||
interface Callback {
|
|
||||||
fun onUpdatedTimelineItem(timelineItem: MatrixTimelineItem) = Unit
|
|
||||||
fun onPushedTimelineItem(timelineItem: MatrixTimelineItem) = Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
fun timelineItems(): Flow<List<MatrixTimelineItem>>
|
fun timelineItems(): Flow<List<MatrixTimelineItem>>
|
||||||
suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result<Unit>
|
suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result<Unit>
|
||||||
fun addListener(timelineListener: TimelineListener)
|
|
||||||
fun initialize()
|
fun initialize()
|
||||||
fun dispose()
|
fun dispose()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ package io.element.android.libraries.matrix.timeline
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.matrix.core.EventId
|
import io.element.android.libraries.matrix.core.EventId
|
||||||
import io.element.android.libraries.matrix.room.RustMatrixRoom
|
import io.element.android.libraries.matrix.room.RustMatrixRoom
|
||||||
import io.element.android.libraries.matrix.util.StoppableSpawnBag
|
import io.element.android.libraries.matrix.util.TaskHandleBag
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
@ -32,9 +32,9 @@ import org.matrix.rustcomponents.sdk.Room
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
||||||
import org.matrix.rustcomponents.sdk.TimelineChange
|
import org.matrix.rustcomponents.sdk.TimelineChange
|
||||||
import org.matrix.rustcomponents.sdk.TimelineDiff
|
import org.matrix.rustcomponents.sdk.TimelineDiff
|
||||||
|
import org.matrix.rustcomponents.sdk.TimelineItem
|
||||||
import org.matrix.rustcomponents.sdk.TimelineListener
|
import org.matrix.rustcomponents.sdk.TimelineListener
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.Collections
|
|
||||||
|
|
||||||
class RustMatrixTimeline(
|
class RustMatrixTimeline(
|
||||||
private val matrixRoom: RustMatrixRoom,
|
private val matrixRoom: RustMatrixRoom,
|
||||||
|
|
@ -54,12 +54,10 @@ class RustMatrixTimeline(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override var callback: MatrixTimeline.Callback? = null
|
|
||||||
|
|
||||||
private val timelineItems: MutableStateFlow<List<MatrixTimelineItem>> =
|
private val timelineItems: MutableStateFlow<List<MatrixTimelineItem>> =
|
||||||
MutableStateFlow(emptyList())
|
MutableStateFlow(emptyList())
|
||||||
|
|
||||||
private val listenerTokens = StoppableSpawnBag()
|
private val listenerTokens = TaskHandleBag()
|
||||||
|
|
||||||
@OptIn(FlowPreview::class)
|
@OptIn(FlowPreview::class)
|
||||||
override fun timelineItems(): Flow<List<MatrixTimelineItem>> {
|
override fun timelineItems(): Flow<List<MatrixTimelineItem>> {
|
||||||
|
|
@ -68,37 +66,42 @@ class RustMatrixTimeline(
|
||||||
|
|
||||||
private fun MutableList<MatrixTimelineItem>.applyDiff(diff: TimelineDiff) {
|
private fun MutableList<MatrixTimelineItem>.applyDiff(diff: TimelineDiff) {
|
||||||
when (diff.change()) {
|
when (diff.change()) {
|
||||||
TimelineChange.PUSH -> {
|
TimelineChange.APPEND -> {
|
||||||
val item = diff.push()?.asMatrixTimelineItem() ?: return
|
val items = diff.append()?.map { it.asMatrixTimelineItem() } ?: return
|
||||||
callback?.onPushedTimelineItem(item)
|
addAll(items)
|
||||||
|
}
|
||||||
|
TimelineChange.PUSH_BACK -> {
|
||||||
|
val item = diff.pushBack()?.asMatrixTimelineItem() ?: return
|
||||||
add(item)
|
add(item)
|
||||||
}
|
}
|
||||||
TimelineChange.UPDATE_AT -> {
|
TimelineChange.PUSH_FRONT -> {
|
||||||
val updateAtData = diff.updateAt() ?: return
|
val item = diff.pushFront()?.asMatrixTimelineItem() ?: return
|
||||||
|
add(0, item)
|
||||||
|
}
|
||||||
|
TimelineChange.SET -> {
|
||||||
|
val updateAtData = diff.set() ?: return
|
||||||
val item = updateAtData.item.asMatrixTimelineItem()
|
val item = updateAtData.item.asMatrixTimelineItem()
|
||||||
callback?.onUpdatedTimelineItem(item)
|
|
||||||
set(updateAtData.index.toInt(), item)
|
set(updateAtData.index.toInt(), item)
|
||||||
}
|
}
|
||||||
TimelineChange.INSERT_AT -> {
|
TimelineChange.INSERT -> {
|
||||||
val insertAtData = diff.insertAt() ?: return
|
val insertAtData = diff.insert() ?: return
|
||||||
val item = insertAtData.item.asMatrixTimelineItem()
|
val item = insertAtData.item.asMatrixTimelineItem()
|
||||||
add(insertAtData.index.toInt(), item)
|
add(insertAtData.index.toInt(), item)
|
||||||
}
|
}
|
||||||
TimelineChange.MOVE -> {
|
TimelineChange.REMOVE -> {
|
||||||
val moveData = diff.move() ?: return
|
val removeAtData = diff.remove() ?: return
|
||||||
Collections.swap(this, moveData.oldIndex.toInt(), moveData.newIndex.toInt())
|
|
||||||
}
|
|
||||||
TimelineChange.REMOVE_AT -> {
|
|
||||||
val removeAtData = diff.removeAt() ?: return
|
|
||||||
removeAt(removeAtData.toInt())
|
removeAt(removeAtData.toInt())
|
||||||
}
|
}
|
||||||
TimelineChange.REPLACE -> {
|
TimelineChange.RESET -> {
|
||||||
clear()
|
clear()
|
||||||
val items = diff.replace()?.map { it.asMatrixTimelineItem() } ?: return
|
val items = diff.reset()?.map { it.asMatrixTimelineItem() } ?: return
|
||||||
addAll(items)
|
addAll(items)
|
||||||
}
|
}
|
||||||
TimelineChange.POP -> {
|
TimelineChange.POP_FRONT -> {
|
||||||
removeLast()
|
removeFirstOrNull()
|
||||||
|
}
|
||||||
|
TimelineChange.POP_BACK -> {
|
||||||
|
removeLastOrNull()
|
||||||
}
|
}
|
||||||
TimelineChange.CLEAR -> {
|
TimelineChange.CLEAR -> {
|
||||||
clear()
|
clear()
|
||||||
|
|
@ -128,8 +131,12 @@ class RustMatrixTimeline(
|
||||||
timelineItems.value = mutableTimelineItems
|
timelineItems.value = mutableTimelineItems
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(timelineListener: TimelineListener) {
|
private suspend fun addListener(timelineListener: TimelineListener): Result<List<TimelineItem>> = withContext(coroutineDispatchers.computation) {
|
||||||
listenerTokens += slidingSyncRoom.subscribeAndAddTimelineListener(timelineListener, null)
|
runCatching {
|
||||||
|
val result = slidingSyncRoom.subscribeAndAddTimelineListener(timelineListener, null)
|
||||||
|
listenerTokens += result.taskHandle
|
||||||
|
result.items
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initialize() {
|
override fun initialize() {
|
||||||
|
|
@ -142,7 +149,17 @@ class RustMatrixTimeline(
|
||||||
Timber.v("Success fetching members for room ${slidingSyncRoom.roomId()}")
|
Timber.v("Success fetching members for room ${slidingSyncRoom.roomId()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addListener(innerTimelineListener)
|
coroutineScope.launch {
|
||||||
|
val result = addListener(innerTimelineListener)
|
||||||
|
result
|
||||||
|
.onSuccess { timelineItems ->
|
||||||
|
val matrixTimelineItems = timelineItems.map { it.asMatrixTimelineItem() }
|
||||||
|
updateTimelineItems { addAll(matrixTimelineItems) }
|
||||||
|
}
|
||||||
|
.onFailure {
|
||||||
|
Timber.e("Failed adding timeline listener on room with identifier: ${slidingSyncRoom.roomId()})")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,13 @@ package io.element.android.libraries.matrix.util
|
||||||
import kotlinx.coroutines.channels.ProducerScope
|
import kotlinx.coroutines.channels.ProducerScope
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
import org.matrix.rustcomponents.sdk.StoppableSpawn
|
import org.matrix.rustcomponents.sdk.TaskHandle
|
||||||
|
|
||||||
internal fun <T> mxCallbackFlow(block: suspend ProducerScope<T>.() -> StoppableSpawn) =
|
internal fun <T> mxCallbackFlow(block: suspend ProducerScope<T>.() -> TaskHandle) =
|
||||||
callbackFlow {
|
callbackFlow {
|
||||||
val token: StoppableSpawn = block(this)
|
val token: TaskHandle = block(this)
|
||||||
awaitClose {
|
awaitClose {
|
||||||
token.cancel()
|
token.cancel()
|
||||||
|
token.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.util
|
package io.element.android.libraries.matrix.util
|
||||||
|
|
||||||
import org.matrix.rustcomponents.sdk.StoppableSpawn
|
import org.matrix.rustcomponents.sdk.TaskHandle
|
||||||
import java.util.concurrent.CopyOnWriteArraySet
|
import java.util.concurrent.CopyOnWriteArraySet
|
||||||
|
|
||||||
class StoppableSpawnBag(private val tokens: MutableSet<StoppableSpawn> = CopyOnWriteArraySet()) : Set<StoppableSpawn> by tokens {
|
class TaskHandleBag(private val tokens: MutableSet<TaskHandle> = CopyOnWriteArraySet()) : Set<TaskHandle> by tokens {
|
||||||
|
|
||||||
operator fun plusAssign(stoppableSpawn: StoppableSpawn?) {
|
operator fun plusAssign(taskHandle: TaskHandle?) {
|
||||||
if (stoppableSpawn == null) return
|
if (taskHandle == null) return
|
||||||
tokens += stoppableSpawn
|
tokens += taskHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
|
|
@ -51,6 +51,7 @@ dependencies {
|
||||||
implementation(projects.libraries.designsystem)
|
implementation(projects.libraries.designsystem)
|
||||||
implementation(projects.libraries.architecture)
|
implementation(projects.libraries.architecture)
|
||||||
implementation(projects.libraries.core)
|
implementation(projects.libraries.core)
|
||||||
|
implementation(projects.libraries.dateformatter)
|
||||||
implementation(projects.features.roomlist)
|
implementation(projects.features.roomlist)
|
||||||
implementation(projects.features.login)
|
implementation(projects.features.login)
|
||||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2")
|
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2")
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,24 @@ package io.element.android.samples.minimal
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import io.element.android.features.roomlist.LastMessageFormatter
|
|
||||||
import io.element.android.features.roomlist.RoomListPresenter
|
import io.element.android.features.roomlist.RoomListPresenter
|
||||||
import io.element.android.features.roomlist.RoomListView
|
import io.element.android.features.roomlist.RoomListView
|
||||||
|
import io.element.android.libraries.dateformatter.impl.DefaultLastMessageFormatter
|
||||||
import io.element.android.libraries.matrix.MatrixClient
|
import io.element.android.libraries.matrix.MatrixClient
|
||||||
import io.element.android.libraries.matrix.core.RoomId
|
import io.element.android.libraries.matrix.core.RoomId
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.datetime.Clock
|
||||||
|
import kotlinx.datetime.TimeZone
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class RoomListScreen(private val matrixClient: MatrixClient) {
|
class RoomListScreen(private val matrixClient: MatrixClient) {
|
||||||
|
|
||||||
|
private val clock = Clock.System
|
||||||
|
private val locale = Locale.getDefault()
|
||||||
|
private val timeZone = TimeZone.currentSystemDefault()
|
||||||
|
private val presenter = RoomListPresenter(matrixClient, DefaultLastMessageFormatter(clock, locale, timeZone))
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Content(modifier: Modifier = Modifier) {
|
fun Content(modifier: Modifier = Modifier) {
|
||||||
fun onRoomClicked(roomId: RoomId) {
|
fun onRoomClicked(roomId: RoomId) {
|
||||||
|
|
@ -43,9 +50,6 @@ class RoomListScreen(private val matrixClient: MatrixClient) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val presenter = remember {
|
|
||||||
RoomListPresenter(matrixClient, LastMessageFormatter())
|
|
||||||
}
|
|
||||||
val state = presenter.present()
|
val state = presenter.present()
|
||||||
RoomListView(
|
RoomListView(
|
||||||
state = state,
|
state = state,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue