summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2022-11-07 10:19:48 +0100
committerOskar Nyberg <oskar@mullvad.net>2022-11-07 14:45:54 +0100
commitc48585f44062138a1abc42f8a3d9dafa4172e923 (patch)
tree7921c63578a79de74aaaa4a708cb752cff548f49
parent349e339110616cd01a8bd58a77b22d232228eb66 (diff)
downloadmullvadvpn-c48585f44062138a1abc42f8a3d9dafa4172e923.tar.xz
mullvadvpn-c48585f44062138a1abc42f8a3d9dafa4172e923.zip
Add developer tools view
-rw-r--r--gui/src/renderer/components/AppRouter.tsx2
-rw-r--r--gui/src/renderer/components/Debug.tsx90
-rw-r--r--gui/src/renderer/components/Settings.tsx17
-rw-r--r--gui/src/renderer/lib/routes.ts1
4 files changed, 110 insertions, 0 deletions
diff --git a/gui/src/renderer/components/AppRouter.tsx b/gui/src/renderer/components/AppRouter.tsx
index 4dad09a773..cab40d9db9 100644
--- a/gui/src/renderer/components/AppRouter.tsx
+++ b/gui/src/renderer/components/AppRouter.tsx
@@ -7,6 +7,7 @@ import { useAppContext } from '../context';
import { ITransitionSpecification, transitions, useHistory } from '../lib/history';
import { RoutePath } from '../lib/routes';
import Account from './Account';
+import Debug from './Debug';
import { DeviceRevokedView } from './DeviceRevokedView';
import {
SetupFinished,
@@ -79,6 +80,7 @@ export default function AppRouter() {
<Route exact path={RoutePath.splitTunneling} component={SplitTunnelingSettings} />
<Route exact path={RoutePath.support} component={Support} />
<Route exact path={RoutePath.problemReport} component={ProblemReport} />
+ <Route exact path={RoutePath.debug} component={Debug} />
<Route exact path={RoutePath.selectLocation} component={SelectLocationPage} />
<Route exact path={RoutePath.filter} component={Filter} />
</Switch>
diff --git a/gui/src/renderer/components/Debug.tsx b/gui/src/renderer/components/Debug.tsx
new file mode 100644
index 0000000000..f81fb85402
--- /dev/null
+++ b/gui/src/renderer/components/Debug.tsx
@@ -0,0 +1,90 @@
+import { useCallback } from 'react';
+import styled from 'styled-components';
+
+import { useHistory } from '../lib/history';
+import { useBoolean } from '../lib/utilityHooks';
+import * as AppButton from './AppButton';
+import { measurements } from './common-styles';
+import { BackAction } from './KeyboardNavigation';
+import { Layout, SettingsContainer } from './Layout';
+import {
+ NavigationBar,
+ NavigationContainer,
+ NavigationItems,
+ NavigationScrollbars,
+ TitleBarItem,
+} from './NavigationBar';
+import SettingsHeader, { HeaderTitle } from './SettingsHeader';
+
+const StyledContent = styled.div({
+ display: 'flex',
+ flexDirection: 'column',
+ flex: 1,
+ marginBottom: '2px',
+});
+
+const StyledButtonGroup = styled.div({
+ margin: measurements.viewMargin,
+});
+
+export default function Debug() {
+ const { pop } = useHistory();
+
+ return (
+ <BackAction action={pop}>
+ <Layout>
+ <SettingsContainer>
+ <NavigationContainer>
+ <NavigationBar>
+ <NavigationItems>
+ <TitleBarItem>Developer tools</TitleBarItem>
+ </NavigationItems>
+ </NavigationBar>
+
+ <NavigationScrollbars>
+ <SettingsHeader>
+ <HeaderTitle>Developer tools</HeaderTitle>
+ </SettingsHeader>
+
+ <StyledContent>
+ <StyledButtonGroup>
+ <AppButton.ButtonGroup>
+ <ThrowErrorButton />
+ <UnhandledRejectionButton />
+ <ErrorDuringRender />
+ </AppButton.ButtonGroup>
+ </StyledButtonGroup>
+ </StyledContent>
+ </NavigationScrollbars>
+ </NavigationContainer>
+ </SettingsContainer>
+ </Layout>
+ </BackAction>
+ );
+}
+
+function ThrowErrorButton() {
+ const handleClick = useCallback(() => {
+ throw new Error('This is a test error');
+ }, []);
+
+ return <AppButton.RedButton onClick={handleClick}>Throw error</AppButton.RedButton>;
+}
+
+function UnhandledRejectionButton() {
+ const handleClick = useCallback(() => {
+ return new Promise((_resolve, reject) => setTimeout(reject, 100));
+ }, []);
+
+ return <AppButton.RedButton onClick={handleClick}>Unhandled rejection</AppButton.RedButton>;
+}
+
+function ErrorDuringRender() {
+ const [error, setError] = useBoolean(false);
+
+ if (error) {
+ throw new Error('This is a test error during render');
+ }
+
+ return <AppButton.RedButton onClick={setError}>Error next render</AppButton.RedButton>;
+}
diff --git a/gui/src/renderer/components/Settings.tsx b/gui/src/renderer/components/Settings.tsx
index 69d4e2b80a..fb4feec8fd 100644
--- a/gui/src/renderer/components/Settings.tsx
+++ b/gui/src/renderer/components/Settings.tsx
@@ -84,6 +84,12 @@ export default function Support() {
<SupportButton />
<AppVersionButton />
</Cell.Group>
+
+ {window.env.development && (
+ <Cell.Group>
+ <DebugButton />
+ </Cell.Group>
+ )}
</StyledSettingsContent>
</StyledContent>
@@ -237,6 +243,17 @@ function SupportButton() {
);
}
+function DebugButton() {
+ const history = useHistory();
+ const navigate = useCallback(() => history.push(RoutePath.debug), [history]);
+
+ return (
+ <Cell.CellNavigationButton onClick={navigate}>
+ <Cell.Label>Developer tools</Cell.Label>
+ </Cell.CellNavigationButton>
+ );
+}
+
function QuitButton() {
const { quit } = useAppContext();
diff --git a/gui/src/renderer/lib/routes.ts b/gui/src/renderer/lib/routes.ts
index 3a82175d3e..eaefb26c67 100644
--- a/gui/src/renderer/lib/routes.ts
+++ b/gui/src/renderer/lib/routes.ts
@@ -22,6 +22,7 @@ export enum RoutePath {
splitTunneling = '/settings/split-tunneling',
support = '/settings/support',
problemReport = '/settings/support/problem-report',
+ debug = '/settings/debug',
selectLocation = '/select-location',
filter = '/select-location/filter',
}