Update rust-sdk (from maven)
This commit is contained in:
@@ -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.matrix.core.EventId
|
||||
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.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@@ -47,17 +45,6 @@ class TimelinePresenter @Inject constructor(
|
||||
|
||||
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
|
||||
override fun present(): TimelineState {
|
||||
val localCoroutineScope = rememberCoroutineScope()
|
||||
@@ -83,10 +70,8 @@ class TimelinePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
timeline.callback = TimelineCallback(localCoroutineScope, timelineItemsFactory)
|
||||
timeline.initialize()
|
||||
onDispose {
|
||||
timeline.callback = null
|
||||
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.virtual.TimelineItemVirtualFactory
|
||||
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.matrix.timeline.MatrixTimelineItem
|
||||
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>) {
|
||||
val newTimelineItemStates = ArrayList<TimelineItem>()
|
||||
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" }
|
||||
molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" }
|
||||
timber = "com.jakewharton.timber:timber:5.0.1"
|
||||
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.2"
|
||||
|
||||
# Di
|
||||
inject = "javax.inject:javax.inject:1"
|
||||
|
||||
@@ -31,7 +31,8 @@ anvil {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.libraries.rustsdk)
|
||||
//api(projects.libraries.rustsdk)
|
||||
api(libs.matrix.sdk)
|
||||
implementation(projects.libraries.di)
|
||||
implementation(libs.dagger)
|
||||
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.SlidingSyncRequestListFilters
|
||||
import org.matrix.rustcomponents.sdk.SlidingSyncViewBuilder
|
||||
import org.matrix.rustcomponents.sdk.StoppableSpawn
|
||||
import org.matrix.rustcomponents.sdk.TaskHandle
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
@@ -114,7 +114,7 @@ class RustMatrixClient constructor(
|
||||
dispatchers,
|
||||
::onRestartSync
|
||||
)
|
||||
private var slidingSyncObserverToken: StoppableSpawn? = null
|
||||
private var slidingSyncObserverToken: TaskHandle? = null
|
||||
|
||||
private val mediaResolver = RustMediaResolver(this)
|
||||
private val isSyncing = AtomicBoolean(false)
|
||||
|
||||
@@ -37,7 +37,6 @@ import org.matrix.rustcomponents.sdk.SlidingSyncViewRoomsListDiff
|
||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
||||
import timber.log.Timber
|
||||
import java.io.Closeable
|
||||
import java.util.Collections
|
||||
import java.util.UUID
|
||||
|
||||
interface RoomSummaryDataSource {
|
||||
@@ -128,30 +127,40 @@ internal class RustRoomSummaryDataSource(
|
||||
}
|
||||
Timber.v("ApplyDiff: $diff for list with size: $size")
|
||||
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)
|
||||
add(roomSummary)
|
||||
}
|
||||
is SlidingSyncViewRoomsListDiff.UpdateAt -> {
|
||||
is SlidingSyncViewRoomsListDiff.PushFront -> {
|
||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
||||
add(0, roomSummary)
|
||||
}
|
||||
is SlidingSyncViewRoomsListDiff.Set -> {
|
||||
fillUntil(diff.index.toInt())
|
||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
||||
set(diff.index.toInt(), roomSummary)
|
||||
}
|
||||
is SlidingSyncViewRoomsListDiff.InsertAt -> {
|
||||
is SlidingSyncViewRoomsListDiff.Insert -> {
|
||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
||||
add(diff.index.toInt(), roomSummary)
|
||||
}
|
||||
is SlidingSyncViewRoomsListDiff.Move -> {
|
||||
Collections.swap(this, diff.oldIndex.toInt(), diff.newIndex.toInt())
|
||||
}
|
||||
is SlidingSyncViewRoomsListDiff.RemoveAt -> {
|
||||
is SlidingSyncViewRoomsListDiff.Remove -> {
|
||||
removeAt(diff.index.toInt())
|
||||
}
|
||||
is SlidingSyncViewRoomsListDiff.Replace -> {
|
||||
is SlidingSyncViewRoomsListDiff.Reset -> {
|
||||
clear()
|
||||
addAll(diff.values.map { buildSummaryForRoomListEntry(it) })
|
||||
}
|
||||
SlidingSyncViewRoomsListDiff.Pop -> {
|
||||
SlidingSyncViewRoomsListDiff.PopBack -> {
|
||||
removeFirstOrNull()
|
||||
}
|
||||
SlidingSyncViewRoomsListDiff.PopFront -> {
|
||||
removeLastOrNull()
|
||||
}
|
||||
SlidingSyncViewRoomsListDiff.Clear -> {
|
||||
@@ -185,13 +194,4 @@ internal class RustRoomSummaryDataSource(
|
||||
block(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
|
||||
|
||||
interface MatrixTimeline {
|
||||
var callback: Callback?
|
||||
|
||||
interface Callback {
|
||||
fun onUpdatedTimelineItem(timelineItem: MatrixTimelineItem) = Unit
|
||||
fun onPushedTimelineItem(timelineItem: MatrixTimelineItem) = Unit
|
||||
}
|
||||
|
||||
fun timelineItems(): Flow<List<MatrixTimelineItem>>
|
||||
suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result<Unit>
|
||||
fun addListener(timelineListener: TimelineListener)
|
||||
fun initialize()
|
||||
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.matrix.core.EventId
|
||||
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.FlowPreview
|
||||
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.TimelineChange
|
||||
import org.matrix.rustcomponents.sdk.TimelineDiff
|
||||
import org.matrix.rustcomponents.sdk.TimelineItem
|
||||
import org.matrix.rustcomponents.sdk.TimelineListener
|
||||
import timber.log.Timber
|
||||
import java.util.Collections
|
||||
|
||||
class RustMatrixTimeline(
|
||||
private val matrixRoom: RustMatrixRoom,
|
||||
@@ -54,12 +54,10 @@ class RustMatrixTimeline(
|
||||
}
|
||||
}
|
||||
|
||||
override var callback: MatrixTimeline.Callback? = null
|
||||
|
||||
private val timelineItems: MutableStateFlow<List<MatrixTimelineItem>> =
|
||||
MutableStateFlow(emptyList())
|
||||
|
||||
private val listenerTokens = StoppableSpawnBag()
|
||||
private val listenerTokens = TaskHandleBag()
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
override fun timelineItems(): Flow<List<MatrixTimelineItem>> {
|
||||
@@ -68,37 +66,42 @@ class RustMatrixTimeline(
|
||||
|
||||
private fun MutableList<MatrixTimelineItem>.applyDiff(diff: TimelineDiff) {
|
||||
when (diff.change()) {
|
||||
TimelineChange.PUSH -> {
|
||||
val item = diff.push()?.asMatrixTimelineItem() ?: return
|
||||
callback?.onPushedTimelineItem(item)
|
||||
TimelineChange.APPEND -> {
|
||||
val items = diff.append()?.map { it.asMatrixTimelineItem() } ?: return
|
||||
addAll(items)
|
||||
}
|
||||
TimelineChange.PUSH_BACK -> {
|
||||
val item = diff.pushBack()?.asMatrixTimelineItem() ?: return
|
||||
add(item)
|
||||
}
|
||||
TimelineChange.UPDATE_AT -> {
|
||||
val updateAtData = diff.updateAt() ?: return
|
||||
TimelineChange.PUSH_FRONT -> {
|
||||
val item = diff.pushFront()?.asMatrixTimelineItem() ?: return
|
||||
add(0, item)
|
||||
}
|
||||
TimelineChange.SET -> {
|
||||
val updateAtData = diff.set() ?: return
|
||||
val item = updateAtData.item.asMatrixTimelineItem()
|
||||
callback?.onUpdatedTimelineItem(item)
|
||||
set(updateAtData.index.toInt(), item)
|
||||
}
|
||||
TimelineChange.INSERT_AT -> {
|
||||
val insertAtData = diff.insertAt() ?: return
|
||||
TimelineChange.INSERT -> {
|
||||
val insertAtData = diff.insert() ?: return
|
||||
val item = insertAtData.item.asMatrixTimelineItem()
|
||||
add(insertAtData.index.toInt(), item)
|
||||
}
|
||||
TimelineChange.MOVE -> {
|
||||
val moveData = diff.move() ?: return
|
||||
Collections.swap(this, moveData.oldIndex.toInt(), moveData.newIndex.toInt())
|
||||
}
|
||||
TimelineChange.REMOVE_AT -> {
|
||||
val removeAtData = diff.removeAt() ?: return
|
||||
TimelineChange.REMOVE -> {
|
||||
val removeAtData = diff.remove() ?: return
|
||||
removeAt(removeAtData.toInt())
|
||||
}
|
||||
TimelineChange.REPLACE -> {
|
||||
TimelineChange.RESET -> {
|
||||
clear()
|
||||
val items = diff.replace()?.map { it.asMatrixTimelineItem() } ?: return
|
||||
val items = diff.reset()?.map { it.asMatrixTimelineItem() } ?: return
|
||||
addAll(items)
|
||||
}
|
||||
TimelineChange.POP -> {
|
||||
removeLast()
|
||||
TimelineChange.POP_FRONT -> {
|
||||
removeFirstOrNull()
|
||||
}
|
||||
TimelineChange.POP_BACK -> {
|
||||
removeLastOrNull()
|
||||
}
|
||||
TimelineChange.CLEAR -> {
|
||||
clear()
|
||||
@@ -128,8 +131,12 @@ class RustMatrixTimeline(
|
||||
timelineItems.value = mutableTimelineItems
|
||||
}
|
||||
|
||||
override fun addListener(timelineListener: TimelineListener) {
|
||||
listenerTokens += slidingSyncRoom.subscribeAndAddTimelineListener(timelineListener, null)
|
||||
private suspend fun addListener(timelineListener: TimelineListener): Result<List<TimelineItem>> = withContext(coroutineDispatchers.computation) {
|
||||
runCatching {
|
||||
val result = slidingSyncRoom.subscribeAndAddTimelineListener(timelineListener, null)
|
||||
listenerTokens += result.taskHandle
|
||||
result.items
|
||||
}
|
||||
}
|
||||
|
||||
override fun initialize() {
|
||||
@@ -142,7 +149,17 @@ class RustMatrixTimeline(
|
||||
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() {
|
||||
|
||||
@@ -19,12 +19,13 @@ package io.element.android.libraries.matrix.util
|
||||
import kotlinx.coroutines.channels.ProducerScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
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 {
|
||||
val token: StoppableSpawn = block(this)
|
||||
val token: TaskHandle = block(this)
|
||||
awaitClose {
|
||||
token.cancel()
|
||||
token.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package io.element.android.libraries.matrix.util
|
||||
|
||||
import org.matrix.rustcomponents.sdk.StoppableSpawn
|
||||
import org.matrix.rustcomponents.sdk.TaskHandle
|
||||
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?) {
|
||||
if (stoppableSpawn == null) return
|
||||
tokens += stoppableSpawn
|
||||
operator fun plusAssign(taskHandle: TaskHandle?) {
|
||||
if (taskHandle == null) return
|
||||
tokens += taskHandle
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
@@ -51,6 +51,7 @@ dependencies {
|
||||
implementation(projects.libraries.designsystem)
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.core)
|
||||
implementation(projects.libraries.dateformatter)
|
||||
implementation(projects.features.roomlist)
|
||||
implementation(projects.features.login)
|
||||
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.DisposableEffect
|
||||
import androidx.compose.runtime.remember
|
||||
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.RoomListView
|
||||
import io.element.android.libraries.dateformatter.impl.DefaultLastMessageFormatter
|
||||
import io.element.android.libraries.matrix.MatrixClient
|
||||
import io.element.android.libraries.matrix.core.RoomId
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.TimeZone
|
||||
import java.util.Locale
|
||||
|
||||
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
|
||||
fun Content(modifier: Modifier = Modifier) {
|
||||
fun onRoomClicked(roomId: RoomId) {
|
||||
@@ -43,9 +50,6 @@ class RoomListScreen(private val matrixClient: MatrixClient) {
|
||||
}
|
||||
}
|
||||
|
||||
val presenter = remember {
|
||||
RoomListPresenter(matrixClient, LastMessageFormatter())
|
||||
}
|
||||
val state = presenter.present()
|
||||
RoomListView(
|
||||
state = state,
|
||||
|
||||
Reference in New Issue
Block a user