Skip to content

Commit

Permalink
feat(client): add advanced setting to change network mode
Browse files Browse the repository at this point in the history
- three modes: auto (detect through navigator), force offline, force online
- propagated to app through useIsOnline hook
  • Loading branch information
neopostmodern committed Aug 12, 2022
1 parent 9723ae2 commit 88d5936
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 4 deletions.
14 changes: 14 additions & 0 deletions client/src/renderer/actions/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
export enum NetworkMode {
AUTO = 'AUTO',
FORCE_OFFLINE = 'FORCE_OFFLINE',
FORCE_ONLINE = 'FORCE_ONLINE',
}

export const SET_BACKEND_URL = 'SET_BACKEND_URL';
export const REQUEST_RESTART = 'REQUEST_RESTART';
export const SET_NETWORK_MODE = 'SET_NETWORK_MODE';

export function setBackendUrl(backendUrl: string) {
return {
Expand All @@ -13,3 +20,10 @@ export function requestRestart() {
type: REQUEST_RESTART,
};
}

export function setNetworkMode(networkMode: NetworkMode) {
return {
type: SET_NETWORK_MODE,
payload: networkMode,
};
}
32 changes: 31 additions & 1 deletion client/src/renderer/components/AdvancedSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { useApolloClient } from '@apollo/client';
import { Typography } from '@mui/material';
import { Box, MenuItem, Select, Typography } from '@mui/material';
import { useDispatch, useSelector } from 'react-redux';
import { NetworkMode, setNetworkMode } from '../actions/configuration';
import { ENTITIES_UPDATED_SINCE_STORAGE_KEY } from '../hooks/useEntitiesUpdatedSince';
import { RootState } from '../reducers';
import { clearApolloCache } from '../utils/cache';
import SettingsEntry from './SettingsEntry';

const networkModeNames = {
[NetworkMode.AUTO]: 'Auto',
[NetworkMode.FORCE_OFFLINE]: 'Force offline',
[NetworkMode.FORCE_ONLINE]: 'Force online',
};

const AdvancedSettings = () => {
const apolloClient = useApolloClient();
const networkMode = useSelector<RootState, NetworkMode>(
(state) => state.configuration.networkMode
);
const dispatch = useDispatch();

return (
<>
Expand All @@ -22,6 +35,23 @@ const AdvancedSettings = () => {
window.location.reload();
}}
/>
<SettingsEntry title="Network mode">
<Box display="flex" justifyContent="flex-end">
<Select
variant="standard"
value={networkMode}
onChange={(event) => {
dispatch(setNetworkMode(event.target.value as NetworkMode));
}}
>
{Object.values(NetworkMode).map((networkMode) => (
<MenuItem value={networkMode}>
{networkModeNames[networkMode]}
</MenuItem>
))}
</Select>
</Box>
</SettingsEntry>
</>
);
};
Expand Down
14 changes: 14 additions & 0 deletions client/src/renderer/hooks/useIsOnline.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { NetworkMode } from '../actions/configuration';
import { RootState } from '../reducers';

const getOnlineStatus = () =>
typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean'
? navigator.onLine
: true;

const useIsOnline = () => {
const networkMode = useSelector<RootState, NetworkMode>(
(state) => state.configuration.networkMode
);

const [status, setStatus] = useState(getOnlineStatus());

const setOnline = () => setStatus(true);
Expand All @@ -21,6 +28,13 @@ const useIsOnline = () => {
};
}, []);

if (networkMode === NetworkMode.FORCE_ONLINE) {
return true;
}
if (networkMode === NetworkMode.FORCE_OFFLINE) {
return false;
}

return status;
};

Expand Down
17 changes: 14 additions & 3 deletions client/src/renderer/middleware/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { requestRestart, SET_BACKEND_URL } from '../actions/configuration';
import {
requestRestart,
SET_BACKEND_URL,
SET_NETWORK_MODE,
} from '../actions/configuration';

let configurationMiddleware;

Expand All @@ -8,11 +12,18 @@ if (process.env.TARGET !== 'web') {
window.electron.electronStore.set('backend-url', action.payload);
store.dispatch(requestRestart());
}
if (action.type === SET_NETWORK_MODE) {
window.electron.electronStore.set('network-mode', action.payload);
}
return next(action);
};
} else {
// eslint-disable-next-line no-unused-vars
configurationMiddleware = (store) => (next) => (action) => next(action); // no-op middleware
configurationMiddleware = () => (next) => (action) => {
if (action.type === SET_NETWORK_MODE) {
localStorage.setItem('network-mode', action.payload);
}
return next(action);
};
}

export default configurationMiddleware;
13 changes: 13 additions & 0 deletions client/src/renderer/reducers/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,41 @@
import { NetworkMode, SET_NETWORK_MODE } from '../actions/configuration';

export interface ConfigurationStateType {
backendUrl: string;
backendUrlDefault: string;
networkMode: NetworkMode;
}

type Action = { type: string; payload?: any };

let backendUrl;
let networkMode;
if (process.env.TARGET === 'web') {
// no backend customization for web, other backends should host their own frontends
backendUrl = BACKEND_URL;
networkMode =
(localStorage.getItem('network-mode') as NetworkMode) || NetworkMode.AUTO;
} else {
backendUrl = window.electron.electronStore.get('backend-url', BACKEND_URL);
networkMode = window.electron.electronStore.get(
'network-mode',
NetworkMode.AUTO
);
}

const initialState: ConfigurationStateType = {
backendUrl,
backendUrlDefault: BACKEND_URL,
networkMode,
};

export default function configuration(
state: ConfigurationStateType = initialState,
action: Action
) {
switch (action.type) {
case SET_NETWORK_MODE:
return { ...state, networkMode: action.payload };
default:
return state;
}
Expand Down

0 comments on commit 88d5936

Please sign in to comment.