Merge pull request #2376 from element-hq/feature/bma/testUi

More test on MessagesView, and harmonize preview on Dialogs
This commit is contained in:
Benoit Marty 2024-02-12 10:41:46 +01:00 committed by GitHub
commit c13b5566a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 433 additions and 52 deletions

View file

@ -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.MessageComposerState
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.aTimelineState
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.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.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.typing.aTypingNotificationState
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
@ -91,12 +95,20 @@ fun aMessagesState(
roomName: AsyncData<String> = AsyncData.Success("Room name"),
roomAvatar: AsyncData<AvatarData> = AsyncData.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)),
userHasPermissionToSendMessage: Boolean = true,
userHasPermissionToRedactOwn: Boolean = false,
userHasPermissionToRedactOther: Boolean = false,
userHasPermissionToSendReaction: Boolean = true,
composerState: MessageComposerState = aMessageComposerState(
richTextEditorState = RichTextEditorState("Hello", initialFocus = true),
isFullScreen = false,
mode = MessageComposerMode.Normal,
),
voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(),
timelineState: TimelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()),
),
retrySendMenuState: RetrySendMenuState = aRetrySendMenuState(),
readReceiptBottomSheetState: ReadReceiptBottomSheetState = aReadReceiptBottomSheetState(),
actionListState: ActionListState = anActionListState(),
customReactionState: CustomReactionState = aCustomReactionState(),
reactionSummaryState: ReactionSummaryState = aReactionSummaryState(),
@ -110,23 +122,15 @@ fun aMessagesState(
roomName = roomName,
roomAvatar = roomAvatar,
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToRedactOwn = false,
userHasPermissionToRedactOther = false,
userHasPermissionToSendReaction = true,
userHasPermissionToRedactOwn = userHasPermissionToRedactOwn,
userHasPermissionToRedactOther = userHasPermissionToRedactOther,
userHasPermissionToSendReaction = userHasPermissionToSendReaction,
composerState = composerState,
voiceMessageComposerState = voiceMessageComposerState,
timelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()),
),
typingNotificationState = aTypingNotificationState(),
retrySendMenuState = RetrySendMenuState(
selectedEvent = null,
eventSink = {},
),
readReceiptBottomSheetState = ReadReceiptBottomSheetState(
selectedEvent = null,
eventSink = {},
),
timelineState = timelineState,
retrySendMenuState = retrySendMenuState,
readReceiptBottomSheetState = readReceiptBottomSheetState,
actionListState = actionListState,
customReactionState = customReactionState,
reactionSummaryState = reactionSummaryState,
@ -150,9 +154,18 @@ fun aReactionSummaryState(
)
fun aCustomReactionState(
target: CustomReactionState.Target = CustomReactionState.Target.None,
eventSink: (CustomReactionEvents) -> Unit = {},
) = CustomReactionState(
target = CustomReactionState.Target.None,
target = target,
selectedEmoji = persistentSetOf(),
eventSink = eventSink,
)
fun aReadReceiptBottomSheetState(
selectedEvent: TimelineItem.Event? = null,
eventSink: (ReadReceiptBottomSheetEvents) -> Unit = {},
) = ReadReceiptBottomSheetState(
selectedEvent = selectedEvent,
eventSink = eventSink,
)

View file

@ -250,7 +250,6 @@ fun MessagesView(
state = state.customReactionState,
onEmojiSelected = { eventId, emoji ->
state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, eventId))
state.customReactionState.eventSink(CustomReactionEvents.DismissCustomReactionSheet)
}
)

View file

@ -48,12 +48,14 @@ import kotlin.random.Random
fun aTimelineState(
timelineItems: ImmutableList<TimelineItem> = persistentListOf(),
paginationState: MatrixTimeline.PaginationState = aPaginationState(),
renderReadReceipts: Boolean = false,
timelineRoomInfo: TimelineRoomInfo = aTimelineRoomInfo(),
eventSink: (TimelineEvents) -> Unit = {},
) = TimelineState(
timelineItems = timelineItems,
timelineRoomInfo = aTimelineRoomInfo(),
timelineRoomInfo = timelineRoomInfo,
paginationState = paginationState,
renderReadReceipts = false,
renderReadReceipts = renderReadReceipts,
highlightedEventId = null,
newEventState = NewEventState.None,
sessionState = aSessionState(
@ -196,9 +198,11 @@ internal fun aTimelineItemDebugInfo(
latestEditedJson
)
internal fun aTimelineItemReadReceipts(): TimelineItemReadReceipts {
internal fun aTimelineItemReadReceipts(
receipts: List<ReadReceiptData> = emptyList(),
): TimelineItemReadReceipts {
return TimelineItemReadReceipts(
receipts = emptyList<ReadReceiptData>().toImmutableList(),
receipts = receipts.toImmutableList(),
)
}
@ -232,8 +236,9 @@ internal fun aGroupedEvents(
internal fun aTimelineRoomInfo(
isDirect: Boolean = false,
userHasPermissionToSendMessage: Boolean = true,
) = TimelineRoomInfo(
isDirect = isDirect,
userHasPermissionToSendMessage = true,
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToSendReaction = true,
)

View file

@ -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.utils.CommonDrawables
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.CommonStrings
import kotlinx.collections.immutable.ImmutableList
@ -68,6 +70,7 @@ fun TimelineItemReadReceiptView(
ReadReceiptsAvatars(
receipts = state.receipts,
modifier = Modifier
.testTag(TestTags.messageReadReceipts)
.clip(RoundedCornerShape(4.dp))
.clickable {
onReadReceiptsClicked()

View file

@ -22,10 +22,15 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
class RetrySendMenuStateProvider : PreviewParameterProvider<RetrySendMenuState> {
override val values: Sequence<RetrySendMenuState> = sequenceOf(
aRetrySendMenuState(event = null),
aRetrySendMenuState(),
aRetrySendMenuState(event = aTimelineItemEvent()),
)
}
fun aRetrySendMenuState(event: TimelineItem.Event? = aTimelineItemEvent()) =
RetrySendMenuState(selectedEvent = event, eventSink = {})
fun aRetrySendMenuState(
event: TimelineItem.Event? = null,
eventSink: (RetrySendMenuEvents) -> Unit = {},
) = RetrySendMenuState(
selectedEvent = event,
eventSink = eventSink,
)

View file

@ -27,18 +27,35 @@ import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeRight
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.anActionListState
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.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.CustomReactionState
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.event.aTimelineItemTextContent
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.ui.strings.CommonStrings
@ -128,6 +145,136 @@ class MessagesViewTest {
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
fun `clicking on send location invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false)
@ -256,6 +403,74 @@ class MessagesViewTest {
rule.onAllNodesWithContentDescription(moreReactionContentDescription).onFirst().performClick()
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(

View file

@ -35,8 +35,10 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
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.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.DialogPreview
import io.element.android.libraries.designsystem.theme.components.Text
@ -141,8 +143,14 @@ private fun ProgressDialogContent(
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun ProgressDialogPreview() = ElementThemedPreview {
internal fun ProgressDialogContentPreview() = ElementThemedPreview {
DialogPreview {
ProgressDialogContent(text = "test dialog content", isCancellable = true)
}
}
@PreviewsDayNight
@Composable
internal fun ProgressDialogPreview() = ElementPreview {
ProgressDialog(text = "test dialog content", isCancellable = true)
}

View file

@ -22,8 +22,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
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.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.SimpleAlertDialogContent
import io.element.android.libraries.ui.strings.CommonStrings
@ -87,7 +89,7 @@ private fun ConfirmationDialogContent(
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun ConfirmationDialogPreview() =
internal fun ConfirmationDialogContentPreview() =
ElementThemedPreview(showBackground = false) {
DialogPreview {
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 = {}
)
}

View file

@ -22,8 +22,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
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.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.SimpleAlertDialogContent
import io.element.android.libraries.ui.strings.CommonStrings
@ -69,7 +71,7 @@ object ErrorDialogDefaults {
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun ErrorDialogPreview() {
internal fun ErrorDialogContentPreview() {
ElementThemedPreview(showBackground = false) {
DialogPreview {
ErrorDialogContent(
@ -79,3 +81,12 @@ internal fun ErrorDialogPreview() {
}
}
}
@PreviewsDayNight
@Composable
internal fun ErrorDialogPreview() = ElementPreview {
ErrorDialog(
content = "Content",
onDismiss = {},
)
}

View file

@ -24,10 +24,11 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
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.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.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.DialogPreview
@ -100,11 +101,10 @@ private fun ListDialogContent(
}
}
@PreviewsDayNight
@ShowkaseComposable(group = PreviewGroup.Dialogs)
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun ListDialogContentPreview() {
ElementPreview(showBackground = false) {
ElementThemedPreview(showBackground = false) {
DialogPreview {
ListDialogContent(
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",
)
}

View file

@ -26,10 +26,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
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.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.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.DialogPreview
@ -124,11 +125,10 @@ private fun MultipleSelectionDialogContent(
}
}
@PreviewsDayNight
@ShowkaseComposable(group = PreviewGroup.Dialogs)
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun MultipleSelectionDialogContentPreview() {
ElementPreview(showBackground = false) {
ElementThemedPreview(showBackground = false) {
DialogPreview {
val options = persistentListOf(
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),
)
}

View file

@ -22,8 +22,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
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.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.SimpleAlertDialogContent
import io.element.android.libraries.ui.strings.CommonStrings
@ -78,7 +80,7 @@ object RetryDialogDefaults {
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun RetryDialogPreview() {
internal fun RetryDialogContentPreview() {
ElementThemedPreview(showBackground = false) {
DialogPreview {
RetryDialogContent(
@ -89,3 +91,13 @@ internal fun RetryDialogPreview() {
}
}
}
@PreviewsDayNight
@Composable
internal fun RetryDialogPreview() = ElementPreview {
RetryDialog(
content = "Content",
onRetry = {},
onDismiss = {},
)
}

View file

@ -24,8 +24,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
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.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@ -105,8 +105,7 @@ private fun SingleSelectionDialogContent(
}
}
@PreviewsDayNight
@ShowkaseComposable(group = PreviewGroup.Dialogs)
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun SingleSelectionDialogContentPreview() {
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
)
}

View file

@ -63,6 +63,11 @@ object TestTags {
*/
val messageBubble = TestTag("message_bubble")
/**
* Message Read Receipts.
*/
val messageReadReceipts = TestTag("message_read_receipts")
/**
* Dialogs.
*/

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7525d73e2c2e5bb9663a8c287f818d1f9b72e7fbc613a25d961067ac4fb78c3a
size 15690

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9a4007aaf79d6f2a9c22305de68336a8b2a46a34f9d5781c71baae8095fff8e3
size 12549

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6246e1746c470980784f5fce7e29dbf7ffa9a434163832926687c449152d3ba0
size 11603

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5ae12c0fa29906200f79a1269783bc435d072c20518bcdce5dd09a890b0b201a
size 8998

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fcb09c8bf2b019c1a7db261b9c1d983b2f69c3390a19ff4b0df0f4e672239263
size 19972
oid sha256:0de9be99d755f99f287161bac201864c94cff22c3874c80444f172b5d19905bc
size 34453

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a7a7c6db1c2ceae0748793eda9b93602626d52294f041466ca33cb8681b94d87
size 19700

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6eb41b4724e989d37317f94ce388b80360c63306d221d21daa84847b021b9cba
size 22360

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:980b3a32dbc831ed2b769d1f43f8c099f35b3f832e8124a65f794c8e674adfb6
size 17902

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:76aadb1f17f02efa6b0dbbafec5e5a08a1bfdb08e540b494eeaa48825c7c130a
size 30155
oid sha256:9f15b84ce74edea24331947bcd1041f018b1b5c1151303ebacf662b187899546
size 41114

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8bc428ed9ed3c09556ade7fe797e843dad711d8c478936b6dc124933e3c8ce47
size 28366

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9596d444d89470b92a41389a0940e2415215ff70e58be120aec6e6766dbd039f
size 33438

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:51cc8509d8fd6619f3de67a01b35bf821ab2716dc7924fc46b5cbe326f399963
size 28698

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9703210e241b1bff7fe557a0e62e94246f1786ac9384d0dcb9534f46551b5751
size 14743

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ffa9efaa0b03526d74085f8c27159f6c9138f8141369af1dd56173da59c72262
size 11815

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:001a87e1c34d96910971d1071479321d2ca9ed386ebf19de45ad79410d7a60ac
size 19581

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:39c301a15a72acdd02b047c516304ee836f3a4aea4b11612f8acae5e5d6f462e
size 23357

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:16dbbf810d759d8cf50b52a6f3db33c928527a3f130fc62e6f965919f7be9a70
size 19401

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a49346767f539b578b619ae40e1a5ec88775246c03ba3bed5d629022e0f924aa
size 15848

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:56c36ec3f987033c07a2849aa88233f675f7f1df3028daccb73b97f4fae9f390
size 13526