diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-04-07 15:29:43 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-04-07 15:29:43 +0200 |
| commit | 74ec2b59d1fa20604973f1bd4e5cd503631c2365 (patch) | |
| tree | 3fa5771c1ad09e055086dab16c273c2b44d756bf | |
| parent | 3640e7731c8855de871c7d1af97a8d07414a4913 (diff) | |
| parent | a64c38052e9cf316d2819adcee89802f747dd630 (diff) | |
| download | mullvadvpn-74ec2b59d1fa20604973f1bd4e5cd503631c2365.tar.xz mullvadvpn-74ec2b59d1fa20604973f1bd4e5cd503631c2365.zip | |
Merge branch 'handle-post-upgrade-flag'
| -rw-r--r-- | gui/locales/messages.pot | 8 | ||||
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 5 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 29 | ||||
| -rw-r--r-- | gui/src/renderer/app.tsx | 9 | ||||
| -rw-r--r-- | gui/src/renderer/components/Login.tsx | 18 | ||||
| -rw-r--r-- | gui/src/renderer/containers/LoginPage.tsx | 3 | ||||
| -rw-r--r-- | gui/src/renderer/redux/userinterface/actions.ts | 16 | ||||
| -rw-r--r-- | gui/src/renderer/redux/userinterface/reducers.ts | 8 | ||||
| -rw-r--r-- | gui/src/shared/ipc-schema.ts | 2 |
9 files changed, 96 insertions, 2 deletions
diff --git a/gui/locales/messages.pot b/gui/locales/messages.pot index 40810a8e8a..a7ba20c520 100644 --- a/gui/locales/messages.pot +++ b/gui/locales/messages.pot @@ -676,6 +676,10 @@ msgid "Failed to create account" msgstr "" msgctxt "login-view" +msgid "Finishing upgrade." +msgstr "" + +msgctxt "login-view" msgid "Logged in" msgstr "" @@ -710,6 +714,10 @@ msgid "Unknown error" msgstr "" msgctxt "login-view" +msgid "Upgrading..." +msgstr "" + +msgctxt "login-view" msgid "Valid account number" msgstr "" diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index b3add4ec1d..52c43441a6 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -499,6 +499,11 @@ export class DaemonRpc { await this.callEmpty(this.client.checkVolumes); } + public async isPerformingPostUpgrade(): Promise<boolean> { + const response = await this.callEmpty<BoolValue>(this.client.isPerformingPostUpgrade); + return response.getValue(); + } + public async getDevice(): Promise<IDeviceConfig | undefined> { try { const response = await this.callEmpty<grpcTypes.DeviceConfig>(this.client.getDevice); diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index e36c8d1b70..1dfde6537d 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -128,6 +128,7 @@ class ApplicationMain { private reconnectBackoff = new ReconnectionBackoff(); private beforeFirstDaemonConnection = true; private connectedToDaemon = false; + private isPerformingPostUpgrade = false; private quitStage = AppQuitStage.unready; private accountData?: IAccountData = undefined; @@ -626,6 +627,18 @@ class ApplicationMain { return this.handleBootstrapError(error); } + if (firstDaemonConnection) { + // check if daemon is performing post upgrade tasks the first time it's connected to + try { + await this.performPostUpgradeCheck(); + } catch (e) { + const error = e as Error; + log.error(`Failed to check if daemon is performing post upgrade tasks: ${error.message}`); + + return this.handleBootstrapError(error); + } + } + // fetch account history try { this.setAccountHistory(await this.daemonRpc.getAccountHistory()); @@ -808,6 +821,17 @@ class ApplicationMain { return daemonEventListener; } + private async performPostUpgradeCheck(): Promise<void> { + const oldValue = this.isPerformingPostUpgrade; + this.isPerformingPostUpgrade = await this.daemonRpc.isPerformingPostUpgrade(); + if (this.windowController && this.isPerformingPostUpgrade !== oldValue) { + IpcMainEventChannel.daemon.notifyIsPerformingPostUpgrade( + this.windowController.webContents, + this.isPerformingPostUpgrade, + ); + } + } + private connectTunnel = async (): Promise<void> => { if ( connectEnabled( @@ -1125,6 +1149,10 @@ class ApplicationMain { this.deviceConfig = deviceEvent.deviceConfig; this.hasReceivedDeviceConfig = true; + if (this.isPerformingPostUpgrade) { + void this.performPostUpgradeCheck(); + } + // make sure to invalidate the account data cache when account tokens change this.updateAccountDataOnAccountChange( oldDeviceConfig?.accountToken, @@ -1219,6 +1247,7 @@ class ApplicationMain { accountHistory: this.accountHistory, tunnelState: this.tunnelState, settings: this.settings, + isPerformingPostUpgrade: this.isPerformingPostUpgrade, deviceConfig: this.deviceConfig, hasReceivedDeviceConfig: this.hasReceivedDeviceConfig, relayListPair: { diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index b221f0a0e1..ebb7f0e18b 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -122,6 +122,10 @@ export default class AppRenderer { this.onDaemonDisconnected(); }); + IpcRendererEventChannel.daemon.listenIsPerformingPostUpgrade((isPerformingPostUpgrade) => { + this.setIsPerformingPostUpgrade(isPerformingPostUpgrade); + }); + IpcRendererEventChannel.account.listen((newAccountData?: IAccountData) => { this.setAccountExpiry(newAccountData?.expiry); }); @@ -203,6 +207,7 @@ export default class AppRenderer { this.setAccountExpiry(initialState.accountData?.expiry); this.setSettings(initialState.settings); + this.setIsPerformingPostUpgrade(initialState.isPerformingPostUpgrade); this.handleAccountChange({ deviceConfig: initialState.deviceConfig }, undefined); this.hasReceivedDeviceConfig = initialState.hasReceivedDeviceConfig; this.setAccountHistory(initialState.accountHistory); @@ -770,6 +775,10 @@ export default class AppRenderer { this.setBridgeSettings(newSettings.bridgeSettings); } + private setIsPerformingPostUpgrade(isPerformingPostUpgrade: boolean) { + this.reduxActions.userInterface.setIsPerformingPostUpgrade(isPerformingPostUpgrade); + } + private updateBlockedState(tunnelState: TunnelState, blockWhenDisconnected: boolean) { const actions = this.reduxActions.connection; switch (tunnelState.state) { diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx index d9ae7f105f..282f49d01c 100644 --- a/gui/src/renderer/components/Login.tsx +++ b/gui/src/renderer/components/Login.tsx @@ -51,6 +51,7 @@ interface IProps { updateAccountToken: (accountToken: AccountToken) => void; clearAccountHistory: () => Promise<void>; createNewAccount: () => void; + isPerformingPostUpgrade?: boolean; } interface IState { @@ -149,6 +150,10 @@ export default class Login extends React.Component<IProps, IState> { }; private formTitle() { + if (this.props.isPerformingPostUpgrade) { + return messages.pgettext('login-view', 'Upgrading...'); + } + switch (this.props.loginState.type) { case 'logging in': case 'too many devices': @@ -169,6 +174,10 @@ export default class Login extends React.Component<IProps, IState> { } private formSubtitle() { + if (this.props.isPerformingPostUpgrade) { + return messages.pgettext('login-view', 'Finishing upgrade.'); + } + switch (this.props.loginState.type) { case 'failed': return this.props.loginState.method === 'existing_account' @@ -199,6 +208,10 @@ export default class Login extends React.Component<IProps, IState> { } private getStatusIconPath(): string | undefined { + if (this.props.isPerformingPostUpgrade) { + return 'icon-spinner'; + } + switch (this.props.loginState.type) { case 'logging in': return 'icon-spinner'; @@ -213,6 +226,7 @@ export default class Login extends React.Component<IProps, IState> { private allowInteraction() { return ( + !this.props.isPerformingPostUpgrade && this.props.loginState.type !== 'logging in' && this.props.loginState.type !== 'ok' && this.props.loginState.type !== 'too many devices' @@ -291,7 +305,9 @@ export default class Login extends React.Component<IProps, IState> { messages.pgettext('accessibility', 'Login') }> <StyledInputSubmitIcon - visible={this.props.loginState.type !== 'logging in'} + visible={ + this.props.loginState.type !== 'logging in' && !this.props.isPerformingPostUpgrade + } source="icon-arrow" height={16} width={24} diff --git a/gui/src/renderer/containers/LoginPage.tsx b/gui/src/renderer/containers/LoginPage.tsx index 1abfa863a2..fd5aa5cbcd 100644 --- a/gui/src/renderer/containers/LoginPage.tsx +++ b/gui/src/renderer/containers/LoginPage.tsx @@ -13,11 +13,14 @@ const mapStateToProps = (state: IReduxState) => { const showBlockMessage = tunnelState.state === 'error' || blockWhenDisconnected; + const isPerformingPostUpgrade = state.userInterface.isPerformingPostUpgrade; + return { accountToken, accountHistory, loginState: status, showBlockMessage, + isPerformingPostUpgrade, }; }; const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => { diff --git a/gui/src/renderer/redux/userinterface/actions.ts b/gui/src/renderer/redux/userinterface/actions.ts index 78b5bae756..ce0cd5401b 100644 --- a/gui/src/renderer/redux/userinterface/actions.ts +++ b/gui/src/renderer/redux/userinterface/actions.ts @@ -46,6 +46,11 @@ export interface ISetChangelog { changelog: IChangelog; } +export interface ISetIsPerformingPostUpgrade { + type: 'SET_IS_PERFORMING_POST_UPGRADE'; + isPerformingPostUpgrade: boolean; +} + export type UserInterfaceAction = | IUpdateLocaleAction | IUpdateWindowArrowPositionAction @@ -55,7 +60,8 @@ export type UserInterfaceAction = | IRemoveScrollPosition | ISetMacOsScrollbarVisibility | ISetConnectedToDaemon - | ISetChangelog; + | ISetChangelog + | ISetIsPerformingPostUpgrade; function updateLocale(locale: string): IUpdateLocaleAction { return { @@ -122,6 +128,13 @@ function setChangelog(changelog: IChangelog): ISetChangelog { }; } +function setIsPerformingPostUpgrade(isPerformingPostUpgrade: boolean): ISetIsPerformingPostUpgrade { + return { + type: 'SET_IS_PERFORMING_POST_UPGRADE', + isPerformingPostUpgrade, + }; +} + export default { updateLocale, updateWindowArrowPosition, @@ -132,4 +145,5 @@ export default { setMacOsScrollbarVisibility, setConnectedToDaemon, setChangelog, + setIsPerformingPostUpgrade, }; diff --git a/gui/src/renderer/redux/userinterface/reducers.ts b/gui/src/renderer/redux/userinterface/reducers.ts index 58107b455e..ca470a8cba 100644 --- a/gui/src/renderer/redux/userinterface/reducers.ts +++ b/gui/src/renderer/redux/userinterface/reducers.ts @@ -11,6 +11,7 @@ export interface IUserInterfaceReduxState { macOsScrollbarVisibility?: MacOsScrollbarVisibility; connectedToDaemon: boolean; changelog: IChangelog; + isPerformingPostUpgrade: boolean; } const initialState: IUserInterfaceReduxState = { @@ -21,6 +22,7 @@ const initialState: IUserInterfaceReduxState = { macOsScrollbarVisibility: undefined, connectedToDaemon: false, changelog: [], + isPerformingPostUpgrade: false, }; export default function ( @@ -64,6 +66,12 @@ export default function ( changelog: action.changelog, }; + case 'SET_IS_PERFORMING_POST_UPGRADE': + return { + ...state, + isPerformingPostUpgrade: action.isPerformingPostUpgrade, + }; + default: return state; } diff --git a/gui/src/shared/ipc-schema.ts b/gui/src/shared/ipc-schema.ts index 1700ddc606..ce517c8f21 100644 --- a/gui/src/shared/ipc-schema.ts +++ b/gui/src/shared/ipc-schema.ts @@ -55,6 +55,7 @@ export interface IAppStateSnapshot { accountHistory?: AccountToken; tunnelState: TunnelState; settings: ISettings; + isPerformingPostUpgrade: boolean; deviceConfig?: IDeviceConfig; hasReceivedDeviceConfig: boolean; relayListPair: IRelayListPair; @@ -119,6 +120,7 @@ export const ipcSchema = { reset: notifyRenderer<void>(), }, daemon: { + isPerformingPostUpgrade: notifyRenderer<boolean>(), connected: notifyRenderer<void>(), disconnected: notifyRenderer<void>(), }, |
