Merge pull request #3701 from element-hq/renovate/org.matrix.rustcomponents-sdk-android-0.x
Update dependency org.matrix.rustcomponents:sdk-android to v0.2.55
This commit is contained in:
commit
3cdf533c33
26 changed files with 176 additions and 148 deletions
|
|
@ -22,6 +22,8 @@ import io.element.android.features.location.impl.common.permissions.PermissionsS
|
||||||
import io.element.android.features.messages.test.FakeMessageComposerContext
|
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||||
|
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
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
||||||
|
|
@ -397,8 +399,7 @@ class SendLocationPresenterTest {
|
||||||
)
|
)
|
||||||
fakeMessageComposerContext.apply {
|
fakeMessageComposerContext.apply {
|
||||||
composerMode = MessageComposerMode.Edit(
|
composerMode = MessageComposerMode.Edit(
|
||||||
eventId = null,
|
eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(),
|
||||||
transactionId = null,
|
|
||||||
content = ""
|
content = ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -446,8 +447,7 @@ class SendLocationPresenterTest {
|
||||||
)
|
)
|
||||||
fakeMessageComposerContext.apply {
|
fakeMessageComposerContext.apply {
|
||||||
composerMode = MessageComposerMode.Edit(
|
composerMode = MessageComposerMode.Edit(
|
||||||
eventId = null,
|
eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(),
|
||||||
transactionId = null,
|
|
||||||
content = ""
|
content = ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ package io.element.android.features.messages.impl
|
||||||
|
|
||||||
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
|
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
import io.element.android.libraries.matrix.api.core.UniqueId
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
|
|
||||||
sealed interface MessagesEvents {
|
sealed interface MessagesEvents {
|
||||||
data class HandleAction(val action: TimelineItemAction, val event: TimelineItem.Event) : MessagesEvents
|
data class HandleAction(val action: TimelineItemAction, val event: TimelineItem.Event) : MessagesEvents
|
||||||
data class ToggleReaction(val emoji: String, val uniqueId: UniqueId) : MessagesEvents
|
data class ToggleReaction(val emoji: String, val eventOrTransactionId: EventOrTransactionId) : MessagesEvents
|
||||||
data class InviteDialogDismissed(val action: InviteDialogAction) : MessagesEvents
|
data class InviteDialogDismissed(val action: InviteDialogAction) : MessagesEvents
|
||||||
data object Dismiss : MessagesEvents
|
data object Dismiss : MessagesEvents
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
import io.element.android.libraries.matrix.api.core.UniqueId
|
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
|
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
|
||||||
|
|
@ -73,6 +72,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther
|
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn
|
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage
|
import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.map
|
import io.element.android.libraries.matrix.ui.messages.reply.map
|
||||||
import io.element.android.libraries.matrix.ui.model.getAvatarData
|
import io.element.android.libraries.matrix.ui.model.getAvatarData
|
||||||
import io.element.android.libraries.matrix.ui.room.canCall
|
import io.element.android.libraries.matrix.ui.room.canCall
|
||||||
|
|
@ -191,7 +191,7 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is MessagesEvents.ToggleReaction -> {
|
is MessagesEvents.ToggleReaction -> {
|
||||||
localCoroutineScope.toggleReaction(event.emoji, event.uniqueId)
|
localCoroutineScope.toggleReaction(event.emoji, event.eventOrTransactionId)
|
||||||
}
|
}
|
||||||
is MessagesEvents.InviteDialogDismissed -> {
|
is MessagesEvents.InviteDialogDismissed -> {
|
||||||
hasDismissedInviteDialog = true
|
hasDismissedInviteDialog = true
|
||||||
|
|
@ -327,10 +327,10 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
|
|
||||||
private fun CoroutineScope.toggleReaction(
|
private fun CoroutineScope.toggleReaction(
|
||||||
emoji: String,
|
emoji: String,
|
||||||
uniqueId: UniqueId,
|
eventOrTransactionId: EventOrTransactionId,
|
||||||
) = launch(dispatchers.io) {
|
) = launch(dispatchers.io) {
|
||||||
timelineController.invokeOnCurrentTimeline {
|
timelineController.invokeOnCurrentTimeline {
|
||||||
toggleReaction(emoji, uniqueId)
|
toggleReaction(emoji, eventOrTransactionId)
|
||||||
.onFailure { Timber.e(it) }
|
.onFailure { Timber.e(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +360,7 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
|
|
||||||
private suspend fun handleActionRedact(event: TimelineItem.Event) {
|
private suspend fun handleActionRedact(event: TimelineItem.Event) {
|
||||||
timelineController.invokeOnCurrentTimeline {
|
timelineController.invokeOnCurrentTimeline {
|
||||||
redactEvent(eventId = event.eventId, transactionId = event.transactionId, reason = null)
|
redactEvent(eventOrTransactionId = event.eventOrTransactionId, reason = null)
|
||||||
.onFailure { Timber.e(it) }
|
.onFailure { Timber.e(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -377,8 +377,7 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val composerMode = MessageComposerMode.Edit(
|
val composerMode = MessageComposerMode.Edit(
|
||||||
targetEvent.eventId,
|
targetEvent.eventOrTransactionId,
|
||||||
targetEvent.transactionId,
|
|
||||||
(targetEvent.content as? TimelineItemTextBasedContent)?.let {
|
(targetEvent.content as? TimelineItemTextBasedContent)?.let {
|
||||||
if (enableTextFormatting) {
|
if (enableTextFormatting) {
|
||||||
it.htmlBody ?: it.body
|
it.htmlBody ?: it.body
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ fun MessagesView(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onEmojiReactionClick(emoji: String, event: TimelineItem.Event) {
|
fun onEmojiReactionClick(emoji: String, event: TimelineItem.Event) {
|
||||||
state.eventSink(MessagesEvents.ToggleReaction(emoji, event.id))
|
state.eventSink(MessagesEvents.ToggleReaction(emoji, event.eventOrTransactionId))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onEmojiReactionLongClick(emoji: String, event: TimelineItem.Event) {
|
fun onEmojiReactionLongClick(emoji: String, event: TimelineItem.Event) {
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ 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.api.room.draft.ComposerDraftType
|
||||||
import io.element.android.libraries.matrix.api.room.isDm
|
import io.element.android.libraries.matrix.api.room.isDm
|
||||||
import io.element.android.libraries.matrix.api.timeline.TimelineException
|
import io.element.android.libraries.matrix.api.timeline.TimelineException
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache
|
import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.map
|
import io.element.android.libraries.matrix.ui.messages.reply.map
|
||||||
|
|
@ -442,12 +443,11 @@ class MessageComposerPresenter @Inject constructor(
|
||||||
intentionalMentions = message.intentionalMentions
|
intentionalMentions = message.intentionalMentions
|
||||||
)
|
)
|
||||||
is MessageComposerMode.Edit -> {
|
is MessageComposerMode.Edit -> {
|
||||||
val eventId = capturedMode.eventId
|
|
||||||
val transactionId = capturedMode.transactionId
|
|
||||||
timelineController.invokeOnCurrentTimeline {
|
timelineController.invokeOnCurrentTimeline {
|
||||||
// First try to edit the message in the current timeline
|
// First try to edit the message in the current timeline
|
||||||
editMessage(eventId, transactionId, message.markdown, message.html, message.intentionalMentions)
|
editMessage(capturedMode.eventOrTransactionId, message.markdown, message.html, message.intentionalMentions)
|
||||||
.onFailure { cause ->
|
.onFailure { cause ->
|
||||||
|
val eventId = capturedMode.eventOrTransactionId.eventId
|
||||||
if (cause is TimelineException.EventNotFound && eventId != null) {
|
if (cause is TimelineException.EventNotFound && eventId != null) {
|
||||||
// if the event is not found in the timeline, try to edit the message directly
|
// if the event is not found in the timeline, try to edit the message directly
|
||||||
room.editMessage(eventId, message.markdown, message.html, message.intentionalMentions)
|
room.editMessage(eventId, message.markdown, message.html, message.intentionalMentions)
|
||||||
|
|
@ -581,8 +581,7 @@ class MessageComposerPresenter @Inject constructor(
|
||||||
when (val draftType = draft.draftType) {
|
when (val draftType = draft.draftType) {
|
||||||
ComposerDraftType.NewMessage -> messageComposerContext.composerMode = MessageComposerMode.Normal
|
ComposerDraftType.NewMessage -> messageComposerContext.composerMode = MessageComposerMode.Normal
|
||||||
is ComposerDraftType.Edit -> messageComposerContext.composerMode = MessageComposerMode.Edit(
|
is ComposerDraftType.Edit -> messageComposerContext.composerMode = MessageComposerMode.Edit(
|
||||||
eventId = draftType.eventId,
|
eventOrTransactionId = draftType.eventId.toEventOrTransactionId(),
|
||||||
transactionId = null,
|
|
||||||
content = htmlText ?: markdownText
|
content = htmlText ?: markdownText
|
||||||
)
|
)
|
||||||
is ComposerDraftType.Reply -> {
|
is ComposerDraftType.Reply -> {
|
||||||
|
|
@ -611,7 +610,7 @@ class MessageComposerPresenter @Inject constructor(
|
||||||
val draftType = when (val mode = messageComposerContext.composerMode) {
|
val draftType = when (val mode = messageComposerContext.composerMode) {
|
||||||
is MessageComposerMode.Normal -> ComposerDraftType.NewMessage
|
is MessageComposerMode.Normal -> ComposerDraftType.NewMessage
|
||||||
is MessageComposerMode.Edit -> {
|
is MessageComposerMode.Edit -> {
|
||||||
mode.eventId?.let { eventId -> ComposerDraftType.Edit(eventId) }
|
mode.eventOrTransactionId.eventId?.let { eventId -> ComposerDraftType.Edit(eventId) }
|
||||||
}
|
}
|
||||||
is MessageComposerMode.Reply -> ComposerDraftType.Reply(mode.eventId)
|
is MessageComposerMode.Reply -> ComposerDraftType.Reply(mode.eventId)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ import androidx.compose.ui.Modifier
|
||||||
import io.element.android.emojibasebindings.Emoji
|
import io.element.android.emojibasebindings.Emoji
|
||||||
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
|
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
|
||||||
import io.element.android.libraries.designsystem.theme.components.hide
|
import io.element.android.libraries.designsystem.theme.components.hide
|
||||||
import io.element.android.libraries.matrix.api.core.UniqueId
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomReactionBottomSheet(
|
fun CustomReactionBottomSheet(
|
||||||
state: CustomReactionState,
|
state: CustomReactionState,
|
||||||
onSelectEmoji: (UniqueId, Emoji) -> Unit,
|
onSelectEmoji: (EventOrTransactionId, Emoji) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val sheetState = rememberModalBottomSheetState()
|
val sheetState = rememberModalBottomSheetState()
|
||||||
|
|
@ -37,7 +37,7 @@ fun CustomReactionBottomSheet(
|
||||||
if (target?.event == null) return
|
if (target?.event == null) return
|
||||||
sheetState.hide(coroutineScope) {
|
sheetState.hide(coroutineScope) {
|
||||||
state.eventSink(CustomReactionEvents.DismissCustomReactionSheet)
|
state.eventSink(CustomReactionEvents.DismissCustomReactionSheet)
|
||||||
onSelectEmoji(target.event.id, emoji)
|
onSelectEmoji(target.event.eventOrTransactionId, emoji)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ 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.UniqueId
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
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.TimelineItemDebugInfo
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
|
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
|
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShieldProvider
|
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShieldProvider
|
||||||
|
|
@ -92,6 +93,9 @@ sealed interface TimelineItem {
|
||||||
|
|
||||||
val isRemote = eventId != null
|
val isRemote = eventId != null
|
||||||
|
|
||||||
|
val eventOrTransactionId: EventOrTransactionId
|
||||||
|
get() = EventOrTransactionId.from(eventId = eventId, transactionId = transactionId)
|
||||||
|
|
||||||
// No need to be lazy here?
|
// No need to be lazy here?
|
||||||
val messageShield: MessageShield? = messageShieldProvider(strict = false)
|
val messageShield: MessageShield? = messageShieldProvider(strict = false)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,6 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
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.UniqueId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||||
|
|
@ -56,13 +54,14 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
||||||
import io.element.android.libraries.matrix.api.room.MessageEventType
|
import io.element.android.libraries.matrix.api.room.MessageEventType
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
|
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||||
import io.element.android.libraries.matrix.test.A_SESSION_ID_2
|
import io.element.android.libraries.matrix.test.A_SESSION_ID_2
|
||||||
import io.element.android.libraries.matrix.test.A_THROWABLE
|
import io.element.android.libraries.matrix.test.A_THROWABLE
|
||||||
import io.element.android.libraries.matrix.test.A_UNIQUE_ID
|
|
||||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
|
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
|
|
@ -164,8 +163,9 @@ class MessagesPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle toggling a reaction`() = runTest {
|
fun `present - handle toggling a reaction`() = runTest {
|
||||||
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
val toggleReactionSuccess = lambdaRecorder { _: String, _: UniqueId -> Result.success(Unit) }
|
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventOrTransactionId -> Result.success(Unit) }
|
||||||
val toggleReactionFailure = lambdaRecorder { _: String, _: UniqueId -> Result.failure<Unit>(IllegalStateException("Failed to send reaction")) }
|
val toggleReactionFailure =
|
||||||
|
lambdaRecorder { _: String, _: EventOrTransactionId -> Result.failure<Unit>(IllegalStateException("Failed to send reaction")) }
|
||||||
|
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.toggleReactionLambda = toggleReactionSuccess
|
this.toggleReactionLambda = toggleReactionSuccess
|
||||||
|
|
@ -185,23 +185,23 @@ class MessagesPresenterTest {
|
||||||
}.test {
|
}.test {
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", A_UNIQUE_ID))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
assert(toggleReactionSuccess)
|
assert(toggleReactionSuccess)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value("👍"), value(A_UNIQUE_ID))
|
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
// No crashes when sending a reaction failed
|
// No crashes when sending a reaction failed
|
||||||
timeline.apply { toggleReactionLambda = toggleReactionFailure }
|
timeline.apply { toggleReactionLambda = toggleReactionFailure }
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", A_UNIQUE_ID))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
assert(toggleReactionFailure)
|
assert(toggleReactionFailure)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value("👍"), value(A_UNIQUE_ID))
|
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle toggling a reaction twice`() = runTest {
|
fun `present - handle toggling a reaction twice`() = runTest {
|
||||||
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
val toggleReactionSuccess = lambdaRecorder { _: String, _: UniqueId -> Result.success(Unit) }
|
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventOrTransactionId -> Result.success(Unit) }
|
||||||
|
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.toggleReactionLambda = toggleReactionSuccess
|
this.toggleReactionLambda = toggleReactionSuccess
|
||||||
|
|
@ -220,13 +220,13 @@ class MessagesPresenterTest {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", A_UNIQUE_ID))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", A_UNIQUE_ID))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
assert(toggleReactionSuccess)
|
assert(toggleReactionSuccess)
|
||||||
.isCalledExactly(2)
|
.isCalledExactly(2)
|
||||||
.withSequence(
|
.withSequence(
|
||||||
listOf(value("👍"), value(A_UNIQUE_ID)),
|
listOf(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId())),
|
||||||
listOf(value("👍"), value(A_UNIQUE_ID)),
|
listOf(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId())),
|
||||||
)
|
)
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
}
|
}
|
||||||
|
|
@ -452,8 +452,7 @@ class MessagesPresenterTest {
|
||||||
composerRecorder.assertSingle(
|
composerRecorder.assertSingle(
|
||||||
MessageComposerEvents.SetMode(
|
MessageComposerEvents.SetMode(
|
||||||
composerMode = MessageComposerMode.Edit(
|
composerMode = MessageComposerMode.Edit(
|
||||||
eventId = AN_EVENT_ID,
|
eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(),
|
||||||
transactionId = null,
|
|
||||||
content = (aMessageEvent().content as TimelineItemTextContent).body
|
content = (aMessageEvent().content as TimelineItemTextContent).body
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -506,7 +505,7 @@ class MessagesPresenterTest {
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
|
|
||||||
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(Unit) }
|
val redactEventLambda = lambdaRecorder { _: EventOrTransactionId, _: String? -> Result.success(Unit) }
|
||||||
liveTimeline.redactEventLambda = redactEventLambda
|
liveTimeline.redactEventLambda = redactEventLambda
|
||||||
val presenter = createMessagesPresenter(
|
val presenter = createMessagesPresenter(
|
||||||
matrixRoom = matrixRoom,
|
matrixRoom = matrixRoom,
|
||||||
|
|
@ -521,7 +520,7 @@ class MessagesPresenterTest {
|
||||||
awaitItem()
|
awaitItem()
|
||||||
assert(redactEventLambda)
|
assert(redactEventLambda)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value(messageEvent.eventId), value(messageEvent.transactionId), value(null))
|
.with(value(messageEvent.eventOrTransactionId), value(null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -355,7 +355,7 @@ class MessagesViewTest {
|
||||||
state = state,
|
state = state,
|
||||||
)
|
)
|
||||||
rule.onAllNodesWithText("👍️").onFirst().performClick()
|
rule.onAllNodesWithText("👍️").onFirst().performClick()
|
||||||
eventsRecorder.assertSingle(MessagesEvents.ToggleReaction("👍️", timelineItem.id))
|
eventsRecorder.assertSingle(MessagesEvents.ToggleReaction("👍️", timelineItem.eventOrTransactionId))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -484,7 +484,7 @@ class MessagesViewTest {
|
||||||
// Give time for the close animation to complete
|
// Give time for the close animation to complete
|
||||||
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||||
customReactionStateEventsRecorder.assertSingle(CustomReactionEvents.DismissCustomReactionSheet)
|
customReactionStateEventsRecorder.assertSingle(CustomReactionEvents.DismissCustomReactionSheet)
|
||||||
eventsRecorder.assertSingle(MessagesEvents.ToggleReaction(aUnicode, timelineItem.id))
|
eventsRecorder.assertSingle(MessagesEvents.ToggleReaction(aUnicode, timelineItem.eventOrTransactionId))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
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.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
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.ImageInfo
|
import io.element.android.libraries.matrix.api.media.ImageInfo
|
||||||
import io.element.android.libraries.matrix.api.media.VideoInfo
|
import io.element.android.libraries.matrix.api.media.VideoInfo
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
||||||
|
|
@ -44,7 +43,9 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
||||||
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
|
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.api.room.draft.ComposerDraftType
|
||||||
import io.element.android.libraries.matrix.api.timeline.TimelineException
|
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.api.timeline.item.event.InReplyTo
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.test.ANOTHER_MESSAGE
|
import io.element.android.libraries.matrix.test.ANOTHER_MESSAGE
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
import io.element.android.libraries.matrix.test.A_MESSAGE
|
import io.element.android.libraries.matrix.test.A_MESSAGE
|
||||||
|
|
@ -355,7 +356,7 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - edit sent message`() = runTest {
|
fun `present - edit sent message`() = runTest {
|
||||||
val editMessageLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String, _: String?, _: List<IntentionalMention> ->
|
val editMessageLambda = lambdaRecorder { _: EventOrTransactionId, _: String, _: String?, _: List<IntentionalMention> ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
|
|
@ -392,7 +393,7 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
assert(editMessageLambda)
|
assert(editMessageLambda)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value(AN_EVENT_ID), value(null), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
|
.with(value(AN_EVENT_ID.toEventOrTransactionId()), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
|
||||||
|
|
||||||
assertThat(analyticsService.capturedEvents).containsExactly(
|
assertThat(analyticsService.capturedEvents).containsExactly(
|
||||||
Composer(
|
Composer(
|
||||||
|
|
@ -407,7 +408,7 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - edit sent message event not found`() = runTest {
|
fun `present - edit sent message event not found`() = runTest {
|
||||||
val timelineEditMessageLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String, _: String?, _: List<IntentionalMention> ->
|
val timelineEditMessageLambda = lambdaRecorder { _: EventOrTransactionId, _: String, _: String?, _: List<IntentionalMention> ->
|
||||||
Result.failure<Unit>(TimelineException.EventNotFound)
|
Result.failure<Unit>(TimelineException.EventNotFound)
|
||||||
}
|
}
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
|
|
@ -448,7 +449,7 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
assert(timelineEditMessageLambda)
|
assert(timelineEditMessageLambda)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value(AN_EVENT_ID), value(null), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
|
.with(value(AN_EVENT_ID.toEventOrTransactionId()), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
|
||||||
|
|
||||||
assert(roomEditMessageLambda)
|
assert(roomEditMessageLambda)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
|
|
@ -467,7 +468,7 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - edit not sent message`() = runTest {
|
fun `present - edit not sent message`() = runTest {
|
||||||
val editMessageLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String, _: String?, _: List<IntentionalMention> ->
|
val editMessageLambda = lambdaRecorder { _: EventOrTransactionId, _: String, _: String?, _: List<IntentionalMention> ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
|
|
@ -487,7 +488,7 @@ class MessageComposerPresenterTest {
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.textEditorState.messageHtml()).isEqualTo("")
|
assertThat(initialState.textEditorState.messageHtml()).isEqualTo("")
|
||||||
val mode = anEditMode(eventId = null, transactionId = A_TRANSACTION_ID)
|
val mode = anEditMode(eventOrTransactionId = A_TRANSACTION_ID.toEventOrTransactionId())
|
||||||
initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
initialState.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||||
val withMessageState = awaitItem()
|
val withMessageState = awaitItem()
|
||||||
assertThat(withMessageState.mode).isEqualTo(mode)
|
assertThat(withMessageState.mode).isEqualTo(mode)
|
||||||
|
|
@ -504,7 +505,7 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
assert(editMessageLambda)
|
assert(editMessageLambda)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value(null), value(A_TRANSACTION_ID), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
|
.with(value(A_TRANSACTION_ID.toEventOrTransactionId()), value(ANOTHER_MESSAGE), value(ANOTHER_MESSAGE), any())
|
||||||
|
|
||||||
assertThat(analyticsService.capturedEvents).containsExactly(
|
assertThat(analyticsService.capturedEvents).containsExactly(
|
||||||
Composer(
|
Composer(
|
||||||
|
|
@ -1058,7 +1059,7 @@ class MessageComposerPresenterTest {
|
||||||
val replyMessageLambda = lambdaRecorder { _: EventId, _: String, _: String?, _: List<IntentionalMention>, _: Boolean ->
|
val replyMessageLambda = lambdaRecorder { _: EventId, _: String, _: String?, _: List<IntentionalMention>, _: Boolean ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val editMessageLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String, _: String?, _: List<IntentionalMention> ->
|
val editMessageLambda = lambdaRecorder { _: EventOrTransactionId, _: String, _: String?, _: List<IntentionalMention> ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
|
|
@ -1128,7 +1129,7 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
assert(editMessageLambda)
|
assert(editMessageLambda)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(any(), any(), any(), any(), value(listOf(IntentionalMention.User(A_USER_ID_3))))
|
.with(any(), any(), any(), value(listOf(IntentionalMention.User(A_USER_ID_3))))
|
||||||
|
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
}
|
}
|
||||||
|
|
@ -1516,10 +1517,9 @@ class MessageComposerPresenterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun anEditMode(
|
fun anEditMode(
|
||||||
eventId: EventId? = AN_EVENT_ID,
|
eventOrTransactionId: EventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(),
|
||||||
message: String = A_MESSAGE,
|
message: String = A_MESSAGE,
|
||||||
transactionId: TransactionId? = null,
|
) = MessageComposerMode.Edit(eventOrTransactionId, message)
|
||||||
) = MessageComposerMode.Edit(eventId, transactionId, message)
|
|
||||||
|
|
||||||
fun aReplyMode() = MessageComposerMode.Reply(
|
fun aReplyMode() = MessageComposerMode.Reply(
|
||||||
replyToDetails = InReplyToDetails.Loading(AN_EVENT_ID),
|
replyToDetails = InReplyToDetails.Loading(AN_EVENT_ID),
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||||
import io.element.android.libraries.matrix.api.timeline.getActiveTimeline
|
import io.element.android.libraries.matrix.api.timeline.getActiveTimeline
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -63,8 +64,7 @@ class PollRepository @Inject constructor(
|
||||||
timelineProvider
|
timelineProvider
|
||||||
.getActiveTimeline()
|
.getActiveTimeline()
|
||||||
.redactEvent(
|
.redactEvent(
|
||||||
eventId = pollStartId,
|
eventOrTransactionId = pollStartId.toEventOrTransactionId(),
|
||||||
transactionId = null,
|
|
||||||
reason = null,
|
reason = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,11 @@ import io.element.android.features.poll.impl.aPollTimelineItems
|
||||||
import io.element.android.features.poll.impl.anOngoingPollContent
|
import io.element.android.features.poll.impl.anOngoingPollContent
|
||||||
import io.element.android.features.poll.impl.data.PollRepository
|
import io.element.android.features.poll.impl.data.PollRepository
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
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.poll.PollKind
|
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||||
|
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.AN_EVENT_ID
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
|
|
@ -466,7 +467,7 @@ class CreatePollPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `delete confirms`() = runTest {
|
fun `delete confirms`() = runTest {
|
||||||
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId))
|
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId))
|
||||||
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(Unit) }
|
val redactEventLambda = lambdaRecorder { _: EventOrTransactionId, _: String? -> Result.success(Unit) }
|
||||||
timeline.redactEventLambda = redactEventLambda
|
timeline.redactEventLambda = redactEventLambda
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -481,7 +482,7 @@ class CreatePollPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `delete can be cancelled`() = runTest {
|
fun `delete can be cancelled`() = runTest {
|
||||||
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId))
|
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId))
|
||||||
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(Unit) }
|
val redactEventLambda = lambdaRecorder { _: EventOrTransactionId, _: String? -> Result.success(Unit) }
|
||||||
timeline.redactEventLambda = redactEventLambda
|
timeline.redactEventLambda = redactEventLambda
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -499,7 +500,7 @@ class CreatePollPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `delete can be confirmed`() = runTest {
|
fun `delete can be confirmed`() = runTest {
|
||||||
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId))
|
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId))
|
||||||
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(Unit) }
|
val redactEventLambda = lambdaRecorder { _: EventOrTransactionId, _: String? -> Result.success(Unit) }
|
||||||
timeline.redactEventLambda = redactEventLambda
|
timeline.redactEventLambda = redactEventLambda
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -512,7 +513,7 @@ class CreatePollPresenterTest {
|
||||||
}
|
}
|
||||||
assert(redactEventLambda)
|
assert(redactEventLambda)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value(pollEventId), value(null), any())
|
.with(value(pollEventId.toEventOrTransactionId()), any())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ jsoup = "org.jsoup:jsoup:1.18.1"
|
||||||
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
||||||
molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0"
|
molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0"
|
||||||
timber = "com.jakewharton.timber:timber:5.0.1"
|
timber = "com.jakewharton.timber:timber:5.0.1"
|
||||||
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.54"
|
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.55"
|
||||||
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
|
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
|
||||||
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
|
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
|
||||||
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ 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.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
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.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.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
import io.element.android.libraries.matrix.api.media.AudioInfo
|
||||||
|
|
@ -29,6 +28,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerL
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
@ -150,7 +150,7 @@ interface MatrixRoom : Closeable {
|
||||||
|
|
||||||
suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler>
|
suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler>
|
||||||
|
|
||||||
suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit>
|
suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit>
|
||||||
|
|
||||||
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
|
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ 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.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
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.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.AudioInfo
|
||||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
import io.element.android.libraries.matrix.api.media.FileInfo
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
import io.element.android.libraries.matrix.api.media.ImageInfo
|
||||||
|
|
@ -20,7 +19,9 @@ import io.element.android.libraries.matrix.api.media.VideoInfo
|
||||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||||
import io.element.android.libraries.matrix.api.room.IntentionalMention
|
import io.element.android.libraries.matrix.api.room.IntentionalMention
|
||||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||||
|
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.api.timeline.item.event.InReplyTo
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
@ -57,8 +58,7 @@ interface Timeline : AutoCloseable {
|
||||||
): Result<Unit>
|
): Result<Unit>
|
||||||
|
|
||||||
suspend fun editMessage(
|
suspend fun editMessage(
|
||||||
originalEventId: EventId?,
|
eventOrTransactionId: EventOrTransactionId,
|
||||||
transactionId: TransactionId?,
|
|
||||||
body: String, htmlBody: String?,
|
body: String, htmlBody: String?,
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
): Result<Unit>
|
): Result<Unit>
|
||||||
|
|
@ -89,17 +89,18 @@ interface Timeline : AutoCloseable {
|
||||||
progressCallback: ProgressCallback?
|
progressCallback: ProgressCallback?
|
||||||
): Result<MediaUploadHandler>
|
): Result<MediaUploadHandler>
|
||||||
|
|
||||||
suspend fun redactEvent(eventId: EventId?, transactionId: TransactionId?, reason: String?): Result<Unit>
|
suspend fun redactEvent(eventOrTransactionId: EventOrTransactionId, reason: String?): Result<Unit>
|
||||||
|
|
||||||
suspend fun sendAudio(file: File, audioInfo: AudioInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler>
|
suspend fun sendAudio(file: File, audioInfo: AudioInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler>
|
||||||
|
|
||||||
suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler>
|
suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler>
|
||||||
|
|
||||||
suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit>
|
suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit>
|
||||||
|
|
||||||
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
|
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
|
||||||
|
|
||||||
suspend fun cancelSend(transactionId: TransactionId): Result<Unit>
|
suspend fun cancelSend(transactionId: TransactionId): Result<Unit> =
|
||||||
|
redactEvent(transactionId.toEventOrTransactionId(), reason = null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share a location message in the room.
|
* Share a location message in the room.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
* Please see LICENSE in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.matrix.api.timeline.item.event
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.TransactionId
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
sealed interface EventOrTransactionId {
|
||||||
|
@JvmInline
|
||||||
|
value class Event(val id: EventId) : EventOrTransactionId
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class Transaction(val id: TransactionId) : EventOrTransactionId
|
||||||
|
|
||||||
|
val eventId: EventId?
|
||||||
|
get() = (this as? Event)?.id
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(eventId: EventId?, transactionId: TransactionId?): EventOrTransactionId {
|
||||||
|
return when {
|
||||||
|
eventId != null -> Event(eventId)
|
||||||
|
transactionId != null -> Transaction(transactionId)
|
||||||
|
else -> throw IllegalArgumentException("EventId and TransactionId are both null")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EventId.toEventOrTransactionId() = EventOrTransactionId.Event(this)
|
||||||
|
fun TransactionId.toEventOrTransactionId() = EventOrTransactionId.Transaction(this)
|
||||||
|
|
@ -17,7 +17,6 @@ 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.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
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.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.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
import io.element.android.libraries.matrix.api.media.AudioInfo
|
||||||
|
|
@ -42,6 +41,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||||
import io.element.android.libraries.matrix.api.room.roomNotificationSettings
|
import io.element.android.libraries.matrix.api.room.roomNotificationSettings
|
||||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
import io.element.android.libraries.matrix.impl.mapper.map
|
import io.element.android.libraries.matrix.impl.mapper.map
|
||||||
|
|
@ -471,8 +471,8 @@ class RustMatrixRoom(
|
||||||
return liveTimeline.sendFile(file, fileInfo, progressCallback)
|
return liveTimeline.sendFile(file, fileInfo, progressCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit> {
|
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> {
|
||||||
return liveTimeline.toggleReaction(emoji, uniqueId)
|
return liveTimeline.toggleReaction(emoji, eventOrTransactionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> {
|
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
* Please see LICENSE in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.matrix.impl.timeline
|
||||||
|
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
|
import org.matrix.rustcomponents.sdk.EventOrTransactionId as RustEventOrTransactionId
|
||||||
|
|
||||||
|
fun EventOrTransactionId.toRustEventOrTransactionId() = when (this) {
|
||||||
|
is EventOrTransactionId.Event -> RustEventOrTransactionId.EventId(id.value)
|
||||||
|
is EventOrTransactionId.Transaction -> RustEventOrTransactionId.TransactionId(id.value)
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ class MatrixTimelineItemMapper(
|
||||||
private val eventTimelineItemMapper: EventTimelineItemMapper,
|
private val eventTimelineItemMapper: EventTimelineItemMapper,
|
||||||
) {
|
) {
|
||||||
fun map(timelineItem: TimelineItem): MatrixTimelineItem = timelineItem.use {
|
fun map(timelineItem: TimelineItem): MatrixTimelineItem = timelineItem.use {
|
||||||
val uniqueId = UniqueId(timelineItem.uniqueId())
|
val uniqueId = UniqueId(timelineItem.uniqueId().id)
|
||||||
val asEvent = it.asEvent()
|
val asEvent = it.asEvent()
|
||||||
if (asEvent != null) {
|
if (asEvent != null) {
|
||||||
val eventTimelineItem = eventTimelineItemMapper.map(asEvent)
|
val eventTimelineItem = eventTimelineItemMapper.map(asEvent)
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ 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.EventId
|
||||||
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
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.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.AudioInfo
|
||||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
import io.element.android.libraries.matrix.api.media.FileInfo
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
import io.element.android.libraries.matrix.api.media.ImageInfo
|
||||||
|
|
@ -26,6 +24,7 @@ import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
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.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.api.timeline.item.event.InReplyTo
|
||||||
import io.element.android.libraries.matrix.impl.core.toProgressWatcher
|
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.MediaUploadHandlerImpl
|
||||||
|
|
@ -65,8 +64,6 @@ import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.matrix.rustcomponents.sdk.EditedContent
|
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.FormattedBody
|
||||||
import org.matrix.rustcomponents.sdk.MessageFormat
|
import org.matrix.rustcomponents.sdk.MessageFormat
|
||||||
import org.matrix.rustcomponents.sdk.PollData
|
import org.matrix.rustcomponents.sdk.PollData
|
||||||
|
|
@ -75,6 +72,7 @@ import org.matrix.rustcomponents.sdk.use
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uniffi.matrix_sdk_ui.LiveBackPaginationStatus
|
import uniffi.matrix_sdk_ui.LiveBackPaginationStatus
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import org.matrix.rustcomponents.sdk.EventOrTransactionId as RustEventOrTransactionId
|
||||||
import org.matrix.rustcomponents.sdk.Timeline as InnerTimeline
|
import org.matrix.rustcomponents.sdk.Timeline as InnerTimeline
|
||||||
|
|
||||||
private const val PAGINATION_SIZE = 50
|
private const val PAGINATION_SIZE = 50
|
||||||
|
|
@ -280,31 +278,23 @@ class RustTimeline(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun redactEvent(eventId: EventId?, transactionId: TransactionId?, reason: String?): Result<Unit> = withContext(dispatcher) {
|
override suspend fun redactEvent(eventOrTransactionId: EventOrTransactionId, reason: String?): Result<Unit> = withContext(dispatcher) {
|
||||||
runCatching {
|
runCatching {
|
||||||
val eventOrTransactionId = if (eventId != null) {
|
inner.redactEvent(
|
||||||
EventOrTransactionId.EventId(eventId.value)
|
eventOrTransactionId = eventOrTransactionId.toRustEventOrTransactionId(),
|
||||||
} else {
|
reason = reason,
|
||||||
EventOrTransactionId.TransactionId(transactionId!!.value)
|
)
|
||||||
}
|
|
||||||
inner.redactEvent(eventOrTransactionId = eventOrTransactionId, reason = reason)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun editMessage(
|
override suspend fun editMessage(
|
||||||
originalEventId: EventId?,
|
eventOrTransactionId: EventOrTransactionId,
|
||||||
transactionId: TransactionId?,
|
|
||||||
body: String,
|
body: String,
|
||||||
htmlBody: String?,
|
htmlBody: String?,
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
): Result<Unit> =
|
): Result<Unit> =
|
||||||
withContext(dispatcher) {
|
withContext(dispatcher) {
|
||||||
runCatching<Unit> {
|
runCatching<Unit> {
|
||||||
val eventOrTransactionId = if (originalEventId != null) {
|
|
||||||
EventOrTransactionId.EventId(originalEventId.value)
|
|
||||||
} else {
|
|
||||||
EventOrTransactionId.TransactionId(transactionId!!.value)
|
|
||||||
}
|
|
||||||
val editedContent = EditedContent.RoomMessage(
|
val editedContent = EditedContent.RoomMessage(
|
||||||
content = MessageEventContent.from(
|
content = MessageEventContent.from(
|
||||||
body = body,
|
body = body,
|
||||||
|
|
@ -314,7 +304,7 @@ class RustTimeline(
|
||||||
)
|
)
|
||||||
inner.edit(
|
inner.edit(
|
||||||
newContent = editedContent,
|
newContent = editedContent,
|
||||||
eventOrTransactionId = eventOrTransactionId,
|
eventOrTransactionId = eventOrTransactionId.toRustEventOrTransactionId(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -354,21 +344,6 @@ class RustTimeline(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws
|
|
||||||
@Suppress("UnusedPrivateMember")
|
|
||||||
private suspend fun getEventTimelineItem(eventId: EventId?, transactionId: TransactionId?): EventTimelineItem {
|
|
||||||
return try {
|
|
||||||
when {
|
|
||||||
eventId != null -> inner.getEventTimelineItemByEventId(eventId.value)
|
|
||||||
transactionId != null -> inner.getEventTimelineItemByTransactionId(transactionId.value)
|
|
||||||
else -> error("Either eventId or transactionId must be non-null")
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.e(e, "Failed to get event timeline item")
|
|
||||||
throw TimelineException.EventNotFound
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendVideo(
|
override suspend fun sendVideo(
|
||||||
file: File,
|
file: File,
|
||||||
thumbnailFile: File?,
|
thumbnailFile: File?,
|
||||||
|
|
@ -410,9 +385,12 @@ class RustTimeline(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit> = withContext(dispatcher) {
|
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> = withContext(dispatcher) {
|
||||||
runCatching {
|
runCatching {
|
||||||
inner.toggleReaction(key = emoji, uniqueId = uniqueId.value)
|
inner.toggleReaction(
|
||||||
|
key = emoji,
|
||||||
|
itemId = eventOrTransactionId.toRustEventOrTransactionId(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -424,9 +402,6 @@ class RustTimeline(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> =
|
|
||||||
redactEvent(eventId = null, transactionId = transactionId, reason = null)
|
|
||||||
|
|
||||||
override suspend fun sendLocation(
|
override suspend fun sendLocation(
|
||||||
body: String,
|
body: String,
|
||||||
geoUri: String,
|
geoUri: String,
|
||||||
|
|
@ -479,7 +454,7 @@ class RustTimeline(
|
||||||
)
|
)
|
||||||
inner.edit(
|
inner.edit(
|
||||||
newContent = editedContent,
|
newContent = editedContent,
|
||||||
eventOrTransactionId = EventOrTransactionId.EventId(pollStartId.value),
|
eventOrTransactionId = RustEventOrTransactionId.EventId(pollStartId.value),
|
||||||
)
|
)
|
||||||
}.map { }
|
}.map { }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ package io.element.android.libraries.matrix.impl.fixtures.fakes
|
||||||
import org.matrix.rustcomponents.sdk.EventTimelineItem
|
import org.matrix.rustcomponents.sdk.EventTimelineItem
|
||||||
import org.matrix.rustcomponents.sdk.NoPointer
|
import org.matrix.rustcomponents.sdk.NoPointer
|
||||||
import org.matrix.rustcomponents.sdk.TimelineItem
|
import org.matrix.rustcomponents.sdk.TimelineItem
|
||||||
|
import org.matrix.rustcomponents.sdk.TimelineUniqueId
|
||||||
import org.matrix.rustcomponents.sdk.VirtualTimelineItem
|
import org.matrix.rustcomponents.sdk.VirtualTimelineItem
|
||||||
|
|
||||||
class FakeRustTimelineItem(
|
class FakeRustTimelineItem(
|
||||||
|
|
@ -18,5 +19,5 @@ class FakeRustTimelineItem(
|
||||||
override fun asEvent(): EventTimelineItem? = asEventResult
|
override fun asEvent(): EventTimelineItem? = asEventResult
|
||||||
override fun asVirtual(): VirtualTimelineItem? = null
|
override fun asVirtual(): VirtualTimelineItem? = null
|
||||||
override fun fmtDebug(): String = "fmtDebug"
|
override fun fmtDebug(): String = "fmtDebug"
|
||||||
override fun uniqueId(): String = "uniqueId"
|
override fun uniqueId(): TimelineUniqueId = TimelineUniqueId("uniqueId")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ 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.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
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.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.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
import io.element.android.libraries.matrix.api.media.AudioInfo
|
||||||
|
|
@ -38,6 +37,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerL
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
|
|
@ -95,7 +95,7 @@ class FakeMatrixRoom(
|
||||||
private val editMessageLambda: (EventId, String, String?, List<IntentionalMention>) -> Result<Unit> = { _, _, _, _ -> lambdaError() },
|
private val editMessageLambda: (EventId, String, String?, List<IntentionalMention>) -> Result<Unit> = { _, _, _, _ -> lambdaError() },
|
||||||
private val sendMessageResult: (String, String?, List<IntentionalMention>) -> Result<Unit> = { _, _, _ -> lambdaError() },
|
private val sendMessageResult: (String, String?, List<IntentionalMention>) -> Result<Unit> = { _, _, _ -> lambdaError() },
|
||||||
private val updateUserRoleResult: () -> Result<Unit> = { lambdaError() },
|
private val updateUserRoleResult: () -> Result<Unit> = { lambdaError() },
|
||||||
private val toggleReactionResult: (String, UniqueId) -> Result<Unit> = { _, _ -> lambdaError() },
|
private val toggleReactionResult: (String, EventOrTransactionId) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
private val retrySendMessageResult: (TransactionId) -> Result<Unit> = { lambdaError() },
|
private val retrySendMessageResult: (TransactionId) -> Result<Unit> = { lambdaError() },
|
||||||
private val cancelSendResult: (TransactionId) -> Result<Unit> = { lambdaError() },
|
private val cancelSendResult: (TransactionId) -> Result<Unit> = { lambdaError() },
|
||||||
private val forwardEventResult: (EventId, List<RoomId>) -> Result<Unit> = { _, _ -> lambdaError() },
|
private val forwardEventResult: (EventId, List<RoomId>) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
|
@ -236,8 +236,8 @@ class FakeMatrixRoom(
|
||||||
sendMessageResult(body, htmlBody, intentionalMentions)
|
sendMessageResult(body, htmlBody, intentionalMentions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit> {
|
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> {
|
||||||
return toggleReactionResult(emoji, uniqueId)
|
return toggleReactionResult(emoji, eventOrTransactionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun retrySendMessage(transactionId: TransactionId): Result<Unit> = simulateLongTask {
|
override suspend fun retrySendMessage(transactionId: TransactionId): Result<Unit> = simulateLongTask {
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,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.EventId
|
||||||
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
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.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.AudioInfo
|
||||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
import io.element.android.libraries.matrix.api.media.FileInfo
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
import io.element.android.libraries.matrix.api.media.ImageInfo
|
||||||
|
|
@ -23,6 +21,7 @@ import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
|
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.api.timeline.item.event.InReplyTo
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.tests.testutils.lambda.lambdaError
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
|
@ -63,35 +62,31 @@ class FakeTimeline(
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
): Result<Unit> = sendMessageLambda(body, htmlBody, intentionalMentions)
|
): Result<Unit> = sendMessageLambda(body, htmlBody, intentionalMentions)
|
||||||
|
|
||||||
var redactEventLambda: (eventId: EventId?, transactionId: TransactionId?, reason: String?) -> Result<Unit> = { _, _, _ ->
|
var redactEventLambda: (eventOrTransactionId: EventOrTransactionId, reason: String?) -> Result<Unit> = { _, _ ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun redactEvent(
|
override suspend fun redactEvent(
|
||||||
eventId: EventId?,
|
eventOrTransactionId: EventOrTransactionId,
|
||||||
transactionId: TransactionId?,
|
|
||||||
reason: String?
|
reason: String?
|
||||||
): Result<Unit> = redactEventLambda(eventId, transactionId, reason)
|
): Result<Unit> = redactEventLambda(eventOrTransactionId, reason)
|
||||||
|
|
||||||
var editMessageLambda: (
|
var editMessageLambda: (
|
||||||
originalEventId: EventId?,
|
eventOrTransactionId: EventOrTransactionId,
|
||||||
transactionId: TransactionId?,
|
|
||||||
body: String,
|
body: String,
|
||||||
htmlBody: String?,
|
htmlBody: String?,
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
) -> Result<Unit> = { _, _, _, _, _ ->
|
) -> Result<Unit> = { _, _, _, _ ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun editMessage(
|
override suspend fun editMessage(
|
||||||
originalEventId: EventId?,
|
eventOrTransactionId: EventOrTransactionId,
|
||||||
transactionId: TransactionId?,
|
|
||||||
body: String,
|
body: String,
|
||||||
htmlBody: String?,
|
htmlBody: String?,
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
): Result<Unit> = editMessageLambda(
|
): Result<Unit> = editMessageLambda(
|
||||||
originalEventId,
|
eventOrTransactionId,
|
||||||
transactionId,
|
|
||||||
body,
|
body,
|
||||||
htmlBody,
|
htmlBody,
|
||||||
intentionalMentions
|
intentionalMentions
|
||||||
|
|
@ -211,14 +206,15 @@ class FakeTimeline(
|
||||||
progressCallback
|
progressCallback
|
||||||
)
|
)
|
||||||
|
|
||||||
var toggleReactionLambda: (emoji: String, uniqueId: UniqueId) -> Result<Unit> = { _, _ -> Result.success(Unit) }
|
var toggleReactionLambda: (emoji: String, eventOrTransactionId: EventOrTransactionId) -> Result<Unit> = { _, _ -> Result.success(Unit) }
|
||||||
override suspend fun toggleReaction(emoji: String, uniqueId: UniqueId): Result<Unit> = toggleReactionLambda(emoji, uniqueId)
|
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> = toggleReactionLambda(
|
||||||
|
emoji,
|
||||||
|
eventOrTransactionId
|
||||||
|
)
|
||||||
|
|
||||||
var forwardEventLambda: (eventId: EventId, roomIds: List<RoomId>) -> Result<Unit> = { _, _ -> Result.success(Unit) }
|
var forwardEventLambda: (eventId: EventId, roomIds: List<RoomId>) -> Result<Unit> = { _, _ -> Result.success(Unit) }
|
||||||
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = forwardEventLambda(eventId, roomIds)
|
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = forwardEventLambda(eventId, roomIds)
|
||||||
|
|
||||||
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> = redactEvent(null, transactionId, null)
|
|
||||||
|
|
||||||
var sendLocationLambda: (
|
var sendLocationLambda: (
|
||||||
body: String,
|
body: String,
|
||||||
geoUri: String,
|
geoUri: String,
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
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.timeline.item.event.EventOrTransactionId
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetailsProvider
|
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetailsProvider
|
||||||
import io.element.android.libraries.testtags.TestTags
|
import io.element.android.libraries.testtags.TestTags
|
||||||
|
|
@ -719,12 +720,10 @@ fun aRichTextEditorState(
|
||||||
)
|
)
|
||||||
|
|
||||||
fun aMessageComposerModeEdit(
|
fun aMessageComposerModeEdit(
|
||||||
eventId: EventId? = EventId("$1234"),
|
eventOrTransactionId: EventOrTransactionId = EventId("$1234").toEventOrTransactionId(),
|
||||||
transactionId: TransactionId? = TransactionId("1234"),
|
|
||||||
content: String = "Some text",
|
content: String = "Some text",
|
||||||
) = MessageComposerMode.Edit(
|
) = MessageComposerMode.Edit(
|
||||||
eventId = eventId,
|
eventOrTransactionId = eventOrTransactionId,
|
||||||
transactionId = transactionId,
|
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId
|
||||||
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
|
|
@ -77,7 +79,7 @@ internal fun SendButton(
|
||||||
@Composable
|
@Composable
|
||||||
internal fun SendButtonPreview() = ElementPreview {
|
internal fun SendButtonPreview() = ElementPreview {
|
||||||
val normalMode = MessageComposerMode.Normal
|
val normalMode = MessageComposerMode.Normal
|
||||||
val editMode = MessageComposerMode.Edit(null, null, "")
|
val editMode = MessageComposerMode.Edit(EventId("\$id").toEventOrTransactionId(), "")
|
||||||
Row {
|
Row {
|
||||||
SendButton(canSendMessage = true, onClick = {}, composerMode = normalMode)
|
SendButton(canSendMessage = true, onClick = {}, composerMode = normalMode)
|
||||||
SendButton(canSendMessage = false, onClick = {}, composerMode = normalMode)
|
SendButton(canSendMessage = false, onClick = {}, composerMode = normalMode)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ package io.element.android.libraries.textcomposer.model
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
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.timeline.item.event.EventOrTransactionId
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.eventId
|
import io.element.android.libraries.matrix.ui.messages.reply.eventId
|
||||||
|
|
@ -21,8 +21,7 @@ sealed interface MessageComposerMode {
|
||||||
sealed interface Special : MessageComposerMode
|
sealed interface Special : MessageComposerMode
|
||||||
|
|
||||||
data class Edit(
|
data class Edit(
|
||||||
val eventId: EventId?,
|
val eventOrTransactionId: EventOrTransactionId,
|
||||||
val transactionId: TransactionId?,
|
|
||||||
val content: String
|
val content: String
|
||||||
) : Special
|
) : Special
|
||||||
|
|
||||||
|
|
@ -36,7 +35,7 @@ sealed interface MessageComposerMode {
|
||||||
val relatedEventId: EventId?
|
val relatedEventId: EventId?
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
is Normal -> null
|
is Normal -> null
|
||||||
is Edit -> eventId
|
is Edit -> eventOrTransactionId.eventId
|
||||||
is Reply -> eventId
|
is Reply -> eventId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue