Skip to content

Commit 747cf86

Browse files
committed
Support new relay list item in SelectLocationScreen
1 parent 885f371 commit 747cf86

File tree

5 files changed

+49
-39
lines changed

5 files changed

+49
-39
lines changed

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

+21-22
Original file line numberDiff line numberDiff line change
@@ -38,32 +38,28 @@ import net.mullvad.mullvadvpn.lib.theme.color.AlphaInvisible
3838
import net.mullvad.mullvadvpn.lib.theme.color.AlphaVisible
3939
import net.mullvad.mullvadvpn.lib.theme.color.selected
4040
import net.mullvad.mullvadvpn.model.GeographicLocationConstraint
41-
import net.mullvad.mullvadvpn.relaylist.Relay
42-
import net.mullvad.mullvadvpn.relaylist.RelayCity
43-
import net.mullvad.mullvadvpn.relaylist.RelayCountry
4441
import net.mullvad.mullvadvpn.relaylist.RelayItem
45-
import net.mullvad.mullvadvpn.relaylist.RelayItemType
4642

4743
@Composable
4844
@Preview
4945
private fun PreviewRelayLocationCell() {
5046
AppTheme {
5147
Column(Modifier.background(color = MaterialTheme.colorScheme.background)) {
5248
val countryActive =
53-
RelayCountry(
49+
RelayItem.Country(
5450
name = "Relay country Active",
5551
code = "RC1",
5652
expanded = false,
5753
cities =
5854
listOf(
59-
RelayCity(
55+
RelayItem.City(
6056
name = "Relay city 1",
6157
code = "RI1",
6258
expanded = false,
6359
location = GeographicLocationConstraint.City("RC1", "RI1"),
6460
relays =
6561
listOf(
66-
Relay(
62+
RelayItem.Relay(
6763
name = "Relay 1",
6864
active = true,
6965
locationName = "",
@@ -76,14 +72,14 @@ private fun PreviewRelayLocationCell() {
7672
)
7773
)
7874
),
79-
RelayCity(
75+
RelayItem.City(
8076
name = "Relay city 2",
8177
code = "RI2",
8278
expanded = true,
8379
location = GeographicLocationConstraint.City("RC1", "RI2"),
8480
relays =
8581
listOf(
86-
Relay(
82+
RelayItem.Relay(
8783
name = "Relay 2",
8884
active = true,
8985
locationName = "",
@@ -94,7 +90,7 @@ private fun PreviewRelayLocationCell() {
9490
"NER"
9591
)
9692
),
97-
Relay(
93+
RelayItem.Relay(
9894
name = "Relay 3",
9995
active = true,
10096
locationName = "",
@@ -110,20 +106,20 @@ private fun PreviewRelayLocationCell() {
110106
)
111107
)
112108
val countryNotActive =
113-
RelayCountry(
109+
RelayItem.Country(
114110
name = "Not Enabled Relay country",
115111
code = "RC3",
116112
expanded = true,
117113
cities =
118114
listOf(
119-
RelayCity(
115+
RelayItem.City(
120116
name = "Not Enabled city",
121117
code = "RI3",
122118
expanded = true,
123119
location = GeographicLocationConstraint.City("RC3", "RI3"),
124120
relays =
125121
listOf(
126-
Relay(
122+
RelayItem.Relay(
127123
name = "Not Enabled Relay",
128124
active = false,
129125
locationName = "",
@@ -158,23 +154,24 @@ fun RelayLocationCell(
158154
onSelectRelay: (item: RelayItem) -> Unit = {}
159155
) {
160156
val startPadding =
161-
when (relay.type) {
162-
RelayItemType.Country -> Dimens.countryRowPadding
163-
RelayItemType.City -> Dimens.cityRowPadding
164-
RelayItemType.Relay -> Dimens.relayRowPadding
157+
when (relay) {
158+
is RelayItem.Country,
159+
is RelayItem.CustomList -> Dimens.countryRowPadding
160+
is RelayItem.City -> Dimens.cityRowPadding
161+
is RelayItem.Relay -> Dimens.relayRowPadding
165162
}
166163
val selected = selectedItem?.code == relay.code
167164
val expanded =
168165
rememberSaveable(key = relay.expanded.toString()) { mutableStateOf(relay.expanded) }
169166
val backgroundColor =
170167
when {
171168
selected -> MaterialTheme.colorScheme.inversePrimary
172-
relay.type == RelayItemType.Country -> MaterialTheme.colorScheme.primary
173-
relay.type == RelayItemType.City ->
169+
relay is RelayItem.Country -> MaterialTheme.colorScheme.primary
170+
relay is RelayItem.City ->
174171
MaterialTheme.colorScheme.primary
175172
.copy(alpha = Alpha40)
176173
.compositeOver(MaterialTheme.colorScheme.background)
177-
relay.type == RelayItemType.Relay -> MaterialTheme.colorScheme.secondaryContainer
174+
relay is RelayItem.Relay -> MaterialTheme.colorScheme.secondaryContainer
178175
else -> MaterialTheme.colorScheme.primary
179176
}
180177
Column(
@@ -273,7 +270,7 @@ fun RelayLocationCell(
273270
}
274271
if (expanded.value) {
275272
when (relay) {
276-
is RelayCountry -> {
273+
is RelayItem.Country -> {
277274
relay.cities.forEach { relayCity ->
278275
RelayLocationCell(
279276
relay = relayCity,
@@ -283,7 +280,7 @@ fun RelayLocationCell(
283280
)
284281
}
285282
}
286-
is RelayCity -> {
283+
is RelayItem.City -> {
287284
relay.relays.forEach { relay ->
288285
RelayLocationCell(
289286
relay = relay,
@@ -293,6 +290,8 @@ fun RelayLocationCell(
293290
)
294291
}
295292
}
293+
is RelayItem.Relay,
294+
is RelayItem.CustomList -> {}
296295
}
297296
}
298297
}

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

+19-11
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import net.mullvad.mullvadvpn.compose.transitions.SelectLocationTransition
5353
import net.mullvad.mullvadvpn.lib.theme.AppTheme
5454
import net.mullvad.mullvadvpn.lib.theme.Dimens
5555
import net.mullvad.mullvadvpn.lib.theme.color.AlphaScrollbar
56-
import net.mullvad.mullvadvpn.relaylist.RelayCountry
5756
import net.mullvad.mullvadvpn.relaylist.RelayItem
5857
import net.mullvad.mullvadvpn.viewmodel.SelectLocationSideEffect
5958
import net.mullvad.mullvadvpn.viewmodel.SelectLocationViewModel
@@ -69,8 +68,9 @@ private fun PreviewSelectLocationScreen() {
6968
selectedProvidersCount = 0,
7069
relayListState =
7170
RelayListState.RelayList(
72-
countries = listOf(RelayCountry("Country 1", "Code 1", false, emptyList())),
73-
selectedRelay = null,
71+
countries =
72+
listOf(RelayItem.Country("Country 1", "Code 1", false, emptyList())),
73+
selectedItem = null,
7474
)
7575
)
7676
AppTheme {
@@ -172,14 +172,10 @@ fun SelectLocationScreen(
172172
if (
173173
uiState is SelectLocationUiState.Data &&
174174
uiState.relayListState is RelayListState.RelayList &&
175-
uiState.relayListState.selectedRelay != null
175+
uiState.relayListState.selectedItem != null
176176
) {
177-
LaunchedEffect(uiState.relayListState.selectedRelay) {
178-
val index =
179-
uiState.relayListState.countries.indexOfFirst { relayCountry ->
180-
relayCountry.location.location.country ==
181-
uiState.relayListState.selectedRelay.location.location.country
182-
}
177+
LaunchedEffect(uiState.relayListState.selectedItem) {
178+
val index = uiState.relayListState.indexOfSelectedRelayItem()
183179

184180
if (index >= 0) {
185181
lazyListState.scrollToItem(index)
@@ -235,7 +231,7 @@ private fun LazyListScope.relayList(
235231
val country = relayListState.countries[index]
236232
RelayLocationCell(
237233
relay = country,
238-
selectedItem = relayListState.selectedRelay,
234+
selectedItem = relayListState.selectedItem,
239235
onSelectRelay = onSelectRelay,
240236
modifier = Modifier.animateContentSize()
241237
)
@@ -279,6 +275,18 @@ private fun LazyListScope.relayList(
279275
}
280276
}
281277

278+
private fun RelayListState.RelayList.indexOfSelectedRelayItem(): Int =
279+
countries.indexOfFirst { relayCountry ->
280+
relayCountry.location.location.country ==
281+
when (selectedItem) {
282+
is RelayItem.Country -> selectedItem.code
283+
is RelayItem.City -> selectedItem.location.countryCode
284+
is RelayItem.Relay -> selectedItem.location.countryCode
285+
is RelayItem.CustomList,
286+
null -> null
287+
}
288+
}
289+
282290
suspend fun LazyListState.animateScrollAndCentralizeItem(index: Int) {
283291
val itemInfo = this.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
284292
if (itemInfo != null) {

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/SelectLocationUiState.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package net.mullvad.mullvadvpn.compose.state
22

33
import net.mullvad.mullvadvpn.model.Ownership
4-
import net.mullvad.mullvadvpn.relaylist.RelayCountry
54
import net.mullvad.mullvadvpn.relaylist.RelayItem
65

76
sealed interface SelectLocationUiState {
@@ -21,6 +20,6 @@ sealed interface SelectLocationUiState {
2120
sealed interface RelayListState {
2221
data object Empty : RelayListState
2322

24-
data class RelayList(val countries: List<RelayCountry>, val selectedRelay: RelayItem?) :
23+
data class RelayList(val countries: List<RelayItem.Country>, val selectedItem: RelayItem?) :
2524
RelayListState
2625
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import net.mullvad.mullvadvpn.lib.ipc.MessageHandler
1515
import net.mullvad.mullvadvpn.lib.payment.PaymentProvider
1616
import net.mullvad.mullvadvpn.repository.AccountRepository
1717
import net.mullvad.mullvadvpn.repository.ChangelogRepository
18+
import net.mullvad.mullvadvpn.repository.CustomListsRepository
1819
import net.mullvad.mullvadvpn.repository.DeviceRepository
1920
import net.mullvad.mullvadvpn.repository.InAppNotificationController
2021
import net.mullvad.mullvadvpn.repository.PrivacyDisclaimerRepository
@@ -98,6 +99,7 @@ val uiModule = module {
9899
}
99100
single { SettingsRepository(get()) }
100101
single { MullvadProblemReport(get()) }
102+
single { CustomListsRepository(get()) }
101103

102104
single { AccountExpiryNotificationUseCase(get()) }
103105
single { TunnelStateNotificationUseCase(get()) }

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import net.mullvad.mullvadvpn.model.Ownership
2020
import net.mullvad.mullvadvpn.relaylist.Provider
2121
import net.mullvad.mullvadvpn.relaylist.RelayItem
2222
import net.mullvad.mullvadvpn.relaylist.filterOnSearchTerm
23+
import net.mullvad.mullvadvpn.relaylist.toLocationConstraint
2324
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
2425
import net.mullvad.mullvadvpn.ui.serviceconnection.connectionProxy
2526
import net.mullvad.mullvadvpn.usecase.RelayListFilterUseCase
@@ -40,7 +41,7 @@ class SelectLocationViewModel(
4041
relayListFilterUseCase.availableProviders(),
4142
relayListFilterUseCase.selectedProviders()
4243
) {
43-
(relayCountries, relayItem),
44+
(customList, relayCountries, selectedItem),
4445
searchTerm,
4546
selectedOwnership,
4647
allProviders,
@@ -54,7 +55,7 @@ class SelectLocationViewModel(
5455
?.size
5556

5657
val filteredRelayCountries =
57-
relayCountries.filterOnSearchTerm(searchTerm, relayItem)
58+
relayCountries.filterOnSearchTerm(searchTerm, selectedItem)
5859

5960
SelectLocationUiState.Data(
6061
searchTerm = searchTerm,
@@ -64,7 +65,7 @@ class SelectLocationViewModel(
6465
if (filteredRelayCountries.isNotEmpty()) {
6566
RelayListState.RelayList(
6667
countries = filteredRelayCountries,
67-
selectedRelay = relayItem
68+
selectedItem = selectedItem
6869
)
6970
} else {
7071
RelayListState.Empty
@@ -85,7 +86,8 @@ class SelectLocationViewModel(
8586
}
8687

8788
fun selectRelay(relayItem: RelayItem) {
88-
relayListUseCase.updateSelectedRelayLocation(relayItem.location)
89+
val locationConstraint = relayItem.toLocationConstraint()
90+
relayListUseCase.updateSelectedRelayLocation(locationConstraint)
8991
serviceConnectionManager.connectionProxy()?.connect()
9092
viewModelScope.launch { _uiSideEffect.send(SelectLocationSideEffect.CloseScreen) }
9193
}

0 commit comments

Comments
 (0)