Fix SpoolBuddy status bar not updating on printer switch

The bottom message bar showed stale warnings from the previous printer
  after switching via dropdown or swipe. Cached AMS data was shared across
  all printers in a single ref, so switching to a printer whose status
  hadn't loaded fell back to the wrong printer's data. The Layout also
  unconditionally cleared alerts set by child pages. Fixed by keying the
  AMS cache per printer ID and only clearing Layout-owned alerts.
This commit is contained in:
maziggy
2026-04-02 11:34:42 +02:00
parent eec1e43d6d
commit 02262472f8
5 changed files with 74 additions and 65 deletions
@@ -74,14 +74,21 @@ export function SpoolBuddyLayout() {
staleTime: 0,
});
// Update alert based on device state and available updates
// Update alert based on device state and available updates.
// Only clear alerts that the layout itself set (not alerts from child pages).
const layoutAlertRef = useRef<string | null>(null);
useEffect(() => {
if (!effectiveDeviceOnline) {
setAlert({ type: 'warning', message: 'SpoolBuddy device disconnected' });
const msg = 'SpoolBuddy device disconnected';
setAlert({ type: 'warning', message: msg });
layoutAlertRef.current = msg;
} else if (updateCheck?.update_available && updateCheck.latest_version) {
setAlert({ type: 'info', message: `Update available: v${updateCheck.latest_version}` });
} else {
const msg = `Update available: v${updateCheck.latest_version}`;
setAlert({ type: 'info', message: msg });
layoutAlertRef.current = msg;
} else if (layoutAlertRef.current) {
setAlert(null);
layoutAlertRef.current = null;
}
}, [effectiveDeviceOnline, updateCheck?.update_available, updateCheck?.latest_version]);
@@ -125,17 +125,18 @@ export function SpoolBuddyAmsPage() {
const isConnected = status?.connected ?? false;
// Cache AMS data to prevent it disappearing on idle/offline printers
const cachedAmsData = useRef<PrinterStatus['ams']>([]);
// Cache AMS data per printer to prevent it disappearing on idle/offline printers
const cachedAmsData = useRef<Record<number, PrinterStatus['ams']>>({});
useEffect(() => {
if (status?.ams && status.ams.length > 0) {
cachedAmsData.current = status.ams;
if (selectedPrinterId && status?.ams && status.ams.length > 0) {
cachedAmsData.current[selectedPrinterId] = status.ams;
}
}, [status?.ams]);
}, [status?.ams, selectedPrinterId]);
const amsUnits = useMemo(() => {
const live = status?.ams;
return (live && live.length > 0) ? live : (cachedAmsData.current ?? []);
}, [status?.ams]);
if (live && live.length > 0) return live;
return (selectedPrinterId ? cachedAmsData.current[selectedPrinterId] : null) ?? [];
}, [status?.ams, selectedPrinterId]);
const regularAms = useMemo(() => amsUnits.filter(u => !u.is_ams_ht), [amsUnits]);
const htAms = useMemo(() => amsUnits.filter(u => u.is_ams_ht), [amsUnits]);