Skip to content

Commit ee26648

Browse files
committed
Add delete custom list confirmation dialog
1 parent dde9603 commit ee26648

File tree

5 files changed

+114
-9
lines changed

5 files changed

+114
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package net.mullvad.mullvadvpn.compose.dialog
2+
3+
import androidx.compose.foundation.layout.fillMaxWidth
4+
import androidx.compose.foundation.layout.height
5+
import androidx.compose.material3.AlertDialog
6+
import androidx.compose.material3.Icon
7+
import androidx.compose.material3.MaterialTheme
8+
import androidx.compose.material3.Text
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.focus.FocusRequester
12+
import androidx.compose.ui.focus.focusRequester
13+
import androidx.compose.ui.graphics.Color
14+
import androidx.compose.ui.res.painterResource
15+
import androidx.compose.ui.res.stringResource
16+
import androidx.compose.ui.text.font.FontWeight
17+
import androidx.compose.ui.tooling.preview.Preview
18+
import androidx.core.text.HtmlCompat
19+
import com.ramcosta.composedestinations.annotation.Destination
20+
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
21+
import com.ramcosta.composedestinations.result.ResultBackNavigator
22+
import com.ramcosta.composedestinations.spec.DestinationStyle
23+
import net.mullvad.mullvadvpn.R
24+
import net.mullvad.mullvadvpn.compose.button.NegativeButton
25+
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
26+
import net.mullvad.mullvadvpn.compose.component.textResource
27+
import net.mullvad.mullvadvpn.compose.extensions.toAnnotatedString
28+
import net.mullvad.mullvadvpn.lib.theme.AppTheme
29+
import net.mullvad.mullvadvpn.lib.theme.Dimens
30+
31+
@Preview
32+
@Composable
33+
private fun PreviewRemoveDeviceConfirmationDialog() {
34+
AppTheme { DeleteCustomListConfirmationDialog(EmptyResultBackNavigator(), "My Custom List") }
35+
}
36+
37+
@Destination(style = DestinationStyle.Dialog::class)
38+
@Composable
39+
fun DeleteCustomListConfirmationDialog(navigator: ResultBackNavigator<Boolean>, name: String) {
40+
AlertDialog(
41+
onDismissRequest = { navigator.navigateBack() },
42+
icon = {
43+
Icon(
44+
modifier = Modifier.fillMaxWidth().height(Dimens.dialogIconHeight),
45+
painter = painterResource(id = R.drawable.icon_alert),
46+
contentDescription = stringResource(id = R.string.remove_button),
47+
tint = Color.Unspecified
48+
)
49+
},
50+
text = {
51+
val htmlFormattedDialogText =
52+
HtmlCompat.fromHtml(
53+
textResource(id = R.string.delete_custom_list_confirmation_description, name),
54+
HtmlCompat.FROM_HTML_MODE_COMPACT
55+
)
56+
val annotatedText = htmlFormattedDialogText.toAnnotatedString(FontWeight.Bold)
57+
58+
Text(
59+
text = annotatedText,
60+
color = MaterialTheme.colorScheme.onBackground,
61+
style = MaterialTheme.typography.bodySmall,
62+
)
63+
},
64+
dismissButton = {
65+
NegativeButton(
66+
onClick = { navigator.navigateBack(result = true) },
67+
text = stringResource(id = R.string.delete_list)
68+
)
69+
},
70+
confirmButton = {
71+
PrimaryButton(
72+
modifier = Modifier.focusRequester(FocusRequester()),
73+
onClick = { navigator.navigateBack(result = false) },
74+
text = stringResource(id = R.string.cancel)
75+
)
76+
},
77+
containerColor = MaterialTheme.colorScheme.background
78+
)
79+
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RemoveDeviceConfirmationDialog.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package net.mullvad.mullvadvpn.compose.dialog
22

3+
import androidx.compose.foundation.layout.fillMaxWidth
34
import androidx.compose.foundation.layout.height
4-
import androidx.compose.foundation.layout.width
55
import androidx.compose.material3.AlertDialog
66
import androidx.compose.material3.Icon
77
import androidx.compose.material3.MaterialTheme
@@ -13,7 +13,6 @@ import androidx.compose.ui.graphics.Color
1313
import androidx.compose.ui.res.painterResource
1414
import androidx.compose.ui.res.stringResource
1515
import androidx.compose.ui.tooling.preview.Preview
16-
import androidx.compose.ui.unit.dp
1716
import androidx.compose.ui.unit.sp
1817
import com.ramcosta.composedestinations.annotation.Destination
1918
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
@@ -25,6 +24,7 @@ import net.mullvad.mullvadvpn.compose.button.PrimaryButton
2524
import net.mullvad.mullvadvpn.compose.component.HtmlText
2625
import net.mullvad.mullvadvpn.compose.component.textResource
2726
import net.mullvad.mullvadvpn.lib.theme.AppTheme
27+
import net.mullvad.mullvadvpn.lib.theme.Dimens
2828
import net.mullvad.mullvadvpn.model.Device
2929

3030
@Preview
@@ -45,9 +45,9 @@ fun RemoveDeviceConfirmationDialog(navigator: ResultBackNavigator<String>, devic
4545
onDismissRequest = { navigator.navigateBack() },
4646
icon = {
4747
Icon(
48+
modifier = Modifier.fillMaxWidth().height(Dimens.dialogIconHeight),
4849
painter = painterResource(id = R.drawable.icon_alert),
49-
contentDescription = "Remove",
50-
modifier = Modifier.width(50.dp).height(50.dp),
50+
contentDescription = stringResource(id = R.string.remove_button),
5151
tint = Color.Unspecified
5252
)
5353
},

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt

+28-4
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@ import androidx.compose.ui.res.stringResource
2222
import androidx.compose.ui.tooling.preview.Preview
2323
import com.ramcosta.composedestinations.annotation.Destination
2424
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
25+
import com.ramcosta.composedestinations.result.NavResult
26+
import com.ramcosta.composedestinations.result.ResultRecipient
2527
import net.mullvad.mullvadvpn.R
2628
import net.mullvad.mullvadvpn.compose.cell.TwoRowCell
2729
import net.mullvad.mullvadvpn.compose.component.MullvadCircularProgressIndicatorLarge
2830
import net.mullvad.mullvadvpn.compose.component.NavigateBackIconButton
2931
import net.mullvad.mullvadvpn.compose.component.ScaffoldWithMediumTopBar
3032
import net.mullvad.mullvadvpn.compose.component.SpacedColumn
3133
import net.mullvad.mullvadvpn.compose.destinations.CustomListLocationsDestination
34+
import net.mullvad.mullvadvpn.compose.destinations.DeleteCustomListConfirmationDialogDestination
3235
import net.mullvad.mullvadvpn.compose.destinations.EditCustomListNameDestination
3336
import net.mullvad.mullvadvpn.compose.state.EditCustomListState
3437
import net.mullvad.mullvadvpn.compose.transitions.SlideInFromRightTransition
@@ -51,7 +54,12 @@ fun PreviewEditCustomListScreen() {
5154

5255
@Composable
5356
@Destination(style = SlideInFromRightTransition::class)
54-
fun EditCustomList(navigator: DestinationsNavigator, customListId: String) {
57+
fun EditCustomList(
58+
navigator: DestinationsNavigator,
59+
customListId: String,
60+
confirmDeleteListResultRecipient:
61+
ResultRecipient<DeleteCustomListConfirmationDialogDestination, Boolean>
62+
) {
5563
val viewModel =
5664
koinViewModel<EditCustomListViewModel>(parameters = { parametersOf(customListId) })
5765

@@ -63,10 +71,26 @@ fun EditCustomList(navigator: DestinationsNavigator, customListId: String) {
6371
}
6472
}
6573

74+
confirmDeleteListResultRecipient.onNavResult {
75+
when (it) {
76+
NavResult.Canceled -> {
77+
// Do nothing
78+
}
79+
is NavResult.Value ->
80+
if (it.value) {
81+
viewModel.deleteList()
82+
}
83+
}
84+
}
85+
6686
val uiState by viewModel.uiState.collectAsState()
6787
EditCustomListScreen(
6888
uiState = uiState,
69-
onDeleteList = { viewModel.deleteList() },
89+
onDeleteList = { name ->
90+
navigator.navigate(DeleteCustomListConfirmationDialogDestination(name)) {
91+
launchSingleTop = true
92+
}
93+
},
7094
onNameClicked = { id, name -> navigator.navigate(EditCustomListNameDestination(id, name)) },
7195
onLocationsClicked = {
7296
navigator.navigate(CustomListLocationsDestination(customListKey = it, newList = false))
@@ -78,7 +102,7 @@ fun EditCustomList(navigator: DestinationsNavigator, customListId: String) {
78102
@Composable
79103
fun EditCustomListScreen(
80104
uiState: EditCustomListState,
81-
onDeleteList: () -> Unit = {},
105+
onDeleteList: (name: String) -> Unit = {},
82106
onNameClicked: (id: String, name: String) -> Unit = { _, _ -> },
83107
onLocationsClicked: (String) -> Unit = {},
84108
onBackClick: () -> Unit = {}
@@ -91,7 +115,7 @@ fun EditCustomListScreen(
91115
ScaffoldWithMediumTopBar(
92116
appBarTitle = title,
93117
navigationIcon = { NavigateBackIconButton(onNavigateBack = onBackClick) },
94-
actions = { Actions(onDeleteList = onDeleteList) },
118+
actions = { Actions(onDeleteList = { onDeleteList(title) }) },
95119
) { modifier: Modifier ->
96120
SpacedColumn(modifier = modifier, alignment = Alignment.Top) {
97121
when (uiState) {

android/lib/resource/src/main/res/values/strings.xml

+3
Original file line numberDiff line numberDiff line change
@@ -295,4 +295,7 @@
295295
<string name="locations">Locations</string>
296296
<string name="number_of_locations">%d locations</string>
297297
<string name="edit_locations">Edit locations</string>
298+
<string name="delete_custom_list_confirmation_description">
299+
<![CDATA[Do you want to delete the list <b>%s</b>?]]>
300+
</string>
298301
</resources>

android/lib/theme/src/main/kotlin/net/mullvad/mullvadvpn/lib/theme/dimensions/Dimensions.kt

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ data class Dimensions(
3636
val customPortBoxMinWidth: Dp = 80.dp,
3737
val deleteIconSize: Dp = 24.dp,
3838
val dialogIconHeight: Dp = 44.dp,
39-
val dialogIconSize: Dp = 48.dp,
4039
val expandableCellChevronSize: Dp = 30.dp,
4140
val filterTittlePadding: Dp = 4.dp,
4241
val iconFailSuccessTopMargin: Dp = 30.dp,

0 commit comments

Comments
 (0)