Add tests on MessagesView
This commit is contained in:
parent
4e0f308cac
commit
fa52ff54c8
8 changed files with 376 additions and 23 deletions
|
|
@ -17,13 +17,16 @@
|
|||
package io.element.android.features.messages.impl
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
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.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.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.ReadReceiptBottomSheetState
|
||||
import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState
|
||||
|
|
@ -93,10 +96,14 @@ fun aMessagesState(
|
|||
mode = MessageComposerMode.Normal,
|
||||
),
|
||||
voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(),
|
||||
actionListState: ActionListState = anActionListState(),
|
||||
customReactionState: CustomReactionState = aCustomReactionState(),
|
||||
reactionSummaryState: ReactionSummaryState = aReactionSummaryState(),
|
||||
hasNetworkConnection: Boolean = true,
|
||||
showReinvitePrompt: Boolean = false,
|
||||
enableVoiceMessages: Boolean = true,
|
||||
callState: RoomCallState = RoomCallState.ENABLED,
|
||||
eventSink: (MessagesEvents) -> Unit = {},
|
||||
) = MessagesState(
|
||||
roomId = RoomId("!id:domain"),
|
||||
roomName = roomName,
|
||||
|
|
@ -118,16 +125,9 @@ fun aMessagesState(
|
|||
selectedEvent = null,
|
||||
eventSink = {},
|
||||
),
|
||||
actionListState = anActionListState(),
|
||||
customReactionState = CustomReactionState(
|
||||
target = CustomReactionState.Target.None,
|
||||
eventSink = {},
|
||||
selectedEmoji = persistentSetOf(),
|
||||
),
|
||||
reactionSummaryState = ReactionSummaryState(
|
||||
target = null,
|
||||
eventSink = {},
|
||||
),
|
||||
actionListState = actionListState,
|
||||
customReactionState = customReactionState,
|
||||
reactionSummaryState = reactionSummaryState,
|
||||
hasNetworkConnection = hasNetworkConnection,
|
||||
snackbarMessage = null,
|
||||
inviteProgress = AsyncData.Uninitialized,
|
||||
|
|
@ -136,5 +136,21 @@ fun aMessagesState(
|
|||
enableVoiceMessages = enableVoiceMessages,
|
||||
callState = callState,
|
||||
appName = "Element",
|
||||
eventSink = {}
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
fun aReactionSummaryState(
|
||||
target: ReactionSummaryState.Summary? = null,
|
||||
eventSink: (ReactionSummaryEvents) -> Unit = {}
|
||||
) = ReactionSummaryState(
|
||||
target = target,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
fun aCustomReactionState(
|
||||
eventSink: (CustomReactionEvents) -> Unit = {},
|
||||
) = CustomReactionState(
|
||||
target = CustomReactionState.Target.None,
|
||||
selectedEmoji = persistentSetOf(),
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -122,9 +122,12 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
|
|||
}
|
||||
}
|
||||
|
||||
fun anActionListState() = ActionListState(
|
||||
target = ActionListState.Target.None,
|
||||
eventSink = {}
|
||||
fun anActionListState(
|
||||
target: ActionListState.Target = ActionListState.Target.None,
|
||||
eventSink: (ActionListEvents) -> Unit = {},
|
||||
) = ActionListState(
|
||||
target = target,
|
||||
eventSink = eventSink
|
||||
)
|
||||
|
||||
fun aTimelineItemActionList(): ImmutableList<TimelineItemAction> {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
|
|
@ -86,6 +87,7 @@ import io.element.android.libraries.designsystem.theme.components.hide
|
|||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -101,28 +103,52 @@ fun ActionListView(
|
|||
val targetItem = (state.target as? ActionListState.Target.Success)?.event
|
||||
|
||||
fun onItemActionClicked(
|
||||
itemAction: TimelineItemAction
|
||||
itemAction: TimelineItemAction,
|
||||
immediate: Boolean,
|
||||
) {
|
||||
if (targetItem == null) return
|
||||
sheetState.hide(coroutineScope) {
|
||||
if (immediate) {
|
||||
coroutineScope.launch { sheetState.hide() }
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
onActionSelected(itemAction, targetItem)
|
||||
} else {
|
||||
sheetState.hide(coroutineScope) {
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
onActionSelected(itemAction, targetItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onEmojiReactionClicked(emoji: String) {
|
||||
fun onEmojiReactionClicked(
|
||||
emoji: String,
|
||||
immediate: Boolean,
|
||||
) {
|
||||
if (targetItem == null) return
|
||||
sheetState.hide(coroutineScope) {
|
||||
if (immediate) {
|
||||
coroutineScope.launch { sheetState.hide() }
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
onEmojiReactionClicked(emoji, targetItem)
|
||||
} else {
|
||||
sheetState.hide(coroutineScope) {
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
onEmojiReactionClicked(emoji, targetItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onCustomReactionClicked() {
|
||||
fun onCustomReactionClicked(
|
||||
immediate: Boolean,
|
||||
) {
|
||||
if (targetItem == null) return
|
||||
sheetState.hide(coroutineScope) {
|
||||
if (immediate) {
|
||||
coroutineScope.launch { sheetState.hide() }
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
onCustomReactionClicked(targetItem)
|
||||
} else {
|
||||
sheetState.hide(coroutineScope) {
|
||||
state.eventSink(ActionListEvents.Clear)
|
||||
onCustomReactionClicked(targetItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,11 +162,18 @@ fun ActionListView(
|
|||
onDismissRequest = ::onDismiss,
|
||||
modifier = modifier,
|
||||
) {
|
||||
val immediate = LocalInspectionMode.current
|
||||
SheetContent(
|
||||
state = state,
|
||||
onActionClicked = ::onItemActionClicked,
|
||||
onEmojiReactionClicked = ::onEmojiReactionClicked,
|
||||
onCustomReactionClicked = ::onCustomReactionClicked,
|
||||
onActionClicked = {
|
||||
onItemActionClicked(it, immediate)
|
||||
},
|
||||
onEmojiReactionClicked = {
|
||||
onEmojiReactionClicked(it, immediate)
|
||||
},
|
||||
onCustomReactionClicked = {
|
||||
onCustomReactionClicked(immediate)
|
||||
},
|
||||
modifier = Modifier
|
||||
.navigationBarsPadding()
|
||||
.imePadding()
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ import io.element.android.libraries.designsystem.theme.components.Surface
|
|||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.messageFromMeBackground
|
||||
import io.element.android.libraries.designsystem.theme.messageFromOtherBackground
|
||||
import io.element.android.libraries.testtags.TestTags
|
||||
import io.element.android.libraries.testtags.testTag
|
||||
|
||||
private val BUBBLE_RADIUS = 12.dp
|
||||
internal val BUBBLE_INCOMING_OFFSET = 16.dp
|
||||
|
|
@ -115,6 +117,7 @@ fun MessageEventBubble(
|
|||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.testTag(TestTags.messageBubble)
|
||||
.widthIn(min = 80.dp)
|
||||
.clip(bubbleShape)
|
||||
.combinedClickable(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue