aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-05-26 16:16:41 -0700
committerAnton Tananaev <anton@traccar.org>2022-05-26 16:16:41 -0700
commit3a651e5f02a90857e4023edb7ac9785d569417dd (patch)
tree8ca8ac15c3c2a708236e5db1fd1b577e880046aa
parente01380561a113f868538e9a3399fc2406e250368 (diff)
downloadtrackermap-web-3a651e5f02a90857e4023edb7ac9785d569417dd.tar.gz
trackermap-web-3a651e5f02a90857e4023edb7ac9785d569417dd.tar.bz2
trackermap-web-3a651e5f02a90857e4023edb7ac9785d569417dd.zip
Socket status and backup
-rw-r--r--modern/src/SocketController.js19
-rw-r--r--modern/src/common/components/BottomMenu.js12
-rw-r--r--modern/src/store/session.js4
3 files changed, 31 insertions, 4 deletions
diff --git a/modern/src/SocketController.js b/modern/src/SocketController.js
index 05236971..a6f1fa11 100644
--- a/modern/src/SocketController.js
+++ b/modern/src/SocketController.js
@@ -33,8 +33,23 @@ const SocketController = () => {
const socket = new WebSocket(`${protocol}//${window.location.host}/api/socket`);
socketRef.current = socket;
- socket.onerror = () => {
- setTimeout(() => connectSocket(), 60 * 1000);
+ socket.onopen = () => {
+ dispatch(sessionActions.updateSocket(true));
+ };
+
+ socket.onclose = async () => {
+ dispatch(sessionActions.updateSocket(false));
+ const devicesResponse = await fetch('/api/devices');
+ if (devicesResponse.ok) {
+ dispatch(devicesActions.update(await devicesResponse.json()));
+ }
+ const positionsResponse = await fetch('/api/positions', {
+ headers: { 'Content-Type': 'application/json' },
+ });
+ if (positionsResponse.ok) {
+ dispatch(positionsActions.update(await positionsResponse.json()));
+ }
+ setTimeout(() => connectSocket(), 60000);
};
socket.onmessage = (event) => {
diff --git a/modern/src/common/components/BottomMenu.js b/modern/src/common/components/BottomMenu.js
index b011638e..274c4f1a 100644
--- a/modern/src/common/components/BottomMenu.js
+++ b/modern/src/common/components/BottomMenu.js
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate, useLocation } from 'react-router-dom';
import {
- Paper, BottomNavigation, BottomNavigationAction, Menu, MenuItem, Typography,
+ Paper, BottomNavigation, BottomNavigationAction, Menu, MenuItem, Typography, Badge,
} from '@mui/material';
import DescriptionIcon from '@mui/icons-material/Description';
@@ -23,6 +23,7 @@ const BottomMenu = () => {
const readonly = useReadonly();
const userId = useSelector((state) => state.session.user?.id);
+ const socket = useSelector((state) => state.session.socket);
const [anchorEl, setAnchorEl] = useState(null);
@@ -77,7 +78,14 @@ const BottomMenu = () => {
return (
<Paper square elevation={3}>
<BottomNavigation value={currentSelection()} onChange={handleSelection} showLabels>
- <BottomNavigationAction label={t('mapTitle')} icon={<MapIcon />} />
+ <BottomNavigationAction
+ label={t('mapTitle')}
+ icon={(
+ <Badge color="error" variant="dot" overlap="circular" invisible={socket !== false}>
+ <MapIcon />
+ </Badge>
+ )}
+ />
<BottomNavigationAction label={t('reportTitle')} icon={<DescriptionIcon />} />
<BottomNavigationAction label={t('settingsTitle')} icon={<SettingsIcon />} />
{readonly
diff --git a/modern/src/store/session.js b/modern/src/store/session.js
index 9f98b8ae..88d1eb44 100644
--- a/modern/src/store/session.js
+++ b/modern/src/store/session.js
@@ -5,6 +5,7 @@ const { reducer, actions } = createSlice({
initialState: {
server: null,
user: null,
+ socket: null,
},
reducers: {
updateServer(state, action) {
@@ -13,6 +14,9 @@ const { reducer, actions } = createSlice({
updateUser(state, action) {
state.user = action.payload;
},
+ updateSocket(state, action) {
+ state.socket = action.payload;
+ },
},
});