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 c6ca70b7b1
commit 90ad9616c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 85 additions and 147 deletions

View file

@ -32,7 +32,6 @@ import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeImage
import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeVideo
import io.element.android.libraries.di.annotations.SessionCoroutineScope
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.permalink.PermalinkBuilder
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig
import io.element.android.libraries.mediaupload.api.MediaSender
@ -47,7 +46,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import timber.log.Timber
import kotlin.coroutines.coroutineContext
class AttachmentsPreviewPresenter @AssistedInject constructor(
@Assisted private val attachment: Attachment,
@ -304,20 +302,11 @@ class AttachmentsPreviewPresenter @AssistedInject constructor(
dismissAfterSend: Boolean,
inReplyToEventId: EventId?,
) = runCatchingExceptions {
val context = coroutineContext
val progressCallback = object : ProgressCallback {
override fun onProgress(current: Long, total: Long) {
// Note will not happen if useSendQueue is true
if (context.isActive) {
sendActionState.value = SendActionState.Sending.Uploading(current.toFloat() / total.toFloat(), mediaUploadInfo)
}
}
}
sendActionState.value = SendActionState.Sending.Uploading(mediaUploadInfo)
mediaSender.sendPreProcessedMedia(
mediaUploadInfo = mediaUploadInfo,
caption = caption,
formattedCaption = null,
progressCallback = progressCallback,
inReplyToEventId = inReplyToEventId,
).getOrThrow()
}.fold(

View file

@ -30,7 +30,7 @@ sealed interface SendActionState {
sealed interface Sending : SendActionState {
data class Processing(val displayProgress: Boolean) : Sending
data class ReadyToUpload(val mediaInfo: MediaUploadInfo) : Sending
data class Uploading(val progress: Float, val mediaUploadInfo: MediaUploadInfo) : Sending
data class Uploading(val mediaUploadInfo: MediaUploadInfo) : Sending
}
data class Failure(val error: Throwable, val mediaUploadInfo: MediaUploadInfo?) : SendActionState

View file

@ -39,7 +39,7 @@ open class AttachmentsPreviewStateProvider : PreviewParameterProvider<Attachment
),
anAttachmentsPreviewState(sendActionState = SendActionState.Sending.Processing(displayProgress = true)),
anAttachmentsPreviewState(sendActionState = SendActionState.Sending.ReadyToUpload(aMediaUploadInfo())),
anAttachmentsPreviewState(sendActionState = SendActionState.Sending.Uploading(0.5f, aMediaUploadInfo())),
anAttachmentsPreviewState(sendActionState = SendActionState.Sending.Uploading(aMediaUploadInfo())),
anAttachmentsPreviewState(sendActionState = SendActionState.Failure(RuntimeException("error"), aMediaUploadInfo())),
anAttachmentsPreviewState(displayFileTooLargeError = true),
anAttachmentsPreviewState(

View file

@ -143,7 +143,7 @@ private fun AttachmentSendStateView(
}
is SendActionState.Sending.Uploading -> {
ProgressDialog(
type = ProgressDialogType.Determinate(sendActionState.progress),
type = ProgressDialogType.Indeterminate,
text = stringResource(id = CommonStrings.common_sending),
showCancelButton = true,
onDismissRequest = onDismissClick,

View file

@ -510,7 +510,6 @@ class MessageComposerPresenter @AssistedInject constructor(
mediaSender.sendMedia(
uri = uri,
mimeType = mimeType,
progressCallback = null,
mediaOptimizationConfig = mediaOptimizationConfigProvider.get(),
).getOrThrow()
}

View file

@ -19,7 +19,7 @@ class TimelineItemEventForTimestampViewProvider : PreviewParameterProvider<Timel
override val values: Sequence<TimelineItem.Event>
get() = sequenceOf(
aTimelineItemEvent(),
aTimelineItemEvent().copy(localSendState = LocalEventSendState.Sending),
aTimelineItemEvent().copy(localSendState = LocalEventSendState.Sending.Event),
aTimelineItemEvent().copy(localSendState = LocalEventSendState.Failed.Unknown("AN_ERROR")),
// Edited
aTimelineItemEvent().copy(content = aTimelineItemTextContent().copy(isEdited = true)),

View file

@ -17,7 +17,7 @@ class ReadReceiptViewStateForTimelineItemEventRowProvider :
override val values: Sequence<ReadReceiptViewState>
get() = sequenceOf(
aReadReceiptViewState(
sendState = LocalEventSendState.Sending,
sendState = LocalEventSendState.Sending.Event,
),
aReadReceiptViewState(
sendState = LocalEventSendState.Sent(EventId("\$eventId")),

View file

@ -20,7 +20,7 @@ class ReadReceiptViewStateProvider : PreviewParameterProvider<ReadReceiptViewSta
override val values: Sequence<ReadReceiptViewState>
get() = sequenceOf(
aReadReceiptViewState(),
aReadReceiptViewState(sendState = LocalEventSendState.Sending),
aReadReceiptViewState(sendState = LocalEventSendState.Sending.Event),
aReadReceiptViewState(sendState = LocalEventSendState.Sent(EventId("\$eventId"))),
aReadReceiptViewState(
sendState = LocalEventSendState.Sent(EventId("\$eventId")),

View file

@ -76,7 +76,7 @@ fun TimelineItemReadReceiptView(
}
} else {
when (state.sendState) {
LocalEventSendState.Sending -> {
is LocalEventSendState.Sending -> {
ReadReceiptsRow(modifier) {
Icon(
modifier = Modifier.padding(2.dp),

View file

@ -26,7 +26,6 @@ import io.element.android.libraries.androidutils.file.TemporaryUriDeleter
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.core.mimetype.MimeTypes
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.media.AudioInfo
import io.element.android.libraries.matrix.api.media.FileInfo
import io.element.android.libraries.matrix.api.media.ImageInfo
@ -90,17 +89,11 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send media success scenario`() = runTest {
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
lambdaRecorder<File, FileInfo, String?, String?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val room = FakeJoinedRoom(
liveTimeline = FakeTimeline(
progressCallbackValues = listOf(
Pair(0, 10),
Pair(5, 10),
Pair(10, 10)
),
).apply {
liveTimeline = FakeTimeline().apply {
sendFileLambda = sendFileResult
},
)
@ -120,9 +113,7 @@ class AttachmentsPreviewPresenterTest {
initialState.eventSink(AttachmentsPreviewEvents.SendAttachment)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = true))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.ReadyToUpload(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(0f, mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(0.5f, mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(1f, mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Done)
sendFileResult.assertions().isCalledOnce()
onDoneListener.assertions().isCalledOnce()
@ -133,7 +124,7 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send media after pre-processing success scenario`() = runTest {
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
lambdaRecorder<File, FileInfo, String?, String?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val room = FakeJoinedRoom(
@ -160,6 +151,7 @@ class AttachmentsPreviewPresenterTest {
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
initialState.eventSink(AttachmentsPreviewEvents.SendAttachment)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.ReadyToUpload(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Done)
sendFileResult.assertions().isCalledOnce()
onDoneListener.assertions().isCalledOnce()
@ -170,7 +162,7 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send media before pre-processing success scenario`() = runTest {
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
lambdaRecorder<File, FileInfo, String?, String?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val room = FakeJoinedRoom(
@ -197,6 +189,7 @@ class AttachmentsPreviewPresenterTest {
processLatch.complete(Unit)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = true))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.ReadyToUpload(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Done)
sendFileResult.assertions().isCalledOnce()
onDoneListener.assertions().isCalledOnce()
@ -281,7 +274,7 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send image with caption success scenario`() = runTest {
val sendImageResult =
lambdaRecorder { _: File, _: File?, _: ImageInfo, _: String?, _: String?, _: ProgressCallback?, _: EventId? ->
lambdaRecorder { _: File, _: File?, _: ImageInfo, _: String?, _: String?, _: EventId? ->
Result.success(FakeMediaUploadHandler())
}
val mediaPreProcessor = FakeMediaPreProcessor().apply {
@ -307,6 +300,7 @@ class AttachmentsPreviewPresenterTest {
initialState.eventSink(AttachmentsPreviewEvents.SendAttachment)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
assertThat(awaitItem().sendActionState).isInstanceOf(SendActionState.Sending.ReadyToUpload::class.java)
assertThat(awaitItem().sendActionState).isInstanceOf(SendActionState.Sending.Uploading::class.java)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Done)
sendImageResult.assertions().isCalledOnce().with(
any(),
@ -315,7 +309,6 @@ class AttachmentsPreviewPresenterTest {
value(A_CAPTION),
any(),
any(),
any(),
)
onDoneListener.assertions().isCalledOnce()
}
@ -324,7 +317,7 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send video with caption success scenario`() = runTest {
val sendVideoResult =
lambdaRecorder { _: File, _: File?, _: VideoInfo, _: String?, _: String?, _: ProgressCallback?, _: EventId? ->
lambdaRecorder { _: File, _: File?, _: VideoInfo, _: String?, _: String?, _: EventId? ->
Result.success(FakeMediaUploadHandler())
}
val mediaPreProcessor = FakeMediaPreProcessor().apply {
@ -350,6 +343,7 @@ class AttachmentsPreviewPresenterTest {
initialState.eventSink(AttachmentsPreviewEvents.SendAttachment)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
assertThat(awaitItem().sendActionState).isInstanceOf(SendActionState.Sending.ReadyToUpload::class.java)
assertThat(awaitItem().sendActionState).isInstanceOf(SendActionState.Sending.Uploading::class.java)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Done)
sendVideoResult.assertions().isCalledOnce().with(
any(),
@ -358,7 +352,6 @@ class AttachmentsPreviewPresenterTest {
value(A_CAPTION),
any(),
any(),
any(),
)
onDoneListener.assertions().isCalledOnce()
}
@ -367,7 +360,7 @@ class AttachmentsPreviewPresenterTest {
@Test
fun `present - send audio with caption success scenario`() = runTest {
val sendAudioResult =
lambdaRecorder<File, AudioInfo, String?, String?, ProgressCallback?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
lambdaRecorder<File, AudioInfo, String?, String?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
val mediaPreProcessor = FakeMediaPreProcessor().apply {
@ -391,6 +384,7 @@ class AttachmentsPreviewPresenterTest {
initialState.eventSink(AttachmentsPreviewEvents.SendAttachment)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
assertThat(awaitItem().sendActionState).isInstanceOf(SendActionState.Sending.ReadyToUpload::class.java)
assertThat(awaitItem().sendActionState).isInstanceOf(SendActionState.Sending.Uploading::class.java)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Done)
sendAudioResult.assertions().isCalledOnce().with(
any(),
@ -398,7 +392,6 @@ class AttachmentsPreviewPresenterTest {
value(A_CAPTION),
any(),
any(),
any(),
)
onDoneListener.assertions().isCalledOnce()
}
@ -408,7 +401,7 @@ class AttachmentsPreviewPresenterTest {
fun `present - send media failure scenario`() = runTest {
val failure = MediaPreProcessor.Failure(null)
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
lambdaRecorder<File, FileInfo, String?, String?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
Result.failure(failure)
}
val onDoneListenerResult = lambdaRecorder<Unit> {}
@ -426,6 +419,7 @@ class AttachmentsPreviewPresenterTest {
initialState.eventSink(AttachmentsPreviewEvents.SendAttachment)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.ReadyToUpload(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(mediaUploadInfo))
// Check that the onDoneListener is called so the screen would be dismissed
onDoneListenerResult.assertions().isCalledOnce()
@ -445,7 +439,7 @@ class AttachmentsPreviewPresenterTest {
val presenter = createAttachmentsPreviewPresenter(
room = FakeJoinedRoom(
liveTimeline = FakeTimeline().apply {
sendFileLambda = { _, _, _, _, _, _ ->
sendFileLambda = { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
}
@ -460,7 +454,9 @@ class AttachmentsPreviewPresenterTest {
initialState.eventSink(AttachmentsPreviewEvents.SendAttachment)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing(displayProgress = false))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.ReadyToUpload(mediaUploadInfo))
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(mediaUploadInfo))
initialState.eventSink(AttachmentsPreviewEvents.CancelAndClearSendState)
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.ReadyToUpload(mediaUploadInfo))
// The sending is cancelled and the state is kept at ReadyToUpload
ensureAllEventsConsumed()
@ -480,7 +476,7 @@ class AttachmentsPreviewPresenterTest {
localMedia = localMedia,
room = FakeJoinedRoom(
liveTimeline = FakeTimeline().apply {
sendFileLambda = { _, _, _, _, _, _ ->
sendFileLambda = { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
}
@ -521,7 +517,7 @@ class AttachmentsPreviewPresenterTest {
localMedia = localMedia,
room = FakeJoinedRoom(
liveTimeline = FakeTimeline().apply {
sendFileLambda = { _, _, _, _, _, _ ->
sendFileLambda = { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
}

View file

@ -17,10 +17,21 @@ class SendActionStateTest {
@Test
fun `mediaUploadInfo() should return the value from Uploading class`() {
val mediaUploadInfo: MediaUploadInfo = aMediaUploadInfo()
val state: SendActionState = SendActionState.Sending.Uploading(
progress = 0.5f,
mediaUploadInfo = aMediaUploadInfo()
)
val state: SendActionState = SendActionState.Sending.Uploading(mediaUploadInfo = aMediaUploadInfo())
assertThat(state.mediaUploadInfo()).isEqualTo(mediaUploadInfo)
}
@Test
fun `mediaUploadInfo() should return the value from ReadyToUpload class`() {
val mediaUploadInfo: MediaUploadInfo = aMediaUploadInfo()
val state: SendActionState = SendActionState.Sending.ReadyToUpload(mediaInfo = aMediaUploadInfo())
assertThat(state.mediaUploadInfo()).isEqualTo(mediaUploadInfo)
}
@Test
fun `mediaUploadInfo() should return the value from Failure class`() {
val mediaUploadInfo: MediaUploadInfo = aMediaUploadInfo()
val state: SendActionState = SendActionState.Failure(error = IllegalStateException("An error"), mediaUploadInfo = aMediaUploadInfo())
assertThat(state.mediaUploadInfo()).isEqualTo(mediaUploadInfo)
}
}

View file

@ -1181,7 +1181,7 @@ class MessageComposerPresenterTest {
room = FakeJoinedRoom(
typingNoticeResult = { Result.success(Unit) },
liveTimeline = FakeTimeline().apply {
sendFileLambda = { _, _, _, _, _, _ ->
sendFileLambda = { _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
}

View file

@ -20,7 +20,6 @@ import im.vector.app.features.analytics.plan.Composer
import io.element.android.features.messages.impl.messagecomposer.aReplyMode
import io.element.android.features.messages.test.FakeMessageComposerContext
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.media.AudioInfo
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
@ -64,7 +63,7 @@ class VoiceMessageComposerPresenterTest {
)
private val analyticsService = FakeAnalyticsService()
private val sendVoiceMessageResult =
lambdaRecorder<File, AudioInfo, List<Float>, ProgressCallback?, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _, _ ->
lambdaRecorder<File, AudioInfo, List<Float>, EventId?, Result<FakeMediaUploadHandler>> { _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
private val joinedRoom = FakeJoinedRoom(