Update dependency org.matrix.rustcomponents:sdk-android to v0.2.41 (#3384)

* Introduce value class UniqueId.

* Allow reactions on non-sent Event, the SDK can now handle it.

Also the SDK will manage local echo for reactions.

* Update dependency org.matrix.rustcomponents:sdk-android to v0.2.41

* Fixes after SDK upgrade:

- Use `ClientBuilderSlidingSync` to set `SlidingSyncVersionBuilder` in `RustMatrixClientFactory`.
- `Room.toggleReaction(emoji: String, eventId: EventId)` is now `Room.toggleReaction(emoji: String, uniqueId: UniqueId)`, since reactions can now be applied to local echoes too in the SDK.

* Rename exception case

* Fix wrong error case being used in test

---------

Co-authored-by: Benoit Marty <benoit@matrix.org>
Co-authored-by: Benoit Marty <benoitm@matrix.org>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
renovate[bot] 2024-09-03 20:09:33 +02:00 committed by GitHub
parent 5920fd3f45
commit 9fb82a1e86
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 237 additions and 168 deletions

View file

@ -16,6 +16,7 @@
package io.element.android.libraries.matrix.impl
import io.element.android.appconfig.AuthenticationConfig
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.di.CacheDirectory
import io.element.android.libraries.matrix.impl.analytics.UtdTracker
@ -34,6 +35,8 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.ClientBuilder
import org.matrix.rustcomponents.sdk.Session
import org.matrix.rustcomponents.sdk.SlidingSyncVersion
import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder
import org.matrix.rustcomponents.sdk.use
import timber.log.Timber
import java.io.File
@ -56,11 +59,11 @@ class RustMatrixClientFactory @Inject constructor(
val client = getBaseClientBuilder(
sessionPaths = sessionData.getSessionPaths(),
passphrase = sessionData.passphrase,
slidingSync = if (appPreferencesStore.isSimplifiedSlidingSyncEnabledFlow().first()) {
ClientBuilderSlidingSync.Simplified
} else {
ClientBuilderSlidingSync.Restored
},
slidingSync = when {
AuthenticationConfig.SLIDING_SYNC_PROXY_URL != null -> ClientBuilderSlidingSync.CustomProxy(AuthenticationConfig.SLIDING_SYNC_PROXY_URL!!)
appPreferencesStore.isSimplifiedSlidingSyncEnabledFlow().first() -> ClientBuilderSlidingSync.Simplified
else -> ClientBuilderSlidingSync.Restored
}
)
.homeserverUrl(sessionData.homeserverUrl)
.username(sessionData.userId)
@ -91,7 +94,6 @@ class RustMatrixClientFactory @Inject constructor(
internal fun getBaseClientBuilder(
sessionPaths: SessionPaths,
passphrase: String?,
slidingSyncProxy: String? = null,
slidingSync: ClientBuilderSlidingSync,
): ClientBuilder {
return ClientBuilder()
@ -100,16 +102,17 @@ class RustMatrixClientFactory @Inject constructor(
cachePath = sessionPaths.cacheDirectory.absolutePath,
)
.passphrase(passphrase)
.slidingSyncProxy(slidingSyncProxy)
.userAgent(userAgentProvider.provide())
.addRootCertificates(userCertificatesProvider.provides())
.autoEnableBackups(true)
.autoEnableCrossSigning(true)
.run {
// Apply sliding sync version settings
when (slidingSync) {
ClientBuilderSlidingSync.Restored -> this
ClientBuilderSlidingSync.Discovered -> requiresSlidingSync()
ClientBuilderSlidingSync.Simplified -> simplifiedSlidingSync(true)
is ClientBuilderSlidingSync.CustomProxy -> slidingSyncVersionBuilder(SlidingSyncVersionBuilder.Proxy(slidingSync.url))
ClientBuilderSlidingSync.Discovered -> slidingSyncVersionBuilder(SlidingSyncVersionBuilder.DiscoverProxy)
ClientBuilderSlidingSync.Simplified -> slidingSyncVersionBuilder(SlidingSyncVersionBuilder.Native)
}
}
.run {
@ -119,15 +122,18 @@ class RustMatrixClientFactory @Inject constructor(
}
}
enum class ClientBuilderSlidingSync {
sealed interface ClientBuilderSlidingSync {
// The proxy is set by the user.
data class CustomProxy(val url: String) : ClientBuilderSlidingSync
// The proxy will be supplied when restoring the Session.
Restored,
data object Restored : ClientBuilderSlidingSync
// A proxy must be discovered whilst building the session.
Discovered,
data object Discovered : ClientBuilderSlidingSync
// Use Simplified Sliding Sync (discovery isn't a thing yet).
Simplified,
data object Simplified : ClientBuilderSlidingSync
}
private fun SessionData.toSession() = Session(
@ -136,6 +142,6 @@ private fun SessionData.toSession() = Session(
userId = userId,
deviceId = deviceId,
homeserverUrl = homeserverUrl,
slidingSyncProxy = slidingSyncProxy,
slidingSyncVersion = slidingSyncProxy?.let(SlidingSyncVersion::Proxy) ?: SlidingSyncVersion.Native,
oidcData = oidcData,
)

View file

@ -24,7 +24,7 @@ fun Throwable.mapAuthenticationException(): AuthenticationException {
return when (this) {
is RustAuthenticationException.Generic -> AuthenticationException.Generic(message)
is RustAuthenticationException.InvalidServerName -> AuthenticationException.InvalidServerName(message)
is RustAuthenticationException.SlidingSyncNotAvailable -> AuthenticationException.SlidingSyncNotAvailable(message)
is RustAuthenticationException.SlidingSyncVersion -> AuthenticationException.SlidingSyncVersion(message)
else -> AuthenticationException.Generic(message)
}
}

View file

@ -17,7 +17,6 @@
package io.element.android.libraries.matrix.impl.auth
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.appconfig.AuthenticationConfig
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.extensions.mapFailure
import io.element.android.libraries.di.AppScope
@ -223,7 +222,6 @@ class RustMatrixAuthenticationService @Inject constructor(
val client = rustMatrixClientFactory.getBaseClientBuilder(
sessionPaths = emptySessionPaths,
passphrase = pendingPassphrase,
slidingSyncProxy = AuthenticationConfig.SLIDING_SYNC_PROXY_URL,
slidingSync = ClientBuilderSlidingSync.Discovered,
)
.buildWithQrCode(
@ -267,7 +265,6 @@ class RustMatrixAuthenticationService @Inject constructor(
.getBaseClientBuilder(
sessionPaths = sessionPaths,
passphrase = pendingPassphrase,
slidingSyncProxy = AuthenticationConfig.SLIDING_SYNC_PROXY_URL,
slidingSync = ClientBuilderSlidingSync.Discovered,
)

View file

@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.impl.paths.SessionPaths
import io.element.android.libraries.sessionstorage.api.LoginType
import io.element.android.libraries.sessionstorage.api.SessionData
import org.matrix.rustcomponents.sdk.Session
import org.matrix.rustcomponents.sdk.SlidingSyncVersion
import java.util.Date
internal fun Session.toSessionData(
@ -35,7 +36,7 @@ internal fun Session.toSessionData(
refreshToken = refreshToken,
homeserverUrl = homeserverUrl ?: this.homeserverUrl,
oidcData = oidcData,
slidingSyncProxy = slidingSyncProxy,
slidingSyncProxy = (slidingSyncVersion as? SlidingSyncVersion.Proxy)?.url,
loginTimestamp = Date(),
isTokenValid = isTokenValid,
loginType = loginType,

View file

@ -25,6 +25,7 @@ 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.SessionId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.media.AudioInfo
import io.element.android.libraries.matrix.api.media.FileInfo
@ -459,8 +460,8 @@ class RustMatrixRoom(
return liveTimeline.sendFile(file, fileInfo, progressCallback)
}
override suspend fun toggleReaction(emoji: String, eventId: EventId): Result<Unit> {
return liveTimeline.toggleReaction(emoji, eventId)
override suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit> {
return liveTimeline.toggleReaction(emoji, uniqueId)
}
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> {

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.impl.timeline
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper
import io.element.android.libraries.matrix.impl.timeline.item.virtual.VirtualTimelineItemMapper
@ -31,7 +32,7 @@ class MatrixTimelineItemMapper(
private val eventTimelineItemMapper: EventTimelineItemMapper = EventTimelineItemMapper(),
) {
fun map(timelineItem: TimelineItem): MatrixTimelineItem = timelineItem.use {
val uniqueId = timelineItem.uniqueId()
val uniqueId = UniqueId(timelineItem.uniqueId())
val asEvent = it.asEvent()
if (asEvent != null) {
val eventTimelineItem = eventTimelineItemMapper.map(asEvent)

View file

@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.ProgressCallback
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.media.AudioInfo
import io.element.android.libraries.matrix.api.media.FileInfo
import io.element.android.libraries.matrix.api.media.ImageInfo
@ -391,9 +392,9 @@ class RustTimeline(
}
}
override suspend fun toggleReaction(emoji: String, eventId: EventId): Result<Unit> = withContext(dispatcher) {
override suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit> = withContext(dispatcher) {
runCatching {
inner.toggleReaction(key = emoji, eventId = eventId.value)
inner.toggleReaction(key = emoji, uniqueId = uniqueId.value)
}
}

View file

@ -16,6 +16,7 @@
package io.element.android.libraries.matrix.impl.timeline.postprocessor
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
@ -25,7 +26,7 @@ import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTime
class LastForwardIndicatorsPostProcessor(
private val isTimelineLive: Boolean,
) {
private val lastForwardIdentifiers = LinkedHashSet<String>()
private val lastForwardIdentifiers = LinkedHashSet<UniqueId>()
fun process(
items: List<MatrixTimelineItem>,
@ -56,17 +57,17 @@ class LastForwardIndicatorsPostProcessor(
}
}
private fun createLastForwardIndicator(identifier: String): MatrixTimelineItem {
private fun createLastForwardIndicator(identifier: UniqueId): MatrixTimelineItem {
return MatrixTimelineItem.Virtual(
uniqueId = "last_forward_indicator_$identifier",
uniqueId = UniqueId("last_forward_indicator_$identifier"),
virtual = VirtualTimelineItem.LastForwardIndicator
)
}
private fun List<MatrixTimelineItem>.latestEventIdentifier(): String {
private fun List<MatrixTimelineItem>.latestEventIdentifier(): UniqueId {
return findLast {
it is MatrixTimelineItem.Event
}?.let {
(it as MatrixTimelineItem.Event).uniqueId
} ?: "fake_id"
} ?: UniqueId("fake_id")
}

View file

@ -16,6 +16,7 @@
package io.element.android.libraries.matrix.impl.timeline.postprocessor
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
@ -33,7 +34,7 @@ class LoadingIndicatorsPostProcessor(private val systemClock: SystemClock) {
return buildList {
if (shouldAddBackwardLoadingIndicator) {
val backwardLoadingIndicator = MatrixTimelineItem.Virtual(
uniqueId = "BackwardLoadingIndicator",
uniqueId = UniqueId("BackwardLoadingIndicator"),
virtual = VirtualTimelineItem.LoadingIndicator(
direction = Timeline.PaginationDirection.BACKWARDS,
timestamp = currentTimestamp
@ -44,7 +45,7 @@ class LoadingIndicatorsPostProcessor(private val systemClock: SystemClock) {
addAll(items)
if (shouldAddForwardLoadingIndicator) {
val forwardLoadingIndicator = MatrixTimelineItem.Virtual(
uniqueId = "ForwardLoadingIndicator",
uniqueId = UniqueId("ForwardLoadingIndicator"),
virtual = VirtualTimelineItem.LoadingIndicator(
direction = Timeline.PaginationDirection.FORWARDS,
timestamp = currentTimestamp

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.impl.timeline.postprocessor
import androidx.annotation.VisibleForTesting
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState
@ -77,7 +78,7 @@ class RoomBeginningPostProcessor {
@VisibleForTesting
fun createRoomBeginningItem(): MatrixTimelineItem.Virtual {
return MatrixTimelineItem.Virtual(
uniqueId = VirtualTimelineItem.RoomBeginning.toString(),
uniqueId = UniqueId("RoomBeginning"),
virtual = VirtualTimelineItem.RoomBeginning
)
}

View file

@ -16,6 +16,7 @@
package io.element.android.libraries.matrix.impl.timeline.postprocessor
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
import kotlinx.coroutines.CoroutineDispatcher
@ -23,6 +24,8 @@ import kotlinx.coroutines.withContext
import timber.log.Timber
import java.util.Date
internal val encryptedHistoryBannerId = UniqueId("EncryptedHistoryBannerId")
class TimelineEncryptedHistoryPostProcessor(
private val dispatcher: CoroutineDispatcher,
private val lastLoginTimestamp: Date?,
@ -44,7 +47,7 @@ class TimelineEncryptedHistoryPostProcessor(
}
return if (lastEncryptedHistoryBannerIndex >= 0) {
val sublist = list.drop(lastEncryptedHistoryBannerIndex + 1).toMutableList()
sublist.add(0, MatrixTimelineItem.Virtual(VirtualTimelineItem.EncryptedHistoryBanner.toString(), VirtualTimelineItem.EncryptedHistoryBanner))
sublist.add(0, MatrixTimelineItem.Virtual(encryptedHistoryBannerId, VirtualTimelineItem.EncryptedHistoryBanner))
sublist
} else {
list