summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer
diff options
context:
space:
mode:
authorHank <hank@mullvad.net>2022-10-13 12:33:19 +0200
committerHank <hank@mullvad.net>2022-10-18 12:55:40 +0200
commit2fe9f440a3a0ec18482bd80bd7ff6d83b5c044b5 (patch)
tree9bbbcfced92bb21dea6631f37f2e476649e48834 /gui/src/renderer
parentefe2100400eb9b9a701f21ba6358c6dc451ac6fd (diff)
downloadmullvadvpn-2fe9f440a3a0ec18482bd80bd7ff6d83b5c044b5.tar.xz
mullvadvpn-2fe9f440a3a0ec18482bd80bd7ff6d83b5c044b5.zip
Make SelectLocationPage use hooks
Diffstat (limited to 'gui/src/renderer')
-rw-r--r--gui/src/renderer/containers/SelectLocationPage.tsx219
1 files changed, 135 insertions, 84 deletions
diff --git a/gui/src/renderer/containers/SelectLocationPage.tsx b/gui/src/renderer/containers/SelectLocationPage.tsx
index 3ca4ca94ac..5c72bc7d28 100644
--- a/gui/src/renderer/containers/SelectLocationPage.tsx
+++ b/gui/src/renderer/containers/SelectLocationPage.tsx
@@ -1,104 +1,114 @@
-import { connect } from 'react-redux';
+import { useCallback, useEffect, useMemo, useState } from 'react';
import BridgeSettingsBuilder from '../../shared/bridge-settings-builder';
import { LiftedConstraint, Ownership, RelayLocation } from '../../shared/daemon-rpc-types';
import log from '../../shared/logging';
import RelaySettingsBuilder from '../../shared/relay-settings-builder';
import SelectLocation from '../components/SelectLocation';
-import withAppContext, { IAppContext } from '../context';
+import { useAppContext } from '../context';
import { createWireguardRelayUpdater } from '../lib/constraint-updater';
import filterLocations from '../lib/filter-locations';
-import { IHistoryProps, withHistory } from '../lib/history';
+import { useHistory } from '../lib/history';
import { RoutePath } from '../lib/routes';
-import { IReduxState, ReduxDispatch } from '../redux/store';
+import { RelaySettingsRedux } from '../redux/settings/reducers';
+import { useSelector } from '../redux/store';
-const mapStateToProps = (state: IReduxState, props: IHistoryProps & IAppContext) => {
- let selectedExitLocation: RelayLocation | undefined;
- let selectedEntryLocation: RelayLocation | undefined;
- let selectedBridgeLocation: LiftedConstraint<RelayLocation> | undefined;
- let multihopEnabled = false;
-
- if ('normal' in state.settings.relaySettings) {
- const exitLocation = state.settings.relaySettings.normal.location;
+const getExitLocation = (relaySettings: RelaySettingsRedux): RelayLocation | undefined => {
+ if ('normal' in relaySettings) {
+ const exitLocation = relaySettings.normal.location;
if (exitLocation !== 'any') {
- selectedExitLocation = exitLocation;
+ return exitLocation;
}
}
+ return undefined;
+};
- const relaySettings = state.settings.relaySettings;
- const tunnelProtocol = 'normal' in relaySettings ? relaySettings.normal.tunnelProtocol : 'any';
+export default function SelectLocationPage() {
+ const history = useHistory();
- if (tunnelProtocol === 'openvpn' && 'normal' in state.settings.bridgeSettings) {
- selectedBridgeLocation = state.settings.bridgeSettings.normal.location;
- } else if ('normal' in relaySettings) {
- multihopEnabled = relaySettings.normal.wireguard.useMultihop;
+ const { updateRelaySettings, connectTunnel, updateBridgeSettings } = useAppContext();
- const entryLocation = relaySettings.normal.wireguard.entryLocation;
- if (multihopEnabled && entryLocation !== 'any') {
- selectedEntryLocation = entryLocation;
- }
- }
+ const locale = useSelector((state) => state.userInterface.locale);
+ const settings = useSelector((state) => state.settings);
+ const { relaySettings, bridgeSettings, bridgeState } = settings;
- const allowEntrySelection =
- (tunnelProtocol === 'openvpn' && state.settings.bridgeState === 'on') ||
- ((tunnelProtocol === 'any' || tunnelProtocol === 'wireguard') && multihopEnabled);
+ const [multihopEnabled, setMultihopEnabled] = useState(false);
+ const [selectedExitLocation, setSelectedExitLocation] = useState<RelayLocation | undefined>(() =>
+ getExitLocation(relaySettings),
+ );
+ const [selectedEntryLocation, setSelectedEntryLocation] = useState<RelayLocation>();
+ const [selectedBridgeLocation, setSelectedBridgeLocation] = useState<
+ LiftedConstraint<RelayLocation>
+ >();
- const providers = 'normal' in relaySettings ? relaySettings.normal.providers : [];
- const ownership = 'normal' in relaySettings ? relaySettings.normal.ownership : Ownership.any;
+ const providers = useMemo(
+ () => ('normal' in relaySettings ? relaySettings.normal.providers : []),
+ [relaySettings],
+ );
- return {
- locale: state.userInterface.locale,
- selectedExitLocation,
- selectedEntryLocation,
- selectedBridgeLocation,
- relayLocations: filterLocations(state.settings.relayLocations, providers, ownership),
- bridgeLocations: filterLocations(state.settings.bridgeLocations, providers, ownership),
- allowEntrySelection,
- tunnelProtocol,
- providers,
- ownership,
+ const ownership = useMemo(
+ () => ('normal' in relaySettings ? relaySettings.normal.ownership : Ownership.any),
+ [relaySettings],
+ );
- onSelectEntryLocation: async (entryLocation: RelayLocation) => {
- // dismiss the view first
- props.history.dismiss();
+ const tunnelProtocol = useMemo(
+ () => ('normal' in relaySettings ? relaySettings.normal.tunnelProtocol : 'any'),
+ [relaySettings],
+ );
- const relayUpdate = createWireguardRelayUpdater(state.settings.relaySettings)
- .tunnel.wireguard((wireguard) => wireguard.entryLocation.exact(entryLocation))
- .build();
+ const allowEntrySelection = useMemo(() => {
+ return (
+ (tunnelProtocol === 'openvpn' && bridgeState === 'on') ||
+ ((tunnelProtocol === 'any' || tunnelProtocol === 'wireguard') && multihopEnabled)
+ );
+ }, [tunnelProtocol, bridgeState, multihopEnabled]);
+
+ const relayLocations = filterLocations(settings.relayLocations, providers, ownership);
+ const bridgeLocations = filterLocations(settings.bridgeLocations, providers, ownership);
+ const onClose = useCallback(() => history.dismiss(), [history]);
+ const onViewFilter = useCallback(() => history.push(RoutePath.filter), [history]);
+ const onSelectExitLocation = useCallback(
+ async (relayLocation: RelayLocation) => {
+ // dismiss the view first
+ history.dismiss();
try {
- await props.app.updateRelaySettings(relayUpdate);
+ const relayUpdate = RelaySettingsBuilder.normal().location.fromRaw(relayLocation).build();
+
+ await updateRelaySettings(relayUpdate);
+ await connectTunnel();
} catch (e) {
const error = e as Error;
- log.error('Failed to select the entry location', error.message);
+ log.error(`Failed to select the exit location: ${error.message}`);
}
},
- };
-};
-const mapDispatchToProps = (_dispatch: ReduxDispatch, props: IHistoryProps & IAppContext) => {
- return {
- onClose: () => props.history.dismiss(),
- onViewFilter: () => props.history.push(RoutePath.filter),
- onSelectExitLocation: async (relayLocation: RelayLocation) => {
+ [connectTunnel, updateRelaySettings, history],
+ );
+ const onSelectEntryLocation = useCallback(
+ async (entryLocation: RelayLocation) => {
// dismiss the view first
- props.history.dismiss();
+ history.dismiss();
- try {
- const relayUpdate = RelaySettingsBuilder.normal().location.fromRaw(relayLocation).build();
+ const relayUpdate = createWireguardRelayUpdater(relaySettings)
+ .tunnel.wireguard((wireguard) => wireguard.entryLocation.exact(entryLocation))
+ .build();
- await props.app.updateRelaySettings(relayUpdate);
- await props.app.connectTunnel();
+ try {
+ await updateRelaySettings(relayUpdate);
} catch (e) {
const error = e as Error;
- log.error(`Failed to select the exit location: ${error.message}`);
+ log.error('Failed to select the entry location', error.message);
}
},
- onSelectBridgeLocation: async (bridgeLocation: RelayLocation) => {
+ [history, relaySettings, updateRelaySettings],
+ );
+ const onSelectBridgeLocation = useCallback(
+ async (bridgeLocation: RelayLocation) => {
// dismiss the view first
- props.history.dismiss();
+ history.dismiss();
try {
- await props.app.updateBridgeSettings(
+ await updateBridgeSettings(
new BridgeSettingsBuilder().location.fromRaw(bridgeLocation).build(),
);
} catch (e) {
@@ -106,26 +116,67 @@ const mapDispatchToProps = (_dispatch: ReduxDispatch, props: IHistoryProps & IAp
log.error(`Failed to select the bridge location: ${error.message}`);
}
},
- onSelectClosestToExit: async () => {
- // dismiss the view first
- props.history.dismiss();
+ [history, updateBridgeSettings],
+ );
+ const onSelectClosestToExit = useCallback(async () => {
+ history.dismiss();
- try {
- await props.app.updateBridgeSettings(new BridgeSettingsBuilder().location.any().build());
- } catch (e) {
- const error = e as Error;
- log.error(`Failed to set the bridge location to closest to exit: ${error.message}`);
+ try {
+ await updateBridgeSettings(new BridgeSettingsBuilder().location.any().build());
+ } catch (e) {
+ const error = e as Error;
+ log.error(`Failed to set the bridge location to closest to exit: ${error.message}`);
+ }
+ }, [updateBridgeSettings, history]);
+
+ const onClearProviders = useCallback(async () => {
+ await updateRelaySettings({ normal: { providers: [] } });
+ }, [updateRelaySettings]);
+
+ const onClearOwnership = useCallback(async () => {
+ await updateRelaySettings({ normal: { ownership: Ownership.any } });
+ }, [updateRelaySettings]);
+
+ useEffect(() => {
+ if (tunnelProtocol === 'openvpn' && 'normal' in bridgeSettings) {
+ setSelectedBridgeLocation(bridgeSettings.normal.location);
+ } else if ('normal' in relaySettings) {
+ setMultihopEnabled(relaySettings.normal.wireguard.useMultihop);
+
+ const entryLocation = relaySettings.normal.wireguard.entryLocation;
+ if (multihopEnabled && entryLocation !== 'any') {
+ setSelectedEntryLocation(entryLocation);
}
- },
- onClearProviders: async () => {
- await props.app.updateRelaySettings({ normal: { providers: [] } });
- },
- onClearOwnership: async () => {
- await props.app.updateRelaySettings({ normal: { ownership: Ownership.any } });
- },
- };
-};
+ }
+ }, [multihopEnabled, tunnelProtocol, bridgeSettings, relaySettings]);
+
+ useEffect(() => {
+ const exitLocation = getExitLocation(relaySettings);
+ if (exitLocation) {
+ setSelectedExitLocation(exitLocation);
+ }
+ }, [relaySettings]);
-export default withAppContext(
- withHistory(connect(mapStateToProps, mapDispatchToProps)(SelectLocation)),
-);
+ return (
+ <SelectLocation
+ locale={locale}
+ selectedExitLocation={selectedExitLocation}
+ selectedEntryLocation={selectedEntryLocation}
+ selectedBridgeLocation={selectedBridgeLocation}
+ relayLocations={relayLocations}
+ bridgeLocations={bridgeLocations}
+ allowEntrySelection={allowEntrySelection}
+ tunnelProtocol={tunnelProtocol}
+ providers={providers}
+ ownership={ownership}
+ onClose={onClose}
+ onViewFilter={onViewFilter}
+ onSelectExitLocation={onSelectExitLocation}
+ onSelectEntryLocation={onSelectEntryLocation}
+ onSelectBridgeLocation={onSelectBridgeLocation}
+ onSelectClosestToExit={onSelectClosestToExit}
+ onClearProviders={onClearProviders}
+ onClearOwnership={onClearOwnership}
+ />
+ );
+}