Reworking the deletion dialogs

We removed the 'delete locally' dialog, instead we show the 'delete for everyone' with the second option disabled
pull/1518/head
ThomasSession 7 months ago
parent 31919ee9e5
commit 011efde187

@ -1,23 +1,25 @@
package org.thoughtcrime.securesms.conversation.v2 package org.thoughtcrime.securesms.conversation.v2
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.HideDeleteAllDevicesDialog import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.HideDeleteAllDevicesDialog
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.HideDeleteDeviceOnlyDialog
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.HideDeleteEveryoneDialog import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.HideDeleteEveryoneDialog
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.MarkAsDeletedForEveryone import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.MarkAsDeletedForEveryone
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.MarkAsDeletedLocally import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.MarkAsDeletedLocally
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.ShowOpenUrlDialog import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.ShowOpenUrlDialog
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.DeleteForEveryoneMessageType.NoteToSelf
import org.thoughtcrime.securesms.ui.AlertDialog import org.thoughtcrime.securesms.ui.AlertDialog
import org.thoughtcrime.securesms.ui.DialogButtonModel import org.thoughtcrime.securesms.ui.DialogButtonModel
import org.thoughtcrime.securesms.ui.GetString import org.thoughtcrime.securesms.ui.GetString
@ -26,6 +28,7 @@ import org.thoughtcrime.securesms.ui.RadioOption
import org.thoughtcrime.securesms.ui.components.TitledRadioButton import org.thoughtcrime.securesms.ui.components.TitledRadioButton
import org.thoughtcrime.securesms.ui.theme.LocalColors import org.thoughtcrime.securesms.ui.theme.LocalColors
import org.thoughtcrime.securesms.ui.theme.LocalDimensions import org.thoughtcrime.securesms.ui.theme.LocalDimensions
import org.thoughtcrime.securesms.ui.theme.LocalType
import org.thoughtcrime.securesms.ui.theme.PreviewTheme import org.thoughtcrime.securesms.ui.theme.PreviewTheme
import org.thoughtcrime.securesms.ui.theme.SessionMaterialTheme import org.thoughtcrime.securesms.ui.theme.SessionMaterialTheme
@ -46,34 +49,6 @@ fun ConversationV2Dialogs(
) )
} }
// delete message(s) on device only
if(dialogsState.deleteDeviceOnly != null){
AlertDialog(
onDismissRequest = {
// hide dialog
sendCommand(HideDeleteDeviceOnlyDialog)
},
title = pluralStringResource(
R.plurals.deleteMessage,
dialogsState.deleteDeviceOnly.size,
dialogsState.deleteDeviceOnly.size
),
text = stringResource(R.string.deleteMessageDescriptionDevice), //todo DELETION we need the plural version of this here, which currently is not set up in strings
buttons = listOf(
DialogButtonModel(
text = GetString(stringResource(id = R.string.delete)),
color = LocalColors.current.danger,
onClick = {
sendCommand(MarkAsDeletedLocally(dialogsState.deleteDeviceOnly))
}
),
DialogButtonModel(
GetString(stringResource(R.string.cancel))
)
)
)
}
// delete message(s) for everyone // delete message(s) for everyone
if(dialogsState.deleteEveryone != null){ if(dialogsState.deleteEveryone != null){
var deleteForEveryone by remember { mutableStateOf(dialogsState.deleteEveryone.defaultToEveryone)} var deleteForEveryone by remember { mutableStateOf(dialogsState.deleteEveryone.defaultToEveryone)}
@ -90,6 +65,21 @@ fun ConversationV2Dialogs(
), ),
text = stringResource(R.string.deleteMessageConfirm), //todo DELETION we need the plural version of this here, which currently is not set up in strings text = stringResource(R.string.deleteMessageConfirm), //todo DELETION we need the plural version of this here, which currently is not set up in strings
content = { content = {
// add warning text, if any
dialogsState.deleteEveryone.warning?.let {
//todo DELETION confirm styling once finalised
Text(
text = it,
textAlign = TextAlign.Center,
style = LocalType.current.small,
color = LocalColors.current.warning,
modifier = Modifier.padding(
top = LocalDimensions.current.xxxsSpacing,
bottom = LocalDimensions.current.xxsSpacing
)
)
}
TitledRadioButton( TitledRadioButton(
contentPadding = PaddingValues( contentPadding = PaddingValues(
horizontal = LocalDimensions.current.xxsSpacing, horizontal = LocalDimensions.current.xxsSpacing,
@ -112,7 +102,8 @@ fun ConversationV2Dialogs(
option = RadioOption( option = RadioOption(
value = Unit, value = Unit,
title = GetString(stringResource(R.string.deleteMessageEveryone)), title = GetString(stringResource(R.string.deleteMessageEveryone)),
selected = deleteForEveryone selected = deleteForEveryone,
enabled = dialogsState.deleteEveryone.everyoneEnabled
) )
) { ) {
deleteForEveryone = true deleteForEveryone = true

@ -233,8 +233,6 @@ class ConversationViewModel(
return return
} }
// Refer to our figma document for info on message deletion [https://www.figma.com/design/kau6LggVcMMWmZRMibEo8F/Standardise-Message-Deletion?node-id=0-1&t=dEPcU0SZ9G2s4gh2-0]
//todo DELETION handle multi select scenarios //todo DELETION handle multi select scenarios
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
@ -258,10 +256,11 @@ class ConversationViewModel(
conversationType == MessageType.NOTE_TO_SELF -> { conversationType == MessageType.NOTE_TO_SELF -> {
_dialogsState.update { _dialogsState.update {
it.copy(deleteAllDevices = DeleteForEveryoneDialogData( it.copy(deleteAllDevices = DeleteForEveryoneDialogData(
messages = messages, messages = messages,
defaultToEveryone = false, defaultToEveryone = false,
messageType = DeleteForEveryoneMessageType.NoteToSelf everyoneEnabled = true,
) messageType = conversationType
)
) )
} }
} }
@ -273,13 +272,8 @@ class ConversationViewModel(
deleteEveryone = DeleteForEveryoneDialogData( deleteEveryone = DeleteForEveryoneDialogData(
messages = messages, messages = messages,
defaultToEveryone = isAdmin.value, defaultToEveryone = isAdmin.value,
messageType = when{ everyoneEnabled = true,
conversation.isLocalNumber -> DeleteForEveryoneMessageType.NoteToSelf messageType = conversationType
conversation.isCommunityRecipient -> DeleteForEveryoneMessageType.Community
conversation.isClosedGroupRecipient -> DeleteForEveryoneMessageType.LegacyGroup //todo GROUPS V2 this property will change for groups v2. Check for legacyGroup here
//conversation.isClosedGroup -> DeleteForEveryoneMessageType.GroupV2(isAdmin) //todo GROUPS V2 properly check for GroupV2 type here once available
else -> DeleteForEveryoneMessageType.OneOnOne
}
) )
) )
} }
@ -288,7 +282,15 @@ class ConversationViewModel(
// for non admins, users interacting with someone else's message, or control messages // for non admins, users interacting with someone else's message, or control messages
else -> { else -> {
_dialogsState.update { _dialogsState.update {
it.copy(deleteDeviceOnly = messages) it.copy(
deleteEveryone = DeleteForEveryoneDialogData(
messages = messages,
defaultToEveryone = false,
everyoneEnabled = false, // disable 'delete for everyone' - can only delete locally in this case
messageType = conversationType,
warning = "Some of the messages you have selected cannot be deleted for everyone" //todo DELETION get real string from res once available
)
)
} }
} }
} }
@ -347,11 +349,11 @@ class ConversationViewModel(
// the exact logic for this will depend on the messages type // the exact logic for this will depend on the messages type
when(data.messageType){ when(data.messageType){
is DeleteForEveryoneMessageType.NoteToSelf -> markAsDeletedForEveryoneNoteToSelf(data) MessageType.NOTE_TO_SELF -> markAsDeletedForEveryoneNoteToSelf(data)
is DeleteForEveryoneMessageType.OneOnOne -> markAsDeletedForEveryone1On1(data) MessageType.ONE_ON_ONE -> markAsDeletedForEveryone1On1(data)
is DeleteForEveryoneMessageType.LegacyGroup -> markAsDeletedForEveryoneLegacyGroup(data.messages) MessageType.LEGACY_GROUP -> markAsDeletedForEveryoneLegacyGroup(data.messages)
is DeleteForEveryoneMessageType.GroupV2 -> markAsDeletedForEveryoneGroupsV2(data) MessageType.GROUPS_V2 -> markAsDeletedForEveryoneGroupsV2(data)
is DeleteForEveryoneMessageType.Community -> markAsDeletedForEveryoneCommunity(data) MessageType.COMMUNITY -> markAsDeletedForEveryoneCommunity(data)
} }
} }
@ -708,12 +710,6 @@ class ConversationViewModel(
} }
} }
is Commands.HideDeleteDeviceOnlyDialog -> {
_dialogsState.update {
it.copy(deleteDeviceOnly = null)
}
}
is Commands.HideDeleteEveryoneDialog -> { is Commands.HideDeleteEveryoneDialog -> {
_dialogsState.update { _dialogsState.update {
it.copy(deleteEveryone = null) it.copy(deleteEveryone = null)
@ -729,7 +725,7 @@ class ConversationViewModel(
is Commands.MarkAsDeletedLocally -> { is Commands.MarkAsDeletedLocally -> {
// hide dialog first // hide dialog first
_dialogsState.update { _dialogsState.update {
it.copy(deleteDeviceOnly = null) it.copy(deleteEveryone = null)
} }
deleteLocally(command.messages) deleteLocally(command.messages)
@ -773,28 +769,20 @@ class ConversationViewModel(
data class DialogsState( data class DialogsState(
val openLinkDialogUrl: String? = null, val openLinkDialogUrl: String? = null,
val deleteDeviceOnly: Set<MessageRecord>? = null,
val deleteEveryone: DeleteForEveryoneDialogData? = null, val deleteEveryone: DeleteForEveryoneDialogData? = null,
val deleteAllDevices: DeleteForEveryoneDialogData? = null, val deleteAllDevices: DeleteForEveryoneDialogData? = null,
) )
data class DeleteForEveryoneDialogData( data class DeleteForEveryoneDialogData(
val messages: Set<MessageRecord>, val messages: Set<MessageRecord>,
val messageType: DeleteForEveryoneMessageType, val messageType: MessageType,
val defaultToEveryone: Boolean val defaultToEveryone: Boolean,
val everyoneEnabled: Boolean,
val warning: String? = null
) )
sealed class DeleteForEveryoneMessageType {
data object NoteToSelf: DeleteForEveryoneMessageType()
data object OneOnOne: DeleteForEveryoneMessageType()
data object LegacyGroup: DeleteForEveryoneMessageType()
data object GroupV2: DeleteForEveryoneMessageType()
data object Community: DeleteForEveryoneMessageType()
}
sealed class Commands { sealed class Commands {
data class ShowOpenUrlDialog(val url: String?) : Commands() data class ShowOpenUrlDialog(val url: String?) : Commands()
data object HideDeleteDeviceOnlyDialog : Commands()
data object HideDeleteEveryoneDialog : Commands() data object HideDeleteEveryoneDialog : Commands()
data object HideDeleteAllDevicesDialog : Commands() data object HideDeleteAllDevicesDialog : Commands()

@ -19,6 +19,7 @@ interface ThemeColors {
val isLight: Boolean val isLight: Boolean
val primary: Color val primary: Color
val danger: Color val danger: Color
val warning: Color
val disabled: Color val disabled: Color
val background: Color val background: Color
val backgroundSecondary: Color val backgroundSecondary: Color
@ -100,6 +101,7 @@ fun dangerButtonColors() = ButtonDefaults.buttonColors(
data class ClassicDark(override val primary: Color = primaryGreen) : ThemeColors { data class ClassicDark(override val primary: Color = primaryGreen) : ThemeColors {
override val isLight = false override val isLight = false
override val danger = dangerDark override val danger = dangerDark
override val warning = primaryOrange
override val disabled = disabledDark override val disabled = disabledDark
override val background = classicDark0 override val background = classicDark0
override val backgroundSecondary = classicDark1 override val backgroundSecondary = classicDark1
@ -118,6 +120,7 @@ data class ClassicDark(override val primary: Color = primaryGreen) : ThemeColors
data class ClassicLight(override val primary: Color = primaryGreen) : ThemeColors { data class ClassicLight(override val primary: Color = primaryGreen) : ThemeColors {
override val isLight = true override val isLight = true
override val danger = dangerLight override val danger = dangerLight
override val warning = primaryOrange
override val disabled = disabledLight override val disabled = disabledLight
override val background = classicLight6 override val background = classicLight6
override val backgroundSecondary = classicLight5 override val backgroundSecondary = classicLight5
@ -136,6 +139,7 @@ data class ClassicLight(override val primary: Color = primaryGreen) : ThemeColor
data class OceanDark(override val primary: Color = primaryBlue) : ThemeColors { data class OceanDark(override val primary: Color = primaryBlue) : ThemeColors {
override val isLight = false override val isLight = false
override val danger = dangerDark override val danger = dangerDark
override val warning = primaryOrange
override val disabled = disabledDark override val disabled = disabledDark
override val background = oceanDark2 override val background = oceanDark2
override val backgroundSecondary = oceanDark1 override val backgroundSecondary = oceanDark1
@ -154,6 +158,7 @@ data class OceanDark(override val primary: Color = primaryBlue) : ThemeColors {
data class OceanLight(override val primary: Color = primaryBlue) : ThemeColors { data class OceanLight(override val primary: Color = primaryBlue) : ThemeColors {
override val isLight = true override val isLight = true
override val danger = dangerLight override val danger = dangerLight
override val warning = primaryOrange
override val disabled = disabledLight override val disabled = disabledLight
override val background = oceanLight7 override val background = oceanLight7
override val backgroundSecondary = oceanLight6 override val backgroundSecondary = oceanLight6

Loading…
Cancel
Save