Browse Source

Rust : handle api changes for 0.2.27

pull/3048/head
ganfra 3 months ago
parent
commit
420872fed9
  1. 2
      gradle/libs.versions.toml
  2. 2
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt
  3. 9
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt
  4. 4
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt
  5. 7
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt
  6. 4
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt
  7. 17
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt
  8. 22
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt
  9. 2
      libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt
  10. 3
      libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt

2
gradle/libs.versions.toml

@ -162,7 +162,7 @@ jsoup = "org.jsoup:jsoup:1.17.2"
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0"
timber = "com.jakewharton.timber:timber:5.0.1" timber = "com.jakewharton.timber:timber:5.0.1"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.25" matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.27"
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }

2
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt

@ -20,7 +20,6 @@ import androidx.compose.runtime.Immutable
import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableMap
@ -41,7 +40,6 @@ data class MatrixRoomInfo(
val canonicalAlias: RoomAlias?, val canonicalAlias: RoomAlias?,
val alternativeAliases: ImmutableList<String>, val alternativeAliases: ImmutableList<String>,
val currentUserMembership: CurrentUserMembership, val currentUserMembership: CurrentUserMembership,
val latestEvent: EventTimelineItem?,
val inviter: RoomMember?, val inviter: RoomMember?,
val activeMembersCount: Long, val activeMembersCount: Long,
val invitedMembersCount: Long, val invitedMembersCount: Long,

9
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt

@ -23,19 +23,15 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper
import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toPersistentMap
import org.matrix.rustcomponents.sdk.use
import org.matrix.rustcomponents.sdk.Membership as RustMembership import org.matrix.rustcomponents.sdk.Membership as RustMembership
import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo
import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode
class MatrixRoomInfoMapper( class MatrixRoomInfoMapper {
private val timelineItemMapper: EventTimelineItemMapper = EventTimelineItemMapper(), fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.let {
) {
fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.use {
return MatrixRoomInfo( return MatrixRoomInfo(
id = RoomId(it.id), id = RoomId(it.id),
name = it.displayName, name = it.displayName,
@ -50,7 +46,6 @@ class MatrixRoomInfoMapper(
canonicalAlias = it.canonicalAlias?.let(::RoomAlias), canonicalAlias = it.canonicalAlias?.let(::RoomAlias),
alternativeAliases = it.alternativeAliases.toImmutableList(), alternativeAliases = it.alternativeAliases.toImmutableList(),
currentUserMembership = it.membership.map(), currentUserMembership = it.membership.map(),
latestEvent = it.latestEvent?.use(timelineItemMapper::map),
inviter = it.inviter?.let(RoomMemberMapper::map), inviter = it.inviter?.let(RoomMemberMapper::map),
activeMembersCount = it.activeMembersCount.toLong(), activeMembersCount = it.activeMembersCount.toLong(),
invitedMembersCount = it.invitedMembersCount.toLong(), invitedMembersCount = it.invitedMembersCount.toLong(),

4
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt

@ -111,7 +111,7 @@ class RustMatrixRoom(
override val roomInfoFlow: Flow<MatrixRoomInfo> = mxCallbackFlow { override val roomInfoFlow: Flow<MatrixRoomInfo> = mxCallbackFlow {
launch { launch {
val initial = innerRoom.roomInfo().use(matrixRoomInfoMapper::map) val initial = innerRoom.roomInfo().let(matrixRoomInfoMapper::map)
channel.trySend(initial) channel.trySend(initial)
} }
innerRoom.subscribeToRoomInfoUpdates(object : RoomInfoListener { innerRoom.subscribeToRoomInfoUpdates(object : RoomInfoListener {
@ -199,7 +199,7 @@ class RustMatrixRoom(
} }
override val displayName: String override val displayName: String
get() = runCatching { innerRoom.displayName() }.getOrDefault("") get() = runCatching { innerRoom.displayName() ?: "" }.getOrDefault("")
override val topic: String? override val topic: String?
get() = runCatching { innerRoom.topic() }.getOrDefault(null) get() = runCatching { innerRoom.topic() }.getOrDefault(null)

7
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt

@ -23,12 +23,13 @@ import io.element.android.libraries.matrix.impl.notificationsettings.RoomNotific
import io.element.android.libraries.matrix.impl.room.map import io.element.android.libraries.matrix.impl.room.map
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory
import org.matrix.rustcomponents.sdk.RoomInfo import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.use
class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) { class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) {
fun create(roomInfo: RoomInfo): RoomSummaryDetails { suspend fun create(roomListItem: RoomListItem): RoomSummaryDetails {
val latestRoomMessage = roomInfo.latestEvent?.use { val roomInfo = roomListItem.roomInfo()
val latestRoomMessage = roomListItem.latestEvent()?.use {
roomMessageFactory.create(it) roomMessageFactory.create(it)
} }
return RoomSummaryDetails( return RoomSummaryDetails(

4
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt

@ -120,11 +120,9 @@ class RoomSummaryListProcessor(
private suspend fun buildAndCacheRoomSummaryForIdentifier(identifier: String): RoomSummary { private suspend fun buildAndCacheRoomSummaryForIdentifier(identifier: String): RoomSummary {
val builtRoomSummary = roomListService.roomOrNull(identifier)?.use { roomListItem -> val builtRoomSummary = roomListService.roomOrNull(identifier)?.use { roomListItem ->
roomListItem.roomInfo().use { roomInfo ->
RoomSummary.Filled( RoomSummary.Filled(
details = roomSummaryDetailsFactory.create(roomInfo) details = roomSummaryDetailsFactory.create(roomListItem)
) )
}
} ?: buildEmptyRoomSummary() } ?: buildEmptyRoomSummary()
roomSummariesByIdentifier[builtRoomSummary.identifier()] = builtRoomSummary roomSummariesByIdentifier[builtRoomSummary.identifier()] = builtRoomSummary
return builtRoomSummary return builtRoomSummary

17
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt

@ -17,7 +17,6 @@
package io.element.android.libraries.matrix.impl.timeline package io.element.android.libraries.matrix.impl.timeline
import io.element.android.libraries.matrix.impl.util.cancelAndDestroy import io.element.android.libraries.matrix.impl.util.cancelAndDestroy
import io.element.android.libraries.matrix.impl.util.destroyAll
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking import kotlinx.coroutines.channels.trySendBlocking
@ -28,7 +27,6 @@ import kotlinx.coroutines.flow.catch
import org.matrix.rustcomponents.sdk.PaginationStatusListener import org.matrix.rustcomponents.sdk.PaginationStatusListener
import org.matrix.rustcomponents.sdk.Timeline import org.matrix.rustcomponents.sdk.Timeline
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 uniffi.matrix_sdk_ui.LiveBackPaginationStatus import uniffi.matrix_sdk_ui.LiveBackPaginationStatus
@ -47,7 +45,7 @@ internal fun Timeline.liveBackPaginationStatus(): Flow<LiveBackPaginationStatus>
Timber.d(it, "liveBackPaginationStatus() failed") Timber.d(it, "liveBackPaginationStatus() failed")
}.buffer(Channel.UNLIMITED) }.buffer(Channel.UNLIMITED)
internal fun Timeline.timelineDiffFlow(onInitialList: suspend (List<TimelineItem>) -> Unit): Flow<List<TimelineDiff>> = internal fun Timeline.timelineDiffFlow(): Flow<List<TimelineDiff>> =
callbackFlow { callbackFlow {
val listener = object : TimelineListener { val listener = object : TimelineListener {
override fun onUpdate(diff: List<TimelineDiff>) { override fun onUpdate(diff: List<TimelineDiff>) {
@ -55,16 +53,10 @@ internal fun Timeline.timelineDiffFlow(onInitialList: suspend (List<TimelineItem
} }
} }
Timber.d("Open timelineDiffFlow for TimelineInterface ${this@timelineDiffFlow}") Timber.d("Open timelineDiffFlow for TimelineInterface ${this@timelineDiffFlow}")
val result = addListener(listener) val taskHandle = addListener(listener)
try {
onInitialList(result.items)
} catch (exception: Exception) {
Timber.d(exception, "Catch failure in timelineDiffFlow of TimelineInterface ${this@timelineDiffFlow}")
}
awaitClose { awaitClose {
Timber.d("Close timelineDiffFlow for TimelineInterface ${this@timelineDiffFlow}") Timber.d("Close timelineDiffFlow for TimelineInterface ${this@timelineDiffFlow}")
result.itemsStream.cancelAndDestroy() taskHandle.cancelAndDestroy()
result.items.destroyAll()
} }
}.catch { }.catch {
Timber.d(it, "timelineDiffFlow() failed") Timber.d(it, "timelineDiffFlow() failed")
@ -75,8 +67,7 @@ internal suspend fun Timeline.runWithTimelineListenerRegistered(action: suspend
try { try {
action() action()
} finally { } finally {
result.itemsStream.cancelAndDestroy() result.cancelAndDestroy()
result.items.destroyAll()
} }
} }

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

@ -72,6 +72,7 @@ import org.matrix.rustcomponents.sdk.FormattedBody
import org.matrix.rustcomponents.sdk.MessageFormat import org.matrix.rustcomponents.sdk.MessageFormat
import org.matrix.rustcomponents.sdk.RoomMessageEventContentWithoutRelation import org.matrix.rustcomponents.sdk.RoomMessageEventContentWithoutRelation
import org.matrix.rustcomponents.sdk.SendAttachmentJoinHandle import org.matrix.rustcomponents.sdk.SendAttachmentJoinHandle
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.TimelineItem
import org.matrix.rustcomponents.sdk.messageEventContentFromHtml import org.matrix.rustcomponents.sdk.messageEventContentFromHtml
@ -143,14 +144,14 @@ class RustTimeline(
init { init {
roomCoroutineScope.launch(dispatcher) { roomCoroutineScope.launch(dispatcher) {
inner.timelineDiffFlow { initialList -> inner.timelineDiffFlow()
postItems(initialList) .onEach { diffs ->
}.onEach { diffs ->
if (diffs.any { diff -> diff.eventOrigin() == EventItemOrigin.SYNC }) { if (diffs.any { diff -> diff.eventOrigin() == EventItemOrigin.SYNC }) {
onNewSyncedEvent() onNewSyncedEvent()
} }
postDiffs(diffs) postDiffs(diffs)
}.launchIn(this) }
.launchIn(this)
launch { launch {
fetchMembers() fetchMembers()
@ -273,8 +274,19 @@ class RustTimeline(
} }
private suspend fun postDiffs(diffs: List<TimelineDiff>) { private suspend fun postDiffs(diffs: List<TimelineDiff>) {
val diffsToProcess = diffs.toMutableList()
if (!isInit.get()) {
val resetDiff = diffsToProcess.firstOrNull { it.change() == TimelineChange.RESET }
if (resetDiff != null) {
// Keep using the postItems logic so we can post the timelineItems asap.
postItems(resetDiff.reset() ?: emptyList())
diffsToProcess.remove(resetDiff)
}
}
initLatch.await() initLatch.await()
timelineDiffProcessor.postDiffs(diffs) if (diffsToProcess.isNotEmpty()) {
timelineDiffProcessor.postDiffs(diffsToProcess)
}
} }
override suspend fun sendMessage(body: String, htmlBody: String?, mentions: List<Mention>): Result<Unit> = withContext(dispatcher) { override suspend fun sendMessage(body: String, htmlBody: String?, mentions: List<Mention>): Result<Unit> = withContext(dispatcher) {

2
libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt

@ -170,7 +170,7 @@ class RoomSummaryListProcessorTest {
override suspend fun applyInput(input: RoomListInput) = Unit override suspend fun applyInput(input: RoomListInput) = Unit
override suspend fun room(roomId: String): RoomListItem { override fun room(roomId: String): RoomListItem {
return RoomListItem(Pointer.NULL) return RoomListItem(Pointer.NULL)
} }

3
libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt

@ -45,7 +45,6 @@ import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerL
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_AVATAR_URL
@ -746,7 +745,6 @@ fun aRoomInfo(
canonicalAlias: RoomAlias? = null, canonicalAlias: RoomAlias? = null,
alternativeAliases: List<String> = emptyList(), alternativeAliases: List<String> = emptyList(),
currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED,
latestEvent: EventTimelineItem? = null,
inviter: RoomMember? = null, inviter: RoomMember? = null,
activeMembersCount: Long = 1, activeMembersCount: Long = 1,
invitedMembersCount: Long = 0, invitedMembersCount: Long = 0,
@ -771,7 +769,6 @@ fun aRoomInfo(
canonicalAlias = canonicalAlias, canonicalAlias = canonicalAlias,
alternativeAliases = alternativeAliases.toImmutableList(), alternativeAliases = alternativeAliases.toImmutableList(),
currentUserMembership = currentUserMembership, currentUserMembership = currentUserMembership,
latestEvent = latestEvent,
inviter = inviter, inviter = inviter,
activeMembersCount = activeMembersCount, activeMembersCount = activeMembersCount,
invitedMembersCount = invitedMembersCount, invitedMembersCount = invitedMembersCount,

Loading…
Cancel
Save