Skip to content

Commit ca1d45e

Browse files
committed
Add delete custom list entry bottom sheet
1 parent 1d58cd6 commit ca1d45e

File tree

6 files changed

+107
-4
lines changed

6 files changed

+107
-4
lines changed

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fun StatusRelayLocationCell(
136136
disabledColor: Color = MaterialTheme.colorScheme.onSecondary,
137137
selectedItem: RelayItem? = null,
138138
onSelectRelay: (item: RelayItem) -> Unit = {},
139-
onLongClick: (item: RelayItem) -> Unit = {}
139+
onLongClick: (item: RelayItem) -> Unit = {},
140140
) {
141141
RelayLocationCell(
142142
relay = relay,

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

+77-3
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,22 @@ fun SelectLocation(
136136
LaunchedEffectCollect(vm.uiSideEffect) {
137137
when (it) {
138138
SelectLocationSideEffect.CloseScreen -> navigator.navigateUp()
139-
is SelectLocationSideEffect.LocationAddedToCustomList -> {
139+
is SelectLocationSideEffect.LocationAddedToCustomList ->
140+
launch {
141+
snackbarHostState.showResultSnackbar(
142+
context = context,
143+
result = it.result,
144+
onUndo = vm::performAction
145+
)
146+
}
147+
is SelectLocationSideEffect.LocationRemovedFromCustomList ->
140148
launch {
141149
snackbarHostState.showResultSnackbar(
142150
context = context,
143151
result = it.result,
144152
onUndo = vm::performAction
145153
)
146154
}
147-
}
148155
}
149156
}
150157

@@ -181,6 +188,7 @@ fun SelectLocation(
181188
removeOwnershipFilter = vm::removeOwnerFilter,
182189
removeProviderFilter = vm::removeProviderFilter,
183190
onAddLocationToList = vm::addLocationToList,
191+
onRemoveLocationFromList = vm::removeLocationFromList,
184192
onEditCustomListName = {
185193
navigator.navigate(
186194
EditCustomListNameDestination(customListId = it.id, initialName = it.name)
@@ -213,6 +221,9 @@ fun SelectLocationScreen(
213221
removeProviderFilter: () -> Unit = {},
214222
onAddLocationToList: (location: RelayItem, customList: RelayItem.CustomList) -> Unit = { _, _ ->
215223
},
224+
onRemoveLocationFromList: (location: RelayItem, customList: RelayItem.CustomList) -> Unit =
225+
{ _, _ ->
226+
},
216227
onEditCustomListName: (RelayItem.CustomList) -> Unit = {},
217228
onEditLocationsCustomList: (RelayItem.CustomList) -> Unit = {},
218229
onDeleteCustomList: (RelayItem.CustomList) -> Unit = {}
@@ -233,6 +244,7 @@ fun SelectLocationScreen(
233244
onCreateCustomList = onCreateCustomList,
234245
onEditCustomLists = onEditCustomLists,
235246
onAddLocationToList = onAddLocationToList,
247+
onRemoveLocationFromList = onRemoveLocationFromList,
236248
onEditCustomListName = onEditCustomListName,
237249
onEditLocationsCustomList = onEditLocationsCustomList,
238250
onDeleteCustomList = onDeleteCustomList,
@@ -331,6 +343,15 @@ fun SelectLocationScreen(
331343
onShowEditBottomSheet = { customList ->
332344
bottomSheetState =
333345
BottomSheetState.ShowEditCustomListBottomSheet(customList)
346+
},
347+
onShowEditCustomListEntryBottomSheet = {
348+
item: RelayItem,
349+
customList: RelayItem.CustomList ->
350+
bottomSheetState =
351+
BottomSheetState.ShowCustomListsEntryBottomSheet(
352+
customList,
353+
item,
354+
)
334355
}
335356
)
336357
item {
@@ -379,7 +400,8 @@ private fun LazyListScope.customLists(
379400
backgroundColor: Color,
380401
onSelectRelay: (item: RelayItem) -> Unit,
381402
onShowCustomListBottomSheet: () -> Unit,
382-
onShowEditBottomSheet: (RelayItem.CustomList) -> Unit
403+
onShowEditBottomSheet: (RelayItem.CustomList) -> Unit,
404+
onShowEditCustomListEntryBottomSheet: (item: RelayItem, RelayItem.CustomList) -> Unit
383405
) {
384406
item(
385407
contentType = { ContentType.HEADER },
@@ -407,6 +429,8 @@ private fun LazyListScope.customLists(
407429
onLongClick = {
408430
if (it is RelayItem.CustomList) {
409431
onShowEditBottomSheet(it)
432+
} else if (it in customList.locations) {
433+
onShowEditCustomListEntryBottomSheet(it, customList)
410434
}
411435
},
412436
modifier = Modifier.animateContentSize().animateItemPlacement(),
@@ -467,6 +491,7 @@ private fun BottomSheets(
467491
onCreateCustomList: (RelayItem?) -> Unit,
468492
onEditCustomLists: () -> Unit,
469493
onAddLocationToList: (RelayItem, RelayItem.CustomList) -> Unit,
494+
onRemoveLocationFromList: (RelayItem, RelayItem.CustomList) -> Unit,
470495
onEditCustomListName: (RelayItem.CustomList) -> Unit,
471496
onEditLocationsCustomList: (RelayItem.CustomList) -> Unit,
472497
onDeleteCustomList: (RelayItem.CustomList) -> Unit,
@@ -522,6 +547,16 @@ private fun BottomSheets(
522547
closeBottomSheet = onCloseBottomSheet
523548
)
524549
}
550+
is BottomSheetState.ShowCustomListsEntryBottomSheet -> {
551+
CustomListEntryBottomSheet(
552+
sheetState = sheetState,
553+
onBackgroundColor = onBackgroundColor,
554+
customList = bottomSheetState.customList,
555+
item = bottomSheetState.item,
556+
onRemoveLocationFromList = onRemoveLocationFromList,
557+
closeBottomSheet = onCloseBottomSheet
558+
)
559+
}
525560
null -> {
526561
/* Do nothing */
527562
}
@@ -715,6 +750,40 @@ private fun EditCustomListBottomSheet(
715750
}
716751
}
717752

753+
@OptIn(ExperimentalMaterial3Api::class)
754+
@Composable
755+
private fun CustomListEntryBottomSheet(
756+
onBackgroundColor: Color,
757+
sheetState: SheetState,
758+
customList: RelayItem.CustomList,
759+
item: RelayItem,
760+
onRemoveLocationFromList: (location: RelayItem, customList: RelayItem.CustomList) -> Unit,
761+
closeBottomSheet: (animate: Boolean) -> Unit
762+
) {
763+
MullvadModalBottomSheet(
764+
sheetState = sheetState,
765+
onDismissRequest = { closeBottomSheet(false) },
766+
modifier = Modifier.testTag(SELECT_LOCATION_LOCATION_BOTTOM_SHEET_TEST_TAG)
767+
) { ->
768+
HeaderCell(
769+
text = stringResource(id = R.string.remove_location_from_list, item.name),
770+
background = Color.Unspecified
771+
)
772+
HorizontalDivider(color = onBackgroundColor)
773+
774+
IconCell(
775+
iconId = R.drawable.ic_remove,
776+
title = stringResource(id = R.string.remove_button),
777+
titleColor = onBackgroundColor,
778+
onClick = {
779+
onRemoveLocationFromList(item, customList)
780+
closeBottomSheet(true)
781+
},
782+
background = Color.Unspecified
783+
)
784+
}
785+
}
786+
718787
private suspend fun LazyListState.animateScrollAndCentralizeItem(index: Int) {
719788
val itemInfo = this.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
720789
if (itemInfo != null) {
@@ -785,6 +854,11 @@ sealed interface BottomSheetState {
785854

786855
data class ShowCustomListsBottomSheet(val editListEnabled: Boolean) : BottomSheetState
787856

857+
data class ShowCustomListsEntryBottomSheet(
858+
val customList: RelayItem.CustomList,
859+
val item: RelayItem
860+
) : BottomSheetState
861+
788862
data class ShowLocationBottomSheet(
789863
val customLists: List<RelayItem.CustomList>,
790864
val item: RelayItem

android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt

+16
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,19 @@ class SelectLocationViewModel(
154154
viewModelScope.launch { customListActionUseCase.performAction(action) }
155155
}
156156

157+
fun removeLocationFromList(item: RelayItem, customList: RelayItem.CustomList) {
158+
viewModelScope.launch {
159+
val newLocations = (customList.locations - item).map { it.code }
160+
val result =
161+
customListActionUseCase.performAction(
162+
CustomListAction.UpdateLocations(customList.id, newLocations)
163+
)
164+
_uiSideEffect.send(
165+
SelectLocationSideEffect.LocationRemovedFromCustomList(result.getOrThrow())
166+
)
167+
}
168+
}
169+
157170
companion object {
158171
private const val EMPTY_SEARCH_TERM = ""
159172
}
@@ -164,4 +177,7 @@ sealed interface SelectLocationSideEffect {
164177

165178
data class LocationAddedToCustomList(val result: CustomListResult.LocationsChanged) :
166179
SelectLocationSideEffect
180+
181+
class LocationRemovedFromCustomList(val result: CustomListResult.LocationsChanged) :
182+
SelectLocationSideEffect
167183
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="960"
5+
android:viewportHeight="960">
6+
<path
7+
android:fillColor="#FF000000"
8+
android:pathData="M200,520v-80h560v80L200,520Z"/>
9+
</vector>

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

+1
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@
311311
<string name="discard_changes">Discard changes?</string>
312312
<string name="discard">Discard</string>
313313
<string name="add_location_to_list">Add %s to list</string>
314+
<string name="remove_location_from_list">Remove %s from list</string>
314315
<string name="location_was_added_to_list">%s was added to \"%s\"</string>
315316
<string name="location_added">%s (added)</string>
316317
<string name="edit_name">Edit name</string>

gui/locales/messages.pot

+3
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,9 @@ msgstr ""
23352335
msgid "Remove"
23362336
msgstr ""
23372337

2338+
msgid "Remove %s from list"
2339+
msgstr ""
2340+
23382341
msgid "Remove custom port"
23392342
msgstr ""
23402343

0 commit comments

Comments
 (0)