Skip to content

Refactor UI into embeddable Quantosaurus class and floating taskbar#10

Open
Modjular wants to merge 2 commits into
mainfrom
claude/floating-taskbar-redesign-1ta4vq
Open

Refactor UI into embeddable Quantosaurus class and floating taskbar#10
Modjular wants to merge 2 commits into
mainfrom
claude/floating-taskbar-redesign-1ta4vq

Conversation

@Modjular

Copy link
Copy Markdown
Owner

Summary

This refactors the app architecture to separate the core logic from the UI chrome, making Quantosaurus embeddable while modernizing the interface. The sidebar and top bar are replaced with a floating bottom taskbar, and all app state/methods are now exposed through a Quantosaurus class that emits events for state changes.

Key Changes

  • New Quantosaurus class (js/quantosaurus.js): Encapsulates the shared app state and exposes it through methods and CustomEvents, enabling embedders to swap out or customize the UI layer without touching core logic.

  • Floating taskbar UI: Replaces the sidebar + top bar with a single bottom-center floating toolbar containing:

    • Tool buttons (grab/paint/erase)
    • Brush size input
    • Class selector dropdown
    • Sigma (feature scale) slider
    • Overflow menu (add images, export, cheatsheet, theme, feedback)
  • Event-driven architecture: Every state mutation now emits a CustomEvent (imageadded, dirtychange, toolchanged, brushsizechanged, sigmachanged, classchanged, trainingstart, trainingcomplete, statscomputed, etc.), allowing the UI to be a pure subscriber rather than tightly coupled to the core.

  • Simplified HTML structure: Removed sidebar/top-bar markup; the viewport now fills the screen with floating chrome (taskbar, corner chips, empty state) positioned via position: fixed.

  • Corner chips: Moved status indicators to fixed corners:

    • Top-left: dirty/save indicator
    • Top-right: image/label counts
    • Center-top: loading toast
  • Empty state: Centered drop target with file picker button, shown only when no images are loaded.

  • Export modal: Moved export controls from sidebar into a modal opened from the taskbar overflow menu.

  • Refactored ui.js: bindChrome(q) wires the floating chrome onto a Quantosaurus instance's events; the chrome is now a pure consumer that calls methods on q rather than mutating state directly.

  • Module event dispatch: images.js and training.js now emit CustomEvents on state.events (the Quantosaurus instance) instead of calling UI functions directly, decoupling them from the presentation layer.

Implementation Details

  • The Quantosaurus class owns state and exposes it for backward compatibility with existing modules, but provides typed getter/setter methods (setTool, setBrushSize, setClass, setSigma, etc.) as the preferred API.

  • Brush size is now a first-class state property (state.brushSize) with bounds checking via clampBrushSize() in config.js.

  • The taskbar uses CSS Grid/Flexbox with position: fixed and bottom: calc(env(safe-area-inset-bottom) + 16px) for mobile-safe positioning.

  • Dropdowns (class selector, overflow menu) open upward from the taskbar using position: absolute; bottom: calc(100% + 8px).

  • The [hidden] attribute now has !important to ensure it overrides display values set on menus/popups.

  • Settings (class colors/names) are still persisted via loadSettings/saveSettings, called during Quantosaurus construction.

  • The .ilp file handle is now owned by the shell script (index.html's inline module) rather than the app core, making it a host concern rather than an app concern — embedders can persist differently.

https://claude.ai/code/session_01VobFMvLSfYoBDLD1tAANma

claude added 2 commits July 13, 2026 03:21
Introduce js/quantosaurus.js: an EventTarget-based app core that owns the
shared state object (images, forest, tools, camera) and attaches to a board
element. Every state change now flows out as a CustomEvent (imageadded,
labelschanged, trainingstart/complete, statscomputed, dirtychange, etc.), so
chrome subscribes instead of being hard-wired — the groundwork for embedding
the board without the sidebar.

- images.js/training.js stop importing ui.js and reach into document by id;
  they read state.board/state.brushSize and dispatch via state.events
  (optional-chained so the CPU unit tests stay Node-importable).
- Brush size becomes real instance state instead of being read off the slider
  DOM inside the paint handlers.
- ui.js gains bindChrome(q), a pure event subscriber reproducing today's
  sidebar rows, status line, save indicator, and count badges unchanged.
- index.html's inline script becomes a consumer of the class; the File System
  Access .ilp save stays in the shell and calls q.markSaved().
- Consolidate the two duplicate class-rename onblur handlers into one path
  through q.setClassName (the old second copy dropped saveSettings).
- config.js: add BRUSH_SIZE_* constants + pure clampBrushSize, covered by
  config.test.mjs.

No visual or behavioral change; verified in a headless browser (load, paint,
train, counts, brush hotkeys, recolor, rename+persist, contrast, delete) with
zero console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VobFMvLSfYoBDLD1tAANma
Condense all chrome into one bottom-center floating taskbar (Figma-style) for a
mobile-first, embeddable posture. The taskbar is a pure consumer of the
Quantosaurus class API introduced in the previous commit.

- Remove the sidebar and top bar. Tools, a numeric brush-size input, a class
  dropdown (color + editable name + selection), the sigma slider, and an
  overflow menu (Add images / Export / Cheatsheet / Theme / Feedback) all live
  in the taskbar.
- Per-class object counts move to a floating chip in the upper right, each with
  a marker-visibility toggle dot; the "unsaved changes" indicator moves to a
  chip in the upper left. A load toast covers the gap left by the old per-row
  loading bar.
- Import: drag-and-drop plus a centered empty-state "Select Files" shown only
  when no images are loaded (an "Add images…" overflow item covers the
  non-empty case, notably on touch).
- Export options move into a modal opened from the overflow menu; Cmd/Ctrl+S
  still saves the .ilp.
- Per-image controls (reorder / contrast / delete) move to a hover (always-on
  for coarse pointers) overlay on each board tile; the contrast popover
  re-anchors to the tile button.
- New chrome is fixed-position outside #viewport so taps aren't swallowed by
  its touch-action:none, uses env(safe-area-inset-*) for mobile, and themes via
  the existing surface/border tokens. Added a global [hidden] reset so the
  menus' display rules don't override the attribute.

CLAUDE.md's data-flow section updated for the class + event architecture.
Verified in a headless browser end to end (empty state, load, paint→train→
counts, brush clamp, class dropdown recolor/rename/select, marker toggle,
overflow menu, export modal, tile contrast, theme toggle, delete) with zero
console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VobFMvLSfYoBDLD1tAANma
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants