Skip to content

Commit 8eecff1

Browse files
committed
Merge branch 'custom-lists-add-country-snackbartoast-text-wrong-droid-972'
2 parents d54bcf0 + bf23a89 commit 8eecff1

24 files changed

+456
-185
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package net.mullvad.mullvadvpn.compose.communication
2+
3+
import android.os.Parcelable
4+
import kotlinx.parcelize.Parcelize
5+
import net.mullvad.mullvadvpn.lib.model.CustomListName
6+
7+
sealed interface CustomListActionResultData : Parcelable {
8+
9+
sealed interface Success : CustomListActionResultData, Parcelable {
10+
val undo: CustomListAction
11+
12+
@Parcelize
13+
data class CreatedWithLocations(
14+
val customListName: CustomListName,
15+
val locationNames: List<String>,
16+
override val undo: CustomListAction
17+
) : Success
18+
19+
@Parcelize
20+
data class Deleted(
21+
val customListName: CustomListName,
22+
override val undo: CustomListAction.Create
23+
) : Success
24+
25+
@Parcelize
26+
data class Renamed(
27+
val newName: CustomListName,
28+
override val undo: CustomListAction.Rename
29+
) : Success
30+
31+
@Parcelize
32+
data class LocationAdded(
33+
val customListName: CustomListName,
34+
val locationName: String,
35+
override val undo: CustomListAction
36+
) : Success
37+
38+
@Parcelize
39+
data class LocationRemoved(
40+
val customListName: CustomListName,
41+
val locationName: String,
42+
override val undo: CustomListAction
43+
) : Success
44+
45+
@Parcelize
46+
data class LocationChanged(
47+
val customListName: CustomListName,
48+
override val undo: CustomListAction
49+
) : Success
50+
}
51+
52+
@Parcelize data object GenericError : CustomListActionResultData
53+
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/CustomListSuccess.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package net.mullvad.mullvadvpn.compose.communication
22

33
import android.os.Parcelable
4+
import kotlinx.parcelize.IgnoredOnParcel
45
import kotlinx.parcelize.Parcelize
56
import net.mullvad.mullvadvpn.lib.model.CustomListId
67
import net.mullvad.mullvadvpn.lib.model.CustomListName
8+
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
79

810
sealed interface CustomListSuccess : Parcelable {
911
val undo: CustomListAction
@@ -31,6 +33,14 @@ data class Renamed(override val undo: CustomListAction.Rename) : CustomListSucce
3133

3234
@Parcelize
3335
data class LocationsChanged(
36+
val id: CustomListId,
3437
val name: CustomListName,
38+
val locations: List<GeoLocationId>,
39+
val oldLocations: List<GeoLocationId>,
40+
) : CustomListSuccess {
3541
override val undo: CustomListAction.UpdateLocations
36-
) : CustomListSuccess
42+
get() = CustomListAction.UpdateLocations(id, oldLocations)
43+
44+
@IgnoredOnParcel val addedLocations = locations - oldLocations
45+
@IgnoredOnParcel val removedLocations = oldLocations - locations
46+
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import com.ramcosta.composedestinations.result.ResultBackNavigator
2323
import com.ramcosta.composedestinations.spec.DestinationStyle
2424
import net.mullvad.mullvadvpn.R
2525
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
26-
import net.mullvad.mullvadvpn.compose.communication.Created
26+
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
2727
import net.mullvad.mullvadvpn.compose.component.CustomListNameTextField
2828
import net.mullvad.mullvadvpn.compose.state.CreateCustomListUiState
2929
import net.mullvad.mullvadvpn.compose.test.CREATE_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG
@@ -63,7 +63,7 @@ data class CreateCustomListNavArgs(val locationCode: GeoLocationId?)
6363
)
6464
fun CreateCustomList(
6565
navigator: DestinationsNavigator,
66-
backNavigator: ResultBackNavigator<Created>,
66+
backNavigator: ResultBackNavigator<CustomListActionResultData.Success.CreatedWithLocations>,
6767
) {
6868
val vm: CreateCustomListDialogViewModel = koinViewModel()
6969
LaunchedEffect(key1 = Unit) {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.ramcosta.composedestinations.annotation.RootGraph
1111
import com.ramcosta.composedestinations.result.ResultBackNavigator
1212
import com.ramcosta.composedestinations.spec.DestinationStyle
1313
import net.mullvad.mullvadvpn.R
14-
import net.mullvad.mullvadvpn.compose.communication.Deleted
14+
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
1515
import net.mullvad.mullvadvpn.compose.state.DeleteCustomListUiState
1616
import net.mullvad.mullvadvpn.compose.util.LaunchedEffectCollect
1717
import net.mullvad.mullvadvpn.lib.model.CustomListId
@@ -39,7 +39,7 @@ data class DeleteCustomListNavArgs(val customListId: CustomListId, val name: Cus
3939
navArgs = DeleteCustomListNavArgs::class
4040
)
4141
fun DeleteCustomList(
42-
navigator: ResultBackNavigator<Deleted>,
42+
navigator: ResultBackNavigator<CustomListActionResultData.Success.Deleted>,
4343
) {
4444
val viewModel: DeleteCustomListConfirmationViewModel = koinViewModel()
4545
val state by viewModel.uiState.collectAsStateWithLifecycle()

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import com.ramcosta.composedestinations.result.ResultBackNavigator
1717
import com.ramcosta.composedestinations.spec.DestinationStyle
1818
import net.mullvad.mullvadvpn.R
1919
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
20-
import net.mullvad.mullvadvpn.compose.communication.Renamed
20+
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
2121
import net.mullvad.mullvadvpn.compose.component.CustomListNameTextField
2222
import net.mullvad.mullvadvpn.compose.state.EditCustomListNameUiState
2323
import net.mullvad.mullvadvpn.compose.test.EDIT_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG
@@ -50,7 +50,7 @@ data class EditCustomListNameNavArgs(
5050
navArgs = EditCustomListNameNavArgs::class
5151
)
5252
fun EditCustomListName(
53-
backNavigator: ResultBackNavigator<Renamed>,
53+
backNavigator: ResultBackNavigator<CustomListActionResultData.Success.Renamed>,
5454
) {
5555
val vm: EditCustomListNameDialogViewModel = koinViewModel()
5656
LaunchedEffectCollect(vm.uiSideEffect) { sideEffect ->

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

+3-23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package net.mullvad.mullvadvpn.compose.screen
22

3-
import android.content.Context
43
import androidx.compose.foundation.layout.Column
54
import androidx.compose.foundation.layout.Spacer
65
import androidx.compose.foundation.layout.fillMaxWidth
@@ -13,16 +12,12 @@ import androidx.compose.foundation.lazy.rememberLazyListState
1312
import androidx.compose.material3.ButtonDefaults
1413
import androidx.compose.material3.HorizontalDivider
1514
import androidx.compose.material3.MaterialTheme
16-
import androidx.compose.material3.SnackbarDuration
17-
import androidx.compose.material3.SnackbarHostState
1815
import androidx.compose.material3.Text
1916
import androidx.compose.material3.TextButton
2017
import androidx.compose.runtime.Composable
2118
import androidx.compose.runtime.getValue
22-
import androidx.compose.runtime.remember
2319
import androidx.compose.ui.Alignment
2420
import androidx.compose.ui.Modifier
25-
import androidx.compose.ui.platform.LocalContext
2621
import androidx.compose.ui.platform.testTag
2722
import androidx.compose.ui.res.stringResource
2823
import androidx.compose.ui.tooling.preview.Preview
@@ -35,10 +30,9 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
3530
import com.ramcosta.composedestinations.result.NavResult
3631
import com.ramcosta.composedestinations.result.ResultBackNavigator
3732
import com.ramcosta.composedestinations.result.ResultRecipient
38-
import kotlinx.coroutines.launch
3933
import net.mullvad.mullvadvpn.R
4034
import net.mullvad.mullvadvpn.compose.cell.CheckableRelayLocationCell
41-
import net.mullvad.mullvadvpn.compose.communication.LocationsChanged
35+
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
4236
import net.mullvad.mullvadvpn.compose.component.LocationsEmptyText
4337
import net.mullvad.mullvadvpn.compose.component.MullvadCircularProgressIndicatorLarge
4438
import net.mullvad.mullvadvpn.compose.component.NavigateBackIconButton
@@ -52,7 +46,6 @@ import net.mullvad.mullvadvpn.compose.test.SAVE_BUTTON_TEST_TAG
5246
import net.mullvad.mullvadvpn.compose.textfield.SearchTextField
5347
import net.mullvad.mullvadvpn.compose.transitions.SlideInFromRightTransition
5448
import net.mullvad.mullvadvpn.compose.util.LaunchedEffectCollect
55-
import net.mullvad.mullvadvpn.compose.util.showSnackbarImmediately
5649
import net.mullvad.mullvadvpn.lib.model.CustomListId
5750
import net.mullvad.mullvadvpn.lib.model.RelayItem
5851
import net.mullvad.mullvadvpn.lib.theme.Dimens
@@ -79,7 +72,7 @@ data class CustomListLocationsNavArgs(
7972
)
8073
fun CustomListLocations(
8174
navigator: DestinationsNavigator,
82-
backNavigator: ResultBackNavigator<LocationsChanged>,
75+
backNavigator: ResultBackNavigator<CustomListActionResultData>,
8376
discardChangesResultRecipient: ResultRecipient<DiscardChangesDestination, Boolean>,
8477
) {
8578
val customListsViewModel = koinViewModel<CustomListLocationsViewModel>()
@@ -95,27 +88,16 @@ fun CustomListLocations(
9588
}
9689
}
9790

98-
val snackbarHostState = remember { SnackbarHostState() }
99-
val context: Context = LocalContext.current
10091
LaunchedEffectCollect(customListsViewModel.uiSideEffect) { sideEffect ->
10192
when (sideEffect) {
102-
is CustomListLocationsSideEffect.ReturnWithResult ->
93+
is CustomListLocationsSideEffect.ReturnWithResultData ->
10394
backNavigator.navigateBack(result = sideEffect.result)
104-
CustomListLocationsSideEffect.CloseScreen -> backNavigator.navigateBack()
105-
CustomListLocationsSideEffect.Error ->
106-
launch {
107-
snackbarHostState.showSnackbarImmediately(
108-
message = context.getString(R.string.error_occurred),
109-
duration = SnackbarDuration.Short
110-
)
111-
}
11295
}
11396
}
11497

11598
val state by customListsViewModel.uiState.collectAsStateWithLifecycle()
11699
CustomListLocationsScreen(
117100
state = state,
118-
snackbarHostState = snackbarHostState,
119101
onSearchTermInput = customListsViewModel::onSearchTermInput,
120102
onSaveClick = customListsViewModel::save,
121103
onRelaySelectionClick = customListsViewModel::onRelaySelectionClick,
@@ -134,15 +116,13 @@ fun CustomListLocations(
134116
@Composable
135117
fun CustomListLocationsScreen(
136118
state: CustomListLocationsUiState,
137-
snackbarHostState: SnackbarHostState = SnackbarHostState(),
138119
onSearchTermInput: (String) -> Unit = {},
139120
onSaveClick: () -> Unit = {},
140121
onRelaySelectionClick: (RelayItem.Location, selected: Boolean) -> Unit = { _, _ -> },
141122
onExpand: (RelayItem.Location, selected: Boolean) -> Unit = { _, _ -> },
142123
onBackClick: () -> Unit = {}
143124
) {
144125
ScaffoldWithSmallTopBar(
145-
snackbarHostState = snackbarHostState,
146126
appBarTitle =
147127
stringResource(
148128
if (state.newList) {

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import com.ramcosta.composedestinations.result.ResultRecipient
3434
import kotlinx.coroutines.launch
3535
import net.mullvad.mullvadvpn.R
3636
import net.mullvad.mullvadvpn.compose.cell.NavigationComposeCell
37+
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
3738
import net.mullvad.mullvadvpn.compose.communication.Deleted
3839
import net.mullvad.mullvadvpn.compose.component.MullvadCircularProgressIndicatorLarge
3940
import net.mullvad.mullvadvpn.compose.component.NavigateBackIconButton
@@ -63,7 +64,8 @@ private fun PreviewCustomListsScreen() {
6364
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
6465
fun CustomLists(
6566
navigator: DestinationsNavigator,
66-
editCustomListResultRecipient: ResultRecipient<EditCustomListDestination, Deleted>
67+
editCustomListResultRecipient:
68+
ResultRecipient<EditCustomListDestination, CustomListActionResultData.Success.Deleted>
6769
) {
6870
val viewModel = koinViewModel<CustomListsViewModel>()
6971
val state by viewModel.uiState.collectAsStateWithLifecycle()
@@ -82,7 +84,7 @@ fun CustomLists(
8284
message =
8385
context.getString(
8486
R.string.delete_custom_list_message,
85-
result.value.name
87+
result.value.customListName
8688
),
8789
actionLabel = context.getString(R.string.undo),
8890
duration = SnackbarDuration.Long,

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import com.ramcosta.composedestinations.result.ResultBackNavigator
3333
import com.ramcosta.composedestinations.result.ResultRecipient
3434
import net.mullvad.mullvadvpn.R
3535
import net.mullvad.mullvadvpn.compose.cell.TwoRowCell
36+
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
3637
import net.mullvad.mullvadvpn.compose.communication.Deleted
3738
import net.mullvad.mullvadvpn.compose.component.MullvadCircularProgressIndicatorLarge
3839
import net.mullvad.mullvadvpn.compose.component.NavigateBackIconButton
@@ -83,8 +84,9 @@ data class EditCustomListNavArgs(val customListId: CustomListId)
8384
)
8485
fun EditCustomList(
8586
navigator: DestinationsNavigator,
86-
backNavigator: ResultBackNavigator<Deleted>,
87-
confirmDeleteListResultRecipient: ResultRecipient<DeleteCustomListDestination, Deleted>
87+
backNavigator: ResultBackNavigator<CustomListActionResultData.Success.Deleted>,
88+
confirmDeleteListResultRecipient:
89+
ResultRecipient<DeleteCustomListDestination, CustomListActionResultData.Success.Deleted>
8890
) {
8991
val viewModel = koinViewModel<EditCustomListViewModel>()
9092

0 commit comments

Comments
 (0)