Skip to content

Commit ca19e63

Browse files
committed
Add dropUnlessResumed to prevent duplicate navigation
1 parent 889af23 commit ca19e63

15 files changed

+2172
-193
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.compose.ui.platform.testTag
1414
import androidx.compose.ui.res.stringResource
1515
import androidx.compose.ui.tooling.preview.Preview
1616
import androidx.lifecycle.compose.collectAsStateWithLifecycle
17+
import androidx.lifecycle.compose.dropUnlessResumed
1718
import com.ramcosta.composedestinations.annotation.Destination
1819
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
1920
import com.ramcosta.composedestinations.result.ResultBackNavigator
@@ -86,7 +87,7 @@ fun CreateCustomList(
8687
state = state,
8788
createCustomList = vm::createCustomList,
8889
onInputChanged = vm::clearError,
89-
onDismiss = backNavigator::navigateBack
90+
onDismiss = dropUnlessResumed { backNavigator.navigateBack() }
9091
)
9192
}
9293

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import androidx.compose.ui.res.painterResource
1818
import androidx.compose.ui.res.stringResource
1919
import androidx.compose.ui.tooling.preview.Preview
2020
import androidx.lifecycle.compose.collectAsStateWithLifecycle
21+
import androidx.lifecycle.compose.dropUnlessResumed
2122
import com.ramcosta.composedestinations.annotation.Destination
2223
import com.ramcosta.composedestinations.result.ResultBackNavigator
2324
import com.ramcosta.composedestinations.spec.DestinationStyle
@@ -69,7 +70,7 @@ fun DeleteCustomList(
6970
state = state.value,
7071
name = name,
7172
onDelete = viewModel::deleteCustomList,
72-
onBack = navigator::navigateBack
73+
onBack = dropUnlessResumed { navigator.navigateBack() }
7374
)
7475
}
7576

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.compose.ui.Modifier
88
import androidx.compose.ui.focus.FocusRequester
99
import androidx.compose.ui.focus.focusRequester
1010
import androidx.compose.ui.res.stringResource
11+
import androidx.lifecycle.compose.dropUnlessResumed
1112
import com.ramcosta.composedestinations.annotation.Destination
1213
import com.ramcosta.composedestinations.result.ResultBackNavigator
1314
import com.ramcosta.composedestinations.spec.DestinationStyle
@@ -18,18 +19,18 @@ import net.mullvad.mullvadvpn.compose.button.PrimaryButton
1819
@Composable
1920
fun DiscardChangesDialog(resultBackNavigator: ResultBackNavigator<Boolean>) {
2021
AlertDialog(
21-
onDismissRequest = resultBackNavigator::navigateBack,
22+
onDismissRequest = dropUnlessResumed { resultBackNavigator.navigateBack() },
2223
title = { Text(text = stringResource(id = R.string.discard_changes)) },
2324
dismissButton = {
2425
PrimaryButton(
2526
modifier = Modifier.focusRequester(FocusRequester()),
26-
onClick = resultBackNavigator::navigateBack,
27+
onClick = dropUnlessResumed {resultBackNavigator.navigateBack()},
2728
text = stringResource(id = R.string.cancel)
2829
)
2930
},
3031
confirmButton = {
3132
PrimaryButton(
32-
onClick = { resultBackNavigator.navigateBack(result = true) },
33+
onClick = dropUnlessResumed { resultBackNavigator.navigateBack(result = true) },
3334
text = stringResource(id = R.string.discard)
3435
)
3536
},

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.compose.ui.graphics.Color
1414
import androidx.compose.ui.res.stringResource
1515
import androidx.compose.ui.tooling.preview.Preview
1616
import androidx.lifecycle.compose.collectAsStateWithLifecycle
17+
import androidx.lifecycle.compose.dropUnlessResumed
1718
import com.ramcosta.composedestinations.annotation.Destination
1819
import com.ramcosta.composedestinations.result.ResultBackNavigator
1920
import com.ramcosta.composedestinations.spec.DestinationStyle
@@ -75,7 +76,7 @@ fun DnsDialog(
7576
viewModel::onDnsInputChange,
7677
onSaveDnsClick = viewModel::onSaveDnsClick,
7778
onRemoveDnsClick = viewModel::onRemoveDnsClick,
78-
onDismiss = { resultNavigator.navigateBack(result = DnsDialogResult.Cancel) }
79+
onDismiss = dropUnlessResumed { resultNavigator.navigateBack(result = DnsDialogResult.Cancel) }
7980
)
8081
}
8182

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.ui.platform.testTag
1313
import androidx.compose.ui.res.stringResource
1414
import androidx.compose.ui.tooling.preview.Preview
1515
import androidx.lifecycle.compose.collectAsStateWithLifecycle
16+
import androidx.lifecycle.compose.dropUnlessResumed
1617
import com.ramcosta.composedestinations.annotation.Destination
1718
import com.ramcosta.composedestinations.result.ResultBackNavigator
1819
import com.ramcosta.composedestinations.spec.DestinationStyle
@@ -63,7 +64,7 @@ fun EditCustomListName(
6364
state = state,
6465
updateName = vm::updateCustomListName,
6566
onInputChanged = vm::clearError,
66-
onDismiss = backNavigator::navigateBack
67+
onDismiss = dropUnlessResumed { backNavigator.navigateBack() }
6768
)
6869
}
6970

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.res.stringResource
1414
import androidx.compose.ui.tooling.preview.Preview
1515
import androidx.lifecycle.compose.collectAsStateWithLifecycle
16+
import androidx.lifecycle.compose.dropUnlessResumed
1617
import com.ramcosta.composedestinations.annotation.Destination
1718
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
1819
import com.ramcosta.composedestinations.result.ResultBackNavigator
@@ -57,7 +58,7 @@ fun MtuDialog(mtuInitial: Mtu?, navigator: ResultBackNavigator<Boolean>) {
5758
onInputChanged = viewModel::onInputChanged,
5859
onSaveMtu = viewModel::onSaveClick,
5960
onResetMtu = viewModel::onRestoreClick,
60-
onDismiss = { navigator.navigateBack(true) }
61+
onDismiss = dropUnlessResumed { navigator.navigateBack() }
6162
)
6263
}
6364

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import androidx.compose.ui.res.stringResource
1515
import androidx.compose.ui.tooling.preview.Preview
1616
import androidx.compose.ui.tooling.preview.PreviewParameter
1717
import androidx.compose.ui.unit.sp
18+
import androidx.lifecycle.compose.dropUnlessResumed
1819
import com.ramcosta.composedestinations.annotation.Destination
1920
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
2021
import com.ramcosta.composedestinations.result.ResultBackNavigator
@@ -42,7 +43,7 @@ private fun PreviewRemoveDeviceConfirmationDialog(
4243
@Composable
4344
fun RemoveDeviceConfirmationDialog(navigator: ResultBackNavigator<DeviceId>, device: Device) {
4445
AlertDialog(
45-
onDismissRequest = navigator::navigateBack,
46+
onDismissRequest = dropUnlessResumed { navigator.navigateBack() },
4647
icon = {
4748
Icon(
4849
modifier = Modifier.fillMaxWidth().height(Dimens.dialogIconHeight),
@@ -62,14 +63,14 @@ fun RemoveDeviceConfirmationDialog(navigator: ResultBackNavigator<DeviceId>, dev
6263
},
6364
dismissButton = {
6465
NegativeButton(
65-
onClick = { navigator.navigateBack(result = device.id) },
66+
onClick = dropUnlessResumed { navigator.navigateBack(result = device.id) },
6667
text = stringResource(id = R.string.confirm_removal)
6768
)
6869
},
6970
confirmButton = {
7071
PrimaryButton(
7172
modifier = Modifier.focusRequester(FocusRequester()),
72-
onClick = { navigator.navigateBack() },
73+
onClick = dropUnlessResumed { navigator.navigateBack() },
7374
text = stringResource(id = R.string.back)
7475
)
7576
},

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.compose.ui.graphics.Color
1212
import androidx.compose.ui.res.painterResource
1313
import androidx.compose.ui.res.stringResource
1414
import androidx.compose.ui.tooling.preview.Preview
15+
import androidx.lifecycle.compose.dropUnlessResumed
1516
import com.ramcosta.composedestinations.annotation.Destination
1617
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
1718
import com.ramcosta.composedestinations.result.ResultBackNavigator
@@ -32,7 +33,7 @@ private fun PreviewReportProblemNoEmailDialog() {
3233
@Composable
3334
fun ReportProblemNoEmailDialog(resultBackNavigator: ResultBackNavigator<Boolean>) {
3435
AlertDialog(
35-
onDismissRequest = resultBackNavigator::navigateBack,
36+
onDismissRequest = dropUnlessResumed {resultBackNavigator.navigateBack() },
3637
icon = {
3738
Icon(
3839
painter = painterResource(id = R.drawable.icon_alert),
@@ -52,14 +53,14 @@ fun ReportProblemNoEmailDialog(resultBackNavigator: ResultBackNavigator<Boolean>
5253
dismissButton = {
5354
NegativeButton(
5455
modifier = Modifier.fillMaxWidth(),
55-
onClick = { resultBackNavigator.navigateBack(result = true) },
56+
onClick = dropUnlessResumed { resultBackNavigator.navigateBack(result = true) },
5657
text = stringResource(id = R.string.send_anyway)
5758
)
5859
},
5960
confirmButton = {
6061
PrimaryButton(
6162
modifier = Modifier.fillMaxWidth(),
62-
onClick = resultBackNavigator::navigateBack,
63+
onClick = dropUnlessResumed { resultBackNavigator.navigateBack() },
6364
text = stringResource(id = R.string.back)
6465
)
6566
},

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.ui.Modifier
99
import androidx.compose.ui.platform.testTag
1010
import androidx.compose.ui.res.stringResource
1111
import androidx.compose.ui.tooling.preview.Preview
12+
import androidx.lifecycle.compose.dropUnlessResumed
1213
import com.ramcosta.composedestinations.annotation.Destination
1314
import com.ramcosta.composedestinations.result.ResultBackNavigator
1415
import com.ramcosta.composedestinations.spec.DestinationStyle
@@ -43,7 +44,7 @@ fun ResetServerIpOverridesConfirmation(resultBackNavigator: ResultBackNavigator<
4344
}
4445
ResetServerIpOverridesConfirmationDialog(
4546
onClearAllOverrides = vm::clearAllOverrides,
46-
resultBackNavigator::navigateBack
47+
dropUnlessResumed { resultBackNavigator.navigateBack() }
4748
)
4849
}
4950

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

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import androidx.compose.ui.Modifier
1616
import androidx.compose.ui.platform.testTag
1717
import androidx.compose.ui.res.stringResource
1818
import androidx.compose.ui.tooling.preview.Preview
19+
import androidx.lifecycle.compose.dropUnlessResumed
1920
import com.ramcosta.composedestinations.annotation.Destination
2021
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
2122
import com.ramcosta.composedestinations.result.ResultBackNavigator

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.compose.ui.res.pluralStringResource
2222
import androidx.compose.ui.res.stringResource
2323
import androidx.compose.ui.tooling.preview.Preview
2424
import androidx.lifecycle.compose.collectAsStateWithLifecycle
25+
import androidx.lifecycle.compose.dropUnlessResumed
2526
import com.ramcosta.composedestinations.annotation.Destination
2627
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
2728
import com.ramcosta.composedestinations.result.NavResult
@@ -117,7 +118,7 @@ fun EditCustomList(
117118
launchSingleTop = true
118119
}
119120
},
120-
onBackClick = backNavigator::navigateBack
121+
onBackClick = dropUnlessResumed { backNavigator.navigateBack()}
121122
)
122123
}
123124

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.compose.runtime.setValue
2121
import androidx.compose.ui.Modifier
2222
import androidx.compose.ui.res.stringResource
2323
import androidx.compose.ui.tooling.preview.Preview
24+
import androidx.lifecycle.compose.dropUnlessResumed
2425
import com.ramcosta.composedestinations.annotation.Destination
2526
import com.ramcosta.composedestinations.result.ResultBackNavigator
2627
import net.mullvad.mullvadvpn.R
@@ -40,7 +41,7 @@ fun ImportOverridesByText(
4041
resultNavigator: ResultBackNavigator<String>,
4142
) {
4243
ImportOverridesByTextScreen(
43-
onNavigateBack = resultNavigator::navigateBack,
44+
onNavigateBack = dropUnlessResumed { resultNavigator.navigateBack() },
4445
onImportClicked = { resultNavigator.navigateBack(result = it) }
4546
)
4647
}
@@ -67,7 +68,7 @@ fun ImportOverridesByTextScreen(
6768
colors =
6869
ButtonDefaults.textButtonColors()
6970
.copy(contentColor = MaterialTheme.colorScheme.onPrimary),
70-
onClick = { onImportClicked(text) }
71+
onClick = dropUnlessResumed { onImportClicked(text) }
7172
) {
7273
Text(
7374
text = stringResource(R.string.import_overrides_import),

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import androidx.compose.ui.res.stringResource
4646
import androidx.compose.ui.text.style.TextAlign
4747
import androidx.compose.ui.tooling.preview.Preview
4848
import androidx.lifecycle.compose.collectAsStateWithLifecycle
49+
import androidx.lifecycle.compose.dropUnlessResumed
4950
import com.ramcosta.composedestinations.annotation.Destination
5051
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
5152
import com.ramcosta.composedestinations.result.NavResult
@@ -149,9 +150,10 @@ fun SelectLocation(
149150
val snackbarHostState = remember { SnackbarHostState() }
150151
val context = LocalContext.current
151152

153+
val navigateBack = dropUnlessResumed { backNavigator.navigateBack(result = true)}
152154
LaunchedEffectCollect(vm.uiSideEffect) {
153155
when (it) {
154-
SelectLocationSideEffect.CloseScreen -> backNavigator.navigateBack(result = true, true)
156+
SelectLocationSideEffect.CloseScreen -> navigateBack()
155157
is SelectLocationSideEffect.LocationAddedToCustomList ->
156158
launch {
157159
snackbarHostState.showResultSnackbar(
@@ -200,8 +202,8 @@ fun SelectLocation(
200202
snackbarHostState = snackbarHostState,
201203
onSelectRelay = vm::selectRelay,
202204
onSearchTermInput = vm::onSearchTermInput,
203-
onBackClick = { backNavigator.navigateBack(true) },
204-
onFilterClick = { navigator.navigate(FilterScreenDestination, true) },
205+
onBackClick = dropUnlessResumed { backNavigator.navigateBack() },
206+
onFilterClick = dropUnlessResumed { navigator.navigate(FilterScreenDestination) },
205207
onCreateCustomList = { relayItem ->
206208
navigator.navigate(CreateCustomListDestination(locationCode = relayItem?.id)) {
207209
launchSingleTop = true

android/buildSrc/src/main/kotlin/Versions.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ object Versions {
2525
const val appcompat = "1.6.1"
2626
const val coreKtx = "1.12.0"
2727
const val espresso = "3.5.1"
28-
const val lifecycle = "2.7.0"
28+
const val lifecycle = "2.8.2"
2929
const val fragment = "1.6.2"
3030
const val test = "1.5.0"
3131
const val testMonitor = "1.6.1"

0 commit comments

Comments
 (0)