diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/ConfirmingWithReason.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/ConfirmingWithReason.kt new file mode 100644 index 0000000000..6893dda308 --- /dev/null +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/ConfirmingWithReason.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.roomdetails.impl.members.moderation + +import io.element.android.libraries.architecture.AsyncAction + +data class ConfirmingWithReason( + val reason: String, +) : AsyncAction.Confirming diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationEvents.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationEvents.kt index 824c239a91..348132d9a5 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationEvents.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationEvents.kt @@ -12,8 +12,8 @@ import io.element.android.libraries.matrix.api.room.RoomMember sealed interface RoomMembersModerationEvents { data class SelectRoomMember(val roomMember: RoomMember) : RoomMembersModerationEvents - data object KickUser : RoomMembersModerationEvents - data object BanUser : RoomMembersModerationEvents + data class KickUser(val reason: String, val needsConfirmation: Boolean) : RoomMembersModerationEvents + data class BanUser(val reason: String, val needsConfirmation: Boolean) : RoomMembersModerationEvents data class UnbanUser(val userId: UserId) : RoomMembersModerationEvents data object Reset : RoomMembersModerationEvents } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenter.kt index e9d4a91514..9baee267f2 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenter.kt @@ -96,19 +96,23 @@ class RoomMembersModerationPresenter @Inject constructor( } } is RoomMembersModerationEvents.KickUser -> { - selectedMember?.let { - coroutineScope.kickUser(it.userId, kickUserAsyncAction) - } - selectedMember = null - } - is RoomMembersModerationEvents.BanUser -> { - if (banUserAsyncAction.value.isConfirming()) { + if (event.needsConfirmation) { + kickUserAsyncAction.value = ConfirmingWithReason(event.reason) + } else { selectedMember?.let { - coroutineScope.banUser(it.userId, banUserAsyncAction) + coroutineScope.kickUser(it.userId, event.reason, kickUserAsyncAction) } selectedMember = null + } + } + is RoomMembersModerationEvents.BanUser -> { + if (event.needsConfirmation) { + banUserAsyncAction.value = ConfirmingWithReason(event.reason) } else { - banUserAsyncAction.value = AsyncAction.ConfirmingNoParams + selectedMember?.let { + coroutineScope.banUser(it.userId, event.reason, banUserAsyncAction) + } + selectedMember = null } } is RoomMembersModerationEvents.UnbanUser -> { @@ -138,18 +142,26 @@ class RoomMembersModerationPresenter @Inject constructor( private fun CoroutineScope.kickUser( userId: UserId, + reason: String, kickUserAction: MutableState>, ) = runActionAndWaitForMembershipChange(kickUserAction) { analyticsService.capture(RoomModeration(RoomModeration.Action.KickMember)) - room.kickUser(userId) + room.kickUser( + userId = userId, + reason = reason.takeIf { it.isNotBlank() }, + ) } private fun CoroutineScope.banUser( userId: UserId, + reason: String, banUserAction: MutableState>, ) = runActionAndWaitForMembershipChange(banUserAction) { analyticsService.capture(RoomModeration(RoomModeration.Action.BanMember)) - room.banUser(userId) + room.banUser( + userId = userId, + reason = reason.takeIf { it.isNotBlank() }, + ) } private fun CoroutineScope.unbanUser( diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationStateProvider.kt index 41e61d8351..a5ea00db36 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationStateProvider.kt @@ -37,10 +37,26 @@ class RoomMembersModerationStateProvider : PreviewParameterProvider { - state.eventSink(RoomMembersModerationEvents.KickUser) + state.eventSink(RoomMembersModerationEvents.KickUser(reason = "", needsConfirmation = true)) } is ModerationAction.BanUser -> { - state.eventSink(RoomMembersModerationEvents.BanUser) + state.eventSink(RoomMembersModerationEvents.BanUser(reason = "", needsConfirmation = true)) } } }, @@ -87,6 +89,47 @@ fun RoomMembersModerationView( AsyncIndicatorHost(modifier = Modifier.statusBarsPadding(), state = asyncIndicatorState) when (val action = state.kickUserAsyncAction) { + is AsyncAction.Confirming -> { + if (action is ConfirmingWithReason) { + ListDialog( + title = stringResource(R.string.screen_room_member_list_kick_member_confirmation_title), + submitText = stringResource(R.string.screen_room_member_list_kick_member_confirmation_action), + onSubmit = { + state.eventSink( + RoomMembersModerationEvents.KickUser( + reason = action.reason, + needsConfirmation = false, + ) + ) + }, + applyPaddingToContents = true, + onDismissRequest = { state.eventSink(RoomMembersModerationEvents.Reset) }, + ) { + item { + Text( + text = stringResource(R.string.screen_room_member_list_kick_member_confirmation_description), + style = ElementTheme.materialTypography.bodyMedium, + ) + } + item { + TextFieldListItem( + placeholder = stringResource(id = CommonStrings.common_reason), + label = stringResource(id = CommonStrings.common_reason), + withBorder = true, + text = action.reason, + onTextChange = { newText -> + state.eventSink( + RoomMembersModerationEvents.KickUser( + reason = newText, + needsConfirmation = true, + ) + ) + }, + ) + } + } + } + } is AsyncAction.Loading -> { LaunchedEffect(action) { val userDisplayName = state.selectedRoomMember?.getBestName().orEmpty() @@ -113,13 +156,45 @@ fun RoomMembersModerationView( when (val action = state.banUserAsyncAction) { is AsyncAction.Confirming -> { - ConfirmationDialog( - title = stringResource(R.string.screen_room_member_list_ban_member_confirmation_title), - content = stringResource(R.string.screen_room_member_list_ban_member_confirmation_description), - submitText = stringResource(R.string.screen_room_member_list_ban_member_confirmation_action), - onSubmitClick = { state.eventSink(RoomMembersModerationEvents.BanUser) }, - onDismiss = { state.eventSink(RoomMembersModerationEvents.Reset) } - ) + if (action is ConfirmingWithReason) { + ListDialog( + title = stringResource(R.string.screen_room_member_list_ban_member_confirmation_title), + submitText = stringResource(R.string.screen_room_member_list_ban_member_confirmation_action), + onSubmit = { + state.eventSink( + RoomMembersModerationEvents.BanUser( + reason = action.reason, + needsConfirmation = false, + ) + ) + }, + applyPaddingToContents = true, + onDismissRequest = { state.eventSink(RoomMembersModerationEvents.Reset) }, + ) { + item { + Text( + text = stringResource(R.string.screen_room_member_list_ban_member_confirmation_description), + style = ElementTheme.materialTypography.bodyMedium, + ) + } + item { + TextFieldListItem( + placeholder = stringResource(id = CommonStrings.common_reason), + label = stringResource(id = CommonStrings.common_reason), + withBorder = true, + text = action.reason, + onTextChange = { newText -> + state.eventSink( + RoomMembersModerationEvents.BanUser( + reason = newText, + needsConfirmation = true, + ) + ) + }, + ) + } + } + } } is AsyncAction.Loading -> { LaunchedEffect(action) { diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 62a7e48295..fb2cfc686e 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -75,6 +75,9 @@ "%1$d person" "%1$d people" + "Remove" + "They will be able to join this room again if invited." + "Are you sure you want to remove this member?" "Remove and ban member" "Remove from room" "Remove and ban member" diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt index d86fc49925..14c8669270 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationPresenterTest.kt @@ -17,14 +17,18 @@ import io.element.android.features.roomdetails.impl.members.aRoomMember import io.element.android.features.roomdetails.impl.members.aVictor import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.test.A_REASON import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.collections.immutable.persistentListOf @@ -153,13 +157,14 @@ class RoomMembersModerationPresenterTest { } @Test - fun `present - Kick removes the user`() = runTest { + fun `present - Kick requires confirmation and then kicks the user`() = runTest { val analyticsService = FakeAnalyticsService() + val kickUserResult = lambdaRecorder> { _, _ -> Result.success(Unit) } val room = aMatrixRoom( canKickResult = { Result.success(true) }, canBanResult = { Result.success(true) }, userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - kickUserResult = { _, _ -> Result.success(Unit) }, + kickUserResult = kickUserResult, ) val selectedMember = aVictor() val presenter = createRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService) @@ -168,7 +173,15 @@ class RoomMembersModerationPresenterTest { }.test { skipItems(1) awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - awaitItem().eventSink(RoomMembersModerationEvents.KickUser) + awaitItem().eventSink(RoomMembersModerationEvents.KickUser(reason = "", needsConfirmation = true)) + val confirmingState = awaitItem() + assertThat(confirmingState.kickUserAsyncAction).isEqualTo(ConfirmingWithReason("")) + // Change the reason + confirmingState.eventSink(RoomMembersModerationEvents.KickUser(reason = A_REASON, needsConfirmation = true)) + val confirmingWithReasonState = awaitItem() + assertThat(confirmingWithReasonState.kickUserAsyncAction).isEqualTo(ConfirmingWithReason(A_REASON)) + // Confirm + confirmingState.eventSink(RoomMembersModerationEvents.KickUser(reason = A_REASON, needsConfirmation = false)) skipItems(1) val loadingState = awaitItem() assertThat(loadingState.actions).isEmpty() @@ -178,17 +191,22 @@ class RoomMembersModerationPresenterTest { assertThat(selectedRoomMember).isNull() } assertThat(analyticsService.capturedEvents.last()).isEqualTo(RoomModeration(RoomModeration.Action.KickMember)) + kickUserResult.assertions().isCalledOnce().with( + value(selectedMember.userId), + value(A_REASON), + ) } } @Test fun `present - BanUser requires confirmation and then bans the user`() = runTest { val analyticsService = FakeAnalyticsService() + val banUserResult = lambdaRecorder> { _, _ -> Result.success(Unit) } val room = aMatrixRoom( canKickResult = { Result.success(true) }, canBanResult = { Result.success(true) }, userRoleResult = { Result.success(RoomMember.Role.ADMIN) }, - banUserResult = { _, _ -> Result.success(Unit) }, + banUserResult = banUserResult, ) val selectedMember = aVictor() val presenter = createRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService) @@ -197,12 +215,15 @@ class RoomMembersModerationPresenterTest { }.test { skipItems(1) awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(selectedMember)) - awaitItem().eventSink(RoomMembersModerationEvents.BanUser) + awaitItem().eventSink(RoomMembersModerationEvents.BanUser(reason = "", needsConfirmation = true)) val confirmingState = awaitItem() - assertThat(confirmingState.banUserAsyncAction).isEqualTo(AsyncAction.ConfirmingNoParams) - + assertThat(confirmingState.banUserAsyncAction).isEqualTo(ConfirmingWithReason("")) + // Change the reason + confirmingState.eventSink(RoomMembersModerationEvents.BanUser(reason = A_REASON, needsConfirmation = true)) + val confirmingWithReasonState = awaitItem() + assertThat(confirmingWithReasonState.banUserAsyncAction).isEqualTo(ConfirmingWithReason(A_REASON)) // Confirm - confirmingState.eventSink(RoomMembersModerationEvents.BanUser) + confirmingState.eventSink(RoomMembersModerationEvents.BanUser(reason = A_REASON, needsConfirmation = false)) skipItems(1) val loadingItem = awaitItem() assertThat(loadingItem.actions).isEmpty() @@ -213,6 +234,10 @@ class RoomMembersModerationPresenterTest { assertThat(selectedRoomMember).isNull() } assertThat(analyticsService.capturedEvents.last()).isEqualTo(RoomModeration(RoomModeration.Action.BanMember)) + banUserResult.assertions().isCalledOnce().with( + value(selectedMember.userId), + value(A_REASON), + ) } } @@ -289,7 +314,7 @@ class RoomMembersModerationPresenterTest { val initialItem = awaitItem() // Kick user and fail awaitItem().eventSink(RoomMembersModerationEvents.SelectRoomMember(aVictor())) - awaitItem().eventSink(RoomMembersModerationEvents.KickUser) + awaitItem().eventSink(RoomMembersModerationEvents.KickUser(reason = "", needsConfirmation = false)) skipItems(1) assertThat(awaitItem().kickUserAsyncAction).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().kickUserAsyncAction).isInstanceOf(AsyncAction.Failure::class.java) @@ -299,8 +324,7 @@ class RoomMembersModerationPresenterTest { // Ban user and fail initialItem.eventSink(RoomMembersModerationEvents.SelectRoomMember(aVictor())) - awaitItem().eventSink(RoomMembersModerationEvents.BanUser) - awaitItem().eventSink(RoomMembersModerationEvents.BanUser) + awaitItem().eventSink(RoomMembersModerationEvents.BanUser(reason = "", needsConfirmation = false)) skipItems(1) assertThat(awaitItem().banUserAsyncAction).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().banUserAsyncAction).isInstanceOf(AsyncAction.Failure::class.java) diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt index 6fc9b8a20f..bbf988d9ee 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/moderation/RoomMembersModerationViewTest.kt @@ -10,11 +10,13 @@ package io.element.android.features.roomdetails.impl.members.moderation import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performTextInput import androidx.test.ext.junit.runners.AndroidJUnit4 import io.element.android.features.roomdetails.impl.R import io.element.android.features.roomdetails.impl.members.anAlice -import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.test.A_REASON import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalledWithParam import io.element.android.tests.testutils.EventsRecorder @@ -92,7 +94,57 @@ class RoomMembersModerationViewTest { rule.clickOn(R.string.screen_room_member_list_manage_member_remove) // Give time for the bottom sheet to animate rule.mainClock.advanceTimeBy(1_000) - eventsRecorder.assertSingle(RoomMembersModerationEvents.KickUser) + eventsRecorder.assertSingle(RoomMembersModerationEvents.KickUser(reason = "", needsConfirmation = true)) + } + + @Test + fun `cancelling 'Remove member' confirmation emits the expected event`() { + val eventsRecorder = EventsRecorder() + val roomMember = anAlice() + val state = aRoomMembersModerationState( + selectedRoomMember = roomMember, + kickUserAsyncAction = ConfirmingWithReason(A_REASON), + eventSink = eventsRecorder + ) + rule.setRoomMembersModerationView( + state = state, + ) + // Note: the string key semantics is not perfect here :/ + rule.clickOn(CommonStrings.action_cancel) + eventsRecorder.assertSingle(RoomMembersModerationEvents.Reset) + } + + @Test + fun `confirming 'Remove member' reason edition emits the expected event`() { + val eventsRecorder = EventsRecorder() + val roomMember = anAlice() + val state = aRoomMembersModerationState( + selectedRoomMember = roomMember, + kickUserAsyncAction = ConfirmingWithReason(A_REASON), + eventSink = eventsRecorder + ) + rule.setRoomMembersModerationView( + state = state, + ) + rule.onNodeWithText(A_REASON).performTextInput("z") + eventsRecorder.assertSingle(RoomMembersModerationEvents.KickUser(reason = "z$A_REASON", needsConfirmation = true)) + } + + @Test + fun `confirming 'Remove member' confirmation emits the expected event`() { + val eventsRecorder = EventsRecorder() + val roomMember = anAlice() + val state = aRoomMembersModerationState( + selectedRoomMember = roomMember, + kickUserAsyncAction = ConfirmingWithReason(A_REASON), + eventSink = eventsRecorder + ) + rule.setRoomMembersModerationView( + state = state, + ) + // Note: the string key semantics is not perfect here :/ + rule.clickOn(R.string.screen_room_member_list_kick_member_confirmation_action) + eventsRecorder.assertSingle(RoomMembersModerationEvents.KickUser(reason = A_REASON, needsConfirmation = false)) } @Config(qualifiers = "h1024dp") @@ -116,7 +168,7 @@ class RoomMembersModerationViewTest { rule.clickOn(R.string.screen_room_member_list_manage_member_remove_confirmation_ban) // Give time for the bottom sheet to animate rule.mainClock.advanceTimeBy(1_000) - eventsRecorder.assertSingle(RoomMembersModerationEvents.BanUser) + eventsRecorder.assertSingle(RoomMembersModerationEvents.BanUser(reason = "", needsConfirmation = true)) } @Test @@ -125,7 +177,7 @@ class RoomMembersModerationViewTest { val roomMember = anAlice() val state = aRoomMembersModerationState( selectedRoomMember = roomMember, - banUserAsyncAction = AsyncAction.ConfirmingNoParams, + banUserAsyncAction = ConfirmingWithReason(A_REASON), eventSink = eventsRecorder ) rule.setRoomMembersModerationView( @@ -136,13 +188,29 @@ class RoomMembersModerationViewTest { eventsRecorder.assertSingle(RoomMembersModerationEvents.Reset) } + @Test + fun `confirming 'Remove and ban member' reason edition emits the expected event`() { + val eventsRecorder = EventsRecorder() + val roomMember = anAlice() + val state = aRoomMembersModerationState( + selectedRoomMember = roomMember, + banUserAsyncAction = ConfirmingWithReason(A_REASON), + eventSink = eventsRecorder + ) + rule.setRoomMembersModerationView( + state = state, + ) + rule.onNodeWithText(A_REASON).performTextInput("z") + eventsRecorder.assertSingle(RoomMembersModerationEvents.BanUser(reason = "z$A_REASON", needsConfirmation = true)) + } + @Test fun `confirming 'Remove and ban member' confirmation emits the expected event`() { val eventsRecorder = EventsRecorder() val roomMember = anAlice() val state = aRoomMembersModerationState( selectedRoomMember = roomMember, - banUserAsyncAction = AsyncAction.ConfirmingNoParams, + banUserAsyncAction = ConfirmingWithReason(A_REASON), eventSink = eventsRecorder ) rule.setRoomMembersModerationView( @@ -150,7 +218,7 @@ class RoomMembersModerationViewTest { ) // Note: the string key semantics is not perfect here :/ rule.clickOn(R.string.screen_room_member_list_ban_member_confirmation_action) - eventsRecorder.assertSingle(RoomMembersModerationEvents.BanUser) + eventsRecorder.assertSingle(RoomMembersModerationEvents.BanUser(reason = A_REASON, needsConfirmation = false)) } @Test diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt index 0f8f1e43d8..945384e832 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ListDialog.kt @@ -38,6 +38,7 @@ fun ListDialog( cancelText: String = stringResource(CommonStrings.action_cancel), submitText: String = stringResource(CommonStrings.action_ok), enabled: Boolean = true, + applyPaddingToContents: Boolean = false, listItems: LazyListScope.() -> Unit, ) { val decoratedSubtitle: @Composable (() -> Unit)? = subtitle?.let { @@ -61,6 +62,7 @@ fun ListDialog( onSubmitClick = onSubmit, enabled = enabled, listItems = listItems, + applyPaddingToContents = applyPaddingToContents, ) } } @@ -72,8 +74,9 @@ private fun ListDialogContent( onSubmitClick: () -> Unit, cancelText: String, submitText: String, - title: String? = null, - enabled: Boolean = true, + title: String?, + enabled: Boolean, + applyPaddingToContents: Boolean, subtitle: @Composable (() -> Unit)? = null, ) { SimpleAlertDialogContent( @@ -84,10 +87,12 @@ private fun ListDialogContent( onCancelClick = onDismissRequest, onSubmitClick = onSubmitClick, enabled = enabled, - applyPaddingToContents = false, + applyPaddingToContents = applyPaddingToContents, ) { + // No start padding if padding is already applied to the content + val horizontalPadding = if (applyPaddingToContents) 0.dp else 8.dp LazyColumn( - modifier = Modifier.padding(start = 8.dp) + modifier = Modifier.padding(horizontal = horizontalPadding) ) { listItems() } } } @@ -111,6 +116,8 @@ internal fun ListDialogContentPreview() { onSubmitClick = {}, cancelText = "Cancel", submitText = "Save", + enabled = true, + applyPaddingToContents = false, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/TextFieldListItem.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/TextFieldListItem.kt index 299b41ad94..76429348cf 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/TextFieldListItem.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/TextFieldListItem.kt @@ -29,6 +29,8 @@ fun TextFieldListItem( modifier: Modifier = Modifier, error: String? = null, maxLines: Int = 1, + withBorder: Boolean = false, + label: String? = null, keyboardOptions: KeyboardOptions = KeyboardOptions.Default, keyboardActions: KeyboardActions = KeyboardActions.Default, ) { @@ -38,12 +40,17 @@ fun TextFieldListItem( value = text, onValueChange = { onTextChange(it) }, placeholder = placeholder?.let { @Composable { Text(it) } }, - colors = OutlinedTextFieldDefaults.colors( - disabledBorderColor = Color.Transparent, - errorBorderColor = Color.Transparent, - focusedBorderColor = Color.Transparent, - unfocusedBorderColor = Color.Transparent, - ), + label = label?.let { @Composable { Text(it) } }, + colors = if (withBorder) { + OutlinedTextFieldDefaults.colors() + } else { + OutlinedTextFieldDefaults.colors( + disabledBorderColor = Color.Transparent, + errorBorderColor = Color.Transparent, + focusedBorderColor = Color.Transparent, + unfocusedBorderColor = Color.Transparent, + ) + }, isError = error != null, supportingText = error?.let { @Composable { Text(it) } }, keyboardOptions = keyboardOptions, @@ -124,3 +131,31 @@ internal fun TextFieldListItemTextFieldValuePreview() { ) } } + +@Preview("Text field List item with border - empty", group = PreviewGroup.ListItems) +@Composable +internal fun TextFieldListItemWithBorderEmptyPreview() { + ElementThemedPreview { + TextFieldListItem( + placeholder = "Placeholder", + label = "Label", + text = "", + withBorder = true, + onTextChange = {}, + ) + } +} + +@Preview("Text field List item with border - text", group = PreviewGroup.ListItems) +@Composable +internal fun TextFieldListItemWithBorderPreview() { + ElementThemedPreview { + TextFieldListItem( + placeholder = "Placeholder", + label = "Label", + text = "Text", + withBorder = true, + onTextChange = {}, + ) + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index 509fac833c..7f9e218697 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -63,6 +63,7 @@ const val A_MESSAGE = "Hello world!" const val A_REPLY = "OK, I'll be there!" const val ANOTHER_MESSAGE = "Hello universe!" const val A_CAPTION = "A media caption" +const val A_REASON = "A reason" const val A_REDACTION_REASON = "A redaction reason" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index d857db0555..3c3a90cf63 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -228,6 +228,7 @@ Reason: %1$s." "Privacy policy" "Reaction" "Reactions" + "Reason" "Recovery key" "Refreshing…" "Replying to %1$s" diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_10_en.png new file mode 100644 index 0000000000..6f43e3db48 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f83d60c7e1d963ccef24668c219bd9df36494dc8bd8f57af7aa63a3b73ee6882 +size 7545 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_11_en.png new file mode 100644 index 0000000000..d220520bfc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b323796ccdf27e5c445aa02e3f7b73f65df961dd88f3ee480efcba14d8038281 +size 19426 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_12_en.png new file mode 100644 index 0000000000..1b6fb4bab8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_12_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96a867cb12498cbdc97957bee07855dfaa13602baddaf933aff2b666ef4c7650 +size 3642 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_3_en.png index 908e311bb1..80c195780c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d06a58bb3b3fe7b01740cc04ed3128d24a13717be84cb4a70ced228d2256b41 -size 9435 +oid sha256:b9a5256bf2af8a8e9ee87bbab2ebdc7cd5823bc6b2cfde6267a68bd797e6eb61 +size 29650 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_4_en.png index 31231ab57a..e1c80c4a3c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:571207325446195a58251e7ece1ecaabc8a782cbb526315abe2a82f21e6441eb -size 9006 +oid sha256:501ebaae1e09a4f7853b574b788ddb3a73cd470d37d5dbef1f46b2967761e612 +size 31207 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_5_en.png index 1b6fb4bab8..908e311bb1 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96a867cb12498cbdc97957bee07855dfaa13602baddaf933aff2b666ef4c7650 -size 3642 +oid sha256:2d06a58bb3b3fe7b01740cc04ed3128d24a13717be84cb4a70ced228d2256b41 +size 9435 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_6_en.png index 6f43e3db48..27ac4de00f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f83d60c7e1d963ccef24668c219bd9df36494dc8bd8f57af7aa63a3b73ee6882 -size 7545 +oid sha256:39b34e0940f38ab0d66ba68b61c07ba70a51acfb54f995eedce800231ea6a2c5 +size 28257 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_7_en.png index 34ded1ba23..bf62183c98 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:16685ff4d5d52c5cb15f87fd14178cf791a85f3295b9869f997f4dac9fda1373 -size 25819 +oid sha256:96e0f2e3c32eedf2c85e243661a7947d28cbfe2eee7df81b239c5331770e7f7c +size 29835 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_en.png index d220520bfc..31231ab57a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b323796ccdf27e5c445aa02e3f7b73f65df961dd88f3ee480efcba14d8038281 -size 19426 +oid sha256:571207325446195a58251e7ece1ecaabc8a782cbb526315abe2a82f21e6441eb +size 9006 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_10_en.png new file mode 100644 index 0000000000..08349f1edb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba213b12d181b04695b9271670cb7d96ce83dfccc3c2031ee002ba1cf180cc8d +size 6408 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_11_en.png new file mode 100644 index 0000000000..51ce6077b5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9def02bcb5784681dc26327791510a9a25f0772644cdae363d7a4b90e69067c +size 17479 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_12_en.png new file mode 100644 index 0000000000..d6fd8eeb70 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_12_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bb36ccd718f3fec5b04f1bc812dc7718b5ea7fa4619c8b031466297a8d016fd +size 3659 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_3_en.png index 13b79b35d3..091915ab82 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:273043114950e000953fbede780f3ad8adcce9d3d579edea2cad58f8e3c48881 -size 8175 +oid sha256:e07ab4816ff009eaa26e1f3cf69b613a9a34baea0dd55e0eface745ee7328758 +size 27486 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_4_en.png index 3631712dc9..3a9c0ea87a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b0d51e2c5b255fb2f94959734293d4b7807f002acb0217c84856f0002297293 -size 7636 +oid sha256:83e72d7332d7574dd2f4ea42b9fa18995359720b18105f08bfde1f7f14cf8725 +size 29080 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_5_en.png index d6fd8eeb70..13b79b35d3 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5bb36ccd718f3fec5b04f1bc812dc7718b5ea7fa4619c8b031466297a8d016fd -size 3659 +oid sha256:273043114950e000953fbede780f3ad8adcce9d3d579edea2cad58f8e3c48881 +size 8175 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_6_en.png index 08349f1edb..9144b78743 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba213b12d181b04695b9271670cb7d96ce83dfccc3c2031ee002ba1cf180cc8d -size 6408 +oid sha256:19483b4fae4026098273e6e4c941592074f08b3e7f9fa44e759bdab9daf2b27a +size 26233 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_7_en.png index 1e509dbffd..34963bd636 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dfb80116e111dcc2fff42ea4a6c26e2857eecfbfcdb6a43d09aaaaf63a990fca -size 24019 +oid sha256:0c36a1bfdfdf92ac180436b8c4aef3d017911119f10f02e2a940b5ab242ac324 +size 27856 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_8_en.png index 51ce6077b5..3631712dc9 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9def02bcb5784681dc26327791510a9a25f0772644cdae363d7a4b90e69067c -size 17479 +oid sha256:2b0d51e2c5b255fb2f94959734293d4b7807f002acb0217c84856f0002297293 +size 7636 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialogContent_Dialogs_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialogContent_Dialogs_en.png index c920765764..9c9335b1b2 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialogContent_Dialogs_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialogContent_Dialogs_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24d042c0c4e9f9d01c5937d42cf16d05ad24e2d8cfd8026038126531b8304cd4 -size 30195 +oid sha256:114c59fd334979528721e0409e22096a058f965b0cfb5b7860816590d7c84652 +size 29924 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Day_0_en.png index bce67de223..83dccb1356 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:390153008f59d4915895498d3d6fa3354502f3f3a902b3ae5e53045aec27432d -size 18116 +oid sha256:c5f9152fbdce0823fb728586486e8625f96caceb23b69685680313b62a81c1a8 +size 18073 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Night_0_en.png index 7de5764954..bedc583552 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_ListDialog_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ad10053328a529721e5f6564e493e4d0ea1d9e4e098867f1a4daa938396d712 -size 16273 +oid sha256:1d324a3cf4090c18459f06753d28bee13102457da07ef17358a7d65797df965b +size 16234 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.list_TextFieldListItemWithBorderEmpty_Text_field_List_item_with_border_-_empty_List_items_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.list_TextFieldListItemWithBorderEmpty_Text_field_List_item_with_border_-_empty_List_items_en.png new file mode 100644 index 0000000000..1d1eb1de3a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.list_TextFieldListItemWithBorderEmpty_Text_field_List_item_with_border_-_empty_List_items_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dc297457b140b0bcf72fb3de3e2fd8061983ab70ad2d5299cc5ba85d5a7db55 +size 7270 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.list_TextFieldListItemWithBorder_Text_field_List_item_with_border_-_text_List_items_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.list_TextFieldListItemWithBorder_Text_field_List_item_with_border_-_text_List_items_en.png new file mode 100644 index 0000000000..7e325e90bf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.list_TextFieldListItemWithBorder_Text_field_List_item_with_border_-_text_List_items_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a3648b24b1640410c19eb5ee5c9808c48be5cb2dc0862d84f8419289988fd39 +size 8708 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en.png index 540f1b6ec4..29cc2b7605 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d966380d44d4fdfa87c17135cb540aec7b5e5d9dd433ddb9945d088b46eb76a -size 13485 +oid sha256:f4393abc83861f1ab67e0637d7192887c31d94ecad9642691bcfe87e68df3a42 +size 13422 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en.png index 74852be96b..3a063e589a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:808978903883f938d08c594c9a87f97774f9a0c11847088a623e199809882adb -size 11916 +oid sha256:57c8c7fa3b993fc52c3fbc2014252e8fff1395f855d6f4acd1681d843eedf2c0 +size 11825 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en.png index ae450922c0..602069b0e1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce993fc311dd889c5a709941cec6224af603f3e9db62c02eda36adcb43d9c8d2 -size 14697 +oid sha256:57d2c9529a6cef0b9a009710645f92d50f93563f4f765994f6f006ef4db1d5c4 +size 14684 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en.png index d4209f72ff..47a56348f4 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e256f644dd8cbb96d0d97c0f41e036f41f137cd09e322da9807ad7271943a6a -size 12999 +oid sha256:a43a5ebccf177014e2d7726e9a0f0cf4970252b7301843b98c5ae7e72dc34aee +size 12955