diff options
| author | Kalle Lindström <karl.lindstrom@mullvad.net> | 2024-10-08 15:15:34 +0200 |
|---|---|---|
| committer | Kalle Lindström <karl.lindstrom@mullvad.net> | 2024-10-09 11:44:01 +0200 |
| commit | 4eba8ab50cf08cd1375fb6e8450964c3fb978038 (patch) | |
| tree | 504de69a69646bbea6551711e6e43fda20927b24 | |
| parent | e2cf73ad94dfaabb517090364c204e3f388bcca1 (diff) | |
| download | mullvadvpn-4eba8ab50cf08cd1375fb6e8450964c3fb978038.tar.xz mullvadvpn-4eba8ab50cf08cd1375fb6e8450964c3fb978038.zip | |
Create info confirm dialog base component
3 files changed, 185 insertions, 95 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DaitaConfirmationDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DaitaConfirmationDialog.kt index a79398897a..b79814746c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DaitaConfirmationDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DaitaConfirmationDialog.kt @@ -1,35 +1,24 @@ package net.mullvad.mullvadvpn.compose.dialog -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Error -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.lifecycle.compose.dropUnlessResumed import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph import com.ramcosta.composedestinations.result.EmptyResultBackNavigator import com.ramcosta.composedestinations.result.ResultBackNavigator import com.ramcosta.composedestinations.spec.DestinationStyle import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.button.PrimaryButton -import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar +import net.mullvad.mullvadvpn.compose.dialog.info.InfoConfirmationDialog +import net.mullvad.mullvadvpn.compose.dialog.info.InfoConfirmationDialogTitleType import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.Dimens -import net.mullvad.mullvadvpn.lib.theme.color.AlphaScrollbar @Preview @Composable @@ -40,63 +29,26 @@ private fun PreviewDaitaConfirmationDialog() { @Destination<RootGraph>(style = DestinationStyle.Dialog::class) @Composable fun DaitaConfirmation(navigator: ResultBackNavigator<Boolean>) { - AlertDialog( - onDismissRequest = dropUnlessResumed { navigator.navigateBack(false) }, - icon = { - Icon( - modifier = Modifier.fillMaxWidth().height(Dimens.dialogIconHeight), - imageVector = Icons.Default.Error, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurface, - ) - }, - text = { - val scrollState = rememberScrollState() - Column( - Modifier.drawVerticalScrollbar( - scrollState, - MaterialTheme.colorScheme.onPrimary.copy(alpha = AlphaScrollbar), - ) - .verticalScroll(scrollState), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = stringResource(id = R.string.daita_relay_subset_warning), - color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.bodySmall, - modifier = Modifier.fillMaxWidth(), - ) + InfoConfirmationDialog( + navigator = navigator, + titleType = InfoConfirmationDialogTitleType.IconOnly, + confirmButtonTitle = stringResource(R.string.enable_anyway), + cancelButtonTitle = stringResource(R.string.back), + ) { + Text( + text = stringResource(id = R.string.daita_relay_subset_warning), + color = MaterialTheme.colorScheme.onSurface, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.fillMaxWidth(), + ) - Spacer(modifier = Modifier.height(Dimens.verticalSpace)) + Spacer(modifier = Modifier.height(Dimens.verticalSpace)) - Text( - text = - stringResource( - id = R.string.daita_warning, - stringResource(id = R.string.daita), - ), - color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.bodySmall, - modifier = Modifier.fillMaxWidth(), - ) - } - }, - confirmButton = { - Column(verticalArrangement = Arrangement.spacedBy(Dimens.buttonSpacing)) { - PrimaryButton( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.enable_anyway), - onClick = { navigator.navigateBack(true) }, - ) - - PrimaryButton( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.back), - onClick = dropUnlessResumed { navigator.navigateBack(false) }, - ) - } - }, - containerColor = MaterialTheme.colorScheme.surface, - titleContentColor = MaterialTheme.colorScheme.onSurface, - ) + Text( + text = stringResource(id = R.string.daita_warning, stringResource(id = R.string.daita)), + color = MaterialTheme.colorScheme.onSurface, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.fillMaxWidth(), + ) + } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DiscardChangesDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DiscardChangesDialog.kt index 76b4c20e74..643508792c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DiscardChangesDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DiscardChangesDialog.kt @@ -1,40 +1,32 @@ package net.mullvad.mullvadvpn.compose.dialog -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.res.stringResource -import androidx.lifecycle.compose.dropUnlessResumed +import androidx.compose.ui.tooling.preview.Preview import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph +import com.ramcosta.composedestinations.result.EmptyResultBackNavigator import com.ramcosta.composedestinations.result.ResultBackNavigator import com.ramcosta.composedestinations.spec.DestinationStyle import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.button.PrimaryButton +import net.mullvad.mullvadvpn.compose.dialog.info.InfoConfirmationDialog +import net.mullvad.mullvadvpn.compose.dialog.info.InfoConfirmationDialogTitleType +import net.mullvad.mullvadvpn.lib.theme.AppTheme + +@Preview +@Composable +private fun PreviewDiscardChangesDialog() { + AppTheme { DiscardChanges(EmptyResultBackNavigator()) } +} @Destination<RootGraph>(style = DestinationStyle.Dialog::class) @Composable fun DiscardChanges(resultBackNavigator: ResultBackNavigator<Boolean>) { - AlertDialog( - onDismissRequest = dropUnlessResumed { resultBackNavigator.navigateBack() }, - title = { Text(text = stringResource(id = R.string.discard_changes)) }, - dismissButton = { - PrimaryButton( - modifier = Modifier.focusRequester(FocusRequester()), - onClick = dropUnlessResumed { resultBackNavigator.navigateBack() }, - text = stringResource(id = R.string.cancel), - ) - }, - confirmButton = { - PrimaryButton( - onClick = dropUnlessResumed { resultBackNavigator.navigateBack(result = true) }, - text = stringResource(id = R.string.discard), - ) - }, - containerColor = MaterialTheme.colorScheme.surface, + InfoConfirmationDialog( + navigator = resultBackNavigator, + titleType = + InfoConfirmationDialogTitleType.TitleOnly(stringResource(R.string.discard_changes)), + confirmButtonTitle = stringResource(R.string.discard), + cancelButtonTitle = stringResource(R.string.cancel), ) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/InfoConfirmationDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/InfoConfirmationDialog.kt new file mode 100644 index 0000000000..ef3eb2b48b --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/InfoConfirmationDialog.kt @@ -0,0 +1,146 @@ +package net.mullvad.mullvadvpn.compose.dialog.info + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Error +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import com.ramcosta.composedestinations.result.EmptyResultBackNavigator +import com.ramcosta.composedestinations.result.ResultBackNavigator +import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.compose.button.PrimaryButton +import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar +import net.mullvad.mullvadvpn.lib.theme.AppTheme +import net.mullvad.mullvadvpn.lib.theme.Dimens +import net.mullvad.mullvadvpn.lib.theme.color.AlphaScrollbar + +@Preview +@Composable +private fun PreviewInfoConfirmationDialog() { + AppTheme { + InfoConfirmationDialog( + navigator = EmptyResultBackNavigator(), + titleType = InfoConfirmationDialogTitleType.IconAndTitle("Informative title"), + confirmButtonTitle = stringResource(R.string.enable_anyway), + cancelButtonTitle = stringResource(R.string.back), + ) { + Text( + text = "Info text paragraph one.", + color = MaterialTheme.colorScheme.onSurface, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.fillMaxWidth(), + ) + + Spacer(modifier = Modifier.height(Dimens.verticalSpace)) + + Text( + text = "More text here.", + color = MaterialTheme.colorScheme.onSurface, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.fillMaxWidth(), + ) + } + } +} + +sealed interface InfoConfirmationDialogTitleType { + data object IconOnly : InfoConfirmationDialogTitleType + + data class TitleOnly(val title: String) : InfoConfirmationDialogTitleType + + data class IconAndTitle(val title: String) : InfoConfirmationDialogTitleType +} + +@Composable +fun InfoConfirmationDialog( + navigator: ResultBackNavigator<Boolean>, + titleType: InfoConfirmationDialogTitleType, + confirmButtonTitle: String, + cancelButtonTitle: String, + content: @Composable (() -> Unit)? = null, +) { + val title = + when (titleType) { + is InfoConfirmationDialogTitleType.TitleOnly -> titleType.title + is InfoConfirmationDialogTitleType.IconAndTitle -> titleType.title + InfoConfirmationDialogTitleType.IconOnly -> null + } + + val showIcon = + when (titleType) { + is InfoConfirmationDialogTitleType.IconOnly, + is InfoConfirmationDialogTitleType.IconAndTitle -> true + is InfoConfirmationDialogTitleType.TitleOnly -> false + } + + AlertDialog( + onDismissRequest = { navigator.navigateBack(false) }, + title = + if (title != null) { + @Composable { Text(title) } + } else { + null + }, + icon = + if (showIcon) { + @Composable { + Icon( + modifier = Modifier.fillMaxWidth().height(Dimens.dialogIconHeight), + imageVector = Icons.Default.Error, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurface, + ) + } + } else { + null + }, + text = + if (content != null) { + @Composable { + val scrollState = rememberScrollState() + Column( + Modifier.drawVerticalScrollbar( + scrollState, + MaterialTheme.colorScheme.onPrimary.copy(alpha = AlphaScrollbar), + ) + .verticalScroll(scrollState), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + content() + } + } + } else { + null + }, + confirmButton = { + Column(verticalArrangement = Arrangement.spacedBy(Dimens.buttonSpacing)) { + PrimaryButton( + modifier = Modifier.fillMaxWidth(), + text = confirmButtonTitle, + onClick = { navigator.navigateBack(true) }, + ) + + PrimaryButton( + modifier = Modifier.fillMaxWidth(), + text = cancelButtonTitle, + onClick = { navigator.navigateBack(false) }, + ) + } + }, + containerColor = MaterialTheme.colorScheme.surface, + titleContentColor = MaterialTheme.colorScheme.onSurface, + ) +} |
