diff options
| author | Hank <hank@mullvad.net> | 2022-10-11 17:20:14 +0200 |
|---|---|---|
| committer | Hank <hank@mullvad.net> | 2022-10-11 17:20:14 +0200 |
| commit | 69698a51656d8891526299d427f2f06fe3bc71a4 (patch) | |
| tree | ac12aa79b329852fe88c51f729959780c9c1af33 /gui/src/renderer | |
| parent | a8f08be40447b49f5e8945ffa2563c28dd125044 (diff) | |
| download | mullvadvpn-69698a51656d8891526299d427f2f06fe3bc71a4.tar.xz mullvadvpn-69698a51656d8891526299d427f2f06fe3bc71a4.zip | |
Make AppRouter a functional component
Diffstat (limited to 'gui/src/renderer')
| -rw-r--r-- | gui/src/renderer/components/AppRouter.tsx | 133 |
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; |
