diff options
| author | Oskar <oskar@mullvad.net> | 2024-08-29 21:57:04 +0200 |
|---|---|---|
| committer | Oskar <oskar@mullvad.net> | 2024-08-30 20:04:00 +0200 |
| commit | bda71f3d5860ebff96364ca4d8b6d81f3834ff23 (patch) | |
| tree | ac085421bff827ba457842760de8c01203e50fb6 /gui | |
| parent | 7a135fc03fe0179b2e7b905789855dce5085d789 (diff) | |
| download | mullvadvpn-bda71f3d5860ebff96364ca4d8b6d81f3834ff23.tar.xz mullvadvpn-bda71f3d5860ebff96364ca4d8b6d81f3834ff23.zip | |
Move UDP-over-TCP to a dedicated view
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/src/renderer/components/UdpOverTcp.tsx | 126 | ||||
| -rw-r--r-- | gui/src/renderer/components/WireguardSettings.tsx | 72 |
2 files changed, 143 insertions, 55 deletions
diff --git a/gui/src/renderer/components/UdpOverTcp.tsx b/gui/src/renderer/components/UdpOverTcp.tsx new file mode 100644 index 0000000000..7179daca77 --- /dev/null +++ b/gui/src/renderer/components/UdpOverTcp.tsx @@ -0,0 +1,126 @@ +import { useCallback, useMemo } from 'react'; +import styled from 'styled-components'; + +import { liftConstraint, LiftedConstraint, wrapConstraint } from '../../shared/daemon-rpc-types'; +import { messages } from '../../shared/gettext'; +import { useAppContext } from '../context'; +import { useHistory } from '../lib/history'; +import { useSelector } from '../redux/store'; +import { AriaInputGroup } from './AriaGroup'; +import * as Cell from './cell'; +import Selector, { SelectorItem } from './cell/Selector'; +import { BackAction } from './KeyboardNavigation'; +import { Layout, SettingsContainer } from './Layout'; +import { ModalMessage } from './Modal'; +import { + NavigationBar, + NavigationContainer, + NavigationItems, + NavigationScrollbars, + TitleBarItem, +} from './NavigationBar'; +import SettingsHeader, { HeaderTitle } from './SettingsHeader'; + +const UDP2TCP_PORTS = [80, 5001]; + +function mapPortToSelectorItem(value: number): SelectorItem<number> { + return { label: value.toString(), value }; +} + +const StyledContent = styled.div({ + display: 'flex', + flexDirection: 'column', + flex: 1, + marginBottom: '2px', +}); + +const StyledSelectorContainer = styled.div({ + flex: 0, +}); + +export default function UdpOverTcp() { + const { pop } = useHistory(); + + return ( + <BackAction action={pop}> + <Layout> + <SettingsContainer> + <NavigationContainer> + <NavigationBar> + <NavigationItems> + <TitleBarItem> + { + // TRANSLATORS: Title label in navigation bar + messages.pgettext('wireguard-settings-nav', 'UDP-over-TCP') + } + </TitleBarItem> + </NavigationItems> + </NavigationBar> + + <NavigationScrollbars> + <SettingsHeader> + <HeaderTitle> + {messages.pgettext('wireguard-settings-view', 'UDP-over-TCP')} + </HeaderTitle> + </SettingsHeader> + + <StyledContent> + <Cell.Group> + <Udp2tcpPortSetting /> + </Cell.Group> + </StyledContent> + </NavigationScrollbars> + </NavigationContainer> + </SettingsContainer> + </Layout> + </BackAction> + ); +} + +function Udp2tcpPortSetting() { + const { setObfuscationSettings } = useAppContext(); + const obfuscationSettings = useSelector((state) => state.settings.obfuscationSettings); + + const port = liftConstraint(obfuscationSettings.udp2tcpSettings.port); + const portItems: SelectorItem<number>[] = useMemo( + () => UDP2TCP_PORTS.map(mapPortToSelectorItem), + [], + ); + + const selectPort = useCallback( + async (port: LiftedConstraint<number>) => { + await setObfuscationSettings({ + ...obfuscationSettings, + udp2tcpSettings: { + ...obfuscationSettings.udp2tcpSettings, + port: wrapConstraint(port), + }, + }); + }, + [setObfuscationSettings, obfuscationSettings], + ); + + return ( + <AriaInputGroup> + <StyledSelectorContainer> + <Selector + // TRANSLATORS: The title for the UDP-over-TCP port selector. + title={messages.pgettext('wireguard-settings-view', 'UDP-over-TCP port')} + details={ + <ModalMessage> + {messages.pgettext( + 'wireguard-settings-view', + 'Which TCP port the UDP-over-TCP obfuscation protocol should connect to on the VPN server.', + )} + </ModalMessage> + } + items={portItems} + value={port} + onSelect={selectPort} + thinTitle + automaticValue={'any' as const} + /> + </StyledSelectorContainer> + </AriaInputGroup> + ); +} diff --git a/gui/src/renderer/components/WireguardSettings.tsx b/gui/src/renderer/components/WireguardSettings.tsx index df714866cf..f0aa06fb0f 100644 --- a/gui/src/renderer/components/WireguardSettings.tsx +++ b/gui/src/renderer/components/WireguardSettings.tsx @@ -4,9 +4,8 @@ import styled from 'styled-components'; import { strings } from '../../config.json'; import { + Constraint, IpVersion, - liftConstraint, - LiftedConstraint, ObfuscationType, wrapConstraint, } from '../../shared/daemon-rpc-types'; @@ -16,6 +15,7 @@ import { removeNonNumericCharacters } from '../../shared/string-helpers'; import { useAppContext } from '../context'; import { useRelaySettingsUpdater } from '../lib/constraint-updater'; import { useHistory } from '../lib/history'; +import { RoutePath } from '../lib/routes'; import { useBoolean } from '../lib/utilityHooks'; import { useSelector } from '../redux/store'; import * as AppButton from './AppButton'; @@ -38,7 +38,6 @@ import SettingsHeader, { HeaderTitle } from './SettingsHeader'; const MIN_WIREGUARD_MTU_VALUE = 1280; const MAX_WIREGUARD_MTU_VALUE = 1420; const WIREUGARD_UDP_PORTS = [51820, 53]; -const UDP2TCP_PORTS = [80, 5001]; function mapPortToSelectorItem(value: number): SelectorItem<number> { return { label: value.toString(), value }; @@ -96,7 +95,6 @@ export default function WireguardSettings() { <Cell.Group> <ObfuscationSettings /> - <Udp2tcpPortSetting /> </Cell.Group> <Cell.Group> @@ -212,12 +210,24 @@ function ObfuscationSettings() { const { setObfuscationSettings } = useAppContext(); const obfuscationSettings = useSelector((state) => state.settings.obfuscationSettings); + // TRANSLATORS: Text showing currently selected port. + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(port)s - Can be either a number between 1 and 65000 or the text "Automatic". + const subLabelTemplate = messages.pgettext('wireguard-settings-view', 'Port: %(port)s'); + const obfuscationType = obfuscationSettings.selectedObfuscation; const obfuscationTypeItems: SelectorItem<ObfuscationType>[] = useMemo( () => [ { - label: messages.pgettext('wireguard-settings-view', 'On (UDP-over-TCP)'), + label: messages.pgettext('wireguard-settings-view', 'UDP-over-TCP'), + subLabel: sprintf(subLabelTemplate, { + port: formatPortForSubLabel(obfuscationSettings.udp2tcpSettings.port), + }), value: ObfuscationType.udp2tcp, + details: { + path: RoutePath.udpOverTcp, + ariaLabel: messages.pgettext('accessibility', 'UDP-over-TCP settings'), + }, }, { label: messages.gettext('Off'), @@ -261,56 +271,8 @@ function ObfuscationSettings() { ); } -function Udp2tcpPortSetting() { - const { setObfuscationSettings } = useAppContext(); - const obfuscationSettings = useSelector((state) => state.settings.obfuscationSettings); - - const port = liftConstraint(obfuscationSettings.udp2tcpSettings.port); - const portItems: SelectorItem<number>[] = useMemo( - () => UDP2TCP_PORTS.map(mapPortToSelectorItem), - [], - ); - - const expandableProps = useMemo(() => ({ expandable: true, id: 'udp2tcp-port' }), []); - - const selectPort = useCallback( - async (port: LiftedConstraint<number>) => { - await setObfuscationSettings({ - ...obfuscationSettings, - udp2tcpSettings: { - ...obfuscationSettings.udp2tcpSettings, - port: wrapConstraint(port), - }, - }); - }, - [setObfuscationSettings, obfuscationSettings], - ); - - return ( - <AriaInputGroup> - <StyledSelectorContainer> - <Selector - // TRANSLATORS: The title for the UDP-over-TCP port selector. - title={messages.pgettext('wireguard-settings-view', 'UDP-over-TCP port')} - details={ - <ModalMessage> - {messages.pgettext( - 'wireguard-settings-view', - 'Which TCP port the UDP-over-TCP obfuscation protocol should connect to on the VPN server.', - )} - </ModalMessage> - } - items={portItems} - value={port} - onSelect={selectPort} - disabled={obfuscationSettings.selectedObfuscation === ObfuscationType.off} - expandable={expandableProps} - thinTitle - automaticValue={'any' as const} - /> - </StyledSelectorContainer> - </AriaInputGroup> - ); +function formatPortForSubLabel(port: Constraint<number>): string { + return port === 'any' ? messages.gettext('Automatic') : `${port.only}`; } function MultihopSetting() { |
