Update rust sdk to 0.1.39 (#1024)

Co-authored-by: ganfra <francoisg@element.io>
This commit is contained in:
ganfra 2023-08-02 21:53:05 +02:00 committed by GitHub
parent 30c513b1b5
commit 615b05178e
8 changed files with 39 additions and 41 deletions

View file

@ -145,7 +145,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.38" matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.39"
sqldelight-driver-android = { module = "com.squareup.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-android = { module = "com.squareup.sqldelight:android-driver", version.ref = "sqldelight" }
sqldelight-driver-jvm = { module = "com.squareup.sqldelight:sqlite-driver", version.ref = "sqldelight" } sqldelight-driver-jvm = { module = "com.squareup.sqldelight:sqlite-driver", version.ref = "sqldelight" }
sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions", version.ref = "sqldelight" } sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions", version.ref = "sqldelight" }

View file

@ -20,7 +20,6 @@ import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
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.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationContent
import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.notification.NotificationData
import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.api.room.RoomMembershipState
@ -30,7 +29,7 @@ import org.matrix.rustcomponents.sdk.NotificationItem
import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.use
class NotificationMapper( class NotificationMapper(
private val sessionId: SessionId, sessionId: SessionId,
private val clock: SystemClock, private val clock: SystemClock,
) { ) {
private val notificationContentMapper = NotificationContentMapper(sessionId) private val notificationContentMapper = NotificationContentMapper(sessionId)
@ -40,7 +39,6 @@ class NotificationMapper(
roomId: RoomId, roomId: RoomId,
notificationItem: NotificationItem notificationItem: NotificationItem
): NotificationData { ): NotificationData {
val senderId = UserId(notificationItem.senderInfo.senderId)
return notificationItem.use { item -> return notificationItem.use { item ->
NotificationData( NotificationData(
eventId = eventId, eventId = eventId,
@ -52,22 +50,20 @@ class NotificationMapper(
isDirect = item.roomInfo.isDirect, isDirect = item.roomInfo.isDirect,
isEncrypted = item.roomInfo.isEncrypted.orFalse(), isEncrypted = item.roomInfo.isEncrypted.orFalse(),
isNoisy = item.isNoisy.orFalse(), isNoisy = item.isNoisy.orFalse(),
timestamp = item.timestamp(clock), timestamp = item.timestamp() ?: clock.epochMillis(),
content = item.event.use { notificationContentMapper.map(senderId, it) }, content = item.event.use { notificationContentMapper.map(it) },
contentUrl = null, contentUrl = null,
) )
} }
} }
} }
class NotificationContentMapper( class NotificationContentMapper(private val sessionId: SessionId) {
private val sessionId: SessionId,
) {
private val timelineEventToNotificationContentMapper = TimelineEventToNotificationContentMapper() private val timelineEventToNotificationContentMapper = TimelineEventToNotificationContentMapper()
fun map(senderId: UserId, notificationEvent: NotificationEvent): NotificationContent = fun map(notificationEvent: NotificationEvent): NotificationContent =
when (notificationEvent) { when (notificationEvent) {
is NotificationEvent.Timeline -> timelineEventToNotificationContentMapper.map(senderId, notificationEvent.event) is NotificationEvent.Timeline -> timelineEventToNotificationContentMapper.map(notificationEvent.event)
is NotificationEvent.Invite -> NotificationContent.StateEvent.RoomMemberContent( is NotificationEvent.Invite -> NotificationContent.StateEvent.RoomMemberContent(
userId = sessionId.value, userId = sessionId.value,
membershipState = RoomMembershipState.INVITE, membershipState = RoomMembershipState.INVITE,
@ -75,8 +71,6 @@ class NotificationContentMapper(
} }
} }
private fun NotificationItem.timestamp(clock: SystemClock): Long { private fun NotificationItem.timestamp(): Long? {
// FIXME we can't get the timestamp from the notification item anymore, so we need to fake it return (this.event as? NotificationEvent.Timeline)?.event?.timestamp()?.toLong()
// return (this.event as? NotificationEvent.Timeline)?.event?.timestamp()?.toLong()
return clock.epochMillis()
} }

View file

@ -22,15 +22,18 @@ import io.element.android.libraries.matrix.impl.room.RoomMemberMapper
import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessageMapper import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessageMapper
import org.matrix.rustcomponents.sdk.MessageLikeEventContent import org.matrix.rustcomponents.sdk.MessageLikeEventContent
import org.matrix.rustcomponents.sdk.StateEventContent import org.matrix.rustcomponents.sdk.StateEventContent
import org.matrix.rustcomponents.sdk.TimelineEvent
import org.matrix.rustcomponents.sdk.TimelineEventType import org.matrix.rustcomponents.sdk.TimelineEventType
import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.use
import javax.inject.Inject import javax.inject.Inject
class TimelineEventToNotificationContentMapper @Inject constructor() { class TimelineEventToNotificationContentMapper @Inject constructor() {
fun map(senderId: UserId, timelineEventType: TimelineEventType): NotificationContent { fun map(timelineEvent: TimelineEvent): NotificationContent {
return timelineEventType.use { return timelineEvent.use {
it.toContent(senderId = senderId) timelineEvent.eventType().use { eventType ->
eventType.toContent(senderId = UserId(timelineEvent.senderId()))
}
} }
} }
} }
@ -72,7 +75,7 @@ private fun StateEventContent.toContent(): NotificationContent.StateEvent {
private fun MessageLikeEventContent.toContent(senderId: UserId): NotificationContent.MessageLike { private fun MessageLikeEventContent.toContent(senderId: UserId): NotificationContent.MessageLike {
return use { return use {
when (it) { when (this) {
MessageLikeEventContent.CallAnswer -> NotificationContent.MessageLike.CallAnswer MessageLikeEventContent.CallAnswer -> NotificationContent.MessageLike.CallAnswer
MessageLikeEventContent.CallCandidates -> NotificationContent.MessageLike.CallCandidates MessageLikeEventContent.CallCandidates -> NotificationContent.MessageLike.CallCandidates
MessageLikeEventContent.CallHangup -> NotificationContent.MessageLike.CallHangup MessageLikeEventContent.CallHangup -> NotificationContent.MessageLike.CallHangup
@ -84,10 +87,10 @@ private fun MessageLikeEventContent.toContent(senderId: UserId): NotificationCon
MessageLikeEventContent.KeyVerificationMac -> NotificationContent.MessageLike.KeyVerificationMac MessageLikeEventContent.KeyVerificationMac -> NotificationContent.MessageLike.KeyVerificationMac
MessageLikeEventContent.KeyVerificationReady -> NotificationContent.MessageLike.KeyVerificationReady MessageLikeEventContent.KeyVerificationReady -> NotificationContent.MessageLike.KeyVerificationReady
MessageLikeEventContent.KeyVerificationStart -> NotificationContent.MessageLike.KeyVerificationStart MessageLikeEventContent.KeyVerificationStart -> NotificationContent.MessageLike.KeyVerificationStart
is MessageLikeEventContent.ReactionContent -> NotificationContent.MessageLike.ReactionContent(it.relatedEventId) is MessageLikeEventContent.ReactionContent -> NotificationContent.MessageLike.ReactionContent(relatedEventId)
MessageLikeEventContent.RoomEncrypted -> NotificationContent.MessageLike.RoomEncrypted MessageLikeEventContent.RoomEncrypted -> NotificationContent.MessageLike.RoomEncrypted
is MessageLikeEventContent.RoomMessage -> { is MessageLikeEventContent.RoomMessage -> {
NotificationContent.MessageLike.RoomMessage(senderId, EventMessageMapper().mapMessageType(it.messageType)) NotificationContent.MessageLike.RoomMessage(senderId, EventMessageMapper().mapMessageType(messageType))
} }
MessageLikeEventContent.RoomRedaction -> NotificationContent.MessageLike.RoomRedaction MessageLikeEventContent.RoomRedaction -> NotificationContent.MessageLike.RoomRedaction
MessageLikeEventContent.Sticker -> NotificationContent.MessageLike.Sticker MessageLikeEventContent.Sticker -> NotificationContent.MessageLike.Sticker

View file

@ -80,6 +80,6 @@ class RoomContentForwarder(
} }
private object NoOpTimelineListener : TimelineListener { private object NoOpTimelineListener : TimelineListener {
override fun onUpdate(diff: TimelineDiff) = Unit override fun onUpdate(diff: List<TimelineDiff>) = Unit
} }
} }

View file

@ -372,14 +372,13 @@ class RustMatrixRoom(
} }
//TODO handle cancellation, need refactoring of how we are catching errors //TODO handle cancellation, need refactoring of how we are catching errors
private suspend fun sendAttachment(handle: () -> SendAttachmentJoinHandle): Result<Unit> = withContext(roomDispatcher) { private suspend fun sendAttachment(handle: () -> SendAttachmentJoinHandle): Result<Unit> {
runCatching { return runCatching {
handle().use { handle().use {
it.join() it.join()
} }
} }
} }
} }

View file

@ -23,6 +23,7 @@ import kotlinx.coroutines.sync.withLock
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.TimelineItem
import timber.log.Timber
internal class MatrixTimelineDiffProcessor( internal class MatrixTimelineDiffProcessor(
private val timelineItems: MutableStateFlow<List<MatrixTimelineItem>>, private val timelineItems: MutableStateFlow<List<MatrixTimelineItem>>,
@ -33,14 +34,18 @@ internal class MatrixTimelineDiffProcessor(
suspend fun postItems(items: List<TimelineItem>) { suspend fun postItems(items: List<TimelineItem>) {
updateTimelineItems { updateTimelineItems {
Timber.v("Update timeline items from postItems (with ${items.size} items) on ${Thread.currentThread()}")
val mappedItems = items.map { it.asMatrixTimelineItem() } val mappedItems = items.map { it.asMatrixTimelineItem() }
addAll(0, mappedItems) addAll(0, mappedItems)
} }
} }
suspend fun postDiff(diff: TimelineDiff) { suspend fun postDiffs(diffs: List<TimelineDiff>) {
updateTimelineItems { updateTimelineItems {
applyDiff(diff) Timber.v("Update timeline items from postDiffs (with ${diffs.size} items) on ${Thread.currentThread()}")
diffs.forEach { diff ->
applyDiff(diff)
}
} }
} }

View file

@ -35,10 +35,10 @@ 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
internal fun Room.timelineDiffFlow(onInitialList: suspend (List<TimelineItem>) -> Unit): Flow<TimelineDiff> = internal fun Room.timelineDiffFlow(onInitialList: suspend (List<TimelineItem>) -> Unit): Flow<List<TimelineDiff>> =
callbackFlow { callbackFlow {
val listener = object : TimelineListener { val listener = object : TimelineListener {
override fun onUpdate(diff: TimelineDiff) { override fun onUpdate(diff: List<TimelineDiff>) {
trySendBlocking(diff) trySendBlocking(diff)
} }
} }

View file

@ -32,7 +32,6 @@ import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -43,7 +42,6 @@ import kotlinx.coroutines.flow.getAndUpdate
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.BackPaginationStatus import org.matrix.rustcomponents.sdk.BackPaginationStatus
@ -109,11 +107,11 @@ class RustMatrixTimeline(
roomCoroutineScope.launch(dispatcher) { roomCoroutineScope.launch(dispatcher) {
innerRoom.timelineDiffFlow { initialList -> innerRoom.timelineDiffFlow { initialList ->
postItems(initialList) postItems(initialList)
}.onEach { diff -> }.onEach { diffs ->
if (diff.eventOrigin() == EventItemOrigin.SYNC) { if (diffs.any { diff -> diff.eventOrigin() == EventItemOrigin.SYNC }) {
onNewSyncedEvent() onNewSyncedEvent()
} }
postDiff(diff) postDiffs(diffs)
}.launchIn(this) }.launchIn(this)
innerRoom.backPaginationStatusFlow() innerRoom.backPaginationStatusFlow()
@ -135,11 +133,10 @@ class RustMatrixTimeline(
} }
} }
@OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
override val timelineItems: Flow<List<MatrixTimelineItem>> = _timelineItems.sample(50) override val timelineItems: Flow<List<MatrixTimelineItem>> = _timelineItems.mapLatest { items ->
.mapLatest { items -> encryptedHistoryPostProcessor.process(items)
encryptedHistoryPostProcessor.process(items) }
}
private suspend fun postItems(items: List<TimelineItem>) = coroutineScope { private suspend fun postItems(items: List<TimelineItem>) = coroutineScope {
// Split the initial items in multiple list as there is no pagination in the cached data, so we can post timelineItems asap. // Split the initial items in multiple list as there is no pagination in the cached data, so we can post timelineItems asap.
@ -151,9 +148,9 @@ class RustMatrixTimeline(
initLatch.complete(Unit) initLatch.complete(Unit)
} }
private suspend fun postDiff(timelineDiff: TimelineDiff) { private suspend fun postDiffs(diffs: List<TimelineDiff>) {
initLatch.await() initLatch.await()
timelineDiffProcessor.postDiff(timelineDiff) timelineDiffProcessor.postDiffs(diffs)
} }
private fun postPaginationStatus(status: BackPaginationStatus) { private fun postPaginationStatus(status: BackPaginationStatus) {