|
@@ -1,6 +1,18 @@
|
|
|
import * as React from "react";
|
|
import * as React from "react";
|
|
|
-import { createContext, Suspense, useContext, useEffect, useState, useMemo } from "react";
|
|
|
|
|
-import { Box, Toolbar, CssBaseline, Backdrop, CircularProgress, useMediaQuery, ThemeProvider, createTheme } from "@mui/material";
|
|
|
|
|
|
|
+import { createContext, Suspense, useContext, useEffect, useState, useMemo, useCallback } from "react";
|
|
|
|
|
+import {
|
|
|
|
|
+ Box,
|
|
|
|
|
+ Toolbar,
|
|
|
|
|
+ CssBaseline,
|
|
|
|
|
+ Backdrop,
|
|
|
|
|
+ CircularProgress,
|
|
|
|
|
+ useMediaQuery,
|
|
|
|
|
+ ThemeProvider,
|
|
|
|
|
+ createTheme,
|
|
|
|
|
+ Snackbar,
|
|
|
|
|
+ Button,
|
|
|
|
|
+ Alert,
|
|
|
|
|
+} from "@mui/material";
|
|
|
import { useLiveQuery } from "dexie-react-hooks";
|
|
import { useLiveQuery } from "dexie-react-hooks";
|
|
|
import { BrowserRouter, Outlet, Route, Routes, useParams } from "react-router-dom";
|
|
import { BrowserRouter, Outlet, Route, Routes, useParams } from "react-router-dom";
|
|
|
import { useTranslation } from "react-i18next";
|
|
import { useTranslation } from "react-i18next";
|
|
@@ -14,7 +26,13 @@ import userManager from "../app/UserManager";
|
|
|
import { expandUrl, getKebabCaseLangStr } from "../app/utils";
|
|
import { expandUrl, getKebabCaseLangStr } from "../app/utils";
|
|
|
import ErrorBoundary from "./ErrorBoundary";
|
|
import ErrorBoundary from "./ErrorBoundary";
|
|
|
import routes from "./routes";
|
|
import routes from "./routes";
|
|
|
-import { useAccountListener, useBackgroundProcesses, useConnectionListeners, useWebPushTopics } from "./hooks";
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ useAccountListener,
|
|
|
|
|
+ useBackgroundProcesses,
|
|
|
|
|
+ useConnectionListeners,
|
|
|
|
|
+ useWebPushTopics,
|
|
|
|
|
+ useVersionChangeListener,
|
|
|
|
|
+} from "./hooks";
|
|
|
import PublishDialog from "./PublishDialog";
|
|
import PublishDialog from "./PublishDialog";
|
|
|
import Messaging from "./Messaging";
|
|
import Messaging from "./Messaging";
|
|
|
import Login from "./Login";
|
|
import Login from "./Login";
|
|
@@ -100,10 +118,12 @@ const updateTitle = (newNotificationsCount) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const Layout = () => {
|
|
const Layout = () => {
|
|
|
|
|
+ const { t } = useTranslation();
|
|
|
const params = useParams();
|
|
const params = useParams();
|
|
|
const { account, setAccount } = useContext(AccountContext);
|
|
const { account, setAccount } = useContext(AccountContext);
|
|
|
const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false);
|
|
const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false);
|
|
|
const [sendDialogOpenMode, setSendDialogOpenMode] = useState("");
|
|
const [sendDialogOpenMode, setSendDialogOpenMode] = useState("");
|
|
|
|
|
+ const [versionChanged, setVersionChanged] = useState(false);
|
|
|
const users = useLiveQuery(() => userManager.all());
|
|
const users = useLiveQuery(() => userManager.all());
|
|
|
const subscriptions = useLiveQuery(() => subscriptionManager.all());
|
|
const subscriptions = useLiveQuery(() => subscriptionManager.all());
|
|
|
const webPushTopics = useWebPushTopics();
|
|
const webPushTopics = useWebPushTopics();
|
|
@@ -115,9 +135,18 @@ const Layout = () => {
|
|
|
(config.base_url === s.baseUrl && params.topic === s.topic)
|
|
(config.base_url === s.baseUrl && params.topic === s.topic)
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
|
|
+ const handleVersionChange = useCallback(() => {
|
|
|
|
|
+ setVersionChanged(true);
|
|
|
|
|
+ }, []);
|
|
|
|
|
+
|
|
|
|
|
+ const handleRefresh = useCallback(() => {
|
|
|
|
|
+ window.location.reload();
|
|
|
|
|
+ }, []);
|
|
|
|
|
+
|
|
|
useConnectionListeners(account, subscriptions, users, webPushTopics);
|
|
useConnectionListeners(account, subscriptions, users, webPushTopics);
|
|
|
useAccountListener(setAccount);
|
|
useAccountListener(setAccount);
|
|
|
useBackgroundProcesses();
|
|
useBackgroundProcesses();
|
|
|
|
|
+ useVersionChangeListener(handleVersionChange);
|
|
|
useEffect(() => updateTitle(newNotificationsCount), [newNotificationsCount]);
|
|
useEffect(() => updateTitle(newNotificationsCount), [newNotificationsCount]);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
@@ -140,6 +169,23 @@ const Layout = () => {
|
|
|
/>
|
|
/>
|
|
|
</Main>
|
|
</Main>
|
|
|
<Messaging selected={selected} dialogOpenMode={sendDialogOpenMode} onDialogOpenModeChange={setSendDialogOpenMode} />
|
|
<Messaging selected={selected} dialogOpenMode={sendDialogOpenMode} onDialogOpenModeChange={setSendDialogOpenMode} />
|
|
|
|
|
+ <Snackbar
|
|
|
|
|
+ open={versionChanged}
|
|
|
|
|
+ anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
|
|
|
|
|
+ sx={{ bottom: { xs: 70, md: 24 } }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Alert
|
|
|
|
|
+ severity="info"
|
|
|
|
|
+ variant="filled"
|
|
|
|
|
+ action={
|
|
|
|
|
+ <Button color="inherit" size="small" onClick={handleRefresh}>
|
|
|
|
|
+ {t("common_refresh")}
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ {t("version_update_available")}
|
|
|
|
|
+ </Alert>
|
|
|
|
|
+ </Snackbar>
|
|
|
</Box>
|
|
</Box>
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|