1
1
package net.mullvad.mullvadvpn.repository
2
2
3
+ import arrow.optics.Every
4
+ import arrow.optics.copy
5
+ import arrow.optics.dsl.every
3
6
import kotlinx.coroutines.CoroutineDispatcher
4
7
import kotlinx.coroutines.CoroutineScope
5
8
import kotlinx.coroutines.Dispatchers
6
9
import kotlinx.coroutines.flow.Flow
7
10
import kotlinx.coroutines.flow.SharingStarted
8
11
import kotlinx.coroutines.flow.StateFlow
12
+ import kotlinx.coroutines.flow.combine
9
13
import kotlinx.coroutines.flow.distinctUntilChanged
10
14
import kotlinx.coroutines.flow.map
11
15
import kotlinx.coroutines.flow.stateIn
@@ -17,18 +21,48 @@ import net.mullvad.mullvadvpn.lib.model.RelayItem
17
21
import net.mullvad.mullvadvpn.lib.model.RelayItemId
18
22
import net.mullvad.mullvadvpn.lib.model.WireguardConstraints
19
23
import net.mullvad.mullvadvpn.lib.model.WireguardEndpointData
24
+ import net.mullvad.mullvadvpn.lib.model.cities
25
+ import net.mullvad.mullvadvpn.lib.model.name
26
+ import net.mullvad.mullvadvpn.lib.shared.RelayLocationTranslationRepository
20
27
import net.mullvad.mullvadvpn.relaylist.findByGeoLocationId
28
+ import net.mullvad.mullvadvpn.util.sortedByName
21
29
22
30
class RelayListRepository (
23
31
private val managementService : ManagementService ,
32
+ private val translationRepository : RelayLocationTranslationRepository ,
24
33
dispatcher : CoroutineDispatcher = Dispatchers .IO
25
34
) {
26
35
val relayList: StateFlow <List <RelayItem .Location .Country >> =
27
- managementService.relayCountries.stateIn(
28
- CoroutineScope (dispatcher),
29
- SharingStarted .WhileSubscribed (),
30
- emptyList()
31
- )
36
+ combine(managementService.relayCountries, translationRepository.translations) {
37
+ countries,
38
+ translations ->
39
+ countries.translateRelay(translations)
40
+ }
41
+ .stateIn(CoroutineScope (dispatcher), SharingStarted .WhileSubscribed (), emptyList())
42
+
43
+ private fun List<RelayItem.Location.Country>.translateRelay (
44
+ translations : Map <String , String >
45
+ ): List <RelayItem .Location .Country > {
46
+ if (translations.isEmpty()) {
47
+ return this
48
+ }
49
+
50
+ return Every .list<RelayItem .Location .Country >()
51
+ .modify(this ) {
52
+ it.copy<RelayItem .Location .Country > {
53
+ RelayItem .Location .Country .name set translations.getOrDefault(it.name, it.name)
54
+ RelayItem .Location .Country .cities.every(Every .list()).name transform
55
+ { cityName ->
56
+ translations.getOrDefault(cityName, cityName)
57
+ }
58
+ RelayItem .Location .Country .cities transform
59
+ { cities ->
60
+ cities.sortedByName { it.name }
61
+ }
62
+ }
63
+ }
64
+ .sortedByName { it.name }
65
+ }
32
66
33
67
val wireguardEndpointData: StateFlow <WireguardEndpointData > =
34
68
managementService.wireguardEndpointData.stateIn(
0 commit comments