From 42f86cd12b0d13767ca434f5299e2153517ed193 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 23 Aug 2026 12:22:45 +0200 Subject: [PATCH] get and send system name in AuthenticaionContext to prevent /rest/settings on each render --- interface/src/app/settings/ApplicationSettings.tsx | 11 ++++++++++- interface/src/components/layout/LayoutDrawer.tsx | 13 +++++-------- .../src/contexts/authentication/Authentication.tsx | 10 ++++++++-- interface/src/contexts/authentication/context.ts | 2 ++ interface/src/types/versions.ts | 4 +++- src/web/WebStatusService.cpp | 5 ++++- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index ddcfadeff..15cd5770b 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; import CancelIcon from '@mui/icons-material/Cancel'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; @@ -31,6 +31,7 @@ import { useLayoutTitle } from 'components'; import { toast } from 'components/toast'; +import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import { numberValue, updateValueDirty, useRest } from 'utils'; import { ValidationError, validate } from 'validators'; @@ -68,6 +69,14 @@ const ApplicationSettings = () => { 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(); const { LL } = useI18nContext(); diff --git a/interface/src/components/layout/LayoutDrawer.tsx b/interface/src/components/layout/LayoutDrawer.tsx index debe49bcb..901673cd5 100644 --- a/interface/src/components/layout/LayoutDrawer.tsx +++ b/interface/src/components/layout/LayoutDrawer.tsx @@ -1,10 +1,8 @@ -import { memo } from 'react'; +import { memo, useContext } from 'react'; import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material'; -import { readSettings } from 'api/app'; - -import { useRequest } from 'alova/client'; +import { AuthenticatedContext } from 'contexts/authentication'; import { PROJECT_NAME } from 'env'; import { DRAWER_WIDTH } from './Layout'; @@ -27,8 +25,7 @@ interface LayoutDrawerProps { } const LayoutDrawerComponent = ({ mobileOpen, onClose }: LayoutDrawerProps) => { - const { data: settings } = useRequest(readSettings); - const system_name = settings?.system_name; + const { systemName } = useContext(AuthenticatedContext); const drawer = ( <> @@ -43,9 +40,9 @@ const LayoutDrawerComponent = ({ mobileOpen, onClose }: LayoutDrawerProps) => { }} > {PROJECT_NAME} - {system_name && ( + {systemName && ( - {system_name} + {systemName} )} diff --git a/interface/src/contexts/authentication/Authentication.tsx b/interface/src/contexts/authentication/Authentication.tsx index 2801235b1..ee02a1c55 100644 --- a/interface/src/contexts/authentication/Authentication.tsx +++ b/interface/src/contexts/authentication/Authentication.tsx @@ -23,6 +23,7 @@ const Authentication: FC = ({ children }) => { const [initialized, setInitialized] = useState(false); const [me, setMe] = useState(); const [versions, setVersions] = useState(); + const [systemName, setSystemName] = useState(); const { send: sendVerifyAuthorization } = useRequest(verifyAuthorization(), { immediate: false @@ -33,7 +34,9 @@ const Authentication: FC = ({ children }) => { { immediate: false } ) .onSuccess((event) => { - setVersions(event.data as VersionsResponse); + const response = event.data as VersionsResponse; + setVersions(response); + setSystemName(response.system_name); }) .onError(() => { setVersions(undefined); @@ -60,6 +63,7 @@ const Authentication: FC = ({ children }) => { AuthenticationApi.clearAccessToken(); setMe(undefined); setVersions(undefined); + setSystemName(undefined); if (doRedirect) { void navigate('/', { replace: true }); } @@ -96,8 +100,10 @@ const Authentication: FC = ({ children }) => { signOut, refresh, refreshVersions, + setSystemName, ...(me && { me }), - ...(versions && { versions }) + ...(versions && { versions }), + ...(systemName !== undefined && { systemName }) }} > {children} diff --git a/interface/src/contexts/authentication/context.ts b/interface/src/contexts/authentication/context.ts index 1717bfaef..b1792a169 100644 --- a/interface/src/contexts/authentication/context.ts +++ b/interface/src/contexts/authentication/context.ts @@ -9,6 +9,8 @@ export interface AuthenticationContextValue { me?: Me; versions?: VersionsResponse; refreshVersions: () => Promise; + systemName?: string; + setSystemName: (systemName: string) => void; } const AuthenticationContextDefaultValue = {} as AuthenticationContextValue; diff --git a/interface/src/types/versions.ts b/interface/src/types/versions.ts index 6f081c613..d1ee0d7f1 100644 --- a/interface/src/types/versions.ts +++ b/interface/src/types/versions.ts @@ -1,6 +1,7 @@ // Types for the `getVersions` action response coming from 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 { version: string; @@ -20,4 +21,5 @@ export interface VersionsResponse { current: CurrentVersionInfo; stable?: RemoteVersionInfo; dev?: RemoteVersionInfo; + system_name?: string; } diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 78ecda5f6..ce4fd1a61 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -321,12 +321,15 @@ uint8_t WebStatusService::upgradeImportantMessages(std::string & version) { } // 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 void WebStatusService::getVersions(JsonObject root) { FirmwareVersion current_version(current_version_s); 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(); current["version"] = current_version_s; current["type"] = is_dev ? "dev" : "stable";