summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/src/config.json5
-rw-r--r--gui/src/renderer/components/AdvancedSettings.tsx20
-rw-r--r--gui/src/renderer/components/CustomDnsSettings.tsx17
-rw-r--r--gui/src/renderer/components/OpenVPNSettings.tsx78
-rw-r--r--gui/src/renderer/components/SplitTunnelingSettings.tsx8
-rw-r--r--gui/src/renderer/components/WireguardSettings.tsx43
-rw-r--r--gui/src/shared/notifications/block-when-disconnected.ts12
-rw-r--r--gui/src/shared/notifications/error.ts32
8 files changed, 156 insertions, 59 deletions
diff --git a/gui/src/config.json b/gui/src/config.json
index c573e0214b..4bb1e7a6ce 100644
--- a/gui/src/config.json
+++ b/gui/src/config.json
@@ -34,5 +34,10 @@
"red45": "rgba(227, 64, 57, 0.45)",
"green90": "rgba(68, 173, 77, 0.9)",
"green40": "rgba(68, 173, 77, 0.4)"
+ },
+ "strings": {
+ "wireguard": "WireGuard",
+ "openvpn": "OpenVPN",
+ "splitTunneling": "Split tunneling"
}
}
diff --git a/gui/src/renderer/components/AdvancedSettings.tsx b/gui/src/renderer/components/AdvancedSettings.tsx
index 4e6485a6e6..b00fc77f4c 100644
--- a/gui/src/renderer/components/AdvancedSettings.tsx
+++ b/gui/src/renderer/components/AdvancedSettings.tsx
@@ -1,5 +1,7 @@
import * as React from 'react';
+import { sprintf } from 'sprintf-js';
+import { strings } from '../../config.json';
import { TunnelProtocol } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import {
@@ -56,11 +58,11 @@ export default class AdvancedSettings extends React.Component<IProps, IState> {
value: undefined,
},
{
- label: messages.pgettext('advanced-settings-view', 'WireGuard'),
+ label: strings.wireguard,
value: 'wireguard',
},
{
- label: messages.pgettext('advanced-settings-view', 'OpenVPN'),
+ label: strings.openvpn,
value: 'openvpn',
},
];
@@ -146,7 +148,7 @@ export default class AdvancedSettings extends React.Component<IProps, IState> {
{(window.env.platform === 'linux' || window.env.platform === 'win32') && (
<Cell.CellButtonGroup>
<Cell.CellButton onClick={this.props.onViewSplitTunneling}>
- <Cell.Label>Split tunneling</Cell.Label>
+ <Cell.Label>{strings.splitTunneling}</Cell.Label>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
</Cell.CellButtonGroup>
@@ -168,7 +170,11 @@ export default class AdvancedSettings extends React.Component<IProps, IState> {
onClick={this.props.onViewWireguardSettings}
disabled={this.props.tunnelProtocol === 'openvpn'}>
<Cell.Label>
- {messages.pgettext('advanced-settings-view', 'WireGuard settings')}
+ {sprintf(
+ // TRANSLATORS: %(wireguard)s will be replaced with the string "WireGuard"
+ messages.pgettext('advanced-settings-view', '%(wireguard)s settings'),
+ { wireguard: strings.wireguard },
+ )}
</Cell.Label>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
@@ -177,7 +183,11 @@ export default class AdvancedSettings extends React.Component<IProps, IState> {
onClick={this.props.onViewOpenVpnSettings}
disabled={this.props.tunnelProtocol === 'wireguard'}>
<Cell.Label>
- {messages.pgettext('advanced-settings-view', 'OpenVPN settings')}
+ {sprintf(
+ // TRANSLATORS: %(openvpn)s will be replaced with the string "OpenVPN"
+ messages.pgettext('advanced-settings-view', '%(openvpn)s settings'),
+ { openvpn: strings.openvpn },
+ )}
</Cell.Label>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
diff --git a/gui/src/renderer/components/CustomDnsSettings.tsx b/gui/src/renderer/components/CustomDnsSettings.tsx
index 8c06ae8029..3ab38cf3c3 100644
--- a/gui/src/renderer/components/CustomDnsSettings.tsx
+++ b/gui/src/renderer/components/CustomDnsSettings.tsx
@@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { sprintf } from 'sprintf-js';
-import { colors } from '../../config.json';
+import { colors, strings } from '../../config.json';
import { messages } from '../../shared/gettext';
import { useAppContext } from '../context';
import { IpAddress } from '../lib/ip';
@@ -415,9 +415,18 @@ function ConfirmationDialog(props: IConfirmationDialogProps) {
</AppButton.BlueButton>,
]}
close={props.abort}
- message={messages.pgettext(
- 'advanced-settings-view',
- 'The DNS server you want to add is public and will only work with WireGuard. To ensure that it always works, set the "Tunnel protocol" (in Advanced settings) to WireGuard.',
+ message={sprintf(
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(tunnelProtocol)s - the name of the tunnel protocol setting
+ // TRANSLATORS: %(wireguard)s - will be replaced with "WireGuard"
+ messages.pgettext(
+ 'advanced-settings-view',
+ 'The DNS server you want to add is public and will only work with %(wireguard)s. To ensure that it always works, set the "%(tunnelProtocol)s" (in Advanced settings) to %(wireguard)s.',
+ ),
+ {
+ wireguard: strings.wireguard,
+ tunnelProtocol: messages.pgettext('advanced-settings-view', 'Tunnel protocol'),
+ },
)}></ModalAlert>
);
}
diff --git a/gui/src/renderer/components/OpenVPNSettings.tsx b/gui/src/renderer/components/OpenVPNSettings.tsx
index fdbbd2305e..4aac83014f 100644
--- a/gui/src/renderer/components/OpenVPNSettings.tsx
+++ b/gui/src/renderer/components/OpenVPNSettings.tsx
@@ -2,6 +2,7 @@ import * as React from 'react';
import { sprintf } from 'sprintf-js';
import styled from 'styled-components';
+import { strings } from '../../config.json';
import { BridgeState, RelayProtocol } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import { formatMarkdown } from '../markdown-formatter';
@@ -94,10 +95,13 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> {
<NavigationBar>
<NavigationItems>
<TitleBarItem>
- {
+ {sprintf(
// TRANSLATORS: Title label in navigation bar
- messages.pgettext('openvpn-settings-nav', 'OpenVPN settings')
- }
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(openvpn)s - Will be replaced with "OpenVPN"
+ messages.pgettext('openvpn-settings-nav', '%(openvpn)s settings'),
+ { openvpn: strings.openvpn },
+ )}
</TitleBarItem>
</NavigationItems>
</NavigationBar>
@@ -105,7 +109,13 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> {
<StyledNavigationScrollbars>
<SettingsHeader>
<HeaderTitle>
- {messages.pgettext('openvpn-settings-view', 'OpenVPN settings')}
+ {sprintf(
+ // TRANSLATORS: %(openvpn)s will be replaced with "OpenVPN"
+ messages.pgettext('openvpn-settings-view', '%(openvpn)s settings'),
+ {
+ openvpn: strings.openvpn,
+ },
+ )}
</HeaderTitle>
</SettingsHeader>
@@ -206,13 +216,15 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> {
{sprintf(
// TRANSLATORS: The hint displayed below the Mssfix input field.
// TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(openvpn)s - will be replaced with "OpenVPN"
// TRANSLATORS: %(max)d - the maximum possible mssfix value
// TRANSLATORS: %(min)d - the minimum possible mssfix value
messages.pgettext(
'openvpn-settings-view',
- 'Set OpenVPN MSS value. Valid range: %(min)d - %(max)d.',
+ 'Set %(openvpn)s MSS value. Valid range: %(min)d - %(max)d.',
),
{
+ openvpn: strings.openvpn,
min: MIN_MSSFIX_VALUE,
max: MAX_MSSFIX_VALUE,
},
@@ -298,29 +310,53 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> {
switch (this.props.bridgeModeAvailablity) {
case BridgeModeAvailability.blockedDueToTunnelProtocol:
return formatMarkdown(
- // TRANSLATORS: This is used to instruct users how to make the bridge mode setting
- // TRANSLATORS: available.
- messages.pgettext(
- 'openvpn-settings-view',
- 'To activate Bridge mode, go back and change **Tunnel protocol** to **OpenVPN**.',
+ sprintf(
+ // TRANSLATORS: This is used to instruct users how to make the bridge mode setting
+ // TRANSLATORS: available.
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(tunnelProtocol)s - the name of the tunnel protocol setting
+ // TRANSLATORS: %(openvpn)s - will be replaced with OpenVPN
+ messages.pgettext(
+ 'openvpn-settings-view',
+ 'To activate Bridge mode, go back and change **%(tunnelProtocol)s** to **%(openvpn)s**.',
+ ),
+ {
+ tunnelProtocol: messages.pgettext('advanced-settings-view', 'Tunnel protocol'),
+ openvpn: strings.openvpn,
+ },
),
);
case BridgeModeAvailability.blockedDueToTransportProtocol:
return formatMarkdown(
- // TRANSLATORS: This is used to instruct users how to make the bridge mode setting
- // TRANSLATORS: available.
- messages.pgettext(
- 'openvpn-settings-view',
- 'To activate Bridge mode, change **Transport protocol** to **Automatic** or **TCP**.',
+ sprintf(
+ // TRANSLATORS: This is used to instruct users how to make the bridge mode setting
+ // TRANSLATORS: available.
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(transportProtocol)s - the name of the transport protocol setting
+ // TRANSLATORS: %(automat)s - the translation of "Automatic"
+ // TRANSLATORS: %(openvpn)s - will be replaced with OpenVPN
+ messages.pgettext(
+ 'openvpn-settings-view',
+ 'To activate Bridge mode, change **%(transportProtocol)s** to **%(automatic)s** or **%(tcp)s**.',
+ ),
+ {
+ transportProtocol: messages.pgettext('openvpn-settings-view', 'Transport protocol'),
+ automatic: messages.gettext('Automatic'),
+ tcp: messages.gettext('TCP'),
+ },
),
);
case BridgeModeAvailability.available:
- // This line is here to prevent prettier from moving up the next line.
- // TRANSLATORS: This is used as a description for the bridge mode
- // TRANSLATORS: setting.
- return messages.pgettext(
- 'openvpn-settings-view',
- 'Helps circumvent censorship, by routing your traffic through a bridge server before reaching an OpenVPN server. Obfuscation is added to make fingerprinting harder.',
+ return sprintf(
+ // TRANSLATORS: This is used as a description for the bridge mode
+ // TRANSLATORS: setting.
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(openvpn)s - will be replaced with OpenVPN
+ messages.pgettext(
+ 'openvpn-settings-view',
+ 'Helps circumvent censorship, by routing your traffic through a bridge server before reaching an %(openvpn)s server. Obfuscation is added to make fingerprinting harder.',
+ ),
+ { openvpn: strings.openvpn },
);
}
}
diff --git a/gui/src/renderer/components/SplitTunnelingSettings.tsx b/gui/src/renderer/components/SplitTunnelingSettings.tsx
index c77673953b..77af2b4905 100644
--- a/gui/src/renderer/components/SplitTunnelingSettings.tsx
+++ b/gui/src/renderer/components/SplitTunnelingSettings.tsx
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useSelector } from 'react-redux';
import { sprintf } from 'sprintf-js';
-import { colors } from '../../config.json';
+import { colors, strings } from '../../config.json';
import {
IApplication,
ILinuxSplitTunnelingApplication,
@@ -67,7 +67,7 @@ export default function SplitTunneling() {
<NavigationContainer>
<NavigationBar>
<NavigationItems>
- <TitleBarItem>Split tunneling</TitleBarItem>
+ <TitleBarItem>{strings.splitTunneling}</TitleBarItem>
</NavigationItems>
</NavigationBar>
@@ -168,7 +168,7 @@ function LinuxSplitTunnelingSettings(props: IPlatformSplitTunnelingSettingsProps
return (
<>
<SettingsHeader>
- <HeaderTitle>Split tunneling</HeaderTitle>
+ <HeaderTitle>{strings.splitTunneling}</HeaderTitle>
<HeaderSubTitle>
{messages.pgettext(
'split-tunneling-view',
@@ -415,7 +415,7 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett
<>
<SettingsHeader>
<StyledHeaderTitleContainer>
- <StyledHeaderTitle>Split tunneling</StyledHeaderTitle>
+ <StyledHeaderTitle>{strings.splitTunneling}</StyledHeaderTitle>
<Switch isOn={splitTunnelingEnabled} onChange={setSplitTunnelingState} />
</StyledHeaderTitleContainer>
<HeaderSubTitle>
diff --git a/gui/src/renderer/components/WireguardSettings.tsx b/gui/src/renderer/components/WireguardSettings.tsx
index 1235735012..20c3009574 100644
--- a/gui/src/renderer/components/WireguardSettings.tsx
+++ b/gui/src/renderer/components/WireguardSettings.tsx
@@ -2,6 +2,7 @@ import * as React from 'react';
import { sprintf } from 'sprintf-js';
import styled from 'styled-components';
+import { strings } from '../../config.json';
import { IpVersion } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import * as AppButton from './AppButton';
@@ -104,10 +105,13 @@ export default class WireguardSettings extends React.Component<IProps, IState> {
<NavigationBar>
<NavigationItems>
<TitleBarItem>
- {
+ {sprintf(
// TRANSLATORS: Title label in navigation bar
- messages.pgettext('wireguard-settings-nav', 'WireGuard settings')
- }
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(wireguard)s - Will be replaced with the string "WireGuard"
+ messages.pgettext('wireguard-settings-nav', '%(wireguard)s settings'),
+ { wireguard: strings.wireguard },
+ )}
</TitleBarItem>
</NavigationItems>
</NavigationBar>
@@ -115,7 +119,12 @@ export default class WireguardSettings extends React.Component<IProps, IState> {
<StyledNavigationScrollbars>
<SettingsHeader>
<HeaderTitle>
- {messages.pgettext('wireguard-settings-view', 'WireGuard settings')}
+ {sprintf(
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(wireguard)s - Will be replaced with the string "WireGuard"
+ messages.pgettext('wireguard-settings-view', '%(wireguard)s settings'),
+ { wireguard: strings.wireguard },
+ )}
</HeaderTitle>
</SettingsHeader>
@@ -165,13 +174,16 @@ export default class WireguardSettings extends React.Component<IProps, IState> {
<Cell.Footer>
<AriaDescription>
<Cell.FooterText>
- {
+ {sprintf(
// TRANSLATORS: Description for multihop settings toggle.
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(wireguard)s - Will be replaced with the string "WireGuard"
messages.pgettext(
'advanced-settings-view',
- 'Increases anonymity by routing your traffic into one WireGuard server and out another, making it harder to trace.',
- )
- }
+ 'Increases anonymity by routing your traffic into one %(wireguard)s server and out another, making it harder to trace.',
+ ),
+ { wireguard: strings.wireguard },
+ )}
</Cell.FooterText>
</AriaDescription>
</Cell.Footer>
@@ -190,13 +202,16 @@ export default class WireguardSettings extends React.Component<IProps, IState> {
<Cell.Footer>
<AriaDescription>
<Cell.FooterText>
- {
+ {sprintf(
// TRANSLATORS: The hint displayed below the WireGuard IP version selector.
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(wireguard)s - Will be replaced with the string "WireGuard"
messages.pgettext(
'wireguard-settings-view',
- 'This allows access to WireGuard for devices that only support IPv6.',
- )
- }
+ 'This allows access to %(wireguard)s for devices that only support IPv6.',
+ ),
+ { wireguard: strings.wireguard },
+ )}
</Cell.FooterText>
</AriaDescription>
</Cell.Footer>
@@ -228,13 +243,15 @@ export default class WireguardSettings extends React.Component<IProps, IState> {
{sprintf(
// TRANSLATORS: The hint displayed below the WireGuard MTU input field.
// TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(wireguard)s - Will be replaced with the string "WireGuard"
// TRANSLATORS: %(max)d - the maximum possible wireguard mtu value
// TRANSLATORS: %(min)d - the minimum possible wireguard mtu value
messages.pgettext(
'wireguard-settings-view',
- 'Set WireGuard MTU value. Valid range: %(min)d - %(max)d.',
+ 'Set %(wireguard)s MTU value. Valid range: %(min)d - %(max)d.',
),
{
+ wireguard: strings.wireguard,
min: MIN_WIREGUARD_MTU_VALUE,
max: MAX_WIREGUARD_MTU_VALUE,
},
diff --git a/gui/src/shared/notifications/block-when-disconnected.ts b/gui/src/shared/notifications/block-when-disconnected.ts
index 6dcc3cc749..4cc30c0de0 100644
--- a/gui/src/shared/notifications/block-when-disconnected.ts
+++ b/gui/src/shared/notifications/block-when-disconnected.ts
@@ -1,3 +1,6 @@
+import { sprintf } from 'sprintf-js';
+
+import { strings } from '../../config.json';
import { messages } from '../../shared/gettext';
import { TunnelState } from '../daemon-rpc-types';
import { InAppNotification, InAppNotificationProvider } from './notification';
@@ -22,9 +25,12 @@ export class BlockWhenDisconnectedNotificationProvider implements InAppNotificat
public getInAppNotification(): InAppNotification {
let subtitle = messages.pgettext('in-app-notifications', '"Always require VPN" is enabled.');
if (this.context.hasExcludedApps) {
- subtitle = `${subtitle} ${messages.pgettext(
- 'notifications',
- 'The apps excluded with split tunneling might not work properly right now.',
+ subtitle = `${subtitle} ${sprintf(
+ messages.pgettext(
+ 'notifications',
+ 'The apps excluded with %(splitTunneling)s might not work properly right now.',
+ ),
+ { splitTunneling: strings.splitTunneling.toLowerCase() },
)}`;
}
diff --git a/gui/src/shared/notifications/error.ts b/gui/src/shared/notifications/error.ts
index fa654b8291..dddac8bed9 100644
--- a/gui/src/shared/notifications/error.ts
+++ b/gui/src/shared/notifications/error.ts
@@ -1,3 +1,6 @@
+import { sprintf } from 'sprintf-js';
+
+import { strings } from '../../config.json';
import { hasExpired } from '../account-expiry';
import { AuthFailureKind, parseAuthFailure } from '../auth-failure';
import { IErrorState, TunnelParameterError, TunnelState } from '../daemon-rpc-types';
@@ -24,9 +27,12 @@ export class ErrorNotificationProvider
if (this.context.tunnelState.state === 'error') {
let message = getMessage(this.context.tunnelState.details, this.context.accountExpiry);
if (!this.context.tunnelState.details.blockFailure && this.context.hasExcludedApps) {
- message = `${message} ${messages.pgettext(
- 'notifications',
- 'The apps excluded with split tunneling might not work properly right now.',
+ message = `${message} ${sprintf(
+ messages.pgettext(
+ 'notifications',
+ 'The apps excluded with %(splitTunneling)s might not work properly right now.',
+ ),
+ { splitTunneling: strings.splitTunneling.toLowerCase() },
)}`;
}
@@ -43,9 +49,12 @@ export class ErrorNotificationProvider
if (this.context.tunnelState.state === 'error') {
let subtitle = getMessage(this.context.tunnelState.details, this.context.accountExpiry);
if (!this.context.tunnelState.details.blockFailure && this.context.hasExcludedApps) {
- subtitle = `${subtitle} ${messages.pgettext(
- 'notifications',
- 'The apps excluded with split tunneling might not work properly right now.',
+ subtitle = `${subtitle} ${sprintf(
+ messages.pgettext(
+ 'notifications',
+ 'The apps excluded with %(splitTunneling)s might not work properly right now.',
+ ),
+ { splitTunneling: strings.splitTunneling.toLowerCase() },
)}`;
}
@@ -157,9 +166,14 @@ function getTunnelParameterMessage(err: TunnelParameterError): string {
'No servers in your selected location match your settings.',
);
case 'no_wireguard_key':
- return messages.pgettext(
- 'notifications',
- 'Valid WireGuard key is missing. Manage keys under Advanced settings.',
+ return sprintf(
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(wireguard)s - will be replaced with "WireGuard"
+ messages.pgettext(
+ 'notifications',
+ 'Valid %(wireguard)s key is missing. Manage keys under Advanced settings.',
+ ),
+ { wireguard: strings.wireguard },
);
case 'custom_tunnel_host_resultion_error':
return messages.pgettext(