aboutsummaryrefslogtreecommitdiff
path: root/modern/src
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-06-13 18:47:08 -0700
committerAnton Tananaev <anton@traccar.org>2022-06-13 18:47:08 -0700
commiteb850b4a17fd0eb8e02668ed4330de5c88e79880 (patch)
tree028f0661ceaa16965fba6ed697f699d56b258993 /modern/src
parentd171ec4d0c6a40a47af7870c40d1657da2b511e8 (diff)
downloadtrackermap-web-eb850b4a17fd0eb8e02668ed4330de5c88e79880.tar.gz
trackermap-web-eb850b4a17fd0eb8e02668ed4330de5c88e79880.tar.bz2
trackermap-web-eb850b4a17fd0eb8e02668ed4330de5c88e79880.zip
Refactor server initialization
Diffstat (limited to 'modern/src')
-rw-r--r--modern/src/App.js2
-rw-r--r--modern/src/ServerProvider.js51
-rw-r--r--modern/src/SocketController.js9
-rw-r--r--modern/src/index.js13
4 files changed, 60 insertions, 15 deletions
diff --git a/modern/src/App.js b/modern/src/App.js
index 3ba6b2e1..f6197d0a 100644
--- a/modern/src/App.js
+++ b/modern/src/App.js
@@ -21,7 +21,7 @@ const App = () => {
const desktop = useMediaQuery(theme.breakpoints.up('md'));
- const initialized = useSelector((state) => !!state.session.server && !!state.session.user);
+ const initialized = useSelector((state) => !!state.session.user);
if (!initialized) {
return (<LinearProgress />);
diff --git a/modern/src/ServerProvider.js b/modern/src/ServerProvider.js
new file mode 100644
index 00000000..720d0418
--- /dev/null
+++ b/modern/src/ServerProvider.js
@@ -0,0 +1,51 @@
+import React, { useState } from 'react';
+import { Alert, IconButton, LinearProgress } from '@mui/material';
+import ReplayIcon from '@mui/icons-material/Replay';
+import { useDispatch, useSelector } from 'react-redux';
+import { useEffectAsync } from './reactHelper';
+import { sessionActions } from './store';
+
+const ServerProvider = ({
+ children,
+}) => {
+ const dispatch = useDispatch();
+
+ const initialized = useSelector((state) => !!state.session.server);
+ const [error, setError] = useState(null);
+
+ useEffectAsync(async () => {
+ if (!error) {
+ try {
+ const response = await fetch('/api/server');
+ if (response.ok) {
+ dispatch(sessionActions.updateServer(await response.json()));
+ } else {
+ throw Error(await response.text());
+ }
+ } catch (error) {
+ setError(error.message);
+ }
+ }
+ }, [error]);
+
+ if (error) {
+ return (
+ <Alert
+ severity="error"
+ action={(
+ <IconButton color="inherit" size="small" onClick={() => setError(null)}>
+ <ReplayIcon fontSize="inherit" />
+ </IconButton>
+ )}
+ >
+ {error}
+ </Alert>
+ );
+ }
+ if (!initialized) {
+ return (<LinearProgress />);
+ }
+ return children;
+};
+
+export default ServerProvider;
diff --git a/modern/src/SocketController.js b/modern/src/SocketController.js
index 3e6e6783..79661353 100644
--- a/modern/src/SocketController.js
+++ b/modern/src/SocketController.js
@@ -66,15 +66,6 @@ const SocketController = () => {
};
useEffectAsync(async () => {
- const response = await fetch('/api/server');
- if (response.ok) {
- dispatch(sessionActions.updateServer(await response.json()));
- } else {
- throw Error(await response.text());
- }
- }, []);
-
- useEffectAsync(async () => {
if (authenticated) {
const response = await fetch('/api/devices');
if (response.ok) {
diff --git a/modern/src/index.js b/modern/src/index.js
index bfbb5efe..dbcd4c07 100644
--- a/modern/src/index.js
+++ b/modern/src/index.js
@@ -14,6 +14,7 @@ import Navigation from './Navigation';
import preloadImages from './map/core/preloadImages';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
import NativeInterface from './common/components/NativeInterface';
+import ServerProvider from './ServerProvider';
preloadImages();
@@ -26,11 +27,13 @@ ReactDOM.render(
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<CssBaseline />
- <BrowserRouter basename={base}>
- <SocketController />
- <CachingController />
- <Navigation />
- </BrowserRouter>
+ <ServerProvider>
+ <BrowserRouter basename={base}>
+ <SocketController />
+ <CachingController />
+ <Navigation />
+ </BrowserRouter>
+ </ServerProvider>
<ErrorHandler />
<NativeInterface />
</ThemeProvider>