Skip to content

fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.6.18 #4894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
import io.element.android.libraries.matrix.api.room.message.replyInThread
import io.element.android.libraries.matrix.ui.messages.reply.eventId
import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand Down Expand Up @@ -98,6 +102,18 @@ class SendLocationPresenter @Inject constructor(
event: SendLocationEvents.SendLocation,
mode: SendLocationState.Mode,
) {
val replyMode = messageComposerContext.composerMode as? MessageComposerMode.Reply
val replyParams = replyMode?.replyToDetails?.let { details ->
if (replyMode.inThread) {
replyInThread(details.eventId())
} else {
ReplyParameters(
inReplyToEventId = details.eventId(),
enforceThreadReply = false,
replyWithinThread = false
)
}
}
when (mode) {
SendLocationState.Mode.PinLocation -> {
val geoUri = event.cameraPosition.toGeoUri()
Expand All @@ -106,7 +122,8 @@ class SendLocationPresenter @Inject constructor(
geoUri = geoUri,
description = null,
zoomLevel = MapDefaults.DEFAULT_ZOOM.toInt(),
assetType = AssetType.PIN
assetType = AssetType.PIN,
replyParameters = replyParams,
)
analyticsService.capture(
Composer(
Expand All @@ -124,7 +141,8 @@ class SendLocationPresenter @Inject constructor(
geoUri = geoUri,
description = null,
zoomLevel = MapDefaults.DEFAULT_ZOOM.toInt(),
assetType = AssetType.SENDER
assetType = AssetType.SENDER,
replyParameters = replyParams,
)
analyticsService.capture(
Composer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import io.element.android.features.location.impl.common.permissions.PermissionsS
import io.element.android.features.messages.test.FakeMessageComposerContext
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.core.aBuildMeta
Expand Down Expand Up @@ -263,7 +264,7 @@ class SendLocationPresenterTest {

@Test
fun `share sender location`() = runTest {
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, ReplyParameters?, Result<Unit>> { _, _, _, _, _, _ ->
Result.success(Unit)
}
val joinedRoom = FakeJoinedRoom(
Expand Down Expand Up @@ -310,6 +311,7 @@ class SendLocationPresenterTest {
value(null),
value(15),
value(AssetType.SENDER),
value(null),
)

assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1)
Expand All @@ -326,7 +328,7 @@ class SendLocationPresenterTest {

@Test
fun `share pin location`() = runTest {
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, ReplyParameters?, Result<Unit>> { _, _, _, _, _, _ ->
Result.success(Unit)
}
val joinedRoom = FakeJoinedRoom(
Expand Down Expand Up @@ -373,6 +375,7 @@ class SendLocationPresenterTest {
value(null),
value(15),
value(AssetType.PIN),
value(null),
)

assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1)
Expand All @@ -389,7 +392,7 @@ class SendLocationPresenterTest {

@Test
fun `composer context passes through analytics`() = runTest {
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, ReplyParameters?, Result<Unit>> { _, _, _, _, _, _ ->
Result.success(Unit)
}
val joinedRoom = FakeJoinedRoom(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
package io.element.android.features.messages.impl.draft

import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft

interface ComposerDraftService {
suspend fun loadDraft(roomId: RoomId, isVolatile: Boolean): ComposerDraft?
suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?, isVolatile: Boolean)
suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?, isVolatile: Boolean): ComposerDraft?
suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?, isVolatile: Boolean)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
package io.element.android.features.messages.impl.draft

import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft

interface ComposerDraftStore {
suspend fun loadDraft(roomId: RoomId): ComposerDraft?
suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?)
suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?): ComposerDraft?
suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package io.element.android.features.messages.impl.draft
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import javax.inject.Inject

Expand All @@ -18,12 +19,12 @@ class DefaultComposerDraftService @Inject constructor(
private val volatileComposerDraftStore: VolatileComposerDraftStore,
private val matrixComposerDraftStore: MatrixComposerDraftStore,
) : ComposerDraftService {
override suspend fun loadDraft(roomId: RoomId, isVolatile: Boolean): ComposerDraft? {
return getStore(isVolatile).loadDraft(roomId)
override suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?, isVolatile: Boolean): ComposerDraft? {
return getStore(isVolatile).loadDraft(roomId, threadRoot)
}

override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?, isVolatile: Boolean) {
getStore(isVolatile).updateDraft(roomId, draft)
override suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?, isVolatile: Boolean) {
getStore(isVolatile).updateDraft(roomId, threadRoot, draft)
}

private fun getStore(isVolatile: Boolean): ComposerDraftStore {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package io.element.android.features.messages.impl.draft

import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import timber.log.Timber
import javax.inject.Inject
Expand All @@ -20,26 +21,26 @@ import javax.inject.Inject
class MatrixComposerDraftStore @Inject constructor(
private val client: MatrixClient,
) : ComposerDraftStore {
override suspend fun loadDraft(roomId: RoomId): ComposerDraft? {
override suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?): ComposerDraft? {
return client.getRoom(roomId)?.use { room ->
room.loadComposerDraft()
room.loadComposerDraft(threadRoot)
.onFailure {
Timber.e(it, "Failed to load composer draft for room $roomId")
}
.onSuccess { draft ->
room.clearComposerDraft()
room.clearComposerDraft(threadRoot)
Timber.d("Loaded composer draft for room $roomId : $draft")
}
.getOrNull()
}
}

override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?) {
override suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?) {
client.getRoom(roomId)?.use { room ->
val updateDraftResult = if (draft == null) {
room.clearComposerDraft()
room.clearComposerDraft(threadRoot)
} else {
room.saveComposerDraft(draft)
room.saveComposerDraft(draft, threadRoot)
}
updateDraftResult
.onFailure {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package io.element.android.features.messages.impl.draft

import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import javax.inject.Inject

Expand All @@ -17,18 +18,20 @@ import javax.inject.Inject
* Currently it's used to store draft message when moving to edit mode.
*/
class VolatileComposerDraftStore @Inject constructor() : ComposerDraftStore {
private val drafts: MutableMap<RoomId, ComposerDraft> = mutableMapOf()
private val drafts: MutableMap<String, ComposerDraft> = mutableMapOf()

override suspend fun loadDraft(roomId: RoomId): ComposerDraft? {
override suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?): ComposerDraft? {
val key = threadRoot?.value ?: roomId.value
// Remove the draft from the map when it is loaded
return drafts.remove(roomId)
return drafts.remove(key)
}

override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?) {
override suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?) {
val key = threadRoot?.value ?: roomId.value
if (draft == null) {
drafts.remove(roomId)
drafts.remove(key)
} else {
drafts[roomId] = draft
drafts[key] = draft
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,12 @@ class MessageComposerPresenter @AssistedInject constructor(
)

LaunchedEffect(Unit) {
val draft = draftService.loadDraft(room.roomId, isVolatile = false)
val draft = draftService.loadDraft(
roomId = room.roomId,
// TODO support threads in composer
threadRoot = null,
isVolatile = false
)
if (draft != null) {
applyDraft(draft, markdownTextEditorState, richTextEditorState)
}
Expand Down Expand Up @@ -539,7 +544,9 @@ class MessageComposerPresenter @AssistedInject constructor(
draftService.updateDraft(
roomId = room.roomId,
draft = draft,
isVolatile = isVolatile
isVolatile = isVolatile,
// TODO support threads in composer
threadRoot = null,
)
}

Expand Down Expand Up @@ -700,7 +707,12 @@ class MessageComposerPresenter @AssistedInject constructor(
fromEdit: Boolean,
) {
// Use the volatile draft only when coming from edit mode otherwise.
val draft = draftService.loadDraft(room.roomId, isVolatile = true).takeIf { fromEdit }
val draft = draftService.loadDraft(
roomId = room.roomId,
// TODO support threads in composer
threadRoot = null,
isVolatile = true
).takeIf { fromEdit }
if (draft != null) {
applyDraft(draft, markdownTextEditorState, richTextEditorState)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ internal fun MessageShield.toText(): String {
is MessageShield.UnverifiedIdentity -> CommonStrings.event_shield_reason_unverified_identity
is MessageShield.SentInClear -> CommonStrings.event_shield_reason_sent_in_clear
is MessageShield.VerificationViolation -> CommonStrings.event_shield_reason_previously_verified
is MessageShield.MismatchedSender -> CommonStrings.event_shield_mismatched_sender
}
)
}
Expand All @@ -91,7 +92,8 @@ internal fun MessageShield.toIcon(): ImageVector {
is MessageShield.UnknownDevice,
is MessageShield.UnsignedDevice,
is MessageShield.UnverifiedIdentity,
is MessageShield.VerificationViolation -> CompoundIcons.HelpSolid()
is MessageShield.VerificationViolation,
is MessageShield.MismatchedSender -> CompoundIcons.HelpSolid()
Copy link
Member

@jmartinesp jmartinesp Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the string above match the iOS changes.

is MessageShield.SentInClear -> CompoundIcons.LockOff()
}
}
Expand Down Expand Up @@ -122,6 +124,9 @@ internal fun MessageShieldViewPreview() {
MessageShieldView(
shield = MessageShield.VerificationViolation(false)
)
MessageShieldView(
shield = MessageShield.MismatchedSender(false)
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@
package io.element.android.features.messages.impl.draft

import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft

class FakeComposerDraftService : ComposerDraftService {
var loadDraftLambda: (RoomId, Boolean) -> ComposerDraft? = { _, _ -> null }
override suspend fun loadDraft(roomId: RoomId, isVolatile: Boolean): ComposerDraft? = loadDraftLambda(roomId, isVolatile)
var loadDraftLambda: (RoomId, ThreadId?, Boolean) -> ComposerDraft? = { _, _, _ -> null }
override suspend fun loadDraft(
roomId: RoomId,
threadRoot: ThreadId?,
isVolatile: Boolean
): ComposerDraft? = loadDraftLambda(roomId, threadRoot, isVolatile)

var saveDraftLambda: (RoomId, ComposerDraft?, Boolean) -> Unit = { _, _, _ -> }
override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?, isVolatile: Boolean) = saveDraftLambda(roomId, draft, isVolatile)
var saveDraftLambda: (RoomId, ThreadId?, ComposerDraft?, Boolean) -> Unit = { _, _, _, _ -> }
override suspend fun updateDraft(
roomId: RoomId,
threadRoot: ThreadId?,
draft: ComposerDraft?,
isVolatile: Boolean
) = saveDraftLambda(roomId, threadRoot, draft, isVolatile)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.draft.ComposerDraftType
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_THREAD_ID
import kotlinx.coroutines.test.runTest
import org.junit.Test

Expand All @@ -21,27 +22,51 @@ class VolatileComposerDraftStoreTest {

@Test
fun `when storing a non-null draft and then loading it, it's loaded and removed`() = runTest {
val initialDraft = sut.loadDraft(roomId)
val initialDraft = sut.loadDraft(roomId = roomId, threadRoot = null)
assertThat(initialDraft).isNull()

sut.updateDraft(roomId, draft)
sut.updateDraft(roomId = roomId, threadRoot = null, draft = draft)

val loadedDraft = sut.loadDraft(roomId)
val loadedDraft = sut.loadDraft(roomId = roomId, threadRoot = null)
assertThat(loadedDraft).isEqualTo(draft)

val loadedDraftAfter = sut.loadDraft(roomId)
val loadedDraftAfter = sut.loadDraft(roomId = roomId, threadRoot = null)
assertThat(loadedDraftAfter).isNull()

// In thread:
val threadRoot = A_THREAD_ID
val initialThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot)
assertThat(initialThreadDraft).isNull()

sut.updateDraft(roomId = roomId, threadRoot = threadRoot, draft = draft)

val loadedThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot)
assertThat(loadedThreadDraft).isEqualTo(draft)

val loadedThreadDraftAfter = sut.loadDraft(roomId = roomId, threadRoot = threadRoot)
assertThat(loadedThreadDraftAfter).isNull()
}

@Test
fun `when storing a null draft and then loading it, it's removing the previous one`() = runTest {
val initialDraft = sut.loadDraft(roomId)
val initialDraft = sut.loadDraft(roomId = roomId, threadRoot = null)
assertThat(initialDraft).isNull()

sut.updateDraft(roomId, draft)
sut.updateDraft(roomId, null)
sut.updateDraft(roomId = roomId, threadRoot = null, draft = draft)
sut.updateDraft(roomId = roomId, threadRoot = null, draft = null)

val loadedDraft = sut.loadDraft(roomId)
val loadedDraft = sut.loadDraft(roomId = roomId, threadRoot = null)
assertThat(loadedDraft).isNull()

// In thread:
val threadRoot = A_THREAD_ID
val initialThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot)
assertThat(initialThreadDraft).isNull()

sut.updateDraft(roomId = roomId, threadRoot = threadRoot, draft = draft)
sut.updateDraft(roomId = roomId, threadRoot = threadRoot, draft = null)

val loadedThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot)
assertThat(loadedThreadDraft).isNull()
}
}
Loading
Loading