summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorOskar <oskar@mullvad.net>2024-08-29 21:57:04 +0200
committerOskar <oskar@mullvad.net>2024-08-30 20:04:00 +0200
commitbda71f3d5860ebff96364ca4d8b6d81f3834ff23 (patch)
treeac085421bff827ba457842760de8c01203e50fb6 /gui
parent7a135fc03fe0179b2e7b905789855dce5085d789 (diff)
downloadmullvadvpn-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.tsx126
-rw-r--r--gui/src/renderer/components/WireguardSettings.tsx72
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() {