summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2021-12-21 13:49:21 +0100
committerOskar Nyberg <oskar@mullvad.net>2021-12-21 13:49:21 +0100
commit220948c522328928c16faafca5a553c6bce2e95e (patch)
tree0838e7b51d3d69b7a0640f3a7e53e1a5cf132d6d
parentc50902f92e0c4a4887eb9acc8458691d42e7b219 (diff)
parente33a9a936e7be501e1da44b94cf5805bb8f3c824 (diff)
downloadmullvadvpn-220948c522328928c16faafca5a553c6bce2e95e.tar.xz
mullvadvpn-220948c522328928c16faafca5a553c6bce2e95e.zip
Merge branch 'add-killswitch-info'
-rw-r--r--CHANGELOG.md2
-rw-r--r--gui/assets/images/icon-info.svg3
-rw-r--r--gui/locales/messages.pot8
-rw-r--r--gui/src/renderer/components/AdvancedSettings.tsx2
-rw-r--r--gui/src/renderer/components/CustomDnsSettings.tsx2
-rw-r--r--gui/src/renderer/components/ExpiredAccountErrorView.tsx2
-rw-r--r--gui/src/renderer/components/Modal.tsx5
-rw-r--r--gui/src/renderer/components/Preferences.tsx495
8 files changed, 292 insertions, 227 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 128355bf90..0adac15caf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,8 @@ Line wrap the file at 100 chars. Th
## [Unreleased]
### Added
+- Add information about the always on kill switch in the desktop app.
+
#### macOS
- Add an opt-in feature to leak macOS network check traffic in blocked states to resolve issues with
the app blocking internet connectivity after sleep or when connecting to new wireless networks.
diff --git a/gui/assets/images/icon-info.svg b/gui/assets/images/icon-info.svg
new file mode 100644
index 0000000000..cb2a243e78
--- /dev/null
+++ b/gui/assets/images/icon-info.svg
@@ -0,0 +1,3 @@
+<svg data-name="icon - info" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path d="M12 24A12 12 0 0 1 3.515 3.515a12 12 0 1 1 16.97 16.97A11.922 11.922 0 0 1 12 24zm0-15a1.5 1.5 0 0 0-1.5 1.5V18a1.5 1.5 0 1 0 3 0v-7.5A1.5 1.5 0 0 0 12 9zm0-4.5A1.5 1.5 0 1 0 13.5 6 1.5 1.5 0 0 0 12 4.5z" style="fill:#294d73"/>
+</svg>
diff --git a/gui/locales/messages.pot b/gui/locales/messages.pot
index f4d5af9325..56e3de490c 100644
--- a/gui/locales/messages.pot
+++ b/gui/locales/messages.pot
@@ -857,6 +857,10 @@ msgid "Enable to move the app around as a free-standing window."
msgstr ""
msgctxt "preferences-view"
+msgid "Kill switch"
+msgstr ""
+
+msgctxt "preferences-view"
msgid "Launch app on start-up"
msgstr ""
@@ -885,6 +889,10 @@ msgid "Start minimized"
msgstr ""
msgctxt "preferences-view"
+msgid "The app has a built in kill switch that is enabled by default and cannot be disabled. This is to prevent your traffic from leaking outside of the VPN tunnel if your network suddenly stops working or if the tunnel fails for any reason. Mullvad automatically protects your data until your connection is reestablished."
+msgstr ""
+
+msgctxt "preferences-view"
msgid "This option is unavailable while using a beta version."
msgstr ""
diff --git a/gui/src/renderer/components/AdvancedSettings.tsx b/gui/src/renderer/components/AdvancedSettings.tsx
index 42f48b1b87..f511265464 100644
--- a/gui/src/renderer/components/AdvancedSettings.tsx
+++ b/gui/src/renderer/components/AdvancedSettings.tsx
@@ -233,7 +233,7 @@ export default class AdvancedSettings extends React.Component<IProps, IState> {
private renderConfirmBlockWhenDisconnectedAlert = () => {
return (
<ModalAlert
- type={ModalAlertType.info}
+ type={ModalAlertType.caution}
buttons={[
<AppButton.RedButton key="confirm" onClick={this.confirmEnableBlockWhenDisconnected}>
{messages.pgettext('advanced-settings-view', 'Enable anyway')}
diff --git a/gui/src/renderer/components/CustomDnsSettings.tsx b/gui/src/renderer/components/CustomDnsSettings.tsx
index 7379b4f068..98f0c8f1b2 100644
--- a/gui/src/renderer/components/CustomDnsSettings.tsx
+++ b/gui/src/renderer/components/CustomDnsSettings.tsx
@@ -392,7 +392,7 @@ interface IConfirmationDialogProps {
function ConfirmationDialog(props: IConfirmationDialogProps) {
return (
<ModalAlert
- type={ModalAlertType.info}
+ type={ModalAlertType.caution}
buttons={[
<AppButton.RedButton key="confirm" onClick={props.confirm}>
{messages.pgettext('advanced-settings-view', 'Add anyway')}
diff --git a/gui/src/renderer/components/ExpiredAccountErrorView.tsx b/gui/src/renderer/components/ExpiredAccountErrorView.tsx
index 0fedb67fdf..c24c79da45 100644
--- a/gui/src/renderer/components/ExpiredAccountErrorView.tsx
+++ b/gui/src/renderer/components/ExpiredAccountErrorView.tsx
@@ -194,7 +194,7 @@ export default class ExpiredAccountErrorView extends React.Component<
private renderBlockWhenDisconnectedAlert() {
return (
<ModalAlert
- type={ModalAlertType.info}
+ type={ModalAlertType.caution}
buttons={[
<AppButton.BlueButton
key="cancel"
diff --git a/gui/src/renderer/components/Modal.tsx b/gui/src/renderer/components/Modal.tsx
index 49f0793f5d..97cf4dce22 100644
--- a/gui/src/renderer/components/Modal.tsx
+++ b/gui/src/renderer/components/Modal.tsx
@@ -88,6 +88,7 @@ export function ModalContainer(props: IModalContainerProps) {
export enum ModalAlertType {
info = 1,
+ caution,
warning,
}
@@ -196,6 +197,10 @@ class ModalAlertWithContext extends React.Component<IModalAlertProps & IModalCon
let color = '';
switch (type) {
case ModalAlertType.info:
+ source = 'icon-info';
+ color = colors.white;
+ break;
+ case ModalAlertType.caution:
source = 'icon-alert';
color = colors.white;
break;
diff --git a/gui/src/renderer/components/Preferences.tsx b/gui/src/renderer/components/Preferences.tsx
index ebaa2da359..4f66b60d4a 100644
--- a/gui/src/renderer/components/Preferences.tsx
+++ b/gui/src/renderer/components/Preferences.tsx
@@ -1,11 +1,15 @@
import * as React from 'react';
import { sprintf } from 'sprintf-js';
+import { colors } from '../../config.json';
import { IDnsOptions } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import { formatMarkdown } from '../markdown-formatter';
+import * as AppButton from './AppButton';
import { AriaDescription, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup';
import * as Cell from './cell';
+import ImageView from './ImageView';
import { Layout } from './Layout';
+import { ModalAlert, ModalAlertType, ModalContainer } from './Modal';
import {
BackBarItem,
NavigationBar,
@@ -40,204 +44,194 @@ export interface IProps {
onClose: () => void;
}
-export default class Preferences extends React.Component<IProps> {
+interface IState {
+ showKillSwitchInfo: boolean;
+}
+
+export default class Preferences extends React.Component<IProps, IState> {
+ public state = { showKillSwitchInfo: false };
+
public render() {
return (
- <Layout>
- <StyledContainer>
- <NavigationContainer>
- <NavigationBar>
- <NavigationItems>
- <BackBarItem action={this.props.onClose}>
- {
- // TRANSLATORS: Back button in navigation bar
- messages.pgettext('navigation-bar', 'Settings')
- }
- </BackBarItem>
- <TitleBarItem>
- {
- // TRANSLATORS: Title label in navigation bar
- messages.pgettext('preferences-nav', 'Preferences')
- }
- </TitleBarItem>
- </NavigationItems>
- </NavigationBar>
+ <ModalContainer>
+ <Layout>
+ <StyledContainer>
+ <NavigationContainer>
+ <NavigationBar>
+ <NavigationItems>
+ <BackBarItem action={this.props.onClose}>
+ {
+ // TRANSLATORS: Back button in navigation bar
+ messages.pgettext('navigation-bar', 'Settings')
+ }
+ </BackBarItem>
+ <TitleBarItem>
+ {
+ // TRANSLATORS: Title label in navigation bar
+ messages.pgettext('preferences-nav', 'Preferences')
+ }
+ </TitleBarItem>
+ </NavigationItems>
+ </NavigationBar>
- <NavigationScrollbars>
- <SettingsHeader>
- <HeaderTitle>{messages.pgettext('preferences-view', 'Preferences')}</HeaderTitle>
- </SettingsHeader>
+ <NavigationScrollbars>
+ <SettingsHeader>
+ <HeaderTitle>{messages.pgettext('preferences-view', 'Preferences')}</HeaderTitle>
+ </SettingsHeader>
- <StyledContent>
- <AriaInputGroup>
- <Cell.Container>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Launch app on start-up')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch isOn={this.props.autoStart} onChange={this.props.setAutoStart} />
- </AriaInput>
- </Cell.Container>
- </AriaInputGroup>
- <StyledSeparator />
+ <StyledContent>
+ <Cell.CellButton onClick={this.showKillSwitchInfo}>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Kill switch')}
+ </Cell.InputLabel>
+ <ImageView source="icon-info" width={24} tintColor={colors.white} />
+ </Cell.CellButton>
+ <StyledSeparator height={20} />
- <AriaInputGroup>
- <Cell.Container>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Auto-connect')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch
- isOn={this.props.autoConnect}
- onChange={this.props.setAutoConnect}
- />
- </AriaInput>
- </Cell.Container>
- <Cell.Footer>
- <AriaDescription>
- <Cell.FooterText>
- {messages.pgettext(
- 'preferences-view',
- 'Automatically connect to a server when the app launches.',
- )}
- </Cell.FooterText>
- </AriaDescription>
- </Cell.Footer>
- </AriaInputGroup>
+ <AriaInputGroup>
+ <Cell.Container>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Launch app on start-up')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={this.props.autoStart}
+ onChange={this.props.setAutoStart}
+ />
+ </AriaInput>
+ </Cell.Container>
+ </AriaInputGroup>
+ <StyledSeparator />
- <AriaInputGroup>
- <Cell.Container disabled={this.props.dns.state === 'custom'}>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Block ads')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch
- isOn={
- this.props.dns.state === 'default' &&
- this.props.dns.defaultOptions.blockAds
- }
- onChange={this.setBlockAds}
- />
- </AriaInput>
- </Cell.Container>
- </AriaInputGroup>
- <StyledSeparator />
- <AriaInputGroup>
- <Cell.Container disabled={this.props.dns.state === 'custom'}>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Block trackers')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch
- isOn={
- this.props.dns.state === 'default' &&
- this.props.dns.defaultOptions.blockTrackers
- }
- onChange={this.setBlockTrackers}
- />
- </AriaInput>
- </Cell.Container>
- {this.props.dns.state === 'custom' && <CustomDnsEnabledFooter />}
- </AriaInputGroup>
+ <AriaInputGroup>
+ <Cell.Container>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Auto-connect')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={this.props.autoConnect}
+ onChange={this.props.setAutoConnect}
+ />
+ </AriaInput>
+ </Cell.Container>
+ <Cell.Footer>
+ <AriaDescription>
+ <Cell.FooterText>
+ {messages.pgettext(
+ 'preferences-view',
+ 'Automatically connect to a server when the app launches.',
+ )}
+ </Cell.FooterText>
+ </AriaDescription>
+ </Cell.Footer>
+ </AriaInputGroup>
- {this.props.dns.state !== 'custom' && <StyledSeparator height={20} />}
+ <AriaInputGroup>
+ <Cell.Container disabled={this.props.dns.state === 'custom'}>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Block ads')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={
+ this.props.dns.state === 'default' &&
+ this.props.dns.defaultOptions.blockAds
+ }
+ onChange={this.setBlockAds}
+ />
+ </AriaInput>
+ </Cell.Container>
+ </AriaInputGroup>
+ <StyledSeparator />
+ <AriaInputGroup>
+ <Cell.Container disabled={this.props.dns.state === 'custom'}>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Block trackers')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={
+ this.props.dns.state === 'default' &&
+ this.props.dns.defaultOptions.blockTrackers
+ }
+ onChange={this.setBlockTrackers}
+ />
+ </AriaInput>
+ </Cell.Container>
+ {this.props.dns.state === 'custom' && <CustomDnsEnabledFooter />}
+ </AriaInputGroup>
- <AriaInputGroup>
- <Cell.Container>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Local network sharing')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch isOn={this.props.allowLan} onChange={this.props.setAllowLan} />
- </AriaInput>
- </Cell.Container>
- <Cell.Footer>
- <AriaDescription>
- <Cell.FooterText>
- {messages.pgettext(
- 'preferences-view',
- 'Allows access to other devices on the same network for sharing, printing etc.',
- )}
- </Cell.FooterText>
- </AriaDescription>
- </Cell.Footer>
- </AriaInputGroup>
+ {this.props.dns.state !== 'custom' && <StyledSeparator height={20} />}
- <AriaInputGroup>
- <Cell.Container>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Notifications')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch
- isOn={this.props.enableSystemNotifications}
- onChange={this.props.setEnableSystemNotifications}
- />
- </AriaInput>
- </Cell.Container>
- <Cell.Footer>
- <AriaDescription>
- <Cell.FooterText>
- {messages.pgettext(
- 'preferences-view',
- 'Enable or disable system notifications. The critical notifications will always be displayed.',
- )}
- </Cell.FooterText>
- </AriaDescription>
- </Cell.Footer>
- </AriaInputGroup>
+ <AriaInputGroup>
+ <Cell.Container>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Local network sharing')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch isOn={this.props.allowLan} onChange={this.props.setAllowLan} />
+ </AriaInput>
+ </Cell.Container>
+ <Cell.Footer>
+ <AriaDescription>
+ <Cell.FooterText>
+ {messages.pgettext(
+ 'preferences-view',
+ 'Allows access to other devices on the same network for sharing, printing etc.',
+ )}
+ </Cell.FooterText>
+ </AriaDescription>
+ </Cell.Footer>
+ </AriaInputGroup>
- <AriaInputGroup>
- <Cell.Container>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Monochromatic tray icon')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch
- isOn={this.props.monochromaticIcon}
- onChange={this.props.setMonochromaticIcon}
- />
- </AriaInput>
- </Cell.Container>
- <Cell.Footer>
- <AriaDescription>
- <Cell.FooterText>
- {messages.pgettext(
- 'preferences-view',
- 'Use a monochromatic tray icon instead of a colored one.',
- )}
- </Cell.FooterText>
- </AriaDescription>
- </Cell.Footer>
- </AriaInputGroup>
+ <AriaInputGroup>
+ <Cell.Container>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Notifications')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={this.props.enableSystemNotifications}
+ onChange={this.props.setEnableSystemNotifications}
+ />
+ </AriaInput>
+ </Cell.Container>
+ <Cell.Footer>
+ <AriaDescription>
+ <Cell.FooterText>
+ {messages.pgettext(
+ 'preferences-view',
+ 'Enable or disable system notifications. The critical notifications will always be displayed.',
+ )}
+ </Cell.FooterText>
+ </AriaDescription>
+ </Cell.Footer>
+ </AriaInputGroup>
- {(window.env.platform === 'win32' ||
- (window.env.platform === 'darwin' && window.env.development)) && (
<AriaInputGroup>
<Cell.Container>
<AriaLabel>
<Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Unpin app from taskbar')}
+ {messages.pgettext('preferences-view', 'Monochromatic tray icon')}
</Cell.InputLabel>
</AriaLabel>
<AriaInput>
<Cell.Switch
- isOn={this.props.unpinnedWindow}
- onChange={this.props.setUnpinnedWindow}
+ isOn={this.props.monochromaticIcon}
+ onChange={this.props.setMonochromaticIcon}
/>
</AriaInput>
</Cell.Container>
@@ -246,27 +240,26 @@ export default class Preferences extends React.Component<IProps> {
<Cell.FooterText>
{messages.pgettext(
'preferences-view',
- 'Enable to move the app around as a free-standing window.',
+ 'Use a monochromatic tray icon instead of a colored one.',
)}
</Cell.FooterText>
</AriaDescription>
</Cell.Footer>
</AriaInputGroup>
- )}
- {this.props.unpinnedWindow && (
- <React.Fragment>
+ {(window.env.platform === 'win32' ||
+ (window.env.platform === 'darwin' && window.env.development)) && (
<AriaInputGroup>
<Cell.Container>
<AriaLabel>
<Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Start minimized')}
+ {messages.pgettext('preferences-view', 'Unpin app from taskbar')}
</Cell.InputLabel>
</AriaLabel>
<AriaInput>
<Cell.Switch
- isOn={this.props.startMinimized}
- onChange={this.props.setStartMinimized}
+ isOn={this.props.unpinnedWindow}
+ onChange={this.props.setUnpinnedWindow}
/>
</AriaInput>
</Cell.Container>
@@ -275,50 +268,96 @@ export default class Preferences extends React.Component<IProps> {
<Cell.FooterText>
{messages.pgettext(
'preferences-view',
- 'Show only the tray icon when the app starts.',
+ 'Enable to move the app around as a free-standing window.',
)}
</Cell.FooterText>
</AriaDescription>
</Cell.Footer>
</AriaInputGroup>
- </React.Fragment>
- )}
+ )}
- <AriaInputGroup>
- <Cell.Container disabled={this.props.isBeta}>
- <AriaLabel>
- <Cell.InputLabel>
- {messages.pgettext('preferences-view', 'Beta program')}
- </Cell.InputLabel>
- </AriaLabel>
- <AriaInput>
- <Cell.Switch
- isOn={this.props.showBetaReleases}
- onChange={this.props.setShowBetaReleases}
- />
- </AriaInput>
- </Cell.Container>
- <Cell.Footer>
- <AriaDescription>
- <Cell.FooterText>
- {this.props.isBeta
- ? messages.pgettext(
- 'preferences-view',
- 'This option is unavailable while using a beta version.',
- )
- : messages.pgettext(
- 'preferences-view',
- 'Enable to get notified when new beta versions of the app are released.',
- )}
- </Cell.FooterText>
- </AriaDescription>
- </Cell.Footer>
- </AriaInputGroup>
- </StyledContent>
- </NavigationScrollbars>
- </NavigationContainer>
- </StyledContainer>
- </Layout>
+ {this.props.unpinnedWindow && (
+ <React.Fragment>
+ <AriaInputGroup>
+ <Cell.Container>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Start minimized')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={this.props.startMinimized}
+ onChange={this.props.setStartMinimized}
+ />
+ </AriaInput>
+ </Cell.Container>
+ <Cell.Footer>
+ <AriaDescription>
+ <Cell.FooterText>
+ {messages.pgettext(
+ 'preferences-view',
+ 'Show only the tray icon when the app starts.',
+ )}
+ </Cell.FooterText>
+ </AriaDescription>
+ </Cell.Footer>
+ </AriaInputGroup>
+ </React.Fragment>
+ )}
+
+ <AriaInputGroup>
+ <Cell.Container disabled={this.props.isBeta}>
+ <AriaLabel>
+ <Cell.InputLabel>
+ {messages.pgettext('preferences-view', 'Beta program')}
+ </Cell.InputLabel>
+ </AriaLabel>
+ <AriaInput>
+ <Cell.Switch
+ isOn={this.props.showBetaReleases}
+ onChange={this.props.setShowBetaReleases}
+ />
+ </AriaInput>
+ </Cell.Container>
+ <Cell.Footer>
+ <AriaDescription>
+ <Cell.FooterText>
+ {this.props.isBeta
+ ? messages.pgettext(
+ 'preferences-view',
+ 'This option is unavailable while using a beta version.',
+ )
+ : messages.pgettext(
+ 'preferences-view',
+ 'Enable to get notified when new beta versions of the app are released.',
+ )}
+ </Cell.FooterText>
+ </AriaDescription>
+ </Cell.Footer>
+ </AriaInputGroup>
+ </StyledContent>
+ </NavigationScrollbars>
+ </NavigationContainer>
+ </StyledContainer>
+ </Layout>
+
+ {this.state.showKillSwitchInfo && (
+ <ModalAlert
+ message={messages.pgettext(
+ 'preferences-view',
+ 'The app has a built in kill switch that is enabled by default and cannot be disabled. This is to prevent your traffic from leaking outside of the VPN tunnel if your network suddenly stops working or if the tunnel fails for any reason. Mullvad automatically protects your data until your connection is reestablished.',
+ )}
+ type={ModalAlertType.info}
+ buttons={[
+ <AppButton.BlueButton key="back" onClick={this.hideKillSwitchInfo}>
+ {messages.gettext('Got it!')}
+ </AppButton.BlueButton>,
+ ]}
+ close={this.hideKillSwitchInfo}
+ />
+ )}
+ </ModalContainer>
);
}
@@ -341,6 +380,14 @@ export default class Preferences extends React.Component<IProps> {
},
});
};
+
+ private showKillSwitchInfo = () => {
+ this.setState({ showKillSwitchInfo: true });
+ };
+
+ private hideKillSwitchInfo = () => {
+ this.setState({ showKillSwitchInfo: false });
+ };
}
function CustomDnsEnabledFooter() {