get and send system name in AuthenticaionContext to prevent /rest/settings on each render

This commit is contained in:
proddy
2026-08-23 12:22:45 +02:00
parent 6efc7113b3
commit 42f86cd12b
6 changed files with 32 additions and 13 deletions
@@ -1,4 +1,4 @@
import { useState } from 'react'; import { useContext, useEffect, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
@@ -31,6 +31,7 @@ import {
useLayoutTitle useLayoutTitle
} from 'components'; } from 'components';
import { toast } from 'components/toast'; import { toast } from 'components/toast';
import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import { numberValue, updateValueDirty, useRest } from 'utils'; import { numberValue, updateValueDirty, useRest } from 'utils';
import { ValidationError, validate } from 'validators'; import { ValidationError, validate } from 'validators';
@@ -68,6 +69,14 @@ const ApplicationSettings = () => {
update: writeSettings update: writeSettings
}); });
// the menu drawer reads the system name from the authentication context
const { setSystemName } = useContext(AuthenticatedContext);
useEffect(() => {
if (origData?.system_name !== undefined) {
setSystemName(origData.system_name);
}
}, [origData?.system_name, setSystemName]);
const [restarting, setRestarting] = useState<boolean>(); const [restarting, setRestarting] = useState<boolean>();
const { LL } = useI18nContext(); const { LL } = useI18nContext();
@@ -1,10 +1,8 @@
import { memo } from 'react'; import { memo, useContext } from 'react';
import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material'; import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material';
import { readSettings } from 'api/app'; import { AuthenticatedContext } from 'contexts/authentication';
import { useRequest } from 'alova/client';
import { PROJECT_NAME } from 'env'; import { PROJECT_NAME } from 'env';
import { DRAWER_WIDTH } from './Layout'; import { DRAWER_WIDTH } from './Layout';
@@ -27,8 +25,7 @@ interface LayoutDrawerProps {
} }
const LayoutDrawerComponent = ({ mobileOpen, onClose }: LayoutDrawerProps) => { const LayoutDrawerComponent = ({ mobileOpen, onClose }: LayoutDrawerProps) => {
const { data: settings } = useRequest(readSettings); const { systemName } = useContext(AuthenticatedContext);
const system_name = settings?.system_name;
const drawer = ( const drawer = (
<> <>
@@ -43,9 +40,9 @@ const LayoutDrawerComponent = ({ mobileOpen, onClose }: LayoutDrawerProps) => {
}} }}
> >
<Typography>{PROJECT_NAME}</Typography> <Typography>{PROJECT_NAME}</Typography>
{system_name && ( {systemName && (
<Typography color="secondary" variant="body2"> <Typography color="secondary" variant="body2">
{system_name} {systemName}
</Typography> </Typography>
)} )}
</Box> </Box>
@@ -23,6 +23,7 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
const [initialized, setInitialized] = useState<boolean>(false); const [initialized, setInitialized] = useState<boolean>(false);
const [me, setMe] = useState<Me>(); const [me, setMe] = useState<Me>();
const [versions, setVersions] = useState<VersionsResponse>(); const [versions, setVersions] = useState<VersionsResponse>();
const [systemName, setSystemName] = useState<string>();
const { send: sendVerifyAuthorization } = useRequest(verifyAuthorization(), { const { send: sendVerifyAuthorization } = useRequest(verifyAuthorization(), {
immediate: false immediate: false
@@ -33,7 +34,9 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
{ immediate: false } { immediate: false }
) )
.onSuccess((event) => { .onSuccess((event) => {
setVersions(event.data as VersionsResponse); const response = event.data as VersionsResponse;
setVersions(response);
setSystemName(response.system_name);
}) })
.onError(() => { .onError(() => {
setVersions(undefined); setVersions(undefined);
@@ -60,6 +63,7 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
AuthenticationApi.clearAccessToken(); AuthenticationApi.clearAccessToken();
setMe(undefined); setMe(undefined);
setVersions(undefined); setVersions(undefined);
setSystemName(undefined);
if (doRedirect) { if (doRedirect) {
void navigate('/', { replace: true }); void navigate('/', { replace: true });
} }
@@ -96,8 +100,10 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
signOut, signOut,
refresh, refresh,
refreshVersions, refreshVersions,
setSystemName,
...(me && { me }), ...(me && { me }),
...(versions && { versions }) ...(versions && { versions }),
...(systemName !== undefined && { systemName })
}} }}
> >
{children} {children}
@@ -9,6 +9,8 @@ export interface AuthenticationContextValue {
me?: Me; me?: Me;
versions?: VersionsResponse; versions?: VersionsResponse;
refreshVersions: () => Promise<void>; refreshVersions: () => Promise<void>;
systemName?: string;
setSystemName: (systemName: string) => void;
} }
const AuthenticationContextDefaultValue = {} as AuthenticationContextValue; const AuthenticationContextDefaultValue = {} as AuthenticationContextValue;
+3 -1
View File
@@ -1,6 +1,7 @@
// Types for the `getVersions` action response coming from the device. // Types for the `getVersions` action response coming from the device.
// The device proxies the request to emsesp.org/versions.json. If the device // The device proxies the request to emsesp.org/versions.json. If the device
// is offline the `stable` and `dev` fields are omitted. // is offline the `stable` and `dev` fields are omitted, but `system_name` is
// always sent as it comes from the device itself.
export interface VersionInfo { export interface VersionInfo {
version: string; version: string;
@@ -20,4 +21,5 @@ export interface VersionsResponse {
current: CurrentVersionInfo; current: CurrentVersionInfo;
stable?: RemoteVersionInfo; stable?: RemoteVersionInfo;
dev?: RemoteVersionInfo; dev?: RemoteVersionInfo;
system_name?: string;
} }
+4 -1
View File
@@ -321,12 +321,15 @@ uint8_t WebStatusService::upgradeImportantMessages(std::string & version) {
} }
// action = getVersions // action = getVersions
// returns the device's current version for dev and stable // returns the device's current version for dev and stable, plus the system name
// The remote fetch runs from the main loop task via WebStatusService::loop() so that we never block the AsyncTCP callback // The remote fetch runs from the main loop task via WebStatusService::loop() so that we never block the AsyncTCP callback
void WebStatusService::getVersions(JsonObject root) { void WebStatusService::getVersions(JsonObject root) {
FirmwareVersion current_version(current_version_s); FirmwareVersion current_version(current_version_s);
bool is_dev = current_version.prerelease().find("dev") != std::string::npos; bool is_dev = current_version.prerelease().find("dev") != std::string::npos;
// the WebUI shows this in the menu drawer. It's included here because this action is called once after login
root["system_name"] = EMSESP::system_.system_name();
JsonObject current = root["current"].to<JsonObject>(); JsonObject current = root["current"].to<JsonObject>();
current["version"] = current_version_s; current["version"] = current_version_s;
current["type"] = is_dev ? "dev" : "stable"; current["type"] = is_dev ? "dev" : "stable";