[PR #963] [MERGED] feat: add embedded GCode viewer #1139

Closed
opened 2026-05-06 12:35:17 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/maziggy/bambuddy/pull/963
Author: @Soopahfly
Created: 4/13/2026
Status: Merged
Merged: 4/22/2026
Merged by: @maziggy

Base: devHead: feature/gcode-viewer


📝 Commits (8)

  • 5b710bc feat: add embedded GCode viewer
  • ae804ad fix: address PR review feedback on gcode-viewer
  • 7361d85 test: add tests for gcode-viewer routes and to_absolute_path guard
  • d58d4a5 fix: exempt /gcode-viewer from frame-ancestors 'none' CSP
  • b1e04e5 Merge branch 'dev' into feature/gcode-viewer
  • b69fa61 Merge branch 'dev' into feature/gcode-viewer
  • 0947275 Merge branch 'dev' into pr-963
  • 943765e fix(gcode-viewer): merge-time fixes — i18n parity, auth 401 redirect

📊 Changes

38 files changed (+15895 additions, -67 deletions)

View changed files

📝 backend/app/api/routes/library.py (+12 -3)
📝 backend/app/main.py (+61 -13)
backend/tests/integration/test_gcode_viewer.py (+85 -0)
backend/tests/unit/test_library_file_path_guard.py (+115 -0)
📝 frontend/src/App.tsx (+2 -0)
📝 frontend/src/components/Layout.tsx (+2 -1)
📝 frontend/src/i18n/locales/de.ts (+4 -0)
📝 frontend/src/i18n/locales/en.ts (+4 -0)
📝 frontend/src/i18n/locales/fr.ts (+4 -0)
📝 frontend/src/i18n/locales/it.ts (+4 -0)
📝 frontend/src/i18n/locales/ja.ts (+4 -0)
📝 frontend/src/i18n/locales/pt-BR.ts (+4 -0)
📝 frontend/src/i18n/locales/zh-CN.ts (+4 -0)
📝 frontend/src/i18n/locales/zh-TW.ts (+4 -0)
frontend/src/pages/GCodeViewerPage.tsx (+28 -0)
📝 frontend/vite.config.ts (+68 -1)
gcode_viewer/VENDORED.md (+60 -0)
gcode_viewer/css/prettygcode.css (+417 -0)
gcode_viewer/index.html (+264 -0)
gcode_viewer/js/Line2.js (+31 -0)

...and 18 more files

📄 Description

Summary

Adds PrettyGCode as a built-in GCode visualiser embedded directly in the Bambuddy layout, so users can preview and inspect GCode files without leaving the dashboard.

  • GCode Viewer nav entry (Layers icon) loads the visualiser in the main content pane with the sidebar still visible
  • File picker browses and searches the Bambuddy library for .gcode files across all folders, with live search filtering
  • Printer selector populates from the Bambuddy API; switching printers updates the print bed dimensions automatically for X1C, P1S, A1, A1 Mini and other Bambu models
  • Currently printing file auto-loads when a printer is active
  • Layer slider scrubs through the model layer by layer; play button animates through layers at adjustable speed (1×, 3×, 10×, 25×)
  • Viewer runs in a same-origin <iframe> so it does not interfere with React app state or routing

Technical notes

  • gcode_viewer/ — PrettyGCode static assets with a custom bambuddy_adapter.js that bridges OctoPrint API patterns to Bambuddy's REST/WebSocket API, a slider-shim.js replacing the bootstrap-slider dependency, and a CSP meta tag
  • GCodeViewerPage.tsx — iframe wrapper with a recursion guard (prevents infinite nesting if the SPA catch-all serves the React app into the iframe)
  • Explicit @app.get routes for /gcode-viewer/* placed before the SPA catch-all (app.mount() loses to /{full_path:path} in some Starlette versions)
  • Vite dev-server plugin serves gcode_viewer/ at /gcode-viewer/ without proxying to uvicorn during development
  • Path traversal guard added to library.py to_absolute_path()
  • nav.gcodeViewer i18n key added to all 7 locale files

Docs

This adds a new nav item and feature — a wiki page will be needed. Happy to write it once this PR is reviewed.

Screenshots

Screenshot 2026-04-12 165450

Test plan

  • Navigate to GCode Viewer in the sidebar — viewer loads in main pane with sidebar visible
  • Click Load file — file picker opens and lists .gcode files from the library
  • Select a file — 3D model renders in the viewer
  • Layer slider scrubs through layers; play button animates
  • Printer selector populates with connected printers; switching updates bed size
  • Dev server (npm run dev) serves the viewer correctly at /gcode-viewer/

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/maziggy/bambuddy/pull/963 **Author:** [@Soopahfly](https://github.com/Soopahfly) **Created:** 4/13/2026 **Status:** ✅ Merged **Merged:** 4/22/2026 **Merged by:** [@maziggy](https://github.com/maziggy) **Base:** `dev` ← **Head:** `feature/gcode-viewer` --- ### 📝 Commits (8) - [`5b710bc`](https://github.com/maziggy/bambuddy/commit/5b710bcd10e500258543492d13a2412f726be744) feat: add embedded GCode viewer - [`ae804ad`](https://github.com/maziggy/bambuddy/commit/ae804ad60d180e8445dd5c339cc1314bbbe5aa42) fix: address PR review feedback on gcode-viewer - [`7361d85`](https://github.com/maziggy/bambuddy/commit/7361d85ef89847190d463b78446bcd529cadc1d9) test: add tests for gcode-viewer routes and to_absolute_path guard - [`d58d4a5`](https://github.com/maziggy/bambuddy/commit/d58d4a5233362fd816092d1d435cbc57d345e9b7) fix: exempt /gcode-viewer from frame-ancestors 'none' CSP - [`b1e04e5`](https://github.com/maziggy/bambuddy/commit/b1e04e587aa8c734fb31a9af6566d2c6841c1506) Merge branch 'dev' into feature/gcode-viewer - [`b69fa61`](https://github.com/maziggy/bambuddy/commit/b69fa61973c2d59e332ce494ac192e27611336e3) Merge branch 'dev' into feature/gcode-viewer - [`0947275`](https://github.com/maziggy/bambuddy/commit/0947275ea9e9a46c123879926a3c1bd2b9155e71) Merge branch 'dev' into pr-963 - [`943765e`](https://github.com/maziggy/bambuddy/commit/943765e02eaac15b846f3bd6542c0b58226e1403) fix(gcode-viewer): merge-time fixes — i18n parity, auth 401 redirect ### 📊 Changes **38 files changed** (+15895 additions, -67 deletions) <details> <summary>View changed files</summary> 📝 `backend/app/api/routes/library.py` (+12 -3) 📝 `backend/app/main.py` (+61 -13) ➕ `backend/tests/integration/test_gcode_viewer.py` (+85 -0) ➕ `backend/tests/unit/test_library_file_path_guard.py` (+115 -0) 📝 `frontend/src/App.tsx` (+2 -0) 📝 `frontend/src/components/Layout.tsx` (+2 -1) 📝 `frontend/src/i18n/locales/de.ts` (+4 -0) 📝 `frontend/src/i18n/locales/en.ts` (+4 -0) 📝 `frontend/src/i18n/locales/fr.ts` (+4 -0) 📝 `frontend/src/i18n/locales/it.ts` (+4 -0) 📝 `frontend/src/i18n/locales/ja.ts` (+4 -0) 📝 `frontend/src/i18n/locales/pt-BR.ts` (+4 -0) 📝 `frontend/src/i18n/locales/zh-CN.ts` (+4 -0) 📝 `frontend/src/i18n/locales/zh-TW.ts` (+4 -0) ➕ `frontend/src/pages/GCodeViewerPage.tsx` (+28 -0) 📝 `frontend/vite.config.ts` (+68 -1) ➕ `gcode_viewer/VENDORED.md` (+60 -0) ➕ `gcode_viewer/css/prettygcode.css` (+417 -0) ➕ `gcode_viewer/index.html` (+264 -0) ➕ `gcode_viewer/js/Line2.js` (+31 -0) _...and 18 more files_ </details> ### 📄 Description ## Summary Adds [PrettyGCode](https://github.com/Kragrathea/pgcode) as a built-in GCode visualiser embedded directly in the Bambuddy layout, so users can preview and inspect GCode files without leaving the dashboard. - **GCode Viewer** nav entry (Layers icon) loads the visualiser in the main content pane with the sidebar still visible - **File picker** browses and searches the Bambuddy library for `.gcode` files across all folders, with live search filtering - **Printer selector** populates from the Bambuddy API; switching printers updates the print bed dimensions automatically for X1C, P1S, A1, A1 Mini and other Bambu models - Currently printing file **auto-loads** when a printer is active - **Layer slider** scrubs through the model layer by layer; **play button** animates through layers at adjustable speed (1×, 3×, 10×, 25×) - Viewer runs in a same-origin `<iframe>` so it does not interfere with React app state or routing ## Technical notes - `gcode_viewer/` — PrettyGCode static assets with a custom `bambuddy_adapter.js` that bridges OctoPrint API patterns to Bambuddy's REST/WebSocket API, a `slider-shim.js` replacing the bootstrap-slider dependency, and a CSP meta tag - `GCodeViewerPage.tsx` — iframe wrapper with a recursion guard (prevents infinite nesting if the SPA catch-all serves the React app into the iframe) - Explicit `@app.get` routes for `/gcode-viewer/*` placed before the SPA catch-all (`app.mount()` loses to `/{full_path:path}` in some Starlette versions) - Vite dev-server plugin serves `gcode_viewer/` at `/gcode-viewer/` without proxying to uvicorn during development - Path traversal guard added to `library.py` `to_absolute_path()` - `nav.gcodeViewer` i18n key added to all 7 locale files ## Docs This adds a new nav item and feature — a wiki page will be needed. Happy to write it once this PR is reviewed. ## Screenshots <img width="1883" height="992" alt="Screenshot 2026-04-12 165450" src="https://github.com/user-attachments/assets/d12e18c1-520d-453d-8ef8-826c72e193d4" /> ## Test plan - [ ] Navigate to GCode Viewer in the sidebar — viewer loads in main pane with sidebar visible - [ ] Click Load file — file picker opens and lists `.gcode` files from the library - [ ] Select a file — 3D model renders in the viewer - [ ] Layer slider scrubs through layers; play button animates - [ ] Printer selector populates with connected printers; switching updates bed size - [ ] Dev server (`npm run dev`) serves the viewer correctly at `/gcode-viewer/` 🤖 Generated with [Claude Code](https://claude.ai/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:35:17 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/bambuddy#1139
No description provided.