Update dependency org.matrix.rustcomponents:sdk-android to v25.8.18 (#5182)

* Update dependency org.matrix.rustcomponents:sdk-android to v25.8.18

* Fix broken API changes:
- The send queue usage is now mandatory.
- The media upload progress now comes back in the send queue state (this still hasn't been applied to the UI in the timeline).

* Update screenshots
---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
renovate[bot] 2025-08-18 16:41:14 +02:00 committed by GitHub
parent fcb63c02e1
commit aac9642159
27 changed files with 85 additions and 147 deletions

View file

@ -10,7 +10,6 @@ package io.element.android.libraries.matrix.api
import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.core.MatrixPatterns
import io.element.android.libraries.matrix.api.core.ProgressCallback
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.RoomIdOrAlias
@ -94,7 +93,7 @@ interface MatrixClient {
*/
suspend fun getUserProfile(): Result<MatrixUser>
suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?>
suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result<String>
suspend fun uploadMedia(mimeType: String, data: ByteArray): Result<String>
fun roomMembershipObserver(): RoomMembershipObserver
/**

View file

@ -8,7 +8,6 @@
package io.element.android.libraries.matrix.api.timeline
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.media.AudioInfo
@ -88,7 +87,6 @@ interface Timeline : AutoCloseable {
imageInfo: ImageInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler>
@ -98,7 +96,6 @@ interface Timeline : AutoCloseable {
videoInfo: VideoInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler>
@ -107,7 +104,6 @@ interface Timeline : AutoCloseable {
audioInfo: AudioInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler>
@ -116,7 +112,6 @@ interface Timeline : AutoCloseable {
fileInfo: FileInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler>
@ -145,7 +140,6 @@ interface Timeline : AutoCloseable {
file: File,
audioInfo: AudioInfo,
waveform: List<Float>,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler>

View file

@ -14,7 +14,14 @@ import io.element.android.libraries.matrix.api.core.UserId
@Immutable
sealed interface LocalEventSendState {
data object Sending : LocalEventSendState
sealed interface Sending : LocalEventSendState {
data object Event : Sending
data class MediaWithProgress(
val index: Long,
val progress: Long,
val total: Long
) : Sending
}
sealed interface Failed : LocalEventSendState {
data class Unknown(val error: String) : Failed
data object SendingFromUnverifiedDevice : Failed

View file

@ -16,7 +16,6 @@ import io.element.android.libraries.core.extensions.mapFailure
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.core.ProgressCallback
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.RoomIdOrAlias
@ -48,7 +47,6 @@ import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import io.element.android.libraries.matrix.impl.core.toProgressWatcher
import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService
import io.element.android.libraries.matrix.impl.exception.mapClientException
import io.element.android.libraries.matrix.impl.media.RustMediaLoader
@ -627,9 +625,9 @@ class RustMatrixClient(
}
}
override suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result<String> = withContext(sessionDispatcher) {
override suspend fun uploadMedia(mimeType: String, data: ByteArray): Result<String> = withContext(sessionDispatcher) {
runCatchingExceptions {
innerClient.uploadMedia(mimeType, data, progressCallback?.toProgressWatcher())
innerClient.uploadMedia(mimeType, data, progressWatcher = null)
}
}

View file

@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.impl.timeline
import io.element.android.libraries.core.extensions.runCatchingExceptions
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.media.AudioInfo
import io.element.android.libraries.matrix.api.media.FileInfo
@ -27,7 +26,6 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.TimelineException
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo
import io.element.android.libraries.matrix.impl.core.toProgressWatcher
import io.element.android.libraries.matrix.impl.media.MediaUploadHandlerImpl
import io.element.android.libraries.matrix.impl.media.map
import io.element.android.libraries.matrix.impl.media.toMSC3246range
@ -336,7 +334,6 @@ class RustTimeline(
imageInfo: ImageInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler> {
return sendAttachment(listOfNotNull(file, thumbnailFile)) {
@ -347,13 +344,11 @@ class RustTimeline(
formattedCaption = formattedCaption?.let {
FormattedBody(body = it, format = MessageFormat.Html)
},
useSendQueue = true,
mentions = null,
inReplyTo = inReplyToEventId?.value,
),
thumbnailPath = thumbnailFile?.path,
thumbnailSource = thumbnailFile?.path?.let(UploadSource::File),
imageInfo = imageInfo.map(),
progressWatcher = progressCallback?.toProgressWatcher()
)
}
}
@ -364,7 +359,6 @@ class RustTimeline(
videoInfo: VideoInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler> {
return sendAttachment(listOfNotNull(file, thumbnailFile)) {
@ -375,13 +369,11 @@ class RustTimeline(
formattedCaption = formattedCaption?.let {
FormattedBody(body = it, format = MessageFormat.Html)
},
useSendQueue = true,
mentions = null,
inReplyTo = inReplyToEventId?.value,
),
thumbnailPath = thumbnailFile?.path,
thumbnailSource = thumbnailFile?.path?.let(UploadSource::File),
videoInfo = videoInfo.map(),
progressWatcher = progressCallback?.toProgressWatcher()
)
}
}
@ -391,7 +383,6 @@ class RustTimeline(
audioInfo: AudioInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler> {
return sendAttachment(listOf(file)) {
@ -402,12 +393,10 @@ class RustTimeline(
formattedCaption = formattedCaption?.let {
FormattedBody(body = it, format = MessageFormat.Html)
},
useSendQueue = true,
mentions = null,
inReplyTo = inReplyToEventId?.value,
),
audioInfo = audioInfo.map(),
progressWatcher = progressCallback?.toProgressWatcher()
)
}
}
@ -417,7 +406,6 @@ class RustTimeline(
fileInfo: FileInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler> {
return sendAttachment(listOf(file)) {
@ -428,12 +416,10 @@ class RustTimeline(
formattedCaption = formattedCaption?.let {
FormattedBody(body = it, format = MessageFormat.Html)
},
useSendQueue = true,
mentions = null,
inReplyTo = inReplyToEventId?.value,
),
fileInfo = fileInfo.map(),
progressWatcher = progressCallback?.toProgressWatcher(),
)
}
}
@ -479,7 +465,6 @@ class RustTimeline(
file: File,
audioInfo: AudioInfo,
waveform: List<Float>,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler> {
return sendAttachment(listOf(file)) {
@ -489,13 +474,11 @@ class RustTimeline(
// Maybe allow a caption in the future?
caption = null,
formattedCaption = null,
useSendQueue = true,
mentions = null,
inReplyTo = inReplyToEventId?.value,
),
audioInfo = audioInfo.map(),
waveform = waveform.toMSC3246range(),
progressWatcher = progressCallback?.toProgressWatcher(),
)
}
}

View file

@ -79,7 +79,18 @@ fun RustProfileDetails.map(): ProfileTimelineDetails {
fun RustEventSendState?.map(): LocalEventSendState? {
return when (this) {
null -> null
RustEventSendState.NotSentYet -> LocalEventSendState.Sending
is RustEventSendState.NotSentYet -> {
val mediaUploadProgress = this.progress
if (mediaUploadProgress != null) {
LocalEventSendState.Sending.MediaWithProgress(
index = mediaUploadProgress.index.toLong(),
progress = mediaUploadProgress.progress.current.toLong(),
total = mediaUploadProgress.progress.total.toLong(),
)
} else {
LocalEventSendState.Sending.Event
}
}
is RustEventSendState.SendingFailed -> {
when (val queueWedgeError = error) {
QueueWedgeError.CrossVerificationRequired -> {
@ -98,7 +109,7 @@ fun RustEventSendState?.map(): LocalEventSendState? {
}
is QueueWedgeError.GenericApiError -> {
if (isRecoverable) {
LocalEventSendState.Sending
LocalEventSendState.Sending.Event
} else {
LocalEventSendState.Failed.Unknown(queueWedgeError.msg)
}

View file

@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.test
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.core.ProgressCallback
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.RoomIdOrAlias
@ -201,7 +200,6 @@ class FakeMatrixClient(
override suspend fun uploadMedia(
mimeType: String,
data: ByteArray,
progressCallback: ProgressCallback?
): Result<String> {
return uploadMediaResult
}

View file

@ -8,7 +8,6 @@
package io.element.android.libraries.matrix.test.timeline
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.media.AudioInfo
@ -27,7 +26,6 @@ import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
import io.element.android.tests.testutils.lambda.lambdaError
import io.element.android.tests.testutils.simulateLongTask
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@ -49,7 +47,6 @@ class FakeTimeline(
)
),
override val membershipChangeEventReceived: Flow<Unit> = MutableSharedFlow(),
private val progressCallbackValues: List<Pair<Long, Long>> = emptyList(),
private val cancelSendResult: (TransactionId) -> Result<Unit> = { lambdaError() },
) : Timeline {
var sendMessageLambda: (
@ -150,9 +147,8 @@ class FakeTimeline(
imageInfo: ImageInfo,
body: String?,
formattedBody: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
) -> Result<MediaUploadHandler> = { _, _, _, _, _, _, _ ->
) -> Result<MediaUploadHandler> = { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
@ -162,17 +158,14 @@ class FakeTimeline(
imageInfo: ImageInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
): Result<MediaUploadHandler> = simulateLongTask {
simulateSendMediaProgress(progressCallback)
sendImageLambda(
file,
thumbnailFile,
imageInfo,
caption,
formattedCaption,
progressCallback,
inReplyToEventId,
)
}
@ -183,9 +176,8 @@ class FakeTimeline(
videoInfo: VideoInfo,
body: String?,
formattedBody: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
) -> Result<MediaUploadHandler> = { _, _, _, _, _, _, _ ->
) -> Result<MediaUploadHandler> = { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
@ -195,17 +187,14 @@ class FakeTimeline(
videoInfo: VideoInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
): Result<MediaUploadHandler> = simulateLongTask {
simulateSendMediaProgress(progressCallback)
sendVideoLambda(
file,
thumbnailFile,
videoInfo,
caption,
formattedCaption,
progressCallback,
inReplyToEventId,
)
}
@ -215,9 +204,8 @@ class FakeTimeline(
audioInfo: AudioInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
) -> Result<MediaUploadHandler> = { _, _, _, _, _, _ ->
) -> Result<MediaUploadHandler> = { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
@ -226,16 +214,13 @@ class FakeTimeline(
audioInfo: AudioInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
): Result<MediaUploadHandler> = simulateLongTask {
simulateSendMediaProgress(progressCallback)
sendAudioLambda(
file,
audioInfo,
caption,
formattedCaption,
progressCallback,
inReplyToEventId,
)
}
@ -245,9 +230,8 @@ class FakeTimeline(
fileInfo: FileInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
) -> Result<MediaUploadHandler> = { _, _, _, _, _, _ ->
) -> Result<MediaUploadHandler> = { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
@ -256,16 +240,13 @@ class FakeTimeline(
fileInfo: FileInfo,
caption: String?,
formattedCaption: String?,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
): Result<MediaUploadHandler> = simulateLongTask {
simulateSendMediaProgress(progressCallback)
sendFileLambda(
file,
fileInfo,
caption,
formattedCaption,
progressCallback,
inReplyToEventId,
)
}
@ -274,9 +255,8 @@ class FakeTimeline(
file: File,
audioInfo: AudioInfo,
waveform: List<Float>,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
) -> Result<MediaUploadHandler> = { _, _, _, _, _ ->
) -> Result<MediaUploadHandler> = { _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
@ -284,15 +264,12 @@ class FakeTimeline(
file: File,
audioInfo: AudioInfo,
waveform: List<Float>,
progressCallback: ProgressCallback?,
inReplyToEventId: EventId??,
): Result<MediaUploadHandler> = simulateLongTask {
simulateSendMediaProgress(progressCallback)
sendVoiceMessageLambda(
file,
audioInfo,
waveform,
progressCallback,
inReplyToEventId,
)
}
@ -460,12 +437,5 @@ class FakeTimeline(
closeCounter++
}
private suspend fun simulateSendMediaProgress(progressCallback: ProgressCallback?) {
progressCallbackValues.forEach { (current, total) ->
progressCallback?.onProgress(current, total)
delay(1)
}
}
override fun toString() = "FakeTimeline: $name"
}