Update dependency org.matrix.rustcomponents:sdk-android to v0.2.50 (#3565)

* Adapt to changes in the SDK

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

* Use lambda instead of overriding the `EventDebugInfoProvider` interface

* Fix test proposal.
We may find a better way to compare data class instance if we need to do more comparison in the future...

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benoit Marty <benoit@matrix.org>
This commit is contained in:
renovate[bot] 2024-10-01 09:44:52 +02:00 committed by GitHub
parent 249104bf38
commit 3001efb525
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 216 additions and 175 deletions

View file

@ -114,7 +114,8 @@ internal class RustEncryptionService(
override fun onUpdate(status: RustEnableRecoveryProgress) {
enableRecoveryProgressStateFlow.value = enableRecoveryProgressMapper.map(status)
}
}
},
passphrase = null,
)
// enableRecovery returns the encryption key, but we read it from the state flow
.let { }

View file

@ -18,6 +18,8 @@ import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.withTimeout
import org.matrix.rustcomponents.sdk.RoomListService
import org.matrix.rustcomponents.sdk.Timeline
import org.matrix.rustcomponents.sdk.TimelineItemContent
import org.matrix.rustcomponents.sdk.contentWithoutRelationFromMessage
import kotlin.time.Duration.Companion.milliseconds
/**
@ -40,11 +42,7 @@ class RoomContentForwarder(
toRoomIds: List<RoomId>,
timeoutMs: Long = 5000L
) {
val content = fromTimeline
.getEventTimelineItemByEventId(eventId.value)
.content()
.asMessage()
?.content()
val content = (fromTimeline.getEventTimelineItemByEventId(eventId.value).content as? TimelineItemContent.Message)?.content
?: throw ForwardEventException(toRoomIds)
val targetSlidingSyncRooms = toRoomIds.mapNotNull { roomId -> roomListService.roomOrNull(roomId.value) }
@ -58,7 +56,7 @@ class RoomContentForwarder(
// Sending a message requires a registered timeline listener
targetRoom.timeline().runWithTimelineListenerRegistered {
withTimeout(timeoutMs.milliseconds) {
targetRoom.timeline().send(content)
targetRoom.timeline().send(contentWithoutRelationFromMessage(content))
}
}
}

View file

@ -462,7 +462,7 @@ class RustMatrixRoom(
innerRoom.tryResend(transactionId.value)
}
override suspend fun cancelSend(transactionId: TransactionId): Result<Boolean> {
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> {
return liveTimeline.cancelSend(transactionId)
}

View file

@ -64,6 +64,7 @@ import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.EditedContent
import org.matrix.rustcomponents.sdk.EventOrTransactionId
import org.matrix.rustcomponents.sdk.EventTimelineItem
import org.matrix.rustcomponents.sdk.FormattedBody
import org.matrix.rustcomponents.sdk.MessageFormat
@ -274,11 +275,14 @@ class RustTimeline(
}
}
override suspend fun redactEvent(eventId: EventId?, transactionId: TransactionId?, reason: String?): Result<Boolean> = withContext(dispatcher) {
override suspend fun redactEvent(eventId: EventId?, transactionId: TransactionId?, reason: String?): Result<Unit> = withContext(dispatcher) {
runCatching {
getEventTimelineItem(eventId, transactionId).use { item ->
inner.redactEvent(item = item, reason = reason)
val eventOrTransactionId = if (eventId != null) {
EventOrTransactionId.EventId(eventId.value)
} else {
EventOrTransactionId.TransactionId(transactionId!!.value)
}
inner.redactEvent(eventOrTransactionId = eventOrTransactionId, reason = reason)
}
}
@ -291,19 +295,22 @@ class RustTimeline(
): Result<Unit> =
withContext(dispatcher) {
runCatching<Unit> {
getEventTimelineItem(originalEventId, transactionId).use { item ->
val editedContent = EditedContent.RoomMessage(
content = MessageEventContent.from(
body = body,
htmlBody = htmlBody,
intentionalMentions = intentionalMentions
),
)
inner.edit(
newContent = editedContent,
item = item,
)
val eventOrTransactionId = if (originalEventId != null) {
EventOrTransactionId.EventId(originalEventId.value)
} else {
EventOrTransactionId.TransactionId(transactionId!!.value)
}
val editedContent = EditedContent.RoomMessage(
content = MessageEventContent.from(
body = body,
htmlBody = htmlBody,
intentionalMentions = intentionalMentions
),
)
inner.edit(
newContent = editedContent,
eventOrTransactionId = eventOrTransactionId,
)
}
}
@ -343,6 +350,7 @@ class RustTimeline(
}
@Throws
@Suppress("UnusedPrivateMember")
private suspend fun getEventTimelineItem(eventId: EventId?, transactionId: TransactionId?): EventTimelineItem {
return try {
when {
@ -411,7 +419,8 @@ class RustTimeline(
}
}
override suspend fun cancelSend(transactionId: TransactionId): Result<Boolean> = redactEvent(eventId = null, transactionId = transactionId, reason = null)
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> =
redactEvent(eventId = null, transactionId = transactionId, reason = null)
override suspend fun sendLocation(
body: String,
@ -455,10 +464,6 @@ class RustTimeline(
pollKind: PollKind,
): Result<Unit> = withContext(dispatcher) {
runCatching {
val pollStartEvent =
inner.getEventTimelineItemByEventId(
eventId = pollStartId.value
)
val editedContent = EditedContent.PollStart(
pollData = PollData(
question = question,
@ -467,12 +472,10 @@ class RustTimeline(
pollKind = pollKind.toInner(),
),
)
pollStartEvent.use {
inner.edit(
newContent = editedContent,
item = it,
)
}
inner.edit(
newContent = editedContent,
eventOrTransactionId = EventOrTransactionId.EventId(pollStartId.value),
)
}.map { }
}
@ -482,7 +485,7 @@ class RustTimeline(
): Result<Unit> = withContext(dispatcher) {
runCatching {
inner.sendPollResponse(
pollStartId = pollStartId.value,
pollStartEventId = pollStartId.value,
answers = answers,
)
}
@ -494,7 +497,7 @@ class RustTimeline(
): Result<Unit> = withContext(dispatcher) {
runCatching {
inner.endPoll(
pollStartId = pollStartId.value,
pollStartEventId = pollStartId.value,
text = text,
)
}

View file

@ -41,5 +41,5 @@ internal fun TimelineDiff.eventOrigin(): EventItemOrigin? {
}
private fun TimelineItem.eventOrigin(): EventItemOrigin? {
return asEvent()?.origin()
return asEvent()?.origin
}

View file

@ -23,10 +23,10 @@ import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageT
import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType
import io.element.android.libraries.matrix.impl.media.map
import io.element.android.libraries.matrix.impl.timeline.reply.InReplyToMapper
import org.matrix.rustcomponents.sdk.Message
import org.matrix.rustcomponents.sdk.MessageType
import org.matrix.rustcomponents.sdk.use
import org.matrix.rustcomponents.sdk.FormattedBody as RustFormattedBody
import org.matrix.rustcomponents.sdk.MessageContent as Message
import org.matrix.rustcomponents.sdk.MessageFormat as RustMessageFormat
import org.matrix.rustcomponents.sdk.MessageType as RustMessageType
@ -34,13 +34,13 @@ class EventMessageMapper {
private val inReplyToMapper by lazy { InReplyToMapper(TimelineEventContentMapper()) }
fun map(message: Message): MessageContent = message.use {
val type = it.msgtype().use(this::mapMessageType)
val inReplyToEvent: InReplyTo? = it.inReplyTo()?.use(inReplyToMapper::map)
val type = it.msgType.use(this::mapMessageType)
val inReplyToEvent: InReplyTo? = it.inReplyTo?.use(inReplyToMapper::map)
MessageContent(
body = it.body(),
body = it.body,
inReplyTo = inReplyToEvent,
isEdited = it.isEdited(),
isThreaded = it.isThreaded(),
isEdited = it.isEdited,
isThreaded = it.threadRoot != null,
type = type
)
}

View file

@ -12,7 +12,9 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.api.timeline.item.event.EventDebugInfoProvider
import io.element.android.libraries.matrix.api.timeline.item.event.EventReaction
import io.element.android.libraries.matrix.api.timeline.item.event.EventShieldsProvider
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
@ -23,11 +25,14 @@ import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemE
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import org.matrix.rustcomponents.sdk.EventOrTransactionId
import org.matrix.rustcomponents.sdk.EventSendState
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfoProvider
import org.matrix.rustcomponents.sdk.Reaction
import org.matrix.rustcomponents.sdk.ShieldState
import uniffi.matrix_sdk_common.ShieldStateCode
import org.matrix.rustcomponents.sdk.EventSendState as RustEventSendState
import org.matrix.rustcomponents.sdk.EventShieldsProvider as RustEventShieldsProvider
import org.matrix.rustcomponents.sdk.EventTimelineItem as RustEventTimelineItem
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfo as RustEventTimelineItemDebugInfo
import org.matrix.rustcomponents.sdk.ProfileDetails as RustProfileDetails
@ -37,25 +42,25 @@ import uniffi.matrix_sdk_ui.EventItemOrigin as RustEventItemOrigin
class EventTimelineItemMapper(
private val contentMapper: TimelineEventContentMapper = TimelineEventContentMapper(),
) {
fun map(eventTimelineItem: RustEventTimelineItem): EventTimelineItem = eventTimelineItem.use {
fun map(eventTimelineItem: RustEventTimelineItem): EventTimelineItem = eventTimelineItem.run {
EventTimelineItem(
eventId = it.eventId()?.let(::EventId),
transactionId = it.transactionId()?.let(::TransactionId),
isEditable = it.isEditable(),
canBeRepliedTo = it.canBeRepliedTo(),
isLocal = it.isLocal(),
isOwn = it.isOwn(),
isRemote = it.isRemote(),
localSendState = it.localSendState()?.map(),
reactions = it.reactions().map(),
receipts = it.readReceipts().map(),
sender = UserId(it.sender()),
senderProfile = it.senderProfile().map(),
timestamp = it.timestamp().toLong(),
content = contentMapper.map(it.content()),
debugInfo = it.debugInfo().map(),
origin = it.origin()?.map(),
messageShield = it.getShield(false)?.map(),
eventId = eventOrTransactionId.eventId(),
transactionId = eventOrTransactionId.transactionId(),
isEditable = isEditable,
canBeRepliedTo = canBeRepliedTo,
isLocal = isLocal,
isOwn = isOwn,
isRemote = isRemote,
localSendState = localSendState?.map(),
reactions = reactions.map(),
receipts = readReceipts.map(),
sender = UserId(sender),
senderProfile = senderProfile.map(),
timestamp = timestamp.toLong(),
content = contentMapper.map(content),
debugInfoProvider = RustEventDebugInfoProvider(debugInfoProvider),
origin = origin?.map(),
messageShieldProvider = RustEventShieldsProvider(shieldsProvider)
)
}
}
@ -162,3 +167,23 @@ private fun ShieldState?.map(): MessageShield? {
ShieldStateCode.PREVIOUSLY_VERIFIED -> MessageShield.PreviouslyVerified(isCritical)
}
}
class RustEventDebugInfoProvider(private val debugInfoProvider: EventTimelineItemDebugInfoProvider) : EventDebugInfoProvider {
override fun get(): TimelineItemDebugInfo {
return debugInfoProvider.get().map()
}
}
class RustEventShieldsProvider(private val shieldsProvider: RustEventShieldsProvider) : EventShieldsProvider {
override fun getShield(strict: Boolean): MessageShield? {
return shieldsProvider.getShields(strict)?.map()
}
}
private fun EventOrTransactionId.eventId(): EventId? {
return (this as? EventOrTransactionId.EventId)?.let { EventId(it.eventId) }
}
private fun EventOrTransactionId.transactionId(): TransactionId? {
return (this as? EventOrTransactionId.TransactionId)?.let { TransactionId(it.transactionId) }
}

View file

@ -29,7 +29,6 @@ import io.element.android.libraries.matrix.impl.poll.map
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableMap
import org.matrix.rustcomponents.sdk.TimelineItemContent
import org.matrix.rustcomponents.sdk.TimelineItemContentKind
import org.matrix.rustcomponents.sdk.use
import uniffi.matrix_sdk_ui.RoomPinnedEventsChange
import org.matrix.rustcomponents.sdk.EncryptedMessage as RustEncryptedMessage
@ -42,87 +41,78 @@ class TimelineEventContentMapper(
) {
fun map(content: TimelineItemContent): EventContent {
return content.use {
content.kind().use { kind ->
map(content, kind)
when (it) {
is TimelineItemContent.FailedToParseMessageLike -> {
FailedToParseMessageLikeContent(
eventType = it.eventType,
error = it.error
)
}
is TimelineItemContent.FailedToParseState -> {
FailedToParseStateContent(
eventType = it.eventType,
stateKey = it.stateKey,
error = it.error
)
}
is TimelineItemContent.Message -> {
eventMessageMapper.map(it.content)
}
is TimelineItemContent.ProfileChange -> {
ProfileChangeContent(
displayName = it.displayName,
prevDisplayName = it.prevDisplayName,
avatarUrl = it.avatarUrl,
prevAvatarUrl = it.prevAvatarUrl
)
}
TimelineItemContent.RedactedMessage -> {
RedactedContent
}
is TimelineItemContent.RoomMembership -> {
RoomMembershipContent(
userId = UserId(it.userId),
userDisplayName = it.userDisplayName,
change = it.change?.map()
)
}
is TimelineItemContent.State -> {
StateContent(
stateKey = it.stateKey,
content = it.content.map()
)
}
is TimelineItemContent.Sticker -> {
StickerContent(
body = it.body,
info = it.info.map(),
source = it.source.map(),
)
}
is TimelineItemContent.Poll -> {
PollContent(
question = it.question,
kind = it.kind.map(),
maxSelections = it.maxSelections,
answers = it.answers.map { answer -> answer.map() }.toImmutableList(),
votes = it.votes.mapValues { vote ->
vote.value.map { userId -> UserId(userId) }.toImmutableList()
}.toImmutableMap(),
endTime = it.endTime,
isEdited = it.hasBeenEdited,
)
}
is TimelineItemContent.UnableToDecrypt -> {
UnableToDecryptContent(
data = it.msg.map()
)
}
is TimelineItemContent.CallInvite -> LegacyCallInviteContent
is TimelineItemContent.CallNotify -> CallNotifyContent
else -> UnknownContent
}
}
}
private fun map(content: TimelineItemContent, kind: TimelineItemContentKind) = when (kind) {
is TimelineItemContentKind.FailedToParseMessageLike -> {
FailedToParseMessageLikeContent(
eventType = kind.eventType,
error = kind.error
)
}
is TimelineItemContentKind.FailedToParseState -> {
FailedToParseStateContent(
eventType = kind.eventType,
stateKey = kind.stateKey,
error = kind.error
)
}
TimelineItemContentKind.Message -> {
val message = content.asMessage()
if (message == null) {
UnknownContent
} else {
eventMessageMapper.map(message)
}
}
is TimelineItemContentKind.ProfileChange -> {
ProfileChangeContent(
displayName = kind.displayName,
prevDisplayName = kind.prevDisplayName,
avatarUrl = kind.avatarUrl,
prevAvatarUrl = kind.prevAvatarUrl
)
}
TimelineItemContentKind.RedactedMessage -> {
RedactedContent
}
is TimelineItemContentKind.RoomMembership -> {
RoomMembershipContent(
userId = UserId(kind.userId),
userDisplayName = kind.userDisplayName,
change = kind.change?.map()
)
}
is TimelineItemContentKind.State -> {
StateContent(
stateKey = kind.stateKey,
content = kind.content.map()
)
}
is TimelineItemContentKind.Sticker -> {
StickerContent(
body = kind.body,
info = kind.info.map(),
source = kind.source.map(),
)
}
is TimelineItemContentKind.Poll -> {
PollContent(
question = kind.question,
kind = kind.kind.map(),
maxSelections = kind.maxSelections,
answers = kind.answers.map { answer -> answer.map() }.toImmutableList(),
votes = kind.votes.mapValues { vote ->
vote.value.map { userId -> UserId(userId) }.toImmutableList()
}.toImmutableMap(),
endTime = kind.endTime,
isEdited = kind.hasBeenEdited,
)
}
is TimelineItemContentKind.UnableToDecrypt -> {
UnableToDecryptContent(
data = kind.msg.map()
)
}
is TimelineItemContentKind.CallInvite -> LegacyCallInviteContent
is TimelineItemContentKind.CallNotify -> CallNotifyContent
else -> UnknownContent
}
}
private fun RustMembershipChange.map(): MembershipChange {

View file

@ -19,8 +19,8 @@ class InReplyToMapper(
private val timelineEventContentMapper: TimelineEventContentMapper,
) {
fun map(inReplyToDetails: InReplyToDetails): InReplyTo {
val inReplyToId = EventId(inReplyToDetails.eventId)
return when (val event = inReplyToDetails.event) {
val inReplyToId = EventId(inReplyToDetails.eventId())
return when (val event = inReplyToDetails.event()) {
is RepliedToEventDetails.Ready -> {
InReplyTo.Ready(
eventId = inReplyToId,