Merge pull request #2376 from element-hq/feature/bma/testUi
More test on MessagesView, and harmonize preview on Dialogs
This commit is contained in:
commit
c69d996641
37 changed files with 433 additions and 52 deletions
|
|
@ -22,14 +22,18 @@ import io.element.android.features.messages.impl.actionlist.anActionListState
|
||||||
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
|
||||||
|
import io.element.android.features.messages.impl.timeline.TimelineState
|
||||||
import io.element.android.features.messages.impl.timeline.aTimelineItemList
|
import io.element.android.features.messages.impl.timeline.aTimelineItemList
|
||||||
import io.element.android.features.messages.impl.timeline.aTimelineState
|
import io.element.android.features.messages.impl.timeline.aTimelineState
|
||||||
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents
|
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents
|
||||||
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
|
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
|
||||||
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
|
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
|
||||||
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
|
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
|
||||||
|
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents
|
||||||
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState
|
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState
|
||||||
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState
|
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState
|
||||||
|
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState
|
||||||
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
|
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
|
||||||
import io.element.android.features.messages.impl.typing.aTypingNotificationState
|
import io.element.android.features.messages.impl.typing.aTypingNotificationState
|
||||||
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
|
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
|
||||||
|
|
@ -91,12 +95,20 @@ fun aMessagesState(
|
||||||
roomName: AsyncData<String> = AsyncData.Success("Room name"),
|
roomName: AsyncData<String> = AsyncData.Success("Room name"),
|
||||||
roomAvatar: AsyncData<AvatarData> = AsyncData.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)),
|
roomAvatar: AsyncData<AvatarData> = AsyncData.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)),
|
||||||
userHasPermissionToSendMessage: Boolean = true,
|
userHasPermissionToSendMessage: Boolean = true,
|
||||||
|
userHasPermissionToRedactOwn: Boolean = false,
|
||||||
|
userHasPermissionToRedactOther: Boolean = false,
|
||||||
|
userHasPermissionToSendReaction: Boolean = true,
|
||||||
composerState: MessageComposerState = aMessageComposerState(
|
composerState: MessageComposerState = aMessageComposerState(
|
||||||
richTextEditorState = RichTextEditorState("Hello", initialFocus = true),
|
richTextEditorState = RichTextEditorState("Hello", initialFocus = true),
|
||||||
isFullScreen = false,
|
isFullScreen = false,
|
||||||
mode = MessageComposerMode.Normal,
|
mode = MessageComposerMode.Normal,
|
||||||
),
|
),
|
||||||
voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(),
|
voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(),
|
||||||
|
timelineState: TimelineState = aTimelineState(
|
||||||
|
timelineItems = aTimelineItemList(aTimelineItemTextContent()),
|
||||||
|
),
|
||||||
|
retrySendMenuState: RetrySendMenuState = aRetrySendMenuState(),
|
||||||
|
readReceiptBottomSheetState: ReadReceiptBottomSheetState = aReadReceiptBottomSheetState(),
|
||||||
actionListState: ActionListState = anActionListState(),
|
actionListState: ActionListState = anActionListState(),
|
||||||
customReactionState: CustomReactionState = aCustomReactionState(),
|
customReactionState: CustomReactionState = aCustomReactionState(),
|
||||||
reactionSummaryState: ReactionSummaryState = aReactionSummaryState(),
|
reactionSummaryState: ReactionSummaryState = aReactionSummaryState(),
|
||||||
|
|
@ -110,23 +122,15 @@ fun aMessagesState(
|
||||||
roomName = roomName,
|
roomName = roomName,
|
||||||
roomAvatar = roomAvatar,
|
roomAvatar = roomAvatar,
|
||||||
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
|
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
|
||||||
userHasPermissionToRedactOwn = false,
|
userHasPermissionToRedactOwn = userHasPermissionToRedactOwn,
|
||||||
userHasPermissionToRedactOther = false,
|
userHasPermissionToRedactOther = userHasPermissionToRedactOther,
|
||||||
userHasPermissionToSendReaction = true,
|
userHasPermissionToSendReaction = userHasPermissionToSendReaction,
|
||||||
composerState = composerState,
|
composerState = composerState,
|
||||||
voiceMessageComposerState = voiceMessageComposerState,
|
voiceMessageComposerState = voiceMessageComposerState,
|
||||||
timelineState = aTimelineState(
|
|
||||||
timelineItems = aTimelineItemList(aTimelineItemTextContent()),
|
|
||||||
),
|
|
||||||
typingNotificationState = aTypingNotificationState(),
|
typingNotificationState = aTypingNotificationState(),
|
||||||
retrySendMenuState = RetrySendMenuState(
|
timelineState = timelineState,
|
||||||
selectedEvent = null,
|
retrySendMenuState = retrySendMenuState,
|
||||||
eventSink = {},
|
readReceiptBottomSheetState = readReceiptBottomSheetState,
|
||||||
),
|
|
||||||
readReceiptBottomSheetState = ReadReceiptBottomSheetState(
|
|
||||||
selectedEvent = null,
|
|
||||||
eventSink = {},
|
|
||||||
),
|
|
||||||
actionListState = actionListState,
|
actionListState = actionListState,
|
||||||
customReactionState = customReactionState,
|
customReactionState = customReactionState,
|
||||||
reactionSummaryState = reactionSummaryState,
|
reactionSummaryState = reactionSummaryState,
|
||||||
|
|
@ -150,9 +154,18 @@ fun aReactionSummaryState(
|
||||||
)
|
)
|
||||||
|
|
||||||
fun aCustomReactionState(
|
fun aCustomReactionState(
|
||||||
|
target: CustomReactionState.Target = CustomReactionState.Target.None,
|
||||||
eventSink: (CustomReactionEvents) -> Unit = {},
|
eventSink: (CustomReactionEvents) -> Unit = {},
|
||||||
) = CustomReactionState(
|
) = CustomReactionState(
|
||||||
target = CustomReactionState.Target.None,
|
target = target,
|
||||||
selectedEmoji = persistentSetOf(),
|
selectedEmoji = persistentSetOf(),
|
||||||
eventSink = eventSink,
|
eventSink = eventSink,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun aReadReceiptBottomSheetState(
|
||||||
|
selectedEvent: TimelineItem.Event? = null,
|
||||||
|
eventSink: (ReadReceiptBottomSheetEvents) -> Unit = {},
|
||||||
|
) = ReadReceiptBottomSheetState(
|
||||||
|
selectedEvent = selectedEvent,
|
||||||
|
eventSink = eventSink,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,6 @@ fun MessagesView(
|
||||||
state = state.customReactionState,
|
state = state.customReactionState,
|
||||||
onEmojiSelected = { eventId, emoji ->
|
onEmojiSelected = { eventId, emoji ->
|
||||||
state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, eventId))
|
state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, eventId))
|
||||||
state.customReactionState.eventSink(CustomReactionEvents.DismissCustomReactionSheet)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,14 @@ import kotlin.random.Random
|
||||||
fun aTimelineState(
|
fun aTimelineState(
|
||||||
timelineItems: ImmutableList<TimelineItem> = persistentListOf(),
|
timelineItems: ImmutableList<TimelineItem> = persistentListOf(),
|
||||||
paginationState: MatrixTimeline.PaginationState = aPaginationState(),
|
paginationState: MatrixTimeline.PaginationState = aPaginationState(),
|
||||||
|
renderReadReceipts: Boolean = false,
|
||||||
|
timelineRoomInfo: TimelineRoomInfo = aTimelineRoomInfo(),
|
||||||
eventSink: (TimelineEvents) -> Unit = {},
|
eventSink: (TimelineEvents) -> Unit = {},
|
||||||
) = TimelineState(
|
) = TimelineState(
|
||||||
timelineItems = timelineItems,
|
timelineItems = timelineItems,
|
||||||
timelineRoomInfo = aTimelineRoomInfo(),
|
timelineRoomInfo = timelineRoomInfo,
|
||||||
paginationState = paginationState,
|
paginationState = paginationState,
|
||||||
renderReadReceipts = false,
|
renderReadReceipts = renderReadReceipts,
|
||||||
highlightedEventId = null,
|
highlightedEventId = null,
|
||||||
newEventState = NewEventState.None,
|
newEventState = NewEventState.None,
|
||||||
sessionState = aSessionState(
|
sessionState = aSessionState(
|
||||||
|
|
@ -196,9 +198,11 @@ internal fun aTimelineItemDebugInfo(
|
||||||
latestEditedJson
|
latestEditedJson
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun aTimelineItemReadReceipts(): TimelineItemReadReceipts {
|
internal fun aTimelineItemReadReceipts(
|
||||||
|
receipts: List<ReadReceiptData> = emptyList(),
|
||||||
|
): TimelineItemReadReceipts {
|
||||||
return TimelineItemReadReceipts(
|
return TimelineItemReadReceipts(
|
||||||
receipts = emptyList<ReadReceiptData>().toImmutableList(),
|
receipts = receipts.toImmutableList(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,8 +236,9 @@ internal fun aGroupedEvents(
|
||||||
|
|
||||||
internal fun aTimelineRoomInfo(
|
internal fun aTimelineRoomInfo(
|
||||||
isDirect: Boolean = false,
|
isDirect: Boolean = false,
|
||||||
|
userHasPermissionToSendMessage: Boolean = true,
|
||||||
) = TimelineRoomInfo(
|
) = TimelineRoomInfo(
|
||||||
isDirect = isDirect,
|
isDirect = isDirect,
|
||||||
userHasPermissionToSendMessage = true,
|
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
|
||||||
userHasPermissionToSendReaction = true,
|
userHasPermissionToSendReaction = true,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ 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.designsystem.utils.CommonDrawables
|
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||||
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.testtags.TestTags
|
||||||
|
import io.element.android.libraries.testtags.testTag
|
||||||
import io.element.android.libraries.ui.strings.CommonPlurals
|
import io.element.android.libraries.ui.strings.CommonPlurals
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
@ -68,6 +70,7 @@ fun TimelineItemReadReceiptView(
|
||||||
ReadReceiptsAvatars(
|
ReadReceiptsAvatars(
|
||||||
receipts = state.receipts,
|
receipts = state.receipts,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.testTag(TestTags.messageReadReceipts)
|
||||||
.clip(RoundedCornerShape(4.dp))
|
.clip(RoundedCornerShape(4.dp))
|
||||||
.clickable {
|
.clickable {
|
||||||
onReadReceiptsClicked()
|
onReadReceiptsClicked()
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,15 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
|
|
||||||
class RetrySendMenuStateProvider : PreviewParameterProvider<RetrySendMenuState> {
|
class RetrySendMenuStateProvider : PreviewParameterProvider<RetrySendMenuState> {
|
||||||
override val values: Sequence<RetrySendMenuState> = sequenceOf(
|
override val values: Sequence<RetrySendMenuState> = sequenceOf(
|
||||||
aRetrySendMenuState(event = null),
|
aRetrySendMenuState(),
|
||||||
aRetrySendMenuState(event = aTimelineItemEvent()),
|
aRetrySendMenuState(event = aTimelineItemEvent()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun aRetrySendMenuState(event: TimelineItem.Event? = aTimelineItemEvent()) =
|
fun aRetrySendMenuState(
|
||||||
RetrySendMenuState(selectedEvent = event, eventSink = {})
|
event: TimelineItem.Event? = null,
|
||||||
|
eventSink: (RetrySendMenuEvents) -> Unit = {},
|
||||||
|
) = RetrySendMenuState(
|
||||||
|
selectedEvent = event,
|
||||||
|
eventSink = eventSink,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -27,18 +27,35 @@ import androidx.compose.ui.test.onAllNodesWithTag
|
||||||
import androidx.compose.ui.test.onAllNodesWithText
|
import androidx.compose.ui.test.onAllNodesWithText
|
||||||
import androidx.compose.ui.test.onFirst
|
import androidx.compose.ui.test.onFirst
|
||||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||||
|
import androidx.compose.ui.test.onNodeWithTag
|
||||||
import androidx.compose.ui.test.onNodeWithText
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
import androidx.compose.ui.test.performClick
|
import androidx.compose.ui.test.performClick
|
||||||
import androidx.compose.ui.test.performTouchInput
|
import androidx.compose.ui.test.performTouchInput
|
||||||
|
import androidx.compose.ui.test.swipeRight
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import io.element.android.emojibasebindings.Emoji
|
||||||
|
import io.element.android.emojibasebindings.EmojibaseCategory
|
||||||
|
import io.element.android.emojibasebindings.EmojibaseStore
|
||||||
|
import io.element.android.features.messages.impl.actionlist.ActionListEvents
|
||||||
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.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.messagecomposer.aMessageComposerState
|
import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState
|
||||||
|
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
|
||||||
|
import io.element.android.features.messages.impl.timeline.aTimelineItemList
|
||||||
|
import io.element.android.features.messages.impl.timeline.aTimelineItemReadReceipts
|
||||||
|
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
|
||||||
|
import io.element.android.features.messages.impl.timeline.aTimelineState
|
||||||
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents
|
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents
|
||||||
|
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
|
||||||
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
|
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
|
||||||
|
import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData
|
||||||
|
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents
|
||||||
|
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuEvents
|
||||||
|
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState
|
||||||
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.aTimelineItemTextContent
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.testtags.TestTags
|
import io.element.android.libraries.testtags.TestTags
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
@ -128,6 +145,136 @@ class MessagesViewTest {
|
||||||
callback.assertSuccess()
|
callback.assertSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clicking on an Event timestamp in error emits the expected Event`() {
|
||||||
|
val eventsRecorder = EventsRecorder<RetrySendMenuEvents>()
|
||||||
|
val state = aMessagesState(
|
||||||
|
retrySendMenuState = aRetrySendMenuState(
|
||||||
|
eventSink = eventsRecorder
|
||||||
|
),
|
||||||
|
)
|
||||||
|
val timelineItem = state.timelineState.timelineItems[1] as TimelineItem.Event
|
||||||
|
rule.setMessagesView(
|
||||||
|
state = state,
|
||||||
|
)
|
||||||
|
rule.onAllNodesWithText(timelineItem.sentTime)[1].performClick()
|
||||||
|
eventsRecorder.assertSingle(RetrySendMenuEvents.EventSelected(timelineItem))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `long clicking on an Event emits the expected Event userHasPermissionToSendMessage`() {
|
||||||
|
`long clicking on an Event emits the expected Event`(userHasPermissionToSendMessage = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `long clicking on an Event emits the expected Event userHasPermissionToRedactOwn`() {
|
||||||
|
`long clicking on an Event emits the expected Event`(userHasPermissionToRedactOwn = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `long clicking on an Event emits the expected Event userHasPermissionToRedactOther`() {
|
||||||
|
`long clicking on an Event emits the expected Event`(userHasPermissionToRedactOther = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `long clicking on an Event emits the expected Event userHasPermissionToSendReaction`() {
|
||||||
|
`long clicking on an Event emits the expected Event`(userHasPermissionToSendReaction = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun `long clicking on an Event emits the expected Event`(
|
||||||
|
userHasPermissionToSendMessage: Boolean = false,
|
||||||
|
userHasPermissionToRedactOwn: Boolean = false,
|
||||||
|
userHasPermissionToRedactOther: Boolean = false,
|
||||||
|
userHasPermissionToSendReaction: Boolean = false,
|
||||||
|
) {
|
||||||
|
val eventsRecorder = EventsRecorder<ActionListEvents>()
|
||||||
|
val state = aMessagesState(
|
||||||
|
actionListState = anActionListState(
|
||||||
|
eventSink = eventsRecorder
|
||||||
|
),
|
||||||
|
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
|
||||||
|
userHasPermissionToRedactOwn = userHasPermissionToRedactOwn,
|
||||||
|
userHasPermissionToRedactOther = userHasPermissionToRedactOther,
|
||||||
|
userHasPermissionToSendReaction = userHasPermissionToSendReaction,
|
||||||
|
)
|
||||||
|
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||||
|
rule.setMessagesView(
|
||||||
|
state = state,
|
||||||
|
)
|
||||||
|
// Cannot perform click on "Text", it's not detected. Use tag instead
|
||||||
|
rule.onAllNodesWithTag(TestTags.messageBubble.value).onFirst().performTouchInput { longClick() }
|
||||||
|
eventsRecorder.assertSingle(
|
||||||
|
ActionListEvents.ComputeForMessage(
|
||||||
|
event = timelineItem,
|
||||||
|
canRedactOwn = state.userHasPermissionToRedactOwn,
|
||||||
|
canRedactOther = state.userHasPermissionToRedactOther,
|
||||||
|
canSendMessage = state.userHasPermissionToSendMessage,
|
||||||
|
canSendReaction = state.userHasPermissionToSendReaction,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clicking on a read receipt list emits the expected Event`() {
|
||||||
|
val eventsRecorder = EventsRecorder<ReadReceiptBottomSheetEvents>()
|
||||||
|
val state = aMessagesState(
|
||||||
|
timelineState = aTimelineState(
|
||||||
|
renderReadReceipts = true,
|
||||||
|
timelineItems = persistentListOf(
|
||||||
|
aTimelineItemEvent(
|
||||||
|
readReceiptState = aTimelineItemReadReceipts(
|
||||||
|
receipts = listOf(
|
||||||
|
aReadReceiptData(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
readReceiptBottomSheetState = aReadReceiptBottomSheetState(
|
||||||
|
eventSink = eventsRecorder
|
||||||
|
),
|
||||||
|
)
|
||||||
|
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||||
|
rule.setMessagesView(
|
||||||
|
state = state,
|
||||||
|
)
|
||||||
|
rule.onNodeWithTag(TestTags.messageReadReceipts.value).performClick()
|
||||||
|
eventsRecorder.assertSingle(ReadReceiptBottomSheetEvents.EventSelected(timelineItem))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `swiping on an Event emits the expected Event`() {
|
||||||
|
swipeTest(userHasPermissionToSendMessage = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `swiping on an Event emits no Event if user does not have permission to send message`() {
|
||||||
|
swipeTest(userHasPermissionToSendMessage = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun swipeTest(userHasPermissionToSendMessage: Boolean) {
|
||||||
|
val eventsRecorder = EventsRecorder<MessagesEvents>()
|
||||||
|
val state = aMessagesState(
|
||||||
|
timelineState = aTimelineState(
|
||||||
|
timelineItems = aTimelineItemList(aTimelineItemTextContent()),
|
||||||
|
timelineRoomInfo = aTimelineRoomInfo(
|
||||||
|
userHasPermissionToSendMessage = userHasPermissionToSendMessage
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventSink = eventsRecorder,
|
||||||
|
)
|
||||||
|
rule.setMessagesView(
|
||||||
|
state = state,
|
||||||
|
)
|
||||||
|
rule.onAllNodesWithTag(TestTags.messageBubble.value).onFirst().performTouchInput { swipeRight(endX = 200f) }
|
||||||
|
if (userHasPermissionToSendMessage) {
|
||||||
|
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||||
|
eventsRecorder.assertSingle(MessagesEvents.HandleAction(TimelineItemAction.Reply, timelineItem))
|
||||||
|
} else {
|
||||||
|
eventsRecorder.assertEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `clicking on send location invoke expected callback`() {
|
fun `clicking on send location invoke expected callback`() {
|
||||||
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false)
|
||||||
|
|
@ -256,6 +403,74 @@ class MessagesViewTest {
|
||||||
rule.onAllNodesWithContentDescription(moreReactionContentDescription).onFirst().performClick()
|
rule.onAllNodesWithContentDescription(moreReactionContentDescription).onFirst().performClick()
|
||||||
eventsRecorder.assertSingle(CustomReactionEvents.ShowCustomReactionSheet(timelineItem))
|
eventsRecorder.assertSingle(CustomReactionEvents.ShowCustomReactionSheet(timelineItem))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clicking on more reaction from action list emits the expected Event`() {
|
||||||
|
val eventsRecorder = EventsRecorder<CustomReactionEvents>()
|
||||||
|
val state = aMessagesState()
|
||||||
|
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||||
|
val stateWithActionListState = state.copy(
|
||||||
|
actionListState = anActionListState(
|
||||||
|
target = ActionListState.Target.Success(
|
||||||
|
event = timelineItem,
|
||||||
|
displayEmojiReactions = true,
|
||||||
|
actions = persistentListOf(TimelineItemAction.Edit),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
customReactionState = aCustomReactionState(
|
||||||
|
eventSink = eventsRecorder
|
||||||
|
),
|
||||||
|
)
|
||||||
|
rule.setMessagesView(
|
||||||
|
state = stateWithActionListState,
|
||||||
|
)
|
||||||
|
val moreReactionContentDescription = rule.activity.getString(CommonStrings.a11y_react_with_other_emojis)
|
||||||
|
rule.onNodeWithContentDescription(moreReactionContentDescription).performClick()
|
||||||
|
// Give time for the close animation to complete
|
||||||
|
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||||
|
eventsRecorder.assertSingle(CustomReactionEvents.ShowCustomReactionSheet(timelineItem))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clicking on a custom emoji emits the expected Events`() {
|
||||||
|
val aUnicode = "🙈"
|
||||||
|
val customReactionStateEventsRecorder = EventsRecorder<CustomReactionEvents>()
|
||||||
|
val eventsRecorder = EventsRecorder<MessagesEvents>()
|
||||||
|
val state = aMessagesState(
|
||||||
|
eventSink = eventsRecorder,
|
||||||
|
)
|
||||||
|
val timelineItem = state.timelineState.timelineItems.first() as TimelineItem.Event
|
||||||
|
val stateWithCustomReactionState = state.copy(
|
||||||
|
customReactionState = aCustomReactionState(
|
||||||
|
target = CustomReactionState.Target.Success(
|
||||||
|
event = timelineItem,
|
||||||
|
emojibaseStore = EmojibaseStore(
|
||||||
|
categories = mapOf(
|
||||||
|
EmojibaseCategory.People to listOf(
|
||||||
|
Emoji(
|
||||||
|
hexcode = "",
|
||||||
|
label = "",
|
||||||
|
tags = emptyList(),
|
||||||
|
shortcodes = emptyList(),
|
||||||
|
unicode = aUnicode,
|
||||||
|
skins = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventSink = customReactionStateEventsRecorder
|
||||||
|
),
|
||||||
|
)
|
||||||
|
rule.setMessagesView(
|
||||||
|
state = stateWithCustomReactionState,
|
||||||
|
)
|
||||||
|
rule.onNodeWithText(aUnicode, useUnmergedTree = true).performClick()
|
||||||
|
// Give time for the close animation to complete
|
||||||
|
rule.mainClock.advanceTimeBy(milliseconds = 1_000)
|
||||||
|
customReactionStateEventsRecorder.assertSingle(CustomReactionEvents.DismissCustomReactionSheet)
|
||||||
|
eventsRecorder.assertSingle(MessagesEvents.ToggleReaction(aUnicode, timelineItem.eventId!!))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setMessagesView(
|
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setMessagesView(
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,10 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||||
|
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.DialogPreview
|
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
|
|
@ -141,8 +143,14 @@ private fun ProgressDialogContent(
|
||||||
|
|
||||||
@Preview(group = PreviewGroup.Dialogs)
|
@Preview(group = PreviewGroup.Dialogs)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ProgressDialogPreview() = ElementThemedPreview {
|
internal fun ProgressDialogContentPreview() = ElementThemedPreview {
|
||||||
DialogPreview {
|
DialogPreview {
|
||||||
ProgressDialogContent(text = "test dialog content", isCancellable = true)
|
ProgressDialogContent(text = "test dialog content", isCancellable = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun ProgressDialogPreview() = ElementPreview {
|
||||||
|
ProgressDialog(text = "test dialog content", isCancellable = true)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,10 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||||
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
||||||
import io.element.android.libraries.designsystem.theme.components.SimpleAlertDialogContent
|
import io.element.android.libraries.designsystem.theme.components.SimpleAlertDialogContent
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
@ -87,7 +89,7 @@ private fun ConfirmationDialogContent(
|
||||||
|
|
||||||
@Preview(group = PreviewGroup.Dialogs)
|
@Preview(group = PreviewGroup.Dialogs)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ConfirmationDialogPreview() =
|
internal fun ConfirmationDialogContentPreview() =
|
||||||
ElementThemedPreview(showBackground = false) {
|
ElementThemedPreview(showBackground = false) {
|
||||||
DialogPreview {
|
DialogPreview {
|
||||||
ConfirmationDialogContent(
|
ConfirmationDialogContent(
|
||||||
|
|
@ -102,3 +104,17 @@ internal fun ConfirmationDialogPreview() =
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun ConfirmationDialogPreview() = ElementPreview {
|
||||||
|
ConfirmationDialog(
|
||||||
|
content = "Content",
|
||||||
|
title = "Title",
|
||||||
|
submitText = "OK",
|
||||||
|
cancelText = "Cancel",
|
||||||
|
thirdButtonText = "Disable",
|
||||||
|
onSubmitClicked = {},
|
||||||
|
onDismiss = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,10 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||||
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
||||||
import io.element.android.libraries.designsystem.theme.components.SimpleAlertDialogContent
|
import io.element.android.libraries.designsystem.theme.components.SimpleAlertDialogContent
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
@ -69,7 +71,7 @@ object ErrorDialogDefaults {
|
||||||
|
|
||||||
@Preview(group = PreviewGroup.Dialogs)
|
@Preview(group = PreviewGroup.Dialogs)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ErrorDialogPreview() {
|
internal fun ErrorDialogContentPreview() {
|
||||||
ElementThemedPreview(showBackground = false) {
|
ElementThemedPreview(showBackground = false) {
|
||||||
DialogPreview {
|
DialogPreview {
|
||||||
ErrorDialogContent(
|
ErrorDialogContent(
|
||||||
|
|
@ -79,3 +81,12 @@ internal fun ErrorDialogPreview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun ErrorDialogPreview() = ElementPreview {
|
||||||
|
ErrorDialog(
|
||||||
|
content = "Content",
|
||||||
|
onDismiss = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,11 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.airbnb.android.showkase.annotation.ShowkaseComposable
|
|
||||||
import io.element.android.libraries.designsystem.components.list.TextFieldListItem
|
import io.element.android.libraries.designsystem.components.list.TextFieldListItem
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
||||||
|
|
@ -100,11 +101,10 @@ private fun ListDialogContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreviewsDayNight
|
@Preview(group = PreviewGroup.Dialogs)
|
||||||
@ShowkaseComposable(group = PreviewGroup.Dialogs)
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ListDialogContentPreview() {
|
internal fun ListDialogContentPreview() {
|
||||||
ElementPreview(showBackground = false) {
|
ElementThemedPreview(showBackground = false) {
|
||||||
DialogPreview {
|
DialogPreview {
|
||||||
ListDialogContent(
|
ListDialogContent(
|
||||||
listItems = {
|
listItems = {
|
||||||
|
|
@ -124,3 +124,23 @@ internal fun ListDialogContentPreview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun ListDialogPreview() = ElementPreview {
|
||||||
|
ListDialog(
|
||||||
|
listItems = {
|
||||||
|
item {
|
||||||
|
TextFieldListItem(placeholder = "Text input", text = "", onTextChanged = {})
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
TextFieldListItem(placeholder = "Another text input", text = "", onTextChanged = {})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title = "Dialog title",
|
||||||
|
onDismissRequest = {},
|
||||||
|
onSubmit = {},
|
||||||
|
cancelText = "Cancel",
|
||||||
|
submitText = "Save",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,11 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.toMutableStateList
|
import androidx.compose.runtime.toMutableStateList
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.airbnb.android.showkase.annotation.ShowkaseComposable
|
|
||||||
import io.element.android.libraries.designsystem.components.list.CheckboxListItem
|
import io.element.android.libraries.designsystem.components.list.CheckboxListItem
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
||||||
|
|
@ -124,11 +125,10 @@ private fun MultipleSelectionDialogContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreviewsDayNight
|
@Preview(group = PreviewGroup.Dialogs)
|
||||||
@ShowkaseComposable(group = PreviewGroup.Dialogs)
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MultipleSelectionDialogContentPreview() {
|
internal fun MultipleSelectionDialogContentPreview() {
|
||||||
ElementPreview(showBackground = false) {
|
ElementThemedPreview(showBackground = false) {
|
||||||
DialogPreview {
|
DialogPreview {
|
||||||
val options = persistentListOf(
|
val options = persistentListOf(
|
||||||
ListOption("Option 1", "Supporting line text lorem ipsum dolor sit amet, consectetur."),
|
ListOption("Option 1", "Supporting line text lorem ipsum dolor sit amet, consectetur."),
|
||||||
|
|
@ -147,3 +147,22 @@ internal fun MultipleSelectionDialogContentPreview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun MultipleSelectionDialogPreview() = ElementPreview {
|
||||||
|
val options = persistentListOf(
|
||||||
|
ListOption("Option 1", "Supporting line text lorem ipsum dolor sit amet, consectetur."),
|
||||||
|
ListOption("Option 2"),
|
||||||
|
ListOption("Option 3"),
|
||||||
|
)
|
||||||
|
MultipleSelectionDialog(
|
||||||
|
title = "Dialog title",
|
||||||
|
options = options,
|
||||||
|
onConfirmClicked = {},
|
||||||
|
onDismissRequest = {},
|
||||||
|
confirmButtonTitle = "Save",
|
||||||
|
dismissButtonTitle = "Cancel",
|
||||||
|
initialSelection = persistentListOf(0),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,10 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||||
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
import io.element.android.libraries.designsystem.theme.components.DialogPreview
|
||||||
import io.element.android.libraries.designsystem.theme.components.SimpleAlertDialogContent
|
import io.element.android.libraries.designsystem.theme.components.SimpleAlertDialogContent
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
@ -78,7 +80,7 @@ object RetryDialogDefaults {
|
||||||
|
|
||||||
@Preview(group = PreviewGroup.Dialogs)
|
@Preview(group = PreviewGroup.Dialogs)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun RetryDialogPreview() {
|
internal fun RetryDialogContentPreview() {
|
||||||
ElementThemedPreview(showBackground = false) {
|
ElementThemedPreview(showBackground = false) {
|
||||||
DialogPreview {
|
DialogPreview {
|
||||||
RetryDialogContent(
|
RetryDialogContent(
|
||||||
|
|
@ -89,3 +91,13 @@ internal fun RetryDialogPreview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun RetryDialogPreview() = ElementPreview {
|
||||||
|
RetryDialog(
|
||||||
|
content = "Content",
|
||||||
|
onRetry = {},
|
||||||
|
onDismiss = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.airbnb.android.showkase.annotation.ShowkaseComposable
|
|
||||||
import io.element.android.libraries.designsystem.components.list.RadioButtonListItem
|
import io.element.android.libraries.designsystem.components.list.RadioButtonListItem
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||||
|
|
@ -105,8 +105,7 @@ private fun SingleSelectionDialogContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreviewsDayNight
|
@Preview(group = PreviewGroup.Dialogs)
|
||||||
@ShowkaseComposable(group = PreviewGroup.Dialogs)
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun SingleSelectionDialogContentPreview() {
|
internal fun SingleSelectionDialogContentPreview() {
|
||||||
ElementPreview(showBackground = false) {
|
ElementPreview(showBackground = false) {
|
||||||
|
|
@ -127,3 +126,21 @@ internal fun SingleSelectionDialogContentPreview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun SingleSelectionDialogPreview() = ElementPreview {
|
||||||
|
val options = persistentListOf(
|
||||||
|
ListOption("Option 1"),
|
||||||
|
ListOption("Option 2"),
|
||||||
|
ListOption("Option 3"),
|
||||||
|
)
|
||||||
|
SingleSelectionDialog(
|
||||||
|
title = "Dialog title",
|
||||||
|
options = options,
|
||||||
|
onOptionSelected = {},
|
||||||
|
onDismissRequest = {},
|
||||||
|
dismissButtonTitle = "Cancel",
|
||||||
|
initialSelection = 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,11 @@ object TestTags {
|
||||||
*/
|
*/
|
||||||
val messageBubble = TestTag("message_bubble")
|
val messageBubble = TestTag("message_bubble")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message Read Receipts.
|
||||||
|
*/
|
||||||
|
val messageReadReceipts = TestTag("message_read_receipts")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialogs.
|
* Dialogs.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7525d73e2c2e5bb9663a8c287f818d1f9b72e7fbc613a25d961067ac4fb78c3a
|
||||||
|
size 15690
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9a4007aaf79d6f2a9c22305de68336a8b2a46a34f9d5781c71baae8095fff8e3
|
||||||
|
size 12549
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:6246e1746c470980784f5fce7e29dbf7ffa9a434163832926687c449152d3ba0
|
||||||
|
size 11603
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:5ae12c0fa29906200f79a1269783bc435d072c20518bcdce5dd09a890b0b201a
|
||||||
|
size 8998
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fcb09c8bf2b019c1a7db261b9c1d983b2f69c3390a19ff4b0df0f4e672239263
|
oid sha256:0de9be99d755f99f287161bac201864c94cff22c3874c80444f172b5d19905bc
|
||||||
size 19972
|
size 34453
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:a7a7c6db1c2ceae0748793eda9b93602626d52294f041466ca33cb8681b94d87
|
|
||||||
size 19700
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:6eb41b4724e989d37317f94ce388b80360c63306d221d21daa84847b021b9cba
|
||||||
|
size 22360
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:980b3a32dbc831ed2b769d1f43f8c099f35b3f832e8124a65f794c8e674adfb6
|
||||||
|
size 17902
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:76aadb1f17f02efa6b0dbbafec5e5a08a1bfdb08e540b494eeaa48825c7c130a
|
oid sha256:9f15b84ce74edea24331947bcd1041f018b1b5c1151303ebacf662b187899546
|
||||||
size 30155
|
size 41114
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:8bc428ed9ed3c09556ade7fe797e843dad711d8c478936b6dc124933e3c8ce47
|
|
||||||
size 28366
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9596d444d89470b92a41389a0940e2415215ff70e58be120aec6e6766dbd039f
|
||||||
|
size 33438
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:51cc8509d8fd6619f3de67a01b35bf821ab2716dc7924fc46b5cbe326f399963
|
||||||
|
size 28698
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9703210e241b1bff7fe557a0e62e94246f1786ac9384d0dcb9534f46551b5751
|
||||||
|
size 14743
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:ffa9efaa0b03526d74085f8c27159f6c9138f8141369af1dd56173da59c72262
|
||||||
|
size 11815
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:001a87e1c34d96910971d1071479321d2ca9ed386ebf19de45ad79410d7a60ac
|
|
||||||
size 19581
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:39c301a15a72acdd02b047c516304ee836f3a4aea4b11612f8acae5e5d6f462e
|
||||||
|
size 23357
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:16dbbf810d759d8cf50b52a6f3db33c928527a3f130fc62e6f965919f7be9a70
|
||||||
|
size 19401
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:a49346767f539b578b619ae40e1a5ec88775246c03ba3bed5d629022e0f924aa
|
||||||
|
size 15848
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:56c36ec3f987033c07a2849aa88233f675f7f1df3028daccb73b97f4fae9f390
|
||||||
|
size 13526
|
||||||
Loading…
Add table
Add a link
Reference in a new issue