Replace 'leave room' text with 'leave conversation' for DMs (#2231)
* Replace 'leave room' text with 'leave conversation' for DMs * Add `isDm` property to both `RoomSummary` and `RoomListRoomSummary` * Remove redundant `leave_conversation_alert_subtitle_*` texts * Fix maestro flow --------- Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
committed by
GitHub
parent
a9776f9fcb
commit
64a18afc1b
@@ -9,5 +9,5 @@ appId: ${APP_ID}
|
||||
index: 1
|
||||
- takeScreenshot: build/maestro/330-createAndDeleteDM
|
||||
- tapOn: "maestroelement2"
|
||||
- tapOn: "Leave room"
|
||||
- tapOn: "Leave conversation"
|
||||
- tapOn: "Leave"
|
||||
|
||||
1
changelog.d/2218.misc
Normal file
1
changelog.d/2218.misc
Normal file
@@ -0,0 +1 @@
|
||||
Replace 'leave room' text with 'leave conversation' for DMs.
|
||||
@@ -26,6 +26,7 @@ data class LeaveRoomState(
|
||||
) {
|
||||
sealed interface Confirmation {
|
||||
data object Hidden : Confirmation
|
||||
data class Dm(val roomId: RoomId) : Confirmation
|
||||
data class Generic(val roomId: RoomId) : Confirmation
|
||||
data class PrivateRoom(val roomId: RoomId) : Confirmation
|
||||
data class LastUserInRoom(val roomId: RoomId) : Confirmation
|
||||
|
||||
@@ -28,17 +28,17 @@ class LeaveRoomStateProvider : PreviewParameterProvider<LeaveRoomState> {
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.Generic(A_ROOM_ID),
|
||||
confirmation = LeaveRoomState.Confirmation.Generic(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.PrivateRoom(A_ROOM_ID),
|
||||
confirmation = LeaveRoomState.Confirmation.PrivateRoom(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.LastUserInRoom(A_ROOM_ID),
|
||||
confirmation = LeaveRoomState.Confirmation.LastUserInRoom(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
@@ -52,6 +52,11 @@ class LeaveRoomStateProvider : PreviewParameterProvider<LeaveRoomState> {
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Shown,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.Dm(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -47,21 +47,32 @@ private fun LeaveRoomConfirmationDialog(
|
||||
) {
|
||||
when (state.confirmation) {
|
||||
is LeaveRoomState.Confirmation.Hidden -> {}
|
||||
|
||||
is LeaveRoomState.Confirmation.Dm -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_conversation_alert_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = true,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
|
||||
is LeaveRoomState.Confirmation.PrivateRoom -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_room_alert_private_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = false,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
|
||||
is LeaveRoomState.Confirmation.LastUserInRoom -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_room_alert_empty_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = false,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
|
||||
is LeaveRoomState.Confirmation.Generic -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_room_alert_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = false,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
}
|
||||
@@ -71,10 +82,11 @@ private fun LeaveRoomConfirmationDialog(
|
||||
private fun LeaveRoomConfirmationDialog(
|
||||
@StringRes text: Int,
|
||||
roomId: RoomId,
|
||||
isDm: Boolean,
|
||||
eventSink: (LeaveRoomEvent) -> Unit,
|
||||
) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(CommonStrings.action_leave_room),
|
||||
title = stringResource(if (isDm) CommonStrings.action_leave_conversation else CommonStrings.action_leave_room),
|
||||
content = stringResource(text),
|
||||
submitText = stringResource(CommonStrings.action_leave),
|
||||
onSubmitClicked = { eventSink(LeaveRoomEvent.LeaveRoom(roomId)) },
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="leave_conversation_alert_subtitle">"Are you sure that you want to leave this conversation? This conversation is not public and you won\'t be able to rejoin without an invite."</string>
|
||||
<string name="leave_room_alert_empty_subtitle">"Are you sure that you want to leave this room? You\'re the only person here. If you leave, no one will be able to join in the future, including you."</string>
|
||||
<string name="leave_room_alert_private_subtitle">"Are you sure that you want to leave this room? This room is not public and you won\'t be able to rejoin without an invite."</string>
|
||||
<string name="leave_room_alert_subtitle">"Are you sure that you want to leave the room?"</string>
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomEvent
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomState
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomState.Confirmation.Dm
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomState.Confirmation.Generic
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomState.Confirmation.LastUserInRoom
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomState.Confirmation.PrivateRoom
|
||||
@@ -85,6 +86,7 @@ private suspend fun showLeaveRoomAlert(
|
||||
) {
|
||||
matrixClient.getRoom(roomId)?.use { room ->
|
||||
confirmation.value = when {
|
||||
room.isDm -> Dm(roomId)
|
||||
!room.isPublic -> PrivateRoom(roomId)
|
||||
room.joinedMemberCount == 1L -> LastUserInRoom(roomId)
|
||||
else -> Generic(roomId)
|
||||
|
||||
@@ -114,6 +114,26 @@ class LeaveRoomPresenterImplTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - show DM confirmation`() = runTest {
|
||||
val presenter = createLeaveRoomPresenter(
|
||||
client = FakeMatrixClient().apply {
|
||||
givenGetRoomResult(
|
||||
roomId = A_ROOM_ID,
|
||||
result = FakeMatrixRoom(activeMemberCount = 2, isDirect = true, isOneToOne = true),
|
||||
)
|
||||
}
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(LeaveRoomEvent.ShowConfirmation(A_ROOM_ID))
|
||||
val confirmationState = awaitItem()
|
||||
assertThat(confirmationState.confirmation).isEqualTo(LeaveRoomState.Confirmation.Dm(A_ROOM_ID))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - leaving a room leaves the room`() = runTest {
|
||||
val roomMembershipObserver = RoomMembershipObserver()
|
||||
|
||||
@@ -183,9 +183,8 @@ class MessageComposerPresenter @Inject constructor(
|
||||
val currentUserId = currentSessionIdHolder.current
|
||||
|
||||
suspend fun canSendRoomMention(): Boolean {
|
||||
val roomIsDm = room.isDirect && room.isOneToOne
|
||||
val userCanSendAtRoom = room.canUserTriggerRoomNotification(currentUserId).getOrDefault(false)
|
||||
return !roomIsDm && userCanSendAtRoom
|
||||
return !room.isDm && userCanSendAtRoom
|
||||
}
|
||||
|
||||
// This will trigger a search immediately when `@` is typed
|
||||
|
||||
@@ -190,9 +190,10 @@ fun RoomDetailsView(
|
||||
BlockUserDialogs(roomMemberState)
|
||||
}
|
||||
|
||||
OtherActionsSection(onLeaveRoom = {
|
||||
state.eventSink(RoomDetailsEvent.LeaveRoom)
|
||||
})
|
||||
OtherActionsSection(
|
||||
isDm = state.roomType is RoomDetailsType.Dm,
|
||||
onLeaveRoom = { state.eventSink(RoomDetailsEvent.LeaveRoom) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -410,10 +411,17 @@ private fun SecuritySection(modifier: Modifier = Modifier) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun OtherActionsSection(onLeaveRoom: () -> Unit, modifier: Modifier = Modifier) {
|
||||
private fun OtherActionsSection(isDm: Boolean, onLeaveRoom: () -> Unit, modifier: Modifier = Modifier) {
|
||||
PreferenceCategory(showDivider = false, modifier = modifier) {
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_details_leave_room_title)) },
|
||||
headlineContent = {
|
||||
val leaveText = stringResource(id = if (isDm) {
|
||||
R.string.screen_room_details_leave_conversation_title
|
||||
} else {
|
||||
R.string.screen_room_details_leave_room_title
|
||||
})
|
||||
Text(leaveText)
|
||||
},
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Leave)),
|
||||
style = ListItemStyle.Destructive,
|
||||
onClick = onLeaveRoom,
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
<string name="screen_dm_details_unblock_alert_action">"Unblock"</string>
|
||||
<string name="screen_dm_details_unblock_alert_description">"You\'ll be able to see all messages from them again."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Unblock user"</string>
|
||||
<string name="screen_room_details_leave_conversation_title">"Leave conversation"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Leave room"</string>
|
||||
<string name="screen_room_details_security_title">"Security"</string>
|
||||
<string name="screen_room_details_topic_title">"Topic"</string>
|
||||
|
||||
@@ -95,7 +95,14 @@ private fun RoomListModalBottomSheetContent(
|
||||
style = ListItemStyle.Primary,
|
||||
)
|
||||
ListItem(
|
||||
headlineContent = { Text(text = stringResource(id = CommonStrings.action_leave_room)) },
|
||||
headlineContent = {
|
||||
val leaveText = stringResource(id = if (contextMenu.isDm) {
|
||||
CommonStrings.action_leave_conversation
|
||||
} else {
|
||||
CommonStrings.action_leave_room
|
||||
})
|
||||
Text(text = leaveText)
|
||||
},
|
||||
modifier = Modifier.clickable { onLeaveRoomClicked(contextMenu.roomId) },
|
||||
leadingContent = ListItemContent.Icon(
|
||||
iconSource = IconSource.Vector(
|
||||
@@ -117,7 +124,22 @@ internal fun RoomListModalBottomSheetContentPreview() = ElementPreview {
|
||||
RoomListModalBottomSheetContent(
|
||||
contextMenu = RoomListState.ContextMenu.Shown(
|
||||
roomId = RoomId(value = "!aRoom:aDomain"),
|
||||
roomName = "aRoom"
|
||||
roomName = "aRoom",
|
||||
isDm = false,
|
||||
),
|
||||
onRoomSettingsClicked = {},
|
||||
onLeaveRoomClicked = {}
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RoomListModalBottomSheetContentForDmPreview() = ElementPreview {
|
||||
RoomListModalBottomSheetContent(
|
||||
contextMenu = RoomListState.ContextMenu.Shown(
|
||||
roomId = RoomId(value = "!aRoom:aDomain"),
|
||||
roomName = "aRoom",
|
||||
isDm = true,
|
||||
),
|
||||
onRoomSettingsClicked = {},
|
||||
onLeaveRoomClicked = {}
|
||||
|
||||
@@ -119,7 +119,8 @@ class RoomListPresenter @Inject constructor(
|
||||
is RoomListEvents.ShowContextMenu -> {
|
||||
contextMenu = RoomListState.ContextMenu.Shown(
|
||||
roomId = event.roomListRoomSummary.roomId,
|
||||
roomName = event.roomListRoomSummary.name
|
||||
roomName = event.roomListRoomSummary.name,
|
||||
isDm = event.roomListRoomSummary.isDm,
|
||||
)
|
||||
}
|
||||
is RoomListEvents.HideContextMenu -> contextMenu = RoomListState.ContextMenu.Hidden
|
||||
|
||||
@@ -46,6 +46,7 @@ data class RoomListState(
|
||||
data class Shown(
|
||||
val roomId: RoomId,
|
||||
val roomName: String,
|
||||
val isDm: Boolean,
|
||||
) : ContextMenu
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
|
||||
aRoomListState().copy(
|
||||
contextMenu = RoomListState.ContextMenu.Shown(
|
||||
roomId = RoomId("!aRoom:aDomain"),
|
||||
roomName = "A nice room name"
|
||||
roomName = "A nice room name",
|
||||
isDm = false,
|
||||
)
|
||||
),
|
||||
aRoomListState().copy(displayRecoveryKeyPrompt = true),
|
||||
|
||||
@@ -162,6 +162,7 @@ class RoomListDataSource @Inject constructor(
|
||||
avatarData = avatarData,
|
||||
notificationMode = roomSummary.details.notificationMode,
|
||||
hasOngoingCall = roomSummary.details.hasOngoingCall,
|
||||
isDm = roomSummary.details.isDm,
|
||||
)
|
||||
}
|
||||
null -> null
|
||||
|
||||
@@ -34,4 +34,5 @@ data class RoomListRoomSummary(
|
||||
val isPlaceholder: Boolean = false,
|
||||
val notificationMode: RoomNotificationMode? = null,
|
||||
val hasOngoingCall: Boolean = false,
|
||||
val isDm: Boolean = false,
|
||||
)
|
||||
|
||||
@@ -321,7 +321,7 @@ class RoomListPresenterTests {
|
||||
|
||||
val shownState = awaitItem()
|
||||
assertThat(shownState.contextMenu)
|
||||
.isEqualTo(RoomListState.ContextMenu.Shown(summary.roomId, summary.name))
|
||||
.isEqualTo(RoomListState.ContextMenu.Shown(summary.roomId, summary.name, false))
|
||||
scope.cancel()
|
||||
}
|
||||
}
|
||||
@@ -341,7 +341,7 @@ class RoomListPresenterTests {
|
||||
|
||||
val shownState = awaitItem()
|
||||
assertThat(shownState.contextMenu)
|
||||
.isEqualTo(RoomListState.ContextMenu.Shown(summary.roomId, summary.name))
|
||||
.isEqualTo(RoomListState.ContextMenu.Shown(summary.roomId, summary.name, false))
|
||||
shownState.eventSink(RoomListEvents.HideContextMenu)
|
||||
|
||||
val hiddenState = awaitItem()
|
||||
|
||||
@@ -52,6 +52,9 @@ interface MatrixRoom : Closeable {
|
||||
val activeMemberCount: Long
|
||||
val joinedMemberCount: Long
|
||||
|
||||
/** Whether the room is a direct message. */
|
||||
val isDm: Boolean get() = isDirect && isOneToOne
|
||||
|
||||
val roomInfoFlow: Flow<MatrixRoomInfo>
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,4 +45,5 @@ data class RoomSummaryDetails(
|
||||
val inviter: RoomMember? = null,
|
||||
val notificationMode: RoomNotificationMode? = null,
|
||||
val hasOngoingCall: Boolean = false,
|
||||
val isDm: Boolean = false,
|
||||
)
|
||||
|
||||
@@ -41,6 +41,7 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto
|
||||
inviter = roomInfo.inviter?.let(RoomMemberMapper::map),
|
||||
notificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode),
|
||||
hasOngoingCall = roomInfo.hasRoomCall,
|
||||
isDm = roomInfo.isDirect && roomInfo.activeMembersCount.toLong() == 2L,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
<string name="action_join">"Join"</string>
|
||||
<string name="action_learn_more">"Learn more"</string>
|
||||
<string name="action_leave">"Leave"</string>
|
||||
<string name="action_leave_conversation">"Leave conversation"</string>
|
||||
<string name="action_leave_room">"Leave room"</string>
|
||||
<string name="action_manage_account">"Manage account"</string>
|
||||
<string name="action_manage_devices">"Manage devices"</string>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -97,7 +97,8 @@
|
||||
{
|
||||
"name" : ":features:leaveroom:api",
|
||||
"includeRegex" : [
|
||||
"leave_room_alert_.*"
|
||||
"leave_room_alert_.*",
|
||||
"leave_conversation_alert_.*"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user