diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-04-14 13:23:02 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-04-20 10:51:21 +0200 |
| commit | 9a07f80b235382232ba3c3f34c83e2ce8931aaa8 (patch) | |
| tree | f9a7c76076d5bb3f421b604a270ec3e28903f8d0 /gui/src/renderer | |
| parent | fbdf3932b450ab65940f9f006db05cd35ff10704 (diff) | |
| download | mullvadvpn-9a07f80b235382232ba3c3f34c83e2ce8931aaa8.tar.xz mullvadvpn-9a07f80b235382232ba3c3f34c83e2ce8931aaa8.zip | |
Remember history when replacing window
Diffstat (limited to 'gui/src/renderer')
| -rw-r--r-- | gui/src/renderer/app.tsx | 28 | ||||
| -rw-r--r-- | gui/src/renderer/components/AppRouter.tsx | 8 | ||||
| -rw-r--r-- | gui/src/renderer/lib/history.tsx | 18 |
3 files changed, 45 insertions, 9 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index a0fb5f3266..0d9221c51f 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -25,7 +25,7 @@ import { import { messages, relayLocations } from '../shared/gettext'; import { IGuiSettingsState, SYSTEM_PREFERRED_LOCALE_KEY } from '../shared/gui-settings-state'; import { IRelayListPair, LaunchApplicationResult } from '../shared/ipc-schema'; -import { IChangelog, ICurrentAppVersionInfo } from '../shared/ipc-types'; +import { IChangelog, ICurrentAppVersionInfo, IHistoryObject } from '../shared/ipc-types'; import log, { ConsoleOutput } from '../shared/logging'; import { LogLevel } from '../shared/logging-types'; import { Scheduler } from '../shared/scheduler'; @@ -208,7 +208,11 @@ export default class AppRenderer { this.setAccountExpiry(initialState.accountData?.expiry); this.setSettings(initialState.settings); this.setIsPerformingPostUpgrade(initialState.isPerformingPostUpgrade); - this.handleAccountChange({ deviceConfig: initialState.deviceConfig }, undefined); + this.handleAccountChange( + { deviceConfig: initialState.deviceConfig }, + undefined, + initialState.navigationHistory !== undefined, + ); this.hasReceivedDeviceConfig = initialState.hasReceivedDeviceConfig; this.setAccountHistory(initialState.accountHistory); this.setTunnelState(initialState.tunnelState); @@ -244,8 +248,12 @@ export default class AppRenderer { void this.updateLocation(); - const navigationBase = this.getNavigationBase(); - this.history = new History(navigationBase); + if (initialState.navigationHistory) { + this.history = History.fromSavedHistory(initialState.navigationHistory); + } else { + const navigationBase = this.getNavigationBase(); + this.history = new History(navigationBase); + } } public renderView() { @@ -555,6 +563,10 @@ export default class AppRenderer { IpcRendererEventChannel.currentVersion.displayedChangelog(); }; + public setNavigationHistory(history: IHistoryObject) { + IpcRendererEventChannel.navigation.setHistory(history); + } + // Make sure that the content height is correct and log if it isn't. This is mostly for debugging // purposes since there's a bug in Electron that causes the app height to be another value than // the one we have set. @@ -804,7 +816,11 @@ export default class AppRenderer { } } - private handleAccountChange(newDeviceEvent: IDeviceEvent, oldAccount?: string) { + private handleAccountChange( + newDeviceEvent: IDeviceEvent, + oldAccount?: string, + preventRedirectToConnect?: boolean, + ) { const reduxAccount = this.reduxActions.account; this.deviceConfig = newDeviceEvent.deviceConfig; @@ -828,7 +844,7 @@ export default class AppRenderer { if (this.previousLoginState === 'too many devices') { this.resetNavigation(); - } else { + } else if (!preventRedirectToConnect) { this.redirectToConnect(); } break; diff --git a/gui/src/renderer/components/AppRouter.tsx b/gui/src/renderer/components/AppRouter.tsx index d061c7b9d5..18a8b51063 100644 --- a/gui/src/renderer/components/AppRouter.tsx +++ b/gui/src/renderer/components/AppRouter.tsx @@ -12,6 +12,7 @@ import SelectLocationPage from '../containers/SelectLocationPage'; import SettingsPage from '../containers/SettingsPage'; import SupportPage from '../containers/SupportPage'; import WireguardSettingsPage from '../containers/WireguardSettingsPage'; +import withAppContext, { IAppContext } from '../context'; import { IHistoryProps, ITransitionSpecification, transitions, withHistory } from '../lib/history'; import { RoutePath } from '../lib/routes'; import { DeviceRevokedView } from './DeviceRevokedView'; @@ -36,12 +37,12 @@ interface IAppRoutesState { action?: Action; } -class AppRouter extends React.Component<IHistoryProps, IAppRoutesState> { +class AppRouter extends React.Component<IHistoryProps & IAppContext, IAppRoutesState> { private unobserveHistory?: () => void; private focusRef = React.createRef<IFocusHandle>(); - constructor(props: IHistoryProps) { + constructor(props: IHistoryProps & IAppContext) { super(props); this.state = { @@ -54,6 +55,7 @@ class AppRouter extends React.Component<IHistoryProps, IAppRoutesState> { // React throttles updates, so it's impossible to capture the intermediate navigation without // listening to the history directly. this.unobserveHistory = this.props.history.listen((location, action, transition) => { + this.props.app.setNavigationHistory(this.props.history.asObject); this.setState({ currentLocation: location, transition, @@ -114,6 +116,6 @@ class AppRouter extends React.Component<IHistoryProps, IAppRoutesState> { }; } -const AppRoutesWithRouter = withHistory(AppRouter); +const AppRoutesWithRouter = withAppContext(withHistory(AppRouter)); export default AppRoutesWithRouter; diff --git a/gui/src/renderer/lib/history.tsx b/gui/src/renderer/lib/history.tsx index 2eb08d001d..9a0205b382 100644 --- a/gui/src/renderer/lib/history.tsx +++ b/gui/src/renderer/lib/history.tsx @@ -2,6 +2,7 @@ import { Action, History as OriginalHistory, Location, LocationDescriptorObject import React from 'react'; import { RouteComponentProps, useHistory as useReactRouterHistory, withRouter } from 'react-router'; +import { IHistoryObject } from '../../shared/ipc-types'; import { GeneratedRoutePath, RoutePath } from './routes'; export interface ITransitionSpecification { @@ -61,6 +62,15 @@ export default class History { this.entries = [this.createLocation(location, state)]; } + public static fromSavedHistory(savedHistory: IHistoryObject): History { + const history = new History(RoutePath.launch); + history.entries = savedHistory.entries; + history.index = savedHistory.index; + history.lastAction = savedHistory.lastAction; + + return history; + } + public get location(): Location<S> { return this.entries[this.index]; } @@ -126,6 +136,14 @@ export default class History { return this as OriginalHistory; } + public get asObject(): IHistoryObject { + return { + entries: this.entries, + index: this.index, + lastAction: this.lastAction, + }; + } + public block(): never { throw Error('Not implemented'); } |
