diff options
| author | David Lönnhager <david.l@mullvad.net> | 2023-01-30 12:17:28 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2023-02-01 17:38:39 +0100 |
| commit | 820bcbf9bd3db7cae550af08fb384ff30696f0f8 (patch) | |
| tree | 85d23dc2157f87ddbe28a8c2fca18e74d03d7829 /gui/src/renderer | |
| parent | 669f92d79a97b4de52c250189b916298a4b2570f (diff) | |
| download | mullvadvpn-820bcbf9bd3db7cae550af08fb384ff30696f0f8.tar.xz mullvadvpn-820bcbf9bd3db7cae550af08fb384ff30696f0f8.zip | |
Add 'Go to System Settings' button to launch view
Diffstat (limited to 'gui/src/renderer')
| -rw-r--r-- | gui/src/renderer/app.tsx | 13 | ||||
| -rw-r--r-- | gui/src/renderer/components/ErrorView.tsx | 83 | ||||
| -rw-r--r-- | gui/src/renderer/components/Launch.tsx | 4 | ||||
| -rw-r--r-- | gui/src/renderer/redux/userinterface/actions.ts | 14 | ||||
| -rw-r--r-- | gui/src/renderer/redux/userinterface/reducers.ts | 5 |
5 files changed, 107 insertions, 12 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index 87bf91123b..14fa75f9cc 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -125,6 +125,10 @@ export default class AppRenderer { this.setIsPerformingPostUpgrade(isPerformingPostUpgrade); }); + IpcRendererEventChannel.daemon.listenDaemonAllowed((daemonAllowed) => { + this.reduxActions.userInterface.setDaemonAllowed(daemonAllowed); + }); + IpcRendererEventChannel.account.listen((newAccountData?: IAccountData) => { this.setAccountExpiry(newAccountData?.expiry); }); @@ -204,6 +208,10 @@ export default class AppRenderer { this.setSettings(initialState.settings); this.setIsPerformingPostUpgrade(initialState.isPerformingPostUpgrade); + if (initialState.daemonAllowed !== undefined) { + this.reduxActions.userInterface.setDaemonAllowed(initialState.daemonAllowed); + } + if (initialState.deviceState) { const deviceState = initialState.deviceState; this.handleDeviceEvent( @@ -470,6 +478,10 @@ export default class AppRenderer { void IpcRendererEventChannel.windowsSplitTunneling.removeApplication(application); } + public async showLaunchDaemonSettings() { + await IpcRendererEventChannel.app.showLaunchDaemonSettings(); + } + public async sendProblemReport( email: string, message: string, @@ -617,6 +629,7 @@ export default class AppRenderer { private onDaemonConnected() { this.connectedToDaemon = true; this.reduxActions.userInterface.setConnectedToDaemon(true); + this.reduxActions.userInterface.setDaemonAllowed(true); this.resetNavigation(); } diff --git a/gui/src/renderer/components/ErrorView.tsx b/gui/src/renderer/components/ErrorView.tsx index 12ca510396..04fbbee9f9 100644 --- a/gui/src/renderer/components/ErrorView.tsx +++ b/gui/src/renderer/components/ErrorView.tsx @@ -1,10 +1,14 @@ +import React, { useCallback } from 'react'; import styled from 'styled-components'; import { colors } from '../../config.json'; -import { measurements } from './common-styles'; +import { messages } from '../../shared/gettext'; +import { useAppContext } from '../context'; +import * as AppButton from './AppButton'; +import { measurements, tinyText } from './common-styles'; import { HeaderBarSettingsButton } from './HeaderBar'; import ImageView from './ImageView'; -import { Container, Header, Layout } from './Layout'; +import { Container, Footer, Header, Layout } from './Layout'; const StyledContainer = styled(Container)({ flex: 1, @@ -14,6 +18,31 @@ const StyledContainer = styled(Container)({ marginTop: '-150px', }); +const StyledFooter = styled(Footer)({}, (props: { show: boolean }) => ({ + backgroundColor: colors.blue, + padding: '12px', + position: 'absolute', + bottom: 0, + transform: `translateY(${props.show ? 0 : 100}%)`, + transition: 'transform 250ms ease-in-out', +})); + +const StyledSystemSettingsContainer = styled.div({ + display: 'flex', + flexDirection: 'column', + flex: 1, + alignSelf: 'start', + backgroundColor: colors.darkBlue, + borderRadius: '8px', + margin: 0, + padding: '16px', +}); + +const StyledLaunchFooterPrompt = styled.span(tinyText, { + color: colors.white, + margin: '9px 0 20px 0', +}); + const Logo = styled(ImageView)({ marginBottom: '12px', }); @@ -34,18 +63,50 @@ const Subtitle = styled.span({ interface ErrorViewProps { settingsUnavailable?: boolean; + showSettingsFooter?: boolean; children: React.ReactNode | React.ReactNode[]; } -export default function ErrorView(props: ErrorViewProps) { +export default class ErrorView extends React.Component<ErrorViewProps> { + public render() { + return ( + <Layout> + <Header>{!this.props.settingsUnavailable && <HeaderBarSettingsButton />}</Header> + <StyledContainer> + <Logo height={106} width={106} source="logo-icon" /> + <Title height={18} source="logo-text" /> + <Subtitle role="alert">{this.props.children}</Subtitle> + </StyledContainer> + <SettingsFooter show={this.props.showSettingsFooter} /> + </Layout> + ); + } +} + +interface ISettingsFooterProps { + show?: boolean; +} + +function SettingsFooter(props: ISettingsFooterProps) { + const { showLaunchDaemonSettings } = useAppContext(); + + const openSettings = useCallback(async () => { + await showLaunchDaemonSettings(); + }, []); + return ( - <Layout> - <Header>{!props.settingsUnavailable && <HeaderBarSettingsButton />}</Header> - <StyledContainer> - <Logo height={106} width={106} source="logo-icon" /> - <Title height={18} source="logo-text" /> - <Subtitle role="alert">{props.children}</Subtitle> - </StyledContainer> - </Layout> + <StyledFooter show={props.show ? props.show : false}> + <StyledSystemSettingsContainer> + <StyledLaunchFooterPrompt> + {messages.pgettext( + 'launch-view', + 'Permission for the Mullvad VPN service has been revoked. Please go to System Settings and allow Mullvad VPN under the “Allow in the Background” setting.', + )} + </StyledLaunchFooterPrompt> + <AppButton.BlueButton onClick={openSettings}> + {messages.gettext('Go to System Settings')} + </AppButton.BlueButton> + </StyledSystemSettingsContainer> + </StyledFooter> ); } diff --git a/gui/src/renderer/components/Launch.tsx b/gui/src/renderer/components/Launch.tsx index a3145b8e16..c5406e1578 100644 --- a/gui/src/renderer/components/Launch.tsx +++ b/gui/src/renderer/components/Launch.tsx @@ -1,9 +1,11 @@ import { messages } from '../../shared/gettext'; +import { useSelector } from '../redux/store'; import ErrorView from './ErrorView'; export default function Launch() { + const daemonAllowed = useSelector((state) => state.userInterface.daemonAllowed); return ( - <ErrorView> + <ErrorView showSettingsFooter={daemonAllowed === false}> {messages.pgettext('launch-view', 'Connecting to Mullvad system service...')} </ErrorView> ); diff --git a/gui/src/renderer/redux/userinterface/actions.ts b/gui/src/renderer/redux/userinterface/actions.ts index 46da6bdc3d..b4b5885370 100644 --- a/gui/src/renderer/redux/userinterface/actions.ts +++ b/gui/src/renderer/redux/userinterface/actions.ts @@ -30,6 +30,11 @@ export interface ISetConnectedToDaemon { connectedToDaemon: boolean; } +export interface ISetDaemonAllowed { + type: 'SET_DAEMON_ALLOWED'; + daemonAllowed: boolean; +} + export interface ISetChangelog { type: 'SET_CHANGELOG'; changelog: IChangelog; @@ -52,6 +57,7 @@ export type UserInterfaceAction = | ISetWindowFocusedAction | ISetMacOsScrollbarVisibility | ISetConnectedToDaemon + | ISetDaemonAllowed | ISetChangelog | ISetForceShowChanges | ISetIsPerformingPostUpgrade; @@ -99,6 +105,13 @@ function setConnectedToDaemon(connectedToDaemon: boolean): ISetConnectedToDaemon }; } +function setDaemonAllowed(daemonAllowed: boolean): ISetDaemonAllowed { + return { + type: 'SET_DAEMON_ALLOWED', + daemonAllowed, + }; +} + function setChangelog(changelog: IChangelog): ISetChangelog { return { type: 'SET_CHANGELOG', @@ -127,6 +140,7 @@ export default { setWindowFocused, setMacOsScrollbarVisibility, setConnectedToDaemon, + setDaemonAllowed, setChangelog, setForceShowChanges, setIsPerformingPostUpgrade, diff --git a/gui/src/renderer/redux/userinterface/reducers.ts b/gui/src/renderer/redux/userinterface/reducers.ts index 96d8bc03e6..f9ecc6fdad 100644 --- a/gui/src/renderer/redux/userinterface/reducers.ts +++ b/gui/src/renderer/redux/userinterface/reducers.ts @@ -9,6 +9,7 @@ export interface IUserInterfaceReduxState { windowFocused: boolean; macOsScrollbarVisibility?: MacOsScrollbarVisibility; connectedToDaemon: boolean; + daemonAllowed?: boolean; changelog: IChangelog; forceShowChanges: boolean; isPerformingPostUpgrade: boolean; @@ -20,6 +21,7 @@ const initialState: IUserInterfaceReduxState = { windowFocused: false, macOsScrollbarVisibility: undefined, connectedToDaemon: false, + daemonAllowed: undefined, changelog: [], forceShowChanges: false, isPerformingPostUpgrade: false, @@ -48,6 +50,9 @@ export default function ( case 'SET_CONNECTED_TO_DAEMON': return { ...state, connectedToDaemon: action.connectedToDaemon }; + case 'SET_DAEMON_ALLOWED': + return { ...state, daemonAllowed: action.daemonAllowed }; + case 'SET_CHANGELOG': return { ...state, |
