Просмотр исходного кода

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.
maziggy 5 месяцев назад
Родитель
Сommit
02262472f8

+ 1 - 0
CHANGELOG.md

@@ -37,6 +37,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **SpoolBuddy Kiosk Display Blanking and Crashes** — The kiosk Chromium flags added in 0.2.2.2 caused display instability: `--js-flags=--max-old-space-size=128` crashed the V8 renderer when heap exceeded 128 MB, `--enable-low-end-device-mode` aggressively killed GPU rendering surfaces, and resetting `CHROMIUM_FLAGS` discarded the Pi's GPU defaults (`--enable-gpu-rasterization`, ANGLE/GLES) creating an unstable mixed CPU/GPU rendering path. Fixed by removing both flags, appending kiosk flags to Pi defaults instead of replacing them, adding a `wlr-randr` keep-alive loop to prevent display blanking, and adding `<screenBlankTimeout>0</screenBlankTimeout>` to the labwc config.
 - **Sidebar Bottom Icons Cut Off With Smart Plugs** ([#862](https://github.com/maziggy/bambuddy/issues/862)) — Adding smart plug buttons to the sidebar caused the bottom icon row to overflow and get partially cut off. The footer section could be compressed by the flexbox layout when the navigation area grew. Fixed by preventing the footer from shrinking, allowing the expanded icon row to wrap, and adding scroll overflow to the collapsed sidebar icon stack.
 - **AMS History Cleanup Crash Every ~24 Hours** — The periodic cleanup of old AMS sensor history entries failed with "can't compare offset-naive and offset-aware datetimes". The cleanup cutoff used `datetime.now(timezone.utc)` (timezone-aware) but the `recorded_at` column stores naive datetimes via SQLite's `func.now()`. The mismatch caused a TypeError when SQLAlchemy processed the comparison. Fixed by using a naive UTC datetime for the cutoff. The error only appeared once per ~24h because the cleanup runs every 288 recording cycles (288 × 5 min = 24h).
+- **SpoolBuddy Status Bar Not Updating on Printer Switch** — The bottom status bar on SpoolBuddy kiosk pages showed stale warnings (e.g. low filament) from the previously selected printer after switching to a different printer via the dropdown or swipe gesture. Two issues: (1) the AMS data cache was a single ref shared across all printers, so switching to a printer whose status hadn't loaded yet fell back to the previous printer's cached AMS data; (2) the Layout's alert useEffect unconditionally cleared alerts to null when the device was online, which could overwrite printer-specific alerts set by child pages. Fixed by keying the AMS cache per printer ID and tracking Layout-owned alerts separately so child page alerts aren't clobbered.
 
 ## [0.2.2.2] - 2026-03-27
 

+ 11 - 4
frontend/src/components/spoolbuddy/SpoolBuddyLayout.tsx

@@ -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]);
 

+ 8 - 7
frontend/src/pages/spoolbuddy/SpoolBuddyAmsPage.tsx

@@ -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]);
 

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
static/assets/index-aAUZWkDJ.js


+ 1 - 1
static/index.html

@@ -23,7 +23,7 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-BdvAN3ky.js"></script>
+    <script type="module" crossorigin src="/assets/index-aAUZWkDJ.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-BGA3I7Jb.css">
   </head>
   <body>

Некоторые файлы не были показаны из-за большого количества измененных файлов