Send failure verified user : handle click on failed send icon.
This commit is contained in:
parent
b38f016677
commit
84c8ddacf7
16 changed files with 76 additions and 82 deletions
|
|
@ -30,7 +30,6 @@ import io.element.android.features.messages.impl.actionlist.ActionListEvents
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListPresenter
|
import io.element.android.features.messages.impl.actionlist.ActionListPresenter
|
||||||
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.actionlist.model.TimelineItemActionPostProcessor
|
import io.element.android.features.messages.impl.actionlist.model.TimelineItemActionPostProcessor
|
||||||
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState
|
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
||||||
|
|
@ -96,7 +95,6 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
private val reactionSummaryPresenter: ReactionSummaryPresenter,
|
private val reactionSummaryPresenter: ReactionSummaryPresenter,
|
||||||
private val readReceiptBottomSheetPresenter: ReadReceiptBottomSheetPresenter,
|
private val readReceiptBottomSheetPresenter: ReadReceiptBottomSheetPresenter,
|
||||||
private val pinnedMessagesBannerPresenter: Presenter<PinnedMessagesBannerState>,
|
private val pinnedMessagesBannerPresenter: Presenter<PinnedMessagesBannerState>,
|
||||||
private val resolveVerifiedUserSendFailurePresenter: Presenter<ResolveVerifiedUserSendFailureState>,
|
|
||||||
private val networkMonitor: NetworkMonitor,
|
private val networkMonitor: NetworkMonitor,
|
||||||
private val snackbarDispatcher: SnackbarDispatcher,
|
private val snackbarDispatcher: SnackbarDispatcher,
|
||||||
private val dispatchers: CoroutineDispatchers,
|
private val dispatchers: CoroutineDispatchers,
|
||||||
|
|
@ -130,7 +128,6 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
val reactionSummaryState = reactionSummaryPresenter.present()
|
val reactionSummaryState = reactionSummaryPresenter.present()
|
||||||
val readReceiptBottomSheetState = readReceiptBottomSheetPresenter.present()
|
val readReceiptBottomSheetState = readReceiptBottomSheetPresenter.present()
|
||||||
val pinnedMessagesBannerState = pinnedMessagesBannerPresenter.present()
|
val pinnedMessagesBannerState = pinnedMessagesBannerPresenter.present()
|
||||||
val resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailurePresenter.present()
|
|
||||||
|
|
||||||
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||||
|
|
||||||
|
|
@ -230,7 +227,6 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
appName = buildMeta.applicationName,
|
appName = buildMeta.applicationName,
|
||||||
callState = callState,
|
callState = callState,
|
||||||
pinnedMessagesBannerState = pinnedMessagesBannerState,
|
pinnedMessagesBannerState = pinnedMessagesBannerState,
|
||||||
resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailureState,
|
|
||||||
eventSink = { handleEvents(it) }
|
eventSink = { handleEvents(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ package io.element.android.features.messages.impl
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListState
|
import io.element.android.features.messages.impl.actionlist.ActionListState
|
||||||
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState
|
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
||||||
import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerState
|
import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerState
|
||||||
import io.element.android.features.messages.impl.timeline.TimelineState
|
import io.element.android.features.messages.impl.timeline.TimelineState
|
||||||
|
|
@ -48,7 +47,6 @@ data class MessagesState(
|
||||||
val callState: RoomCallState,
|
val callState: RoomCallState,
|
||||||
val appName: String,
|
val appName: String,
|
||||||
val pinnedMessagesBannerState: PinnedMessagesBannerState,
|
val pinnedMessagesBannerState: PinnedMessagesBannerState,
|
||||||
val resolveVerifiedUserSendFailureState: ResolveVerifiedUserSendFailureState,
|
|
||||||
val eventSink: (MessagesEvents) -> Unit
|
val eventSink: (MessagesEvents) -> Unit
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ package io.element.android.features.messages.impl
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListState
|
import io.element.android.features.messages.impl.actionlist.ActionListState
|
||||||
import io.element.android.features.messages.impl.actionlist.anActionListState
|
import io.element.android.features.messages.impl.actionlist.anActionListState
|
||||||
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState
|
|
||||||
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.aResolveVerifiedUserSendFailureState
|
|
||||||
import io.element.android.features.messages.impl.messagecomposer.AttachmentsState
|
import io.element.android.features.messages.impl.messagecomposer.AttachmentsState
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
||||||
import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState
|
import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState
|
||||||
|
|
@ -115,7 +113,6 @@ fun aMessagesState(
|
||||||
enableVoiceMessages: Boolean = true,
|
enableVoiceMessages: Boolean = true,
|
||||||
callState: RoomCallState = RoomCallState.ENABLED,
|
callState: RoomCallState = RoomCallState.ENABLED,
|
||||||
pinnedMessagesBannerState: PinnedMessagesBannerState = aLoadedPinnedMessagesBannerState(),
|
pinnedMessagesBannerState: PinnedMessagesBannerState = aLoadedPinnedMessagesBannerState(),
|
||||||
resolveVerifiedUserSendFailureState: ResolveVerifiedUserSendFailureState = aResolveVerifiedUserSendFailureState(),
|
|
||||||
eventSink: (MessagesEvents) -> Unit = {},
|
eventSink: (MessagesEvents) -> Unit = {},
|
||||||
) = MessagesState(
|
) = MessagesState(
|
||||||
roomId = RoomId("!id:domain"),
|
roomId = RoomId("!id:domain"),
|
||||||
|
|
@ -140,7 +137,6 @@ fun aMessagesState(
|
||||||
callState = callState,
|
callState = callState,
|
||||||
appName = "Element",
|
appName = "Element",
|
||||||
pinnedMessagesBannerState = pinnedMessagesBannerState,
|
pinnedMessagesBannerState = pinnedMessagesBannerState,
|
||||||
resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailureState,
|
|
||||||
eventSink = eventSink,
|
eventSink = eventSink,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,6 @@ import io.element.android.features.messages.impl.actionlist.ActionListEvents
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListView
|
import io.element.android.features.messages.impl.actionlist.ActionListView
|
||||||
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.attachments.Attachment
|
import io.element.android.features.messages.impl.attachments.Attachment
|
||||||
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureEvents
|
|
||||||
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureView
|
|
||||||
import io.element.android.features.messages.impl.messagecomposer.AttachmentsBottomSheet
|
import io.element.android.features.messages.impl.messagecomposer.AttachmentsBottomSheet
|
||||||
import io.element.android.features.messages.impl.messagecomposer.AttachmentsState
|
import io.element.android.features.messages.impl.messagecomposer.AttachmentsState
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents
|
||||||
|
|
@ -244,14 +242,10 @@ fun MessagesView(
|
||||||
},
|
},
|
||||||
onEmojiReactionClick = ::onEmojiReactionClick,
|
onEmojiReactionClick = ::onEmojiReactionClick,
|
||||||
onVerifiedUserSendFailureClick = { event ->
|
onVerifiedUserSendFailureClick = { event ->
|
||||||
state.resolveVerifiedUserSendFailureState.eventSink(ResolveVerifiedUserSendFailureEvents.ComputeForMessage(event))
|
state.timelineState.eventSink(TimelineEvents.ComputeVerifiedUserSendFailure(event))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ResolveVerifiedUserSendFailureView(
|
|
||||||
state = state.resolveVerifiedUserSendFailureState,
|
|
||||||
)
|
|
||||||
|
|
||||||
CustomReactionBottomSheet(
|
CustomReactionBottomSheet(
|
||||||
state = state.customReactionState,
|
state = state.customReactionState,
|
||||||
onSelectEmoji = { uniqueId, emoji ->
|
onSelectEmoji = { uniqueId, emoji ->
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ fun ResolveVerifiedUserSendFailureView(
|
||||||
state: ResolveVerifiedUserSendFailureState,
|
state: ResolveVerifiedUserSendFailureState,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val sheetState = rememberModalBottomSheetState()
|
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
var showSheet by remember { mutableStateOf(false) }
|
var showSheet by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
fun dismiss() {
|
fun dismiss() {
|
||||||
|
|
|
||||||
|
|
@ -200,19 +200,18 @@ private fun PinnedMessagesListLoaded(
|
||||||
renderReadReceipts = false,
|
renderReadReceipts = false,
|
||||||
isLastOutgoingMessage = false,
|
isLastOutgoingMessage = false,
|
||||||
focusedEventId = null,
|
focusedEventId = null,
|
||||||
onClick = onEventClick,
|
|
||||||
onLongClick = ::onMessageLongClick,
|
|
||||||
onUserDataClick = onUserDataClick,
|
onUserDataClick = onUserDataClick,
|
||||||
onLinkClick = onLinkClick,
|
onLinkClick = onLinkClick,
|
||||||
|
onClick = onEventClick,
|
||||||
|
onLongClick = ::onMessageLongClick,
|
||||||
inReplyToClick = {},
|
inReplyToClick = {},
|
||||||
onReactionClick = { _, _ -> },
|
onReactionClick = { _, _ -> },
|
||||||
onReactionLongClick = { _, _ -> },
|
onReactionLongClick = { _, _ -> },
|
||||||
onMoreReactionsClick = {},
|
onMoreReactionsClick = {},
|
||||||
onReadReceiptClick = {},
|
onReadReceiptClick = {},
|
||||||
eventSink = {},
|
|
||||||
onSwipeToReply = {},
|
onSwipeToReply = {},
|
||||||
onJoinCallClick = {},
|
onJoinCallClick = {},
|
||||||
onShieldClick = {},
|
eventSink = {},
|
||||||
eventContentView = { event, contentModifier, onContentLayoutChange ->
|
eventContentView = { event, contentModifier, onContentLayoutChange ->
|
||||||
TimelineItemEventContentViewWrapper(
|
TimelineItemEventContentViewWrapper(
|
||||||
event = event,
|
event = event,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
package io.element.android.features.messages.impl.timeline
|
package io.element.android.features.messages.impl.timeline
|
||||||
|
|
||||||
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
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.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
|
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
|
||||||
|
|
@ -19,7 +20,6 @@ sealed interface TimelineEvents {
|
||||||
data object OnFocusEventRender : TimelineEvents
|
data object OnFocusEventRender : TimelineEvents
|
||||||
data object JumpToLive : TimelineEvents
|
data object JumpToLive : TimelineEvents
|
||||||
|
|
||||||
data class ShowShieldDialog(val messageShield: MessageShield) : TimelineEvents
|
|
||||||
data object HideShieldDialog : TimelineEvents
|
data object HideShieldDialog : TimelineEvents
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,6 +27,8 @@ sealed interface TimelineEvents {
|
||||||
*/
|
*/
|
||||||
sealed interface EventFromTimelineItem : TimelineEvents
|
sealed interface EventFromTimelineItem : TimelineEvents
|
||||||
|
|
||||||
|
data class ComputeVerifiedUserSendFailure(val event: TimelineItem.Event) : EventFromTimelineItem
|
||||||
|
data class ShowShieldDialog(val messageShield: MessageShield) : EventFromTimelineItem
|
||||||
data class LoadMore(val direction: Timeline.PaginationDirection) : EventFromTimelineItem
|
data class LoadMore(val direction: Timeline.PaginationDirection) : EventFromTimelineItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import io.element.android.features.messages.impl.MessagesNavigator
|
import io.element.android.features.messages.impl.MessagesNavigator
|
||||||
|
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureEvents
|
||||||
|
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState
|
||||||
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory
|
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory
|
||||||
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactoryConfig
|
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactoryConfig
|
||||||
import io.element.android.features.messages.impl.timeline.model.NewEventState
|
import io.element.android.features.messages.impl.timeline.model.NewEventState
|
||||||
|
|
@ -66,6 +68,7 @@ class TimelinePresenter @AssistedInject constructor(
|
||||||
private val endPollAction: EndPollAction,
|
private val endPollAction: EndPollAction,
|
||||||
private val sessionPreferencesStore: SessionPreferencesStore,
|
private val sessionPreferencesStore: SessionPreferencesStore,
|
||||||
private val timelineController: TimelineController,
|
private val timelineController: TimelineController,
|
||||||
|
private val resolveVerifiedUserSendFailurePresenter: Presenter<ResolveVerifiedUserSendFailureState>,
|
||||||
) : Presenter<TimelineState> {
|
) : Presenter<TimelineState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
|
|
@ -101,6 +104,7 @@ class TimelinePresenter @AssistedInject constructor(
|
||||||
val newEventState = remember { mutableStateOf(NewEventState.None) }
|
val newEventState = remember { mutableStateOf(NewEventState.None) }
|
||||||
val messageShield: MutableState<MessageShield?> = remember { mutableStateOf(null) }
|
val messageShield: MutableState<MessageShield?> = remember { mutableStateOf(null) }
|
||||||
|
|
||||||
|
val resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailurePresenter.present()
|
||||||
val isSendPublicReadReceiptsEnabled by sessionPreferencesStore.isSendPublicReadReceiptsEnabled().collectAsState(initial = true)
|
val isSendPublicReadReceiptsEnabled by sessionPreferencesStore.isSendPublicReadReceiptsEnabled().collectAsState(initial = true)
|
||||||
val renderReadReceipts by sessionPreferencesStore.isRenderReadReceiptsEnabled().collectAsState(initial = true)
|
val renderReadReceipts by sessionPreferencesStore.isRenderReadReceiptsEnabled().collectAsState(initial = true)
|
||||||
val isLive by timelineController.isLive().collectAsState(initial = true)
|
val isLive by timelineController.isLive().collectAsState(initial = true)
|
||||||
|
|
@ -156,6 +160,9 @@ class TimelinePresenter @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
TimelineEvents.HideShieldDialog -> messageShield.value = null
|
TimelineEvents.HideShieldDialog -> messageShield.value = null
|
||||||
is TimelineEvents.ShowShieldDialog -> messageShield.value = event.messageShield
|
is TimelineEvents.ShowShieldDialog -> messageShield.value = event.messageShield
|
||||||
|
is TimelineEvents.ComputeVerifiedUserSendFailure -> {
|
||||||
|
resolveVerifiedUserSendFailureState.eventSink(ResolveVerifiedUserSendFailureEvents.ComputeForMessage(event.event))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,6 +239,7 @@ class TimelinePresenter @AssistedInject constructor(
|
||||||
isLive = isLive,
|
isLive = isLive,
|
||||||
focusRequestState = focusRequestState.value,
|
focusRequestState = focusRequestState.value,
|
||||||
messageShield = messageShield.value,
|
messageShield = messageShield.value,
|
||||||
|
resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailureState,
|
||||||
eventSink = { handleEvents(it) }
|
eventSink = { handleEvents(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
package io.element.android.features.messages.impl.timeline
|
package io.element.android.features.messages.impl.timeline
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState
|
||||||
import io.element.android.features.messages.impl.timeline.model.NewEventState
|
import io.element.android.features.messages.impl.timeline.model.NewEventState
|
||||||
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.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
|
@ -25,6 +26,7 @@ data class TimelineState(
|
||||||
val focusRequestState: FocusRequestState,
|
val focusRequestState: FocusRequestState,
|
||||||
// If not null, info will be rendered in a dialog
|
// If not null, info will be rendered in a dialog
|
||||||
val messageShield: MessageShield?,
|
val messageShield: MessageShield?,
|
||||||
|
val resolveVerifiedUserSendFailureState: ResolveVerifiedUserSendFailureState,
|
||||||
val eventSink: (TimelineEvents) -> Unit,
|
val eventSink: (TimelineEvents) -> Unit,
|
||||||
) {
|
) {
|
||||||
val hasAnyEvent = timelineItems.any { it is TimelineItem.Event }
|
val hasAnyEvent = timelineItems.any { it is TimelineItem.Event }
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
package io.element.android.features.messages.impl.timeline
|
package io.element.android.features.messages.impl.timeline
|
||||||
|
|
||||||
|
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState
|
||||||
|
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.aResolveVerifiedUserSendFailureState
|
||||||
import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData
|
import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData
|
||||||
import io.element.android.features.messages.impl.timeline.model.NewEventState
|
import io.element.android.features.messages.impl.timeline.model.NewEventState
|
||||||
import io.element.android.features.messages.impl.timeline.model.ReadReceiptData
|
import io.element.android.features.messages.impl.timeline.model.ReadReceiptData
|
||||||
|
|
@ -44,6 +46,7 @@ fun aTimelineState(
|
||||||
focusedEventIndex: Int = -1,
|
focusedEventIndex: Int = -1,
|
||||||
isLive: Boolean = true,
|
isLive: Boolean = true,
|
||||||
messageShield: MessageShield? = null,
|
messageShield: MessageShield? = null,
|
||||||
|
resolveVerifiedUserSendFailureState: ResolveVerifiedUserSendFailureState = aResolveVerifiedUserSendFailureState(),
|
||||||
eventSink: (TimelineEvents) -> Unit = {},
|
eventSink: (TimelineEvents) -> Unit = {},
|
||||||
): TimelineState {
|
): TimelineState {
|
||||||
val focusedEventId = timelineItems.filterIsInstance<TimelineItem.Event>().getOrNull(focusedEventIndex)?.eventId
|
val focusedEventId = timelineItems.filterIsInstance<TimelineItem.Event>().getOrNull(focusedEventIndex)?.eventId
|
||||||
|
|
@ -60,6 +63,7 @@ fun aTimelineState(
|
||||||
isLive = isLive,
|
isLive = isLive,
|
||||||
focusRequestState = focusRequestState,
|
focusRequestState = focusRequestState,
|
||||||
messageShield = messageShield,
|
messageShield = messageShield,
|
||||||
|
resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailureState,
|
||||||
eventSink = eventSink,
|
eventSink = eventSink,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.compound.theme.ElementTheme
|
import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||||
|
import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureView
|
||||||
import io.element.android.features.messages.impl.timeline.components.TimelineItemRow
|
import io.element.android.features.messages.impl.timeline.components.TimelineItemRow
|
||||||
import io.element.android.features.messages.impl.timeline.components.toText
|
import io.element.android.features.messages.impl.timeline.components.toText
|
||||||
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
|
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
|
||||||
|
|
@ -127,8 +128,8 @@ fun TimelineView(
|
||||||
Box(modifier) {
|
Box(modifier) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.nestedScroll(nestedScrollConnection),
|
.nestedScroll(nestedScrollConnection),
|
||||||
state = lazyListState,
|
state = lazyListState,
|
||||||
reverseLayout = useReverseLayout,
|
reverseLayout = useReverseLayout,
|
||||||
contentPadding = PaddingValues(vertical = 8.dp),
|
contentPadding = PaddingValues(vertical = 8.dp),
|
||||||
|
|
@ -150,19 +151,18 @@ fun TimelineView(
|
||||||
isLastOutgoingMessage = (timelineItem as? TimelineItem.Event)?.isMine == true &&
|
isLastOutgoingMessage = (timelineItem as? TimelineItem.Event)?.isMine == true &&
|
||||||
state.timelineItems.first().identifier() == timelineItem.identifier(),
|
state.timelineItems.first().identifier() == timelineItem.identifier(),
|
||||||
focusedEventId = state.focusedEventId,
|
focusedEventId = state.focusedEventId,
|
||||||
onClick = onMessageClick,
|
|
||||||
onLongClick = onMessageLongClick,
|
|
||||||
onShieldClick = ::onShieldClick,
|
|
||||||
onUserDataClick = onUserDataClick,
|
onUserDataClick = onUserDataClick,
|
||||||
onLinkClick = onLinkClick,
|
onLinkClick = onLinkClick,
|
||||||
|
onClick = onMessageClick,
|
||||||
|
onLongClick = onMessageLongClick,
|
||||||
inReplyToClick = ::inReplyToClick,
|
inReplyToClick = ::inReplyToClick,
|
||||||
onReactionClick = onReactionClick,
|
onReactionClick = onReactionClick,
|
||||||
onReactionLongClick = onReactionLongClick,
|
onReactionLongClick = onReactionLongClick,
|
||||||
onMoreReactionsClick = onMoreReactionsClick,
|
onMoreReactionsClick = onMoreReactionsClick,
|
||||||
onReadReceiptClick = onReadReceiptClick,
|
onReadReceiptClick = onReadReceiptClick,
|
||||||
eventSink = state.eventSink,
|
|
||||||
onSwipeToReply = onSwipeToReply,
|
onSwipeToReply = onSwipeToReply,
|
||||||
onJoinCallClick = onJoinCallClick,
|
onJoinCallClick = onJoinCallClick,
|
||||||
|
eventSink = state.eventSink,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,6 +186,8 @@ fun TimelineView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResolveVerifiedUserSendFailureView(state = state.resolveVerifiedUserSendFailureState)
|
||||||
|
|
||||||
MessageShieldDialog(state)
|
MessageShieldDialog(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,8 +269,8 @@ private fun BoxScope.TimelineScrollHelper(
|
||||||
// Use inverse of canAutoScroll otherwise we might briefly see the before the scroll animation is triggered
|
// Use inverse of canAutoScroll otherwise we might briefly see the before the scroll animation is triggered
|
||||||
isVisible = !canAutoScroll || forceJumpToBottomVisibility || !isLive,
|
isVisible = !canAutoScroll || forceJumpToBottomVisibility || !isLive,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomEnd)
|
.align(Alignment.BottomEnd)
|
||||||
.padding(end = 24.dp, bottom = 12.dp),
|
.padding(end = 24.dp, bottom = 12.dp),
|
||||||
onClick = { jumpToBottom() },
|
onClick = { jumpToBottom() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -295,8 +297,8 @@ private fun JumpToBottomButton(
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(24.dp)
|
.size(24.dp)
|
||||||
.rotate(90f),
|
.rotate(90f),
|
||||||
imageVector = CompoundIcons.ArrowRight(),
|
imageVector = CompoundIcons.ArrowRight(),
|
||||||
contentDescription = stringResource(id = CommonStrings.a11y_jump_to_bottom)
|
contentDescription = stringResource(id = CommonStrings.a11y_jump_to_bottom)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,8 @@ internal fun ATimelineItemEventRow(
|
||||||
isHighlighted = isHighlighted,
|
isHighlighted = isHighlighted,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
onLongClick = {},
|
onLongClick = {},
|
||||||
onShieldClick = {},
|
|
||||||
onUserDataClick = {},
|
|
||||||
onLinkClick = {},
|
onLinkClick = {},
|
||||||
|
onUserDataClick = {},
|
||||||
inReplyToClick = {},
|
inReplyToClick = {},
|
||||||
onReactionClick = { _, _ -> },
|
onReactionClick = { _, _ -> },
|
||||||
onReactionLongClick = { _, _ -> },
|
onReactionLongClick = { _, _ -> },
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.compound.theme.ElementTheme
|
import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||||
|
import io.element.android.features.messages.impl.timeline.TimelineEvents
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
import io.element.android.features.messages.impl.timeline.model.event.isEdited
|
import io.element.android.features.messages.impl.timeline.model.event.isEdited
|
||||||
import io.element.android.libraries.core.bool.orFalse
|
import io.element.android.libraries.core.bool.orFalse
|
||||||
|
|
@ -31,14 +32,13 @@ 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.Text
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
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.isCritical
|
import io.element.android.libraries.matrix.api.timeline.item.event.isCritical
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TimelineEventTimestampView(
|
fun TimelineEventTimestampView(
|
||||||
event: TimelineItem.Event,
|
event: TimelineItem.Event,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val formattedTime = event.sentTime
|
val formattedTime = event.sentTime
|
||||||
|
|
@ -48,8 +48,8 @@ fun TimelineEventTimestampView(
|
||||||
val tint = if (hasError || hasEncryptionCritical) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.secondary
|
val tint = if (hasError || hasEncryptionCritical) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.secondary
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(PaddingValues(start = TimelineEventTimestampViewDefaults.spacing))
|
.padding(PaddingValues(start = TimelineEventTimestampViewDefaults.spacing))
|
||||||
.then(modifier),
|
.then(modifier),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
if (isMessageEdited) {
|
if (isMessageEdited) {
|
||||||
|
|
@ -66,12 +66,17 @@ fun TimelineEventTimestampView(
|
||||||
color = tint,
|
color = tint,
|
||||||
)
|
)
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
|
val isVerifiedUserSendFailure = event.localSendState is LocalEventSendState.Failed.VerifiedUser
|
||||||
Spacer(modifier = Modifier.width(2.dp))
|
Spacer(modifier = Modifier.width(2.dp))
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = CompoundIcons.Error(),
|
imageVector = CompoundIcons.Error(),
|
||||||
contentDescription = stringResource(id = CommonStrings.common_sending_failed),
|
contentDescription = stringResource(id = CommonStrings.common_sending_failed),
|
||||||
tint = tint,
|
tint = tint,
|
||||||
modifier = Modifier.size(15.dp, 18.dp),
|
modifier = Modifier
|
||||||
|
.size(15.dp, 18.dp)
|
||||||
|
.clickable(isVerifiedUserSendFailure) {
|
||||||
|
eventSink(TimelineEvents.ComputeVerifiedUserSendFailure(event))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
event.messageShield?.let { shield ->
|
event.messageShield?.let { shield ->
|
||||||
|
|
@ -80,8 +85,10 @@ fun TimelineEventTimestampView(
|
||||||
imageVector = shield.toIcon(),
|
imageVector = shield.toIcon(),
|
||||||
contentDescription = shield.toText(),
|
contentDescription = shield.toText(),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(15.dp)
|
.size(15.dp)
|
||||||
.clickable { onShieldClick(shield) },
|
.clickable {
|
||||||
|
eventSink(TimelineEvents.ShowShieldDialog(shield))
|
||||||
|
},
|
||||||
tint = shield.toIconColor(),
|
tint = shield.toIconColor(),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(4.dp))
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
|
|
@ -94,7 +101,7 @@ fun TimelineEventTimestampView(
|
||||||
internal fun TimelineEventTimestampViewPreview(@PreviewParameter(TimelineItemEventForTimestampViewProvider::class) event: TimelineItem.Event) = ElementPreview {
|
internal fun TimelineEventTimestampViewPreview(@PreviewParameter(TimelineItemEventForTimestampViewProvider::class) event: TimelineItem.Event) = ElementPreview {
|
||||||
TimelineEventTimestampView(
|
TimelineEventTimestampView(
|
||||||
event = event,
|
event = event,
|
||||||
onShieldClick = {},
|
eventSink = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ import io.element.android.libraries.designsystem.theme.components.Icon
|
||||||
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.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
|
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails
|
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails
|
||||||
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.InReplyToView
|
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToView
|
||||||
|
|
@ -110,7 +109,6 @@ fun TimelineItemEventRow(
|
||||||
isHighlighted: Boolean,
|
isHighlighted: Boolean,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
|
||||||
onLinkClick: (String) -> Unit,
|
onLinkClick: (String) -> Unit,
|
||||||
onUserDataClick: (UserId) -> Unit,
|
onUserDataClick: (UserId) -> Unit,
|
||||||
inReplyToClick: (EventId) -> Unit,
|
inReplyToClick: (EventId) -> Unit,
|
||||||
|
|
@ -161,6 +159,17 @@ fun TimelineItemEventRow(
|
||||||
ReplySwipeIndicator({ offset / 120 })
|
ReplySwipeIndicator({ offset / 120 })
|
||||||
}
|
}
|
||||||
TimelineItemEventRowContent(
|
TimelineItemEventRowContent(
|
||||||
|
event = event,
|
||||||
|
isHighlighted = isHighlighted,
|
||||||
|
timelineRoomInfo = timelineRoomInfo,
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
inReplyToClick = ::inReplyToClick,
|
||||||
|
onUserDataClick = ::onUserDataClick,
|
||||||
|
onReactionClick = { emoji -> onReactionClick(emoji, event) },
|
||||||
|
onReactionLongClick = { emoji -> onReactionLongClick(emoji, event) },
|
||||||
|
onMoreReactionsClick = { onMoreReactionsClick(event) },
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.absoluteOffset { IntOffset(x = offset.roundToInt(), y = 0) }
|
.absoluteOffset { IntOffset(x = offset.roundToInt(), y = 0) }
|
||||||
.draggable(
|
.draggable(
|
||||||
|
|
@ -176,18 +185,7 @@ fun TimelineItemEventRow(
|
||||||
},
|
},
|
||||||
state = state.draggableState,
|
state = state.draggableState,
|
||||||
),
|
),
|
||||||
event = event,
|
eventSink = eventSink,
|
||||||
isHighlighted = isHighlighted,
|
|
||||||
timelineRoomInfo = timelineRoomInfo,
|
|
||||||
interactionSource = interactionSource,
|
|
||||||
onClick = onClick,
|
|
||||||
onLongClick = onLongClick,
|
|
||||||
onShieldClick = onShieldClick,
|
|
||||||
inReplyToClick = ::inReplyToClick,
|
|
||||||
onUserDataClick = ::onUserDataClick,
|
|
||||||
onReactionClick = { emoji -> onReactionClick(emoji, event) },
|
|
||||||
onReactionLongClick = { emoji -> onReactionLongClick(emoji, event) },
|
|
||||||
onMoreReactionsClick = { onMoreReactionsClick(event) },
|
|
||||||
eventContentView = eventContentView,
|
eventContentView = eventContentView,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -200,12 +198,12 @@ fun TimelineItemEventRow(
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
onShieldClick = onShieldClick,
|
|
||||||
inReplyToClick = ::inReplyToClick,
|
inReplyToClick = ::inReplyToClick,
|
||||||
onUserDataClick = ::onUserDataClick,
|
onUserDataClick = ::onUserDataClick,
|
||||||
onReactionClick = { emoji -> onReactionClick(emoji, event) },
|
onReactionClick = { emoji -> onReactionClick(emoji, event) },
|
||||||
onReactionLongClick = { emoji -> onReactionLongClick(emoji, event) },
|
onReactionLongClick = { emoji -> onReactionLongClick(emoji, event) },
|
||||||
onMoreReactionsClick = { onMoreReactionsClick(event) },
|
onMoreReactionsClick = { onMoreReactionsClick(event) },
|
||||||
|
eventSink = eventSink,
|
||||||
eventContentView = eventContentView,
|
eventContentView = eventContentView,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -255,12 +253,12 @@ private fun TimelineItemEventRowContent(
|
||||||
interactionSource: MutableInteractionSource,
|
interactionSource: MutableInteractionSource,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
|
||||||
inReplyToClick: () -> Unit,
|
inReplyToClick: () -> Unit,
|
||||||
onUserDataClick: () -> Unit,
|
onUserDataClick: () -> Unit,
|
||||||
onReactionClick: (emoji: String) -> Unit,
|
onReactionClick: (emoji: String) -> Unit,
|
||||||
onReactionLongClick: (emoji: String) -> Unit,
|
onReactionLongClick: (emoji: String) -> Unit,
|
||||||
onMoreReactionsClick: (event: TimelineItem.Event) -> Unit,
|
onMoreReactionsClick: (event: TimelineItem.Event) -> Unit,
|
||||||
|
eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
eventContentView: @Composable (Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit,
|
eventContentView: @Composable (Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
@ -322,9 +320,9 @@ private fun TimelineItemEventRowContent(
|
||||||
) {
|
) {
|
||||||
MessageEventBubbleContent(
|
MessageEventBubbleContent(
|
||||||
event = event,
|
event = event,
|
||||||
onShieldClick = onShieldClick,
|
|
||||||
onMessageLongClick = onLongClick,
|
onMessageLongClick = onLongClick,
|
||||||
inReplyToClick = inReplyToClick,
|
inReplyToClick = inReplyToClick,
|
||||||
|
eventSink = eventSink,
|
||||||
eventContentView = eventContentView,
|
eventContentView = eventContentView,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -382,9 +380,9 @@ private fun MessageSenderInformation(
|
||||||
@Composable
|
@Composable
|
||||||
private fun MessageEventBubbleContent(
|
private fun MessageEventBubbleContent(
|
||||||
event: TimelineItem.Event,
|
event: TimelineItem.Event,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
|
||||||
onMessageLongClick: () -> Unit,
|
onMessageLongClick: () -> Unit,
|
||||||
inReplyToClick: () -> Unit,
|
inReplyToClick: () -> Unit,
|
||||||
|
eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit,
|
||||||
@SuppressLint("ModifierParameter")
|
@SuppressLint("ModifierParameter")
|
||||||
// need to rename this modifier to prevent linter false positives
|
// need to rename this modifier to prevent linter false positives
|
||||||
@Suppress("ModifierNaming")
|
@Suppress("ModifierNaming")
|
||||||
|
|
@ -422,7 +420,7 @@ private fun MessageEventBubbleContent(
|
||||||
@Composable
|
@Composable
|
||||||
fun WithTimestampLayout(
|
fun WithTimestampLayout(
|
||||||
timestampPosition: TimestampPosition,
|
timestampPosition: TimestampPosition,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
canShrinkContent: Boolean = false,
|
canShrinkContent: Boolean = false,
|
||||||
content: @Composable (onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit) -> Unit,
|
content: @Composable (onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit) -> Unit,
|
||||||
|
|
@ -433,7 +431,7 @@ private fun MessageEventBubbleContent(
|
||||||
content {}
|
content {}
|
||||||
TimelineEventTimestampView(
|
TimelineEventTimestampView(
|
||||||
event = event,
|
event = event,
|
||||||
onShieldClick = onShieldClick,
|
eventSink = eventSink,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
// Outer padding
|
// Outer padding
|
||||||
.padding(horizontal = 4.dp, vertical = 4.dp)
|
.padding(horizontal = 4.dp, vertical = 4.dp)
|
||||||
|
|
@ -454,7 +452,7 @@ private fun MessageEventBubbleContent(
|
||||||
overlay = {
|
overlay = {
|
||||||
TimelineEventTimestampView(
|
TimelineEventTimestampView(
|
||||||
event = event,
|
event = event,
|
||||||
onShieldClick = onShieldClick,
|
eventSink = eventSink,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
)
|
)
|
||||||
|
|
@ -465,7 +463,7 @@ private fun MessageEventBubbleContent(
|
||||||
content {}
|
content {}
|
||||||
TimelineEventTimestampView(
|
TimelineEventTimestampView(
|
||||||
event = event,
|
event = event,
|
||||||
onShieldClick = onShieldClick,
|
eventSink = eventSink,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.End)
|
.align(Alignment.End)
|
||||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
|
|
@ -513,7 +511,7 @@ private fun MessageEventBubbleContent(
|
||||||
val contentWithTimestamp = @Composable {
|
val contentWithTimestamp = @Composable {
|
||||||
WithTimestampLayout(
|
WithTimestampLayout(
|
||||||
timestampPosition = timestampPosition,
|
timestampPosition = timestampPosition,
|
||||||
onShieldClick = onShieldClick,
|
eventSink = eventSink,
|
||||||
canShrinkContent = canShrinkContent,
|
canShrinkContent = canShrinkContent,
|
||||||
modifier = timestampLayoutModifier,
|
modifier = timestampLayoutModifier,
|
||||||
content = { onContentLayoutChange ->
|
content = { onContentLayoutChange ->
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ 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.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
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.event.MessageShield
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TimelineItemGroupedEventsRow(
|
fun TimelineItemGroupedEventsRow(
|
||||||
|
|
@ -40,7 +39,6 @@ fun TimelineItemGroupedEventsRow(
|
||||||
focusedEventId: EventId?,
|
focusedEventId: EventId?,
|
||||||
onClick: (TimelineItem.Event) -> Unit,
|
onClick: (TimelineItem.Event) -> Unit,
|
||||||
onLongClick: (TimelineItem.Event) -> Unit,
|
onLongClick: (TimelineItem.Event) -> Unit,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
|
||||||
inReplyToClick: (EventId) -> Unit,
|
inReplyToClick: (EventId) -> Unit,
|
||||||
onUserDataClick: (UserId) -> Unit,
|
onUserDataClick: (UserId) -> Unit,
|
||||||
onLinkClick: (String) -> Unit,
|
onLinkClick: (String) -> Unit,
|
||||||
|
|
@ -77,7 +75,6 @@ fun TimelineItemGroupedEventsRow(
|
||||||
isLastOutgoingMessage = isLastOutgoingMessage,
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
onShieldClick = onShieldClick,
|
|
||||||
inReplyToClick = inReplyToClick,
|
inReplyToClick = inReplyToClick,
|
||||||
onUserDataClick = onUserDataClick,
|
onUserDataClick = onUserDataClick,
|
||||||
onLinkClick = onLinkClick,
|
onLinkClick = onLinkClick,
|
||||||
|
|
@ -102,7 +99,6 @@ private fun TimelineItemGroupedEventsRowContent(
|
||||||
isLastOutgoingMessage: Boolean,
|
isLastOutgoingMessage: Boolean,
|
||||||
onClick: (TimelineItem.Event) -> Unit,
|
onClick: (TimelineItem.Event) -> Unit,
|
||||||
onLongClick: (TimelineItem.Event) -> Unit,
|
onLongClick: (TimelineItem.Event) -> Unit,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
|
||||||
inReplyToClick: (EventId) -> Unit,
|
inReplyToClick: (EventId) -> Unit,
|
||||||
onUserDataClick: (UserId) -> Unit,
|
onUserDataClick: (UserId) -> Unit,
|
||||||
onLinkClick: (String) -> Unit,
|
onLinkClick: (String) -> Unit,
|
||||||
|
|
@ -143,19 +139,18 @@ private fun TimelineItemGroupedEventsRowContent(
|
||||||
renderReadReceipts = renderReadReceipts,
|
renderReadReceipts = renderReadReceipts,
|
||||||
isLastOutgoingMessage = isLastOutgoingMessage,
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
focusedEventId = focusedEventId,
|
focusedEventId = focusedEventId,
|
||||||
onClick = onClick,
|
|
||||||
onLongClick = onLongClick,
|
|
||||||
onShieldClick = onShieldClick,
|
|
||||||
inReplyToClick = inReplyToClick,
|
|
||||||
onUserDataClick = onUserDataClick,
|
onUserDataClick = onUserDataClick,
|
||||||
onLinkClick = onLinkClick,
|
onLinkClick = onLinkClick,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
inReplyToClick = inReplyToClick,
|
||||||
onReactionClick = onReactionClick,
|
onReactionClick = onReactionClick,
|
||||||
onReactionLongClick = onReactionLongClick,
|
onReactionLongClick = onReactionLongClick,
|
||||||
onMoreReactionsClick = onMoreReactionsClick,
|
onMoreReactionsClick = onMoreReactionsClick,
|
||||||
onReadReceiptClick = onReadReceiptClick,
|
onReadReceiptClick = onReadReceiptClick,
|
||||||
eventSink = eventSink,
|
|
||||||
onSwipeToReply = {},
|
onSwipeToReply = {},
|
||||||
onJoinCallClick = {},
|
onJoinCallClick = {},
|
||||||
|
eventSink = eventSink,
|
||||||
eventContentView = eventContentView,
|
eventContentView = eventContentView,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +183,6 @@ internal fun TimelineItemGroupedEventsRowContentExpandedPreview() = ElementPrevi
|
||||||
isLastOutgoingMessage = false,
|
isLastOutgoingMessage = false,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
onLongClick = {},
|
onLongClick = {},
|
||||||
onShieldClick = {},
|
|
||||||
inReplyToClick = {},
|
inReplyToClick = {},
|
||||||
onUserDataClick = {},
|
onUserDataClick = {},
|
||||||
onLinkClick = {},
|
onLinkClick = {},
|
||||||
|
|
@ -213,7 +207,6 @@ internal fun TimelineItemGroupedEventsRowContentCollapsePreview() = ElementPrevi
|
||||||
isLastOutgoingMessage = false,
|
isLastOutgoingMessage = false,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
onLongClick = {},
|
onLongClick = {},
|
||||||
onShieldClick = {},
|
|
||||||
inReplyToClick = {},
|
inReplyToClick = {},
|
||||||
onUserDataClick = {},
|
onUserDataClick = {},
|
||||||
onLinkClick = {},
|
onLinkClick = {},
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import io.element.android.libraries.designsystem.text.toPx
|
||||||
import io.element.android.libraries.designsystem.theme.highlightedMessageBackgroundColor
|
import io.element.android.libraries.designsystem.theme.highlightedMessageBackgroundColor
|
||||||
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.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun TimelineItemRow(
|
internal fun TimelineItemRow(
|
||||||
|
|
@ -43,7 +42,6 @@ internal fun TimelineItemRow(
|
||||||
onLinkClick: (String) -> Unit,
|
onLinkClick: (String) -> Unit,
|
||||||
onClick: (TimelineItem.Event) -> Unit,
|
onClick: (TimelineItem.Event) -> Unit,
|
||||||
onLongClick: (TimelineItem.Event) -> Unit,
|
onLongClick: (TimelineItem.Event) -> Unit,
|
||||||
onShieldClick: (MessageShield) -> Unit,
|
|
||||||
inReplyToClick: (EventId) -> Unit,
|
inReplyToClick: (EventId) -> Unit,
|
||||||
onReactionClick: (key: String, TimelineItem.Event) -> Unit,
|
onReactionClick: (key: String, TimelineItem.Event) -> Unit,
|
||||||
onReactionLongClick: (key: String, TimelineItem.Event) -> Unit,
|
onReactionLongClick: (key: String, TimelineItem.Event) -> Unit,
|
||||||
|
|
@ -115,9 +113,8 @@ internal fun TimelineItemRow(
|
||||||
isHighlighted = timelineItem.isEvent(focusedEventId),
|
isHighlighted = timelineItem.isEvent(focusedEventId),
|
||||||
onClick = { onClick(timelineItem) },
|
onClick = { onClick(timelineItem) },
|
||||||
onLongClick = { onLongClick(timelineItem) },
|
onLongClick = { onLongClick(timelineItem) },
|
||||||
onShieldClick = onShieldClick,
|
|
||||||
onUserDataClick = onUserDataClick,
|
|
||||||
onLinkClick = onLinkClick,
|
onLinkClick = onLinkClick,
|
||||||
|
onUserDataClick = onUserDataClick,
|
||||||
inReplyToClick = inReplyToClick,
|
inReplyToClick = inReplyToClick,
|
||||||
onReactionClick = onReactionClick,
|
onReactionClick = onReactionClick,
|
||||||
onReactionLongClick = onReactionLongClick,
|
onReactionLongClick = onReactionLongClick,
|
||||||
|
|
@ -141,7 +138,6 @@ internal fun TimelineItemRow(
|
||||||
focusedEventId = focusedEventId,
|
focusedEventId = focusedEventId,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
onShieldClick = onShieldClick,
|
|
||||||
inReplyToClick = inReplyToClick,
|
inReplyToClick = inReplyToClick,
|
||||||
onUserDataClick = onUserDataClick,
|
onUserDataClick = onUserDataClick,
|
||||||
onLinkClick = onLinkClick,
|
onLinkClick = onLinkClick,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue