diff options
| author | David Göransson <david.goransson@mullvad.net> | 2024-04-19 11:09:41 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson@mullvad.net> | 2024-04-19 11:27:23 +0200 |
| commit | ca1d45e7244ce2e7c5d0810d430cf432ccba3381 (patch) | |
| tree | ddefc0e789f5bae14f41e89d2ae3d69fd6646091 | |
| parent | 1d58cd66de9fd61ffc78175fd1f677ec1b026970 (diff) | |
| download | mullvadvpn-ca1d45e7244ce2e7c5d0810d430cf432ccba3381.tar.xz mullvadvpn-ca1d45e7244ce2e7c5d0810d430cf432ccba3381.zip | |
Add delete custom list entry bottom sheet
6 files changed, 107 insertions, 4 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt index 0342a0f5e7..a2d7cc74c1 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt @@ -136,7 +136,7 @@ fun StatusRelayLocationCell( disabledColor: Color = MaterialTheme.colorScheme.onSecondary, selectedItem: RelayItem? = null, onSelectRelay: (item: RelayItem) -> Unit = {}, - onLongClick: (item: RelayItem) -> Unit = {} + onLongClick: (item: RelayItem) -> Unit = {}, ) { RelayLocationCell( relay = relay, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt index 705877951b..4476b8064a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt @@ -136,7 +136,15 @@ fun SelectLocation( LaunchedEffectCollect(vm.uiSideEffect) { when (it) { SelectLocationSideEffect.CloseScreen -> navigator.navigateUp() - is SelectLocationSideEffect.LocationAddedToCustomList -> { + is SelectLocationSideEffect.LocationAddedToCustomList -> + launch { + snackbarHostState.showResultSnackbar( + context = context, + result = it.result, + onUndo = vm::performAction + ) + } + is SelectLocationSideEffect.LocationRemovedFromCustomList -> launch { snackbarHostState.showResultSnackbar( context = context, @@ -144,7 +152,6 @@ fun SelectLocation( onUndo = vm::performAction ) } - } } } @@ -181,6 +188,7 @@ fun SelectLocation( removeOwnershipFilter = vm::removeOwnerFilter, removeProviderFilter = vm::removeProviderFilter, onAddLocationToList = vm::addLocationToList, + onRemoveLocationFromList = vm::removeLocationFromList, onEditCustomListName = { navigator.navigate( EditCustomListNameDestination(customListId = it.id, initialName = it.name) @@ -213,6 +221,9 @@ fun SelectLocationScreen( removeProviderFilter: () -> Unit = {}, onAddLocationToList: (location: RelayItem, customList: RelayItem.CustomList) -> Unit = { _, _ -> }, + onRemoveLocationFromList: (location: RelayItem, customList: RelayItem.CustomList) -> Unit = + { _, _ -> + }, onEditCustomListName: (RelayItem.CustomList) -> Unit = {}, onEditLocationsCustomList: (RelayItem.CustomList) -> Unit = {}, onDeleteCustomList: (RelayItem.CustomList) -> Unit = {} @@ -233,6 +244,7 @@ fun SelectLocationScreen( onCreateCustomList = onCreateCustomList, onEditCustomLists = onEditCustomLists, onAddLocationToList = onAddLocationToList, + onRemoveLocationFromList = onRemoveLocationFromList, onEditCustomListName = onEditCustomListName, onEditLocationsCustomList = onEditLocationsCustomList, onDeleteCustomList = onDeleteCustomList, @@ -331,6 +343,15 @@ fun SelectLocationScreen( onShowEditBottomSheet = { customList -> bottomSheetState = BottomSheetState.ShowEditCustomListBottomSheet(customList) + }, + onShowEditCustomListEntryBottomSheet = { + item: RelayItem, + customList: RelayItem.CustomList -> + bottomSheetState = + BottomSheetState.ShowCustomListsEntryBottomSheet( + customList, + item, + ) } ) item { @@ -379,7 +400,8 @@ private fun LazyListScope.customLists( backgroundColor: Color, onSelectRelay: (item: RelayItem) -> Unit, onShowCustomListBottomSheet: () -> Unit, - onShowEditBottomSheet: (RelayItem.CustomList) -> Unit + onShowEditBottomSheet: (RelayItem.CustomList) -> Unit, + onShowEditCustomListEntryBottomSheet: (item: RelayItem, RelayItem.CustomList) -> Unit ) { item( contentType = { ContentType.HEADER }, @@ -407,6 +429,8 @@ private fun LazyListScope.customLists( onLongClick = { if (it is RelayItem.CustomList) { onShowEditBottomSheet(it) + } else if (it in customList.locations) { + onShowEditCustomListEntryBottomSheet(it, customList) } }, modifier = Modifier.animateContentSize().animateItemPlacement(), @@ -467,6 +491,7 @@ private fun BottomSheets( onCreateCustomList: (RelayItem?) -> Unit, onEditCustomLists: () -> Unit, onAddLocationToList: (RelayItem, RelayItem.CustomList) -> Unit, + onRemoveLocationFromList: (RelayItem, RelayItem.CustomList) -> Unit, onEditCustomListName: (RelayItem.CustomList) -> Unit, onEditLocationsCustomList: (RelayItem.CustomList) -> Unit, onDeleteCustomList: (RelayItem.CustomList) -> Unit, @@ -522,6 +547,16 @@ private fun BottomSheets( closeBottomSheet = onCloseBottomSheet ) } + is BottomSheetState.ShowCustomListsEntryBottomSheet -> { + CustomListEntryBottomSheet( + sheetState = sheetState, + onBackgroundColor = onBackgroundColor, + customList = bottomSheetState.customList, + item = bottomSheetState.item, + onRemoveLocationFromList = onRemoveLocationFromList, + closeBottomSheet = onCloseBottomSheet + ) + } null -> { /* Do nothing */ } @@ -715,6 +750,40 @@ private fun EditCustomListBottomSheet( } } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun CustomListEntryBottomSheet( + onBackgroundColor: Color, + sheetState: SheetState, + customList: RelayItem.CustomList, + item: RelayItem, + onRemoveLocationFromList: (location: RelayItem, customList: RelayItem.CustomList) -> Unit, + closeBottomSheet: (animate: Boolean) -> Unit +) { + MullvadModalBottomSheet( + sheetState = sheetState, + onDismissRequest = { closeBottomSheet(false) }, + modifier = Modifier.testTag(SELECT_LOCATION_LOCATION_BOTTOM_SHEET_TEST_TAG) + ) { -> + HeaderCell( + text = stringResource(id = R.string.remove_location_from_list, item.name), + background = Color.Unspecified + ) + HorizontalDivider(color = onBackgroundColor) + + IconCell( + iconId = R.drawable.ic_remove, + title = stringResource(id = R.string.remove_button), + titleColor = onBackgroundColor, + onClick = { + onRemoveLocationFromList(item, customList) + closeBottomSheet(true) + }, + background = Color.Unspecified + ) + } +} + private suspend fun LazyListState.animateScrollAndCentralizeItem(index: Int) { val itemInfo = this.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index } if (itemInfo != null) { @@ -785,6 +854,11 @@ sealed interface BottomSheetState { data class ShowCustomListsBottomSheet(val editListEnabled: Boolean) : BottomSheetState + data class ShowCustomListsEntryBottomSheet( + val customList: RelayItem.CustomList, + val item: RelayItem + ) : BottomSheetState + data class ShowLocationBottomSheet( val customLists: List<RelayItem.CustomList>, val item: RelayItem diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt index 9772fb6362..27edb95457 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt @@ -154,6 +154,19 @@ class SelectLocationViewModel( viewModelScope.launch { customListActionUseCase.performAction(action) } } + fun removeLocationFromList(item: RelayItem, customList: RelayItem.CustomList) { + viewModelScope.launch { + val newLocations = (customList.locations - item).map { it.code } + val result = + customListActionUseCase.performAction( + CustomListAction.UpdateLocations(customList.id, newLocations) + ) + _uiSideEffect.send( + SelectLocationSideEffect.LocationRemovedFromCustomList(result.getOrThrow()) + ) + } + } + companion object { private const val EMPTY_SEARCH_TERM = "" } @@ -164,4 +177,7 @@ sealed interface SelectLocationSideEffect { data class LocationAddedToCustomList(val result: CustomListResult.LocationsChanged) : SelectLocationSideEffect + + class LocationRemovedFromCustomList(val result: CustomListResult.LocationsChanged) : + SelectLocationSideEffect } diff --git a/android/lib/resource/src/main/res/drawable/ic_remove.xml b/android/lib/resource/src/main/res/drawable/ic_remove.xml new file mode 100644 index 0000000000..93b0990d6b --- /dev/null +++ b/android/lib/resource/src/main/res/drawable/ic_remove.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="960" + android:viewportHeight="960"> + <path + android:fillColor="#FF000000" + android:pathData="M200,520v-80h560v80L200,520Z"/> +</vector> diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml index a8e9978f71..38a839bed3 100644 --- a/android/lib/resource/src/main/res/values/strings.xml +++ b/android/lib/resource/src/main/res/values/strings.xml @@ -311,6 +311,7 @@ <string name="discard_changes">Discard changes?</string> <string name="discard">Discard</string> <string name="add_location_to_list">Add %s to list</string> + <string name="remove_location_from_list">Remove %s from list</string> <string name="location_was_added_to_list">%s was added to \"%s\"</string> <string name="location_added">%s (added)</string> <string name="edit_name">Edit name</string> diff --git a/gui/locales/messages.pot b/gui/locales/messages.pot index b1c39c2d2d..1976d04278 100644 --- a/gui/locales/messages.pot +++ b/gui/locales/messages.pot @@ -2335,6 +2335,9 @@ msgstr "" msgid "Remove" msgstr "" +msgid "Remove %s from list" +msgstr "" + msgid "Remove custom port" msgstr "" |
