Recreating xml dialogs in Compose and moved logic in VM
parent
f73e022cfd
commit
ed38e507ae
@ -0,0 +1,217 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.squareup.phrase.Phrase
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ExpiryType
|
||||
import org.thoughtcrime.securesms.ui.OpenURLAlertDialog
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionMaterialTheme
|
||||
import org.thoughtcrime.securesms.conversation.v2.ConversationViewModel.Commands.*
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.ui.AlertDialog
|
||||
import org.thoughtcrime.securesms.ui.DialogButtonModel
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.RadioOption
|
||||
import org.thoughtcrime.securesms.ui.components.TitledRadioButton
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
@Composable
|
||||
fun ConversationV2Dialogs(
|
||||
dialogsState: ConversationViewModel.DialogsState,
|
||||
sendCommand: (ConversationViewModel.Commands) -> Unit
|
||||
){
|
||||
SessionMaterialTheme {
|
||||
// open link confirmation
|
||||
if(!dialogsState.openLinkDialogUrl.isNullOrEmpty()){
|
||||
OpenURLAlertDialog(
|
||||
url = dialogsState.openLinkDialogUrl,
|
||||
onDismissRequest = {
|
||||
// hide dialog
|
||||
sendCommand(ShowOpenUrlDialog(null))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 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
|
||||
if(dialogsState.deleteEveryone != null){
|
||||
var deleteForEveryone by remember { mutableStateOf(dialogsState.deleteEveryone.defaultToEveryone)}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
// hide dialog
|
||||
sendCommand(HideDeleteEveryoneDialog)
|
||||
},
|
||||
title = pluralStringResource(
|
||||
R.plurals.deleteMessage,
|
||||
dialogsState.deleteEveryone.messages.size,
|
||||
dialogsState.deleteEveryone.messages.size
|
||||
),
|
||||
text = stringResource(R.string.deleteMessageConfirm), //todo DELETION we need the plural version of this here, which currently is not set up in strings
|
||||
content = {
|
||||
TitledRadioButton(
|
||||
contentPadding = PaddingValues(
|
||||
horizontal = LocalDimensions.current.xxsSpacing,
|
||||
vertical = 0.dp
|
||||
),
|
||||
option = RadioOption(
|
||||
value = Unit,
|
||||
title = GetString(stringResource(R.string.deleteMessageDeviceOnly)),
|
||||
selected = !deleteForEveryone
|
||||
)
|
||||
) {
|
||||
deleteForEveryone = false
|
||||
}
|
||||
|
||||
TitledRadioButton(
|
||||
contentPadding = PaddingValues(
|
||||
horizontal = LocalDimensions.current.xxsSpacing,
|
||||
vertical = 0.dp
|
||||
),
|
||||
option = RadioOption(
|
||||
value = Unit,
|
||||
title = GetString(stringResource(R.string.deleteMessageEveryone)),
|
||||
selected = deleteForEveryone
|
||||
)
|
||||
) {
|
||||
deleteForEveryone = true
|
||||
}
|
||||
},
|
||||
buttons = listOf(
|
||||
DialogButtonModel(
|
||||
text = GetString(stringResource(id = R.string.delete)),
|
||||
color = LocalColors.current.danger,
|
||||
onClick = {
|
||||
// delete messages based on chosen option
|
||||
sendCommand(
|
||||
if(deleteForEveryone) MarkAsDeletedForEveryone(dialogsState.deleteEveryone.messages)
|
||||
else MarkAsDeletedLocally(dialogsState.deleteEveryone.messages)
|
||||
)
|
||||
}
|
||||
),
|
||||
DialogButtonModel(
|
||||
GetString(stringResource(R.string.cancel))
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// delete message(s) for all my devices
|
||||
if(dialogsState.deleteAllDevices != null){
|
||||
var deleteAllDevices by remember { mutableStateOf(false) }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
// hide dialog
|
||||
sendCommand(HideDeleteAllDevicesDialog)
|
||||
},
|
||||
title = pluralStringResource(
|
||||
R.plurals.deleteMessage,
|
||||
dialogsState.deleteAllDevices.size,
|
||||
dialogsState.deleteAllDevices.size
|
||||
),
|
||||
text = stringResource(R.string.deleteMessageConfirm), //todo DELETION we need the plural version of this here, which currently is not set up in strings
|
||||
content = {
|
||||
TitledRadioButton(
|
||||
contentPadding = PaddingValues(
|
||||
horizontal = LocalDimensions.current.xxsSpacing,
|
||||
vertical = 0.dp
|
||||
),
|
||||
option = RadioOption(
|
||||
value = Unit,
|
||||
title = GetString(stringResource(R.string.deleteMessageDeviceOnly)),
|
||||
selected = !deleteAllDevices
|
||||
)
|
||||
) {
|
||||
deleteAllDevices = false
|
||||
}
|
||||
|
||||
TitledRadioButton(
|
||||
contentPadding = PaddingValues(
|
||||
horizontal = LocalDimensions.current.xxsSpacing,
|
||||
vertical = 0.dp
|
||||
),
|
||||
option = RadioOption(
|
||||
value = Unit,
|
||||
title = GetString(stringResource(R.string.deleteMessageDevicesAll)),
|
||||
selected = deleteAllDevices
|
||||
)
|
||||
) {
|
||||
deleteAllDevices = true
|
||||
}
|
||||
},
|
||||
buttons = listOf(
|
||||
DialogButtonModel(
|
||||
text = GetString(stringResource(id = R.string.delete)),
|
||||
color = LocalColors.current.danger,
|
||||
onClick = {
|
||||
// delete messages based on chosen option
|
||||
sendCommand(
|
||||
if(deleteAllDevices) MarkAsDeletedForEveryone(dialogsState.deleteAllDevices)
|
||||
else MarkAsDeletedLocally(dialogsState.deleteAllDevices)
|
||||
)
|
||||
}
|
||||
),
|
||||
DialogButtonModel(
|
||||
GetString(stringResource(R.string.cancel))
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewURLDialog(){
|
||||
PreviewTheme {
|
||||
ConversationV2Dialogs(
|
||||
dialogsState = ConversationViewModel.DialogsState(
|
||||
openLinkDialogUrl = "https://google.com"
|
||||
),
|
||||
sendCommand = {}
|
||||
)
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
|
||||
/**
|
||||
* Shown when deleting a message can only be deleted locally
|
||||
*
|
||||
* @param messageCount The number of messages to be deleted.
|
||||
* @param onDeleteDeviceOnly Callback to be executed when the user chooses to delete only on their device.
|
||||
* @param onCancel Callback to be executed when cancelling the dialog.
|
||||
*/
|
||||
class DeleteMessageDeviceOnlyDialog(
|
||||
private val messageCount: Int,
|
||||
private val onDeleteDeviceOnly: () -> Unit,
|
||||
private val onCancel: () -> Unit
|
||||
) : DialogFragment() {
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
val typedValue = TypedValue()
|
||||
val theme = context.theme
|
||||
theme.resolveAttribute(R.attr.danger, typedValue, true)
|
||||
@ColorInt val deleteColor = typedValue.data
|
||||
|
||||
title(resources.getQuantityString(R.plurals.deleteMessage, messageCount, messageCount))
|
||||
text(resources.getString(R.string.deleteMessageDescriptionDevice)) //todo DELETION we need the plural version of this here, which currently is not set up in strings
|
||||
button(
|
||||
text = R.string.delete,
|
||||
textColor = deleteColor,
|
||||
listener = onDeleteDeviceOnly
|
||||
)
|
||||
cancelButton(onCancel)
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
|
||||
/**
|
||||
* Shown when deleting a message that can be removed both locally and for everyone
|
||||
*
|
||||
* @param messageCount The number of messages to be deleted.
|
||||
* @param defaultToEveryone Whether the dialog should default to deleting for everyone.
|
||||
* @param onDeleteDeviceOnly Callback to be executed when the user chooses to delete only on their device.
|
||||
* @param onDeleteForEveryone Callback to be executed when the user chooses to delete for everyone.
|
||||
* @param onCancel Callback to be executed when cancelling the dialog.
|
||||
*/
|
||||
class DeleteMessageDialog(
|
||||
private val messageCount: Int,
|
||||
private val defaultToEveryone: Boolean,
|
||||
private val onDeleteDeviceOnly: () -> Unit,
|
||||
private val onDeleteForEveryone: () -> Unit,
|
||||
private val onCancel: () -> Unit
|
||||
) : DialogFragment() {
|
||||
|
||||
// tracking the user choice from the radio buttons
|
||||
private var deleteForEveryone = defaultToEveryone
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
val typedValue = TypedValue()
|
||||
val theme = context.theme
|
||||
theme.resolveAttribute(R.attr.danger, typedValue, true)
|
||||
@ColorInt val deleteColor = typedValue.data
|
||||
|
||||
title(resources.getQuantityString(R.plurals.deleteMessage, messageCount, messageCount))
|
||||
text(resources.getString(R.string.deleteMessageConfirm)) //todo DELETION we need the plural version of this here, which currently is not set up in strings
|
||||
singleChoiceItems(
|
||||
options = deleteOptions.map { it.label },
|
||||
currentSelected = if (defaultToEveryone) 1 else 0, // some cases require the second option, "delete for everyone", to be the default selected
|
||||
dismissOnRadioSelect = false
|
||||
) { index ->
|
||||
deleteForEveryone = (deleteOptions[index] is DeleteOption.DeleteForEveryone) // we delete for everyone if the selected index is 1
|
||||
}
|
||||
button(
|
||||
text = R.string.delete,
|
||||
textColor = deleteColor,
|
||||
listener = {
|
||||
if (deleteForEveryone) {
|
||||
onDeleteForEveryone()
|
||||
} else {
|
||||
onDeleteDeviceOnly()
|
||||
}
|
||||
}
|
||||
)
|
||||
cancelButton(onCancel)
|
||||
}
|
||||
|
||||
private val deleteOptions: List<DeleteOption> by lazy {
|
||||
listOf(
|
||||
DeleteOption.DeleteDeviceOnly(requireContext()), DeleteOption.DeleteForEveryone(requireContext())
|
||||
)
|
||||
}
|
||||
|
||||
private sealed class DeleteOption(
|
||||
open val label: String
|
||||
){
|
||||
data class DeleteDeviceOnly(
|
||||
val context: Context,
|
||||
override val label: String = context.getString(R.string.deleteMessageDeviceOnly),
|
||||
): DeleteOption(label)
|
||||
|
||||
data class DeleteForEveryone(
|
||||
val context: Context,
|
||||
override val label: String = context.getString(R.string.deleteMessageEveryone),
|
||||
): DeleteOption(label)
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.createSessionDialog
|
||||
|
||||
/**
|
||||
* Shown when deleting a 'note to self'
|
||||
*
|
||||
* @param messageCount The number of messages to be deleted.
|
||||
* @param onDeleteDeviceOnly Callback to be executed when the user chooses to delete only on their device.
|
||||
* @param onDeleteAllDevices Callback to be executed when the user chooses to delete for everyone.
|
||||
* @param onCancel Callback to be executed when cancelling the dialog.
|
||||
*/
|
||||
class DeleteNoteToSelfDialog(
|
||||
private val messageCount: Int,
|
||||
private val onDeleteDeviceOnly: () -> Unit,
|
||||
private val onDeleteAllDevices: () -> Unit,
|
||||
private val onCancel: () -> Unit
|
||||
) : DialogFragment() {
|
||||
|
||||
// tracking the user choice from the radio buttons
|
||||
private var deleteOnAllDevices = false
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog {
|
||||
val typedValue = TypedValue()
|
||||
val theme = context.theme
|
||||
theme.resolveAttribute(R.attr.danger, typedValue, true)
|
||||
@ColorInt val deleteColor = typedValue.data
|
||||
|
||||
title(resources.getQuantityString(R.plurals.deleteMessage, messageCount, messageCount))
|
||||
text(resources.getString(R.string.deleteMessageConfirm)) //todo DELETION we need the plural version of this here, which currently is not set up in strings
|
||||
singleChoiceItems(
|
||||
options = deleteOptions.map { it.label },
|
||||
currentSelected = 0,
|
||||
dismissOnRadioSelect = false
|
||||
) { index ->
|
||||
deleteOnAllDevices = (deleteOptions[index] is DeleteOption.DeleteOnAllMyDevices) // we delete for everyone if the selected index is 1
|
||||
}
|
||||
button(
|
||||
text = R.string.delete,
|
||||
textColor = deleteColor,
|
||||
listener = {
|
||||
if (deleteOnAllDevices) {
|
||||
onDeleteAllDevices()
|
||||
} else {
|
||||
onDeleteDeviceOnly()
|
||||
}
|
||||
}
|
||||
)
|
||||
cancelButton(onCancel)
|
||||
}
|
||||
|
||||
private val deleteOptions: List<DeleteOption> by lazy {
|
||||
listOf(
|
||||
DeleteOption.DeleteDeviceOnly(requireContext()), DeleteOption.DeleteOnAllMyDevices(requireContext())
|
||||
)
|
||||
}
|
||||
|
||||
private sealed class DeleteOption(
|
||||
open val label: String
|
||||
){
|
||||
data class DeleteDeviceOnly(
|
||||
val context: Context,
|
||||
override val label: String = context.getString(R.string.deleteMessageDeviceOnly),
|
||||
): DeleteOption(label)
|
||||
|
||||
data class DeleteOnAllMyDevices(
|
||||
val context: Context,
|
||||
override val label: String = context.getString(R.string.deleteMessageDevicesAll),
|
||||
): DeleteOption(label)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue