Przeglądaj źródła

fix(gcode-viewer): full-page preview draws on wide screens (issue #3371)

- Clip the viewer pane (overflow-hidden). The canvas width set by
  setSize lags the container by one observer round, and the overflow
  counted towards main's scroll area: on lg+ the page is exactly its
  height, so a scrollbar toggled on and off forever and nothing drew
- Test pins the clip
maziggy 2 dni temu
rodzic
commit
2e164555e6

+ 1 - 0
CHANGELOG.md

@@ -185,6 +185,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **The frontend build no longer warns about `path` and `crypto` being externalized for the STEP previewer (#2976)** — `occt-import-js`, the Emscripten build behind STEP previews, requires both modules, but only inside its `ENVIRONMENT_IS_NODE` branches; in the browser it loads its `.wasm` from the URL the preview worker passes and draws randomness from `crypto.getRandomValues`. Vite still externalized both and printed two warnings on every build. `vite.config.ts` now drops exactly those two warnings for that one package through `build.rolldownOptions.onLog`, so an externalization anywhere else, or of any other module, still shows.
 
 ### Fixed
+- **The full-page G-code preview draws on wide screens (#3371, reported by @Underscan007)** — On a window 1024 px wide or more, with classic (non-overlay) scrollbars, **3D Preview** stayed black while the page scrollbar flickered on and off. The canvas was briefly wider than its pane after each resize and pushed the page into scrolling, which narrowed the pane again, without end. The preview is now clipped to its pane, so it settles at once and draws.
 - **A print that finishes while Bambuddy restarts is archived as completed (#3310, reported by @Thomansky)** — When a print ended while Bambuddy was down (a container update, a host reboot), the printer's FINISH arrived as the first status of a new connection, so it never counted as the print ending. The reconnect then closed the archive as aborted with "No status update", logged it with no print time, cancelled its queue job and sent "print stopped". Now, when the printer still reports the archive's own job (the same job ID) as finished, the archive is closed as completed, with the library print count, batch run, finish notification and smart-plug auto-off that go with it. Its end time is the start plus the slicer's estimate for the plate that printed, never later than the reconnect, since the printer doesn't say when it finished. That time counts in the print-time totals but not in time accuracy, on the archive card or in Statistics. A failed job is closed as failed, with the printer's error as the reason when it has one. When the printer is idle, shows another job or reports no job ID, the archive is closed as aborted, as before.
 - **Home Assistant's connection test names a certificate problem (#3300)** — After Home Assistant moved to https, **Test Connection** said "Could not connect to Home Assistant" when Home Assistant was up and answering, because a certificate Bambuddy does not trust fails like an address nothing answers on. It now says the certificate is not trusted, why (self-signed or from your own authority, issued for a hostname while the URL uses the IP address, or expired) and what to do, and says when https was used on a port that serves plain http. The Smart Plugs page of the wiki explains how to add your own certificate authority, also on a native install.
 - **A bug report is no longer sent when debug logging stops (#3363, reported by @choumarin)** — "Stop & Submit" turned debug logging off and filed the report as a public GitHub issue in the same click, and the 5-minute auto-stop did the same with nobody watching, so a report meant only to capture a log was sent before it was ready. The button is now "Stop Logging": it collects the logs and ends on a review that says a public issue will be created and how many log lines were collected, with Submit and Discard. Closing the panel keeps the review, and a failed send goes back to it with the logs kept.

+ 12 - 0
frontend/src/__tests__/components/GcodeToolpathViewerSizing.test.tsx

@@ -112,4 +112,16 @@ describe('GcodeToolpathViewer sizing', () => {
     expect(pane.className).toContain('flex-1');
     expect(pane.contains(canvas())).toBe(true);
   });
+
+  it('clips the canvas to its pane so a stale width cannot reach the page (#3371)', () => {
+    const { container } = render(
+      <GcodeToolpathViewer gcodeUrl="/api/v1/archives/224/gcode" className="flex-1 min-h-0" />,
+    );
+
+    // The canvas width lags the container by one observer round. Unclipped, the
+    // overflow gave `<main>` a scrollbar, which narrowed the container, which
+    // shrank the canvas, which removed the scrollbar -- forever, on lg+ screens.
+    const pane = container.firstElementChild as HTMLElement;
+    expect(pane.className.split(/\s+/)).toContain('overflow-hidden');
+  });
 });

+ 8 - 1
frontend/src/components/GcodeToolpathViewer.tsx

@@ -449,7 +449,14 @@ export function GcodeToolpathViewer({
   }
 
   return (
-    <div className={`relative ${className}`}>
+    <div className={`relative overflow-hidden ${className}`}>
+      {/*
+        `overflow-hidden` (#3371): `setSize` writes the canvas width inline and
+        only runs from the observer, so for one round the canvas keeps the old
+        width. An absolute box that overflows still counts towards the scroll
+        area of `<main>`, so on a page exactly its height the 15px of a scrollbar
+        toggled on and off forever and nothing was drawn.
+      */}
       {/*
         Absolute, not `w-full h-full` (#2887). The canvas is appended here and
         this element is what the ResizeObserver watches, so its height must come