diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2023-10-09 10:36:33 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2023-10-09 10:36:33 +0200 |
| commit | 817866f1843b6b9366153fdfa31288af9e80c26b (patch) | |
| tree | 7e921f6b1673954c80c67a9e54765d36d67560ec /gui/src/renderer/lib | |
| parent | c1f9e782da8d8cd5731fe43017f056b184f126c9 (diff) | |
| parent | 9551fd134a993636ffedcbe42d8d2b1407e93ddf (diff) | |
| download | mullvadvpn-817866f1843b6b9366153fdfa31288af9e80c26b.tar.xz mullvadvpn-817866f1843b6b9366153fdfa31288af9e80c26b.zip | |
Merge branch 'custom-lists-gui-des-198'
Diffstat (limited to 'gui/src/renderer/lib')
| -rw-r--r-- | gui/src/renderer/lib/filter-locations.ts | 87 |
1 files changed, 52 insertions, 35 deletions
diff --git a/gui/src/renderer/lib/filter-locations.ts b/gui/src/renderer/lib/filter-locations.ts index e2a4c5d96d..63ca56cbf2 100644 --- a/gui/src/renderer/lib/filter-locations.ts +++ b/gui/src/renderer/lib/filter-locations.ts @@ -1,9 +1,14 @@ import { Ownership, RelayEndpointType, RelayLocation } from '../../shared/daemon-rpc-types'; import { relayLocations } from '../../shared/gettext'; -import { SpecialLocation } from '../components/select-location/select-location-types'; +import { + RelayLocationCityWithVisibility, + RelayLocationCountryWithVisibility, + RelayLocationRelayWithVisibility, + SpecialLocation, +} from '../components/select-location/select-location-types'; import { IRelayLocationCityRedux, - IRelayLocationRedux, + IRelayLocationCountryRedux, IRelayLocationRelayRedux, NormalRelaySettingsRedux, } from '../redux/settings/reducers'; @@ -15,18 +20,18 @@ export enum EndpointType { } export function filterLocationsByEndPointType( - locations: IRelayLocationRedux[], + locations: IRelayLocationCountryRedux[], endpointType: EndpointType, relaySettings?: NormalRelaySettingsRedux, -): IRelayLocationRedux[] { +): IRelayLocationCountryRedux[] { return filterLocationsImpl(locations, getTunnelProtocolFilter(endpointType, relaySettings)); } export function filterLocations( - locations: IRelayLocationRedux[], + locations: IRelayLocationCountryRedux[], ownership?: Ownership, providers?: Array<string>, -): IRelayLocationRedux[] { +): IRelayLocationCountryRedux[] { const filters = [getOwnershipFilter(ownership), getProviderFilter(providers)]; return filters.some((filter) => filter !== undefined) @@ -74,9 +79,9 @@ function getProviderFilter( } function filterLocationsImpl( - locations: Array<IRelayLocationRedux>, + locations: Array<IRelayLocationCountryRedux>, filter: (relay: IRelayLocationRelayRedux) => boolean, -): Array<IRelayLocationRedux> { +): Array<IRelayLocationCountryRedux> { return locations .map((country) => ({ ...country, @@ -88,39 +93,50 @@ function filterLocationsImpl( } export function searchForLocations( - countries: Array<IRelayLocationRedux>, + countries: Array<IRelayLocationCountryRedux>, searchTerm: string, -): Array<IRelayLocationRedux> { - if (searchTerm === '') { - return countries; - } - - return countries.reduce((countries, country) => { - const matchingCities = searchCities(country.cities, searchTerm); - const expanded = matchingCities.length > 0; +): Array<RelayLocationCountryWithVisibility> { + return countries.map((country) => { const match = - search(searchTerm, country.code) || search(searchTerm, relayLocations.gettext(country.name)); - const resultingCities = match ? country.cities : matchingCities; - return expanded || match ? [...countries, { ...country, cities: resultingCities }] : countries; - }, [] as Array<IRelayLocationRedux>); + searchTerm === '' || + searchMatch(searchTerm, country.code) || + searchMatch(searchTerm, relayLocations.gettext(country.name)); + const cities = searchCities(country.cities, searchTerm, match); + const expanded = cities.some((city) => city.visible); + return { ...country, cities: cities, visible: expanded || match }; + }); } function searchCities( cities: Array<IRelayLocationCityRedux>, searchTerm: string, -): Array<IRelayLocationCityRedux> { - return cities.reduce((cities, city) => { - const matchingRelays = city.relays.filter((relay) => search(searchTerm, relay.hostname)); - const expanded = matchingRelays.length > 0; + countryMatch: boolean, +): Array<RelayLocationCityWithVisibility> { + return cities.map((city) => { const match = - search(searchTerm, city.code) || search(searchTerm, relayLocations.gettext(city.name)); - const resultingRelays = match ? city.relays : matchingRelays; - return expanded || match ? [...cities, { ...city, relays: resultingRelays }] : cities; - }, [] as Array<IRelayLocationCityRedux>); + searchTerm === '' || + countryMatch || + searchMatch(searchTerm, city.code) || + searchMatch(searchTerm, relayLocations.gettext(city.name)); + const relays = searchRelays(city.relays, searchTerm, match); + const expanded = match || relays.some((relay) => relay.visible); + return { ...city, relays: relays, visible: expanded }; + }); +} + +function searchRelays( + relays: Array<IRelayLocationRelayRedux>, + searchTerm: string, + cityMatch: boolean, +): Array<RelayLocationRelayWithVisibility> { + return relays.map((relay) => ({ + ...relay, + visible: searchTerm === '' || cityMatch || searchMatch(searchTerm, relay.hostname), + })); } export function getLocationsExpandedBySearch( - countries: Array<IRelayLocationRedux>, + countries: Array<IRelayLocationCountryRedux>, searchTerm: string, ): Array<RelayLocation> { return countries.reduce((locations, country) => { @@ -130,7 +146,7 @@ export function getLocationsExpandedBySearch( searchTerm, ); const cityMatches = country.cities.some( - (city) => search(searchTerm, city.code) || search(searchTerm, city.name), + (city) => searchMatch(searchTerm, city.code) || searchMatch(searchTerm, city.name), ); const location = { country: country.code }; const expanded = cityMatches || cityLocations.length > 0; @@ -144,13 +160,14 @@ function getCityLocationsExpandecBySearch( searchTerm: string, ): Array<RelayLocation> { return cities.reduce((locations, city) => { - const expanded = city.relays.filter((relay) => search(searchTerm, relay.hostname)).length > 0; - const location: RelayLocation = { city: [countryCode, city.code] }; + const expanded = + city.relays.filter((relay) => searchMatch(searchTerm, relay.hostname)).length > 0; + const location: RelayLocation = { country: countryCode, city: city.code }; return expanded ? [...locations, location] : locations; }, [] as Array<RelayLocation>); } -function search(searchTerm: string, value: string): boolean { +export function searchMatch(searchTerm: string, value: string): boolean { return value.toLowerCase().includes(searchTerm.toLowerCase()); } @@ -158,5 +175,5 @@ export function filterSpecialLocations<T>( searchTerm: string, locations: Array<SpecialLocation<T>>, ): Array<SpecialLocation<T>> { - return locations.filter((location) => search(searchTerm, location.label)); + return locations.filter((location) => searchMatch(searchTerm, location.label)); } |
