summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
authorHank <hank@mullvad.net>2022-10-11 17:20:14 +0200
committerHank <hank@mullvad.net>2022-10-11 17:20:14 +0200
commit69698a51656d8891526299d427f2f06fe3bc71a4 (patch)
treeac12aa79b329852fe88c51f729959780c9c1af33 /gui/src
parenta8f08be40447b49f5e8945ffa2563c28dd125044 (diff)
downloadmullvadvpn-69698a51656d8891526299d427f2f06fe3bc71a4.tar.xz
mullvadvpn-69698a51656d8891526299d427f2f06fe3bc71a4.zip
Make AppRouter a functional component
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/renderer/components/AppRouter.tsx133
1 files changed, 51 insertions, 82 deletions
diff --git a/gui/src/renderer/components/AppRouter.tsx b/gui/src/renderer/components/AppRouter.tsx
index dbc6f538e6..d08498b933 100644
--- a/gui/src/renderer/components/AppRouter.tsx
+++ b/gui/src/renderer/components/AppRouter.tsx
@@ -1,13 +1,12 @@
-import { Action } from 'history';
-import * as React from 'react';
+import { createRef, useCallback, useEffect, useRef, useState } from 'react';
import { Route, Switch } from 'react-router';
import AccountPage from '../containers/AccountPage';
import LoginPage from '../containers/LoginPage';
import ProblemReportPage from '../containers/ProblemReportPage';
import SelectLocationPage from '../containers/SelectLocationPage';
-import withAppContext, { IAppContext } from '../context';
-import { IHistoryProps, ITransitionSpecification, transitions, withHistory } from '../lib/history';
+import { useAppContext } from '../context';
+import { ITransitionSpecification, transitions, useHistory } from '../lib/history';
import { RoutePath } from '../lib/routes';
import { DeviceRevokedView } from './DeviceRevokedView';
import {
@@ -31,90 +30,60 @@ import UserInterfaceSettings from './UserInterfaceSettings';
import VpnSettings from './VpnSettings';
import WireguardSettings from './WireguardSettings';
-interface IAppRoutesState {
- currentLocation: IHistoryProps['history']['location'];
- transition: ITransitionSpecification;
- action?: Action;
-}
-
-class AppRouter extends React.Component<IHistoryProps & IAppContext, IAppRoutesState> {
- private unobserveHistory?: () => void;
-
- private focusRef = React.createRef<IFocusHandle>();
-
- constructor(props: IHistoryProps & IAppContext) {
- super(props);
+export default function AppRouter() {
+ const history = useHistory();
+ const [currentLocation, setCurrentLocation] = useState(history.location);
+ const [transition, setTransition] = useState<ITransitionSpecification>(transitions.none);
+ const { setNavigationHistory } = useAppContext();
+ const focusRef = createRef<IFocusHandle>();
- this.state = {
- currentLocation: props.history.location,
- transition: transitions.none,
- };
- }
+ const unobserveHistory = useRef<() => void>();
- public componentDidMount() {
+ useEffect(() => {
// 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,
- action,
- });
+ unobserveHistory.current = history.listen((location, _, transition) => {
+ setNavigationHistory(history.asObject);
+ setCurrentLocation(location);
+ setTransition(transition);
});
- }
- public componentWillUnmount() {
- if (this.unobserveHistory) {
- this.unobserveHistory();
- }
- }
+ return () => unobserveHistory.current?.();
+ }, []);
- public render() {
- const location = this.state.currentLocation;
+ const onNavigation = useCallback(() => {
+ focusRef.current?.resetFocus();
+ }, []);
- return (
- <Focus ref={this.focusRef}>
- <TransitionContainer onTransitionEnd={this.onNavigation} {...this.state.transition}>
- <TransitionView viewId={location.key || ''}>
- <Switch key={location.key} location={location}>
- <Route exact path={RoutePath.launch} component={Launch} />
- <Route exact path={RoutePath.login} component={LoginPage} />
- <Route exact path={RoutePath.tooManyDevices} component={TooManyDevices} />
- <Route exact path={RoutePath.deviceRevoked} component={DeviceRevokedView} />
- <Route exact path={RoutePath.main} component={MainView} />
- <Route exact path={RoutePath.redeemVoucher} component={VoucherInput} />
- <Route exact path={RoutePath.voucherSuccess} component={VoucherVerificationSuccess} />
- <Route exact path={RoutePath.timeAdded} component={TimeAdded} />
- <Route exact path={RoutePath.setupFinished} component={SetupFinished} />
- <Route exact path={RoutePath.settings} component={Settings} />
- <Route exact path={RoutePath.selectLanguage} component={SelectLanguage} />
- <Route exact path={RoutePath.accountSettings} component={AccountPage} />
- <Route
- exact
- path={RoutePath.userInterfaceSettings}
- component={UserInterfaceSettings}
- />
- <Route exact path={RoutePath.vpnSettings} component={VpnSettings} />
- <Route exact path={RoutePath.wireguardSettings} component={WireguardSettings} />
- <Route exact path={RoutePath.openVpnSettings} component={OpenVpnSettings} />
- <Route exact path={RoutePath.splitTunneling} component={SplitTunnelingSettings} />
- <Route exact path={RoutePath.support} component={Support} />
- <Route exact path={RoutePath.problemReport} component={ProblemReportPage} />
- <Route exact path={RoutePath.selectLocation} component={SelectLocationPage} />
- <Route exact path={RoutePath.filter} component={Filter} />
- </Switch>
- </TransitionView>
- </TransitionContainer>
- </Focus>
- );
- }
-
- private onNavigation = () => {
- this.focusRef.current?.resetFocus();
- };
+ return (
+ <Focus ref={focusRef}>
+ <TransitionContainer onTransitionEnd={onNavigation} {...transition}>
+ <TransitionView viewId={currentLocation.key || ''}>
+ <Switch key={currentLocation.key} location={currentLocation}>
+ <Route exact path={RoutePath.launch} component={Launch} />
+ <Route exact path={RoutePath.login} component={LoginPage} />
+ <Route exact path={RoutePath.tooManyDevices} component={TooManyDevices} />
+ <Route exact path={RoutePath.deviceRevoked} component={DeviceRevokedView} />
+ <Route exact path={RoutePath.main} component={MainView} />
+ <Route exact path={RoutePath.redeemVoucher} component={VoucherInput} />
+ <Route exact path={RoutePath.voucherSuccess} component={VoucherVerificationSuccess} />
+ <Route exact path={RoutePath.timeAdded} component={TimeAdded} />
+ <Route exact path={RoutePath.setupFinished} component={SetupFinished} />
+ <Route exact path={RoutePath.settings} component={Settings} />
+ <Route exact path={RoutePath.selectLanguage} component={SelectLanguage} />
+ <Route exact path={RoutePath.accountSettings} component={AccountPage} />
+ <Route exact path={RoutePath.userInterfaceSettings} component={UserInterfaceSettings} />
+ <Route exact path={RoutePath.vpnSettings} component={VpnSettings} />
+ <Route exact path={RoutePath.wireguardSettings} component={WireguardSettings} />
+ <Route exact path={RoutePath.openVpnSettings} component={OpenVpnSettings} />
+ <Route exact path={RoutePath.splitTunneling} component={SplitTunnelingSettings} />
+ <Route exact path={RoutePath.support} component={Support} />
+ <Route exact path={RoutePath.problemReport} component={ProblemReportPage} />
+ <Route exact path={RoutePath.selectLocation} component={SelectLocationPage} />
+ <Route exact path={RoutePath.filter} component={Filter} />
+ </Switch>
+ </TransitionView>
+ </TransitionContainer>
+ </Focus>
+ );
}
-
-const AppRoutesWithRouter = withAppContext(withHistory(AppRouter));
-
-export default AppRoutesWithRouter;