summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2023-10-17 10:41:44 +0200
committerOskar Nyberg <oskar@mullvad.net>2023-10-17 10:41:44 +0200
commit5f6b0698955a041bed36afd8f0cb2389ca79dc54 (patch)
tree57a5b8b99763f143fe4cc5c3926dfe556eb071fc
parent391268b6e6b864a5f6eeee3c42872156e49cd77f (diff)
parent2f49c7955eb1c5abf8700ac9c3c2408a4529c465 (diff)
downloadmullvadvpn-5f6b0698955a041bed36afd8f0cb2389ca79dc54.tar.xz
mullvadvpn-5f6b0698955a041bed36afd8f0cb2389ca79dc54.zip
Merge branch 'relay-list-filter-shows-incorrect-count-when-having-multiple-des-332'
-rw-r--r--gui/src/renderer/components/Filter.tsx65
-rw-r--r--gui/src/renderer/components/select-location/SelectLocation.tsx4
2 files changed, 45 insertions, 24 deletions
diff --git a/gui/src/renderer/components/Filter.tsx b/gui/src/renderer/components/Filter.tsx
index 6b369aa39b..a8e67b3f9c 100644
--- a/gui/src/renderer/components/Filter.tsx
+++ b/gui/src/renderer/components/Filter.tsx
@@ -61,9 +61,10 @@ export default function Filter() {
const [ownership, setOwnership] = useState<Ownership>(initialOwnership);
// Available providers are used to only show compatible options after activating a filter.
- const { availableProviders, availableOwnershipOptions } = useFilteredFilters(
+ const availableProviders = useFilteredProviders([], ownership);
+ const availableOwnershipOptions = useFilteredOwnershipOptions(
formattedProviderList,
- ownership,
+ Ownership.any,
);
// Applies the changes by sending them to the daemon.
@@ -113,31 +114,21 @@ export default function Filter() {
);
}
-// Returns only the options for each filter that are compatible with current filter selection.
-function useFilteredFilters(providers: string[], ownership: Ownership) {
+// Returns only the ownership options that are compatible with the other filters
+function useFilteredOwnershipOptions(providers: string[], ownership: Ownership): Ownership[] {
const relaySettings = useNormalRelaySettings();
const bridgeState = useSelector((state) => state.settings.bridgeState);
const locations = useSelector((state) => state.settings.relayLocations);
const endpointType = bridgeState === 'on' ? EndpointType.any : EndpointType.exit;
- const availableProviders = useMemo(() => {
- const relayListForEndpointType = filterLocationsByEndPointType(
- locations,
- endpointType,
- relaySettings,
- );
- const relaylistForFilters = filterLocations(relayListForEndpointType, ownership, []);
- return providersFromRelays(relaylistForFilters);
- }, [locations, ownership]);
-
const availableOwnershipOptions = useMemo(() => {
const relayListForEndpointType = filterLocationsByEndPointType(
locations,
endpointType,
relaySettings,
);
- const relaylistForFilters = filterLocations(relayListForEndpointType, Ownership.any, providers);
+ const relaylistForFilters = filterLocations(relayListForEndpointType, ownership, providers);
const filteredRelayOwnership = relaylistForFilters.flatMap((country) =>
country.cities.flatMap((city) => city.relays.map((relay) => relay.owned)),
@@ -152,9 +143,30 @@ function useFilteredFilters(providers: string[], ownership: Ownership) {
}
return ownershipOptions;
- }, [locations, providers]);
+ }, [locations, providers, ownership]);
+
+ return availableOwnershipOptions;
+}
+
+// Returns only the providers that are compatible with the other filters
+export function useFilteredProviders(providers: string[], ownership: Ownership): string[] {
+ const relaySettings = useNormalRelaySettings();
+ const bridgeState = useSelector((state) => state.settings.bridgeState);
+ const locations = useSelector((state) => state.settings.relayLocations);
+
+ const endpointType = bridgeState === 'on' ? EndpointType.any : EndpointType.exit;
+
+ const availableProviders = useMemo(() => {
+ const relayListForEndpointType = filterLocationsByEndPointType(
+ locations,
+ endpointType,
+ relaySettings,
+ );
+ const relaylistForFilters = filterLocations(relayListForEndpointType, ownership, providers);
+ return providersFromRelays(relaylistForFilters);
+ }, [locations, ownership]);
- return { availableProviders, availableOwnershipOptions };
+ return availableProviders;
}
// Returns all available providers in the provided relay list.
@@ -252,15 +264,17 @@ function FilterByProvider(props: IFilterByProviderProps) {
const onToggle = useCallback(
(provider: string) =>
- props.setProviders((providers) => ({ ...providers, [provider]: !providers[provider] })),
- [props.setProviders],
+ props.setProviders((providers) => {
+ const newProviders = { ...providers, [provider]: !providers[provider] };
+ return props.availableOptions.every((provider) => newProviders[provider])
+ ? toggleAllProviders(providers, true)
+ : newProviders;
+ }),
+ [props.availableOptions, props.setProviders],
);
const toggleAll = useCallback(() => {
- props.setProviders((providers) => {
- const shouldSelect = !Object.values(providers).every((value) => value);
- return Object.fromEntries(Object.keys(providers).map((provider) => [provider, shouldSelect]));
- });
+ props.setProviders((providers) => toggleAllProviders(providers));
}, []);
return (
@@ -290,6 +304,11 @@ function FilterByProvider(props: IFilterByProviderProps) {
);
}
+function toggleAllProviders(providers: Record<string, boolean>, value?: boolean) {
+ const shouldSelect = value ?? !Object.values(providers).every((value) => value);
+ return Object.fromEntries(Object.keys(providers).map((provider) => [provider, shouldSelect]));
+}
+
interface IStyledRowTitleProps {
bold?: boolean;
}
diff --git a/gui/src/renderer/components/select-location/SelectLocation.tsx b/gui/src/renderer/components/select-location/SelectLocation.tsx
index 1ea7aeb5aa..c812d84835 100644
--- a/gui/src/renderer/components/select-location/SelectLocation.tsx
+++ b/gui/src/renderer/components/select-location/SelectLocation.tsx
@@ -12,6 +12,7 @@ import { RoutePath } from '../../lib/routes';
import { useNormalBridgeSettings, useNormalRelaySettings } from '../../lib/utilityHooks';
import { useSelector } from '../../redux/store';
import * as Cell from '../cell';
+import { useFilteredProviders } from '../Filter';
import ImageView from '../ImageView';
import { BackAction } from '../KeyboardNavigation';
import { Layout, SettingsContainer } from '../Layout';
@@ -69,6 +70,7 @@ export default function SelectLocation() {
const relaySettings = useNormalRelaySettings();
const ownership = relaySettings?.ownership ?? Ownership.any;
const providers = relaySettings?.providers ?? [];
+ const filteredProviders = useFilteredProviders(providers, ownership);
const [searchValue, setSearchValue] = useState('');
@@ -201,7 +203,7 @@ export default function SelectLocation() {
'select-location-view',
'Providers: %(numberOfProviders)d',
),
- { numberOfProviders: providers.length },
+ { numberOfProviders: filteredProviders.length },
)}
<StyledClearFilterButton
aria-label={messages.gettext('Clear')}