summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src/renderer')
-rw-r--r--gui/src/renderer/components/Filter.tsx12
-rw-r--r--gui/src/renderer/components/OpenVpnSettings.tsx74
-rw-r--r--gui/src/renderer/components/SelectLanguage.tsx6
-rw-r--r--gui/src/renderer/components/VpnSettings.tsx17
-rw-r--r--gui/src/renderer/components/WireguardSettings.tsx93
5 files changed, 92 insertions, 110 deletions
diff --git a/gui/src/renderer/components/Filter.tsx b/gui/src/renderer/components/Filter.tsx
index 79253ed7b0..5c2e7e0f55 100644
--- a/gui/src/renderer/components/Filter.tsx
+++ b/gui/src/renderer/components/Filter.tsx
@@ -191,10 +191,6 @@ function FilterByOwnership(props: IFilterByOwnershipProps) {
() =>
[
{
- label: messages.gettext('Any'),
- value: Ownership.any,
- },
- {
label: messages.pgettext('filter-view', 'Mullvad owned only'),
value: Ownership.mullvadOwned,
},
@@ -220,7 +216,13 @@ function FilterByOwnership(props: IFilterByOwnershipProps) {
</Cell.CellButton>
<Accordion expanded={expanded}>
- <StyledSelector values={values} value={props.ownership} onSelect={props.setOwnership} />
+ <StyledSelector
+ items={values}
+ value={props.ownership}
+ onSelect={props.setOwnership}
+ automaticLabel={messages.gettext('Any')}
+ automaticValue={Ownership.any}
+ />
</Accordion>
</AriaInputGroup>
);
diff --git a/gui/src/renderer/components/OpenVpnSettings.tsx b/gui/src/renderer/components/OpenVpnSettings.tsx
index fce949c6a9..af4404fd1a 100644
--- a/gui/src/renderer/components/OpenVpnSettings.tsx
+++ b/gui/src/renderer/components/OpenVpnSettings.tsx
@@ -7,6 +7,7 @@ import { BridgeState, RelayProtocol, TunnelProtocol } from '../../shared/daemon-
import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
import RelaySettingsBuilder from '../../shared/relay-settings-builder';
+import { removeNonNumericCharacters } from '../../shared/string-helpers';
import { useAppContext } from '../context';
import { useHistory } from '../lib/history';
import { useBoolean } from '../lib/utilityHooks';
@@ -15,7 +16,7 @@ import { useSelector } from '../redux/store';
import * as AppButton from './AppButton';
import { AriaDescription, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup';
import * as Cell from './cell';
-import Selector, { ISelectorItem } from './cell/Selector';
+import Selector, { SelectorItem } from './cell/Selector';
import { BackAction } from './KeyboardNavigation';
import { Layout, SettingsContainer } from './Layout';
import { ModalAlert, ModalAlertType } from './Modal';
@@ -33,17 +34,13 @@ const MAX_MSSFIX_VALUE = 1450;
const UDP_PORTS = [1194, 1195, 1196, 1197, 1300, 1301, 1302];
const TCP_PORTS = [80, 443];
-type OptionalPort = number | undefined;
-
-type OptionalRelayProtocol = RelayProtocol | undefined;
-
export enum BridgeModeAvailability {
available,
blockedDueToTunnelProtocol,
blockedDueToTransportProtocol,
}
-function mapPortToSelectorItem(value: number): ISelectorItem<number> {
+function mapPortToSelectorItem(value: number): SelectorItem<number> {
return { label: value.toString(), value };
}
@@ -127,19 +124,15 @@ function TransportProtocolSelector() {
const bridgeState = useSelector((state) => state.settings.bridgeState);
const protocol = useMemo(() => {
- const protocol = 'normal' in relaySettings ? relaySettings.normal.openvpn.protocol : undefined;
- return protocol === 'any' ? undefined : protocol;
+ const protocol = 'normal' in relaySettings ? relaySettings.normal.openvpn.protocol : 'any';
+ return protocol === 'any' ? null : protocol;
}, [relaySettings]);
const protocolAndPortUpdater = useProtocolAndPortUpdater();
- const items: ISelectorItem<OptionalRelayProtocol>[] = useMemo(
+ const items: SelectorItem<RelayProtocol>[] = useMemo(
() => [
{
- label: messages.gettext('Automatic'),
- value: undefined,
- },
- {
label: messages.gettext('TCP'),
value: 'tcp',
},
@@ -157,9 +150,10 @@ function TransportProtocolSelector() {
<AriaInputGroup>
<Selector
title={messages.pgettext('openvpn-settings-view', 'Transport protocol')}
- values={items}
+ items={items}
value={protocol}
onSelect={protocolAndPortUpdater}
+ automaticValue={null}
/>
{bridgeState === 'on' && (
<Cell.Footer>
@@ -186,7 +180,7 @@ function useProtocolAndPortUpdater() {
const { updateRelaySettings } = useAppContext();
const updater = useCallback(
- async (protocol?: RelayProtocol, port?: number) => {
+ async (protocol: RelayProtocol | null, port?: number | null) => {
const relayUpdate = RelaySettingsBuilder.normal()
.tunnel.openvpn((openvpn) => {
if (protocol) {
@@ -220,35 +214,30 @@ function PortSelector() {
const relaySettings = useSelector((state) => state.settings.relaySettings);
const protocol = useMemo(() => {
- const protocol = 'normal' in relaySettings ? relaySettings.normal.openvpn.protocol : undefined;
- return protocol === 'any' ? undefined : protocol;
+ const protocol = 'normal' in relaySettings ? relaySettings.normal.openvpn.protocol : 'any';
+ return protocol === 'any' ? null : protocol;
}, [relaySettings]);
const port = useMemo(() => {
- const port = 'normal' in relaySettings ? relaySettings.normal.openvpn.port : undefined;
- return port === 'any' ? undefined : port;
+ const port = 'normal' in relaySettings ? relaySettings.normal.openvpn.port : 'any';
+ return port === 'any' ? null : port;
}, [relaySettings]);
const protocolAndPortUpdater = useProtocolAndPortUpdater();
const onSelect = useCallback(
- async (port?: number) => {
+ async (port: number | null) => {
await protocolAndPortUpdater(protocol, port);
},
[protocolAndPortUpdater, protocol],
);
- const automaticPort: ISelectorItem<OptionalPort> = {
- label: messages.gettext('Automatic'),
- value: undefined,
- };
-
const portItems = {
- udp: [automaticPort].concat(UDP_PORTS.map(mapPortToSelectorItem)),
- tcp: [automaticPort].concat(TCP_PORTS.map(mapPortToSelectorItem)),
+ udp: UDP_PORTS.map(mapPortToSelectorItem),
+ tcp: TCP_PORTS.map(mapPortToSelectorItem),
};
- if (protocol === undefined) {
+ if (protocol === null) {
return null;
}
@@ -265,9 +254,10 @@ function PortSelector() {
portType: protocol.toUpperCase(),
},
)}
- values={portItems[protocol]}
+ items={portItems[protocol]}
value={port}
onSelect={onSelect}
+ automaticValue={null}
/>
</AriaInputGroup>
</StyledSelectorContainer>
@@ -281,22 +271,18 @@ function BridgeModeSelector() {
const bridgeState = useSelector((state) => state.settings.bridgeState);
const tunnelProtocol = useMemo(() => {
- const protocol = 'normal' in relaySettings ? relaySettings.normal.tunnelProtocol : undefined;
- return protocol === 'any' ? undefined : protocol;
+ const protocol = 'normal' in relaySettings ? relaySettings.normal.tunnelProtocol : 'any';
+ return protocol === 'any' ? null : protocol;
}, [relaySettings]);
const transportProtocol = useMemo(() => {
- const protocol = 'normal' in relaySettings ? relaySettings.normal.openvpn.protocol : undefined;
- return protocol === 'any' ? undefined : protocol;
+ const protocol = 'normal' in relaySettings ? relaySettings.normal.openvpn.protocol : 'any';
+ return protocol === 'any' ? null : protocol;
}, [relaySettings]);
- const options: ISelectorItem<BridgeState>[] = useMemo(
+ const options: SelectorItem<BridgeState>[] = useMemo(
() => [
{
- label: messages.gettext('Automatic'),
- value: 'auto',
- },
- {
label: messages.gettext('On'),
value: 'on',
disabled: tunnelProtocol !== 'openvpn' || transportProtocol === 'udp',
@@ -348,9 +334,10 @@ function BridgeModeSelector() {
// TRANSLATORS: The title for the shadowsocks bridge selector section.
messages.pgettext('openvpn-settings-view', 'Bridge mode')
}
- values={options}
+ items={options}
value={bridgeState}
onSelect={onSelectBridgeState}
+ automaticValue={'auto' as const}
/>
</StyledSelectorContainer>
<Cell.Footer>
@@ -379,7 +366,10 @@ function BridgeModeSelector() {
);
}
-function bridgeModeFooterText(tunnelProtocol?: TunnelProtocol, transportProtocol?: RelayProtocol) {
+function bridgeModeFooterText(
+ tunnelProtocol: TunnelProtocol | null,
+ transportProtocol: RelayProtocol | null,
+) {
if (tunnelProtocol !== 'openvpn') {
return formatMarkdown(
sprintf(
@@ -433,10 +423,6 @@ function bridgeModeFooterText(tunnelProtocol?: TunnelProtocol, transportProtocol
}
}
-function removeNonNumericCharacters(value: string) {
- return value.replace(/[^0-9]/g, '');
-}
-
function mssfixIsValid(mssfix: string): boolean {
const parsedMssFix = mssfix ? parseInt(mssfix) : undefined;
return (
diff --git a/gui/src/renderer/components/SelectLanguage.tsx b/gui/src/renderer/components/SelectLanguage.tsx
index 419557f700..2b11f0a924 100644
--- a/gui/src/renderer/components/SelectLanguage.tsx
+++ b/gui/src/renderer/components/SelectLanguage.tsx
@@ -3,7 +3,7 @@ import styled from 'styled-components';
import { messages } from '../../shared/gettext';
import { AriaInputGroup } from './AriaGroup';
-import Selector, { ISelectorItem } from './cell/Selector';
+import Selector, { SelectorItem } from './cell/Selector';
import { CustomScrollbarsRef } from './CustomScrollbars';
import { BackAction } from './KeyboardNavigation';
import { Layout, SettingsContainer } from './Layout';
@@ -24,7 +24,7 @@ interface IProps {
}
interface IState {
- source: Array<ISelectorItem<string>>;
+ source: Array<SelectorItem<string>>;
}
const StyledNavigationScrollbars = styled(NavigationScrollbars)({
@@ -79,7 +79,7 @@ export default class SelectLanguage extends React.Component<IProps, IState> {
<AriaInputGroup>
<StyledSelector
title=""
- values={this.state.source}
+ items={this.state.source}
value={this.props.preferredLocale}
onSelect={this.props.setPreferredLocale}
selectedCellRef={this.selectedCellRef}
diff --git a/gui/src/renderer/components/VpnSettings.tsx b/gui/src/renderer/components/VpnSettings.tsx
index 47b48e4fcd..76d8a782b6 100644
--- a/gui/src/renderer/components/VpnSettings.tsx
+++ b/gui/src/renderer/components/VpnSettings.tsx
@@ -17,7 +17,7 @@ import { useSelector } from '../redux/store';
import * as AppButton from './AppButton';
import { AriaDescription, AriaDetails, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup';
import * as Cell from './cell';
-import Selector, { ISelectorItem } from './cell/Selector';
+import Selector, { SelectorItem } from './cell/Selector';
import CustomDnsSettings from './CustomDnsSettings';
import InfoButton, { InfoIcon } from './InfoButton';
import { BackAction } from './KeyboardNavigation';
@@ -612,10 +612,10 @@ function TunnelProtocolSetting() {
);
const { updateRelaySettings } = useAppContext();
- const setTunnelProtocol = useCallback(async (tunnelProtocol: TunnelProtocol | undefined) => {
+ const setTunnelProtocol = useCallback(async (tunnelProtocol: TunnelProtocol | null) => {
const relayUpdate = RelaySettingsBuilder.normal()
.tunnel.tunnelProtocol((config) => {
- if (tunnelProtocol) {
+ if (tunnelProtocol !== null) {
config.tunnelProtocol.exact(tunnelProtocol);
} else {
config.tunnelProtocol.any();
@@ -630,13 +630,9 @@ function TunnelProtocolSetting() {
}
}, []);
- const tunnelProtocolItems: Array<ISelectorItem<TunnelProtocol | undefined>> = useMemo(
+ const tunnelProtocolItems: Array<SelectorItem<TunnelProtocol>> = useMemo(
() => [
{
- label: messages.gettext('Automatic'),
- value: undefined,
- },
- {
label: strings.wireguard,
value: 'wireguard',
},
@@ -653,9 +649,10 @@ function TunnelProtocolSetting() {
<StyledSelectorContainer>
<Selector
title={messages.pgettext('vpn-settings-view', 'Tunnel protocol')}
- values={tunnelProtocolItems}
- value={tunnelProtocol}
+ items={tunnelProtocolItems}
+ value={tunnelProtocol ?? null}
onSelect={setTunnelProtocol}
+ automaticValue={null}
/>
</StyledSelectorContainer>
</AriaInputGroup>
diff --git a/gui/src/renderer/components/WireguardSettings.tsx b/gui/src/renderer/components/WireguardSettings.tsx
index 222e845001..919b37a9e7 100644
--- a/gui/src/renderer/components/WireguardSettings.tsx
+++ b/gui/src/renderer/components/WireguardSettings.tsx
@@ -11,6 +11,7 @@ import {
} from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
+import { removeNonNumericCharacters } from '../../shared/string-helpers';
import { useAppContext } from '../context';
import { createWireguardRelayUpdater } from '../lib/constraint-updater';
import { useHistory } from '../lib/history';
@@ -19,7 +20,7 @@ import { useSelector } from '../redux/store';
import * as AppButton from './AppButton';
import { AriaDescription, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup';
import * as Cell from './cell';
-import Selector, { ISelectorItem } from './cell/Selector';
+import Selector, { SelectorItem } from './cell/Selector';
import { InfoIcon } from './InfoButton';
import { BackAction } from './KeyboardNavigation';
import { Layout, SettingsContainer } from './Layout';
@@ -38,10 +39,7 @@ const MAX_WIREGUARD_MTU_VALUE = 1420;
const WIREUGARD_UDP_PORTS = [51820, 53];
const UDP2TCP_PORTS = [80, 443, 5001];
-type OptionalPort = number | undefined;
-type OptionalIpVersion = IpVersion | undefined;
-
-function mapPortToSelectorItem(value: number): ISelectorItem<number> {
+function mapPortToSelectorItem(value: number): SelectorItem<number> {
return { label: value.toString(), value };
}
@@ -132,25 +130,21 @@ function PortSelector() {
const relaySettings = useSelector((state) => state.settings.relaySettings);
const { updateRelaySettings } = useAppContext();
- const wireguardPortItems = useMemo(() => {
- const automaticPort: ISelectorItem<OptionalPort> = {
- label: messages.gettext('Automatic'),
- value: undefined,
- };
-
- return [automaticPort].concat(WIREUGARD_UDP_PORTS.map(mapPortToSelectorItem));
- }, []);
+ const wireguardPortItems = useMemo<Array<SelectorItem<number>>>(
+ () => WIREUGARD_UDP_PORTS.map(mapPortToSelectorItem),
+ [],
+ );
const port = useMemo(() => {
- const port = 'normal' in relaySettings ? relaySettings.normal.wireguard.port : undefined;
- return port === 'any' ? undefined : port;
+ const port = 'normal' in relaySettings ? relaySettings.normal.wireguard.port : 'any';
+ return port === 'any' ? null : port;
}, [relaySettings]);
const setWireguardPort = useCallback(
- async (port?: number) => {
+ async (port: number | null) => {
const relayUpdate = createWireguardRelayUpdater(relaySettings)
.tunnel.wireguard((wireguard) => {
- if (port) {
+ if (port !== null) {
wireguard.port.exact(port);
} else {
wireguard.port.any();
@@ -173,9 +167,26 @@ function PortSelector() {
<Selector
// TRANSLATORS: The title for the WireGuard port selector.
title={messages.pgettext('wireguard-settings-view', 'Port')}
- values={wireguardPortItems}
+ items={wireguardPortItems}
value={port}
onSelect={setWireguardPort}
+ automaticValue={null}
+ details={
+ <>
+ <ModalMessage>
+ {messages.pgettext(
+ 'wireguard-settings-view',
+ 'The automatic setting will randomly choose from the valid port ranges shown below.',
+ )}
+ </ModalMessage>
+ <ModalMessage>
+ {messages.pgettext(
+ 'wireguard-settings-view',
+ 'The custom port can be any value inside the valid ranges: 53, 4000-33433, 33565-51820, 52000-60000.',
+ )}
+ </ModalMessage>
+ </>
+ }
/>
</StyledSelectorContainer>
<Cell.Footer>
@@ -200,13 +211,9 @@ function ObfuscationSettings() {
const obfuscationSettings = useSelector((state) => state.settings.obfuscationSettings);
const obfuscationType = obfuscationSettings.selectedObfuscation;
- const obfuscationTypeItems: ISelectorItem<ObfuscationType>[] = useMemo(
+ const obfuscationTypeItems: SelectorItem<ObfuscationType>[] = useMemo(
() => [
{
- label: messages.gettext('Automatic'),
- value: ObfuscationType.auto,
- },
- {
label: messages.pgettext('wireguard-settings-view', 'On (UDP-over-TCP)'),
value: ObfuscationType.udp2tcp,
},
@@ -242,9 +249,10 @@ function ObfuscationSettings() {
)}
</ModalMessage>
}
- values={obfuscationTypeItems}
+ items={obfuscationTypeItems}
value={obfuscationType}
onSelect={selectObfuscationType}
+ automaticValue={ObfuscationType.auto}
/>
</StyledSelectorContainer>
</AriaInputGroup>
@@ -256,14 +264,10 @@ function Udp2tcpPortSetting() {
const obfuscationSettings = useSelector((state) => state.settings.obfuscationSettings);
const port = liftConstraint(obfuscationSettings.udp2tcpSettings.port);
- const portItems: ISelectorItem<LiftedConstraint<number>>[] = useMemo(() => {
- const automaticItem: ISelectorItem<LiftedConstraint<number>> = {
- label: messages.gettext('Automatic'),
- value: 'any',
- };
-
- return [automaticItem].concat(UDP2TCP_PORTS.map(mapPortToSelectorItem));
- }, []);
+ const portItems: SelectorItem<number>[] = useMemo(
+ () => UDP2TCP_PORTS.map(mapPortToSelectorItem),
+ [],
+ );
const selectPort = useCallback(
async (port: LiftedConstraint<number>) => {
@@ -292,12 +296,13 @@ function Udp2tcpPortSetting() {
)}
</ModalMessage>
}
- values={portItems}
+ items={portItems}
value={port}
onSelect={selectPort}
disabled={obfuscationSettings.selectedObfuscation === ObfuscationType.off}
expandable
thinTitle
+ automaticValue={'any' as const}
/>
</StyledSelectorContainer>
</AriaInputGroup>
@@ -401,18 +406,13 @@ function IpVersionSetting() {
const { updateRelaySettings } = useAppContext();
const relaySettings = useSelector((state) => state.settings.relaySettings);
const ipVersion = useMemo(() => {
- const ipVersion =
- 'normal' in relaySettings ? relaySettings.normal.wireguard.ipVersion : undefined;
- return ipVersion === 'any' ? undefined : ipVersion;
+ const ipVersion = 'normal' in relaySettings ? relaySettings.normal.wireguard.ipVersion : 'any';
+ return ipVersion === 'any' ? null : ipVersion;
}, [relaySettings]);
- const ipVersionItems: ISelectorItem<OptionalIpVersion>[] = useMemo(
+ const ipVersionItems: SelectorItem<IpVersion>[] = useMemo(
() => [
{
- label: messages.gettext('Automatic'),
- value: undefined,
- },
- {
label: messages.gettext('IPv4'),
value: 'ipv4',
},
@@ -425,10 +425,10 @@ function IpVersionSetting() {
);
const setIpVersion = useCallback(
- async (ipVersion?: IpVersion) => {
+ async (ipVersion: IpVersion | null) => {
const relayUpdate = createWireguardRelayUpdater(relaySettings)
.tunnel.wireguard((wireguard) => {
- if (ipVersion) {
+ if (ipVersion !== null) {
wireguard.ipVersion.exact(ipVersion);
} else {
wireguard.ipVersion.any();
@@ -451,9 +451,10 @@ function IpVersionSetting() {
<Selector
// TRANSLATORS: The title for the WireGuard IP version selector.
title={messages.pgettext('wireguard-settings-view', 'IP version')}
- values={ipVersionItems}
+ items={ipVersionItems}
value={ipVersion}
onSelect={setIpVersion}
+ automaticValue={null}
/>
</StyledSelectorContainer>
<Cell.Footer>
@@ -476,10 +477,6 @@ function IpVersionSetting() {
);
}
-function removeNonNumericCharacters(value: string) {
- return value.replace(/[^0-9]/g, '');
-}
-
function mtuIsValid(mtu: string): boolean {
const parsedMtu = mtu ? parseInt(mtu) : undefined;
return (