diff options
| author | Hank <hank@mullvad.net> | 2022-10-13 12:33:19 +0200 |
|---|---|---|
| committer | Hank <hank@mullvad.net> | 2022-10-18 12:55:40 +0200 |
| commit | 2fe9f440a3a0ec18482bd80bd7ff6d83b5c044b5 (patch) | |
| tree | 9bbbcfced92bb21dea6631f37f2e476649e48834 /gui/src/renderer | |
| parent | efe2100400eb9b9a701f21ba6358c6dc451ac6fd (diff) | |
| download | mullvadvpn-2fe9f440a3a0ec18482bd80bd7ff6d83b5c044b5.tar.xz mullvadvpn-2fe9f440a3a0ec18482bd80bd7ff6d83b5c044b5.zip | |
Make SelectLocationPage use hooks
Diffstat (limited to 'gui/src/renderer')
| -rw-r--r-- | gui/src/renderer/containers/SelectLocationPage.tsx | 219 |
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} + /> + ); +} |
