Skip to content

Mobile/responsive UI polish + cardboard-exit fix - #54

Merged
AlexZ005 merged 19 commits into
mainfrom
fix/ui-polish-connect-settings
Jul 26, 2026
Merged

Mobile/responsive UI polish + cardboard-exit fix#54
AlexZ005 merged 19 commits into
mainfrom
fix/ui-polish-connect-settings

Conversation

@AlexZ005

Copy link
Copy Markdown
Collaborator

A large mobile/responsive UI pass on top of main (not a numbered roadmap batch),
plus the WebXR "cardboard" enter/exit crash. svelte-check held 485/72 and
npm run build passed at every commit.

Connect bar

  • Measure-based docking: the centred pill detects when it would overlap the corner
    chrome (logo left / peers+profile right) and snaps to a full-width top bar; publishes
    --connect-bottom, a .connect-docked root class, and connectDocked/connectBarHeight
    stores. Rooms button hides when docked; the open drawer lifts above the chrome; the logo
    • top-right chrome drop below the docked bar; docked corners square under an open drawer.
  • Role pill CSS was trapped in a @media(max-width:640) block (unstyled at normal
    widths); moved out + the role dropdown is portaled to <body> (list overflow clipped it).

Settings / Sessions / Modules

  • SettingRow component: aligned 3-column grid name | control | description on wide,
    centred stack on narrow, multi-input rows split per line.
  • Shared .tp-modal-* treatment: full-screen on narrow (fill below Connect, header title
    padded to clear the logo), single body scroller (fixes the double scrollbar).
  • Modules Core/User render as real tabs; notifications panel pinned on narrow.

Drawers / sheets

  • Scene notes + object/mesh/scene properties become bottom sheets on ≤640 (slide up,
    drag-to-resize, capped below the profile, bg extends behind the Controls HUD); one sheet
    open at a time; as side drawers they cover the top-right chrome only when Connect is docked.
  • Docked Flow/Explorer content insets above the Controls only on folded screens
    (--dock-inset ≤500px; Flow gated on palette-open).
  • Logo click closes any open modal AND opens the menu in one step (no flicker).

Floating windows

  • May be shoved partly off-screen (grabbable strip stays) and snap fully back when
    reopened; clamp below the Connect pill; body,html{overflow:hidden} stops an
    off-the-right window growing the document / shifting the pill.

WebXR "cardboard" enter/exit

  • @threlte/xr crashed on session end (unguarded handedness reads) → aborted teardown →
    dark viewport, re-entry locked. Fixed with the guardThrelteXr Vite transform plugin
    (guards all four sites at load time, dev + build; no fragile node_modules patch) +
    optimizeDeps.exclude.
  • The dark viewport itself: Outline.svelte drove all rendering through the EffectComposer
    (canvas-sized targets, not the XR framebuffer → glBlitFramebuffer); now renders directly
    through the XR cameras while presenting, composer resumes on desktop.

Also

CharacterModal/ThemedSelect dropdown alignment; ContextMenu raised above the toast tier;
mobileUndockAllowed setting; CLAUDE.md + e2e-verify skill updated.

🤖 Generated with Claude Code

AlexZ005 and others added 19 commits July 26, 2026 10:54
- Connect: measure-based docking to a full-width top bar when the centred pill
  would cover the logo/peers chrome; Rooms button hides when docked; open drawer
  lifts above the corner chrome; corner chrome drops below the pinned tab strip;
  square docked corners under an expanded drawer; chevron tooltip is Open/Close
- Users: role pill and dropdown CSS moved out of the max-640 media query (it
  rendered unstyled at normal widths); role menu portaled to body so the peers
  list overflow no longer clips it
- Settings: new SettingRow component, aligned 3-column grid on wide (control,
  name, description), centred stack on narrow, multi-input rows split per line
- CharacterModal and ThemedSelect: dropdowns fill the row height and seam with
  their labels
- ContextMenu: raised above the toast tier so toasts no longer cover menus
- appStore: connectDocked and connectBarHeight stores

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…croll

- full-screen edge-to-edge on limited width; wider (max 1200px / 94vw) on desktop
- strip the flowbite modal body (role=document) padding that doubled our own and
  wasted space at the top of the panel
- reorder wide columns to name, control, description (mobile keeps its stacked
  control, name, description order with centred controls)
- single scroll container (the modal body); the inner content no longer scrolls,
  fixing the double scrollbar; desktop height capped at 88vh
- narrower control column so dropdowns are not stretched out

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Explorer: long-press a card to pick it up, drag a ghost onto the viewport and
  release to place it (reuses dropExplorerItem raycast); desktop native HTML5
  drag unchanged (touch path early-returns for mouse)
- hide the undock button on pointer:coarse (Flow, Explorer, Flow Code, Animation)
  and force Flow + Explorer docked on load
- docking.js: disable edge side-docking on pointer:coarse (covers Flow, Explorer
  and the object-list window); no room to float or side-dock on a phone

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…setting

- Inspector (object/mesh/scene settings): tuck under the Connect bar (via a
  published --connect-bottom var) and extend down over the chat + mic buttons;
  hide the top-right chrome while a settings drawer is open on narrow so the
  taller drawer owns that space; reduce the narrow controls-inset accordingly
- Profile Settings modal: stack each label above its control on narrow (.pf-row)
- floating windows (dragWindow + the object-list drag) clamp below the Connect
  bar/pill when they overlap it horizontally, so they cannot slide behind it
- Settings > Allow undocking (touch): opt back into undocking Flow/Explorer on
  touch (default off keeps them docked with the undock button hidden)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Sessions/Modules/Settings share a full-screen-on-narrow treatment: single body
  scroller (fixes the Sessions double scrollbar), fill below the Connect bar (which
  stays visible on top), no radius, header title padded so it clears the logo
- clicking the logo while any modal is open now closes it AND opens the menu in one
  step (deferred past the modal restorePanels so the menu no longer flickers open
  then shut); Profile Settings modal state is a shared store so it closes too
- Inspector: round the bottom-left corner when the drawer floats above the bottom
  (docked panel or narrow Controls inset), square when flush
- Profile Settings rows: clean full rounding per label/control when stacked narrow
- floating windows (dragWindow + object-list) may be shoved partly off-screen (a
  grabbable strip always stays), and snap fully back on-screen when reopened

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tom sheet

- Modules: Core/User render as underlined tabs instead of two plain buttons
- notifications panel pins to the viewport on narrow so its 20rem width no longer
  spills off the edge
- Scene notes: on a narrow/folded screen it becomes a full-width bottom sheet (like
  the Flow/Explorer dock) with a top drag handle to adjust height, instead of the
  right-side drawer the profile chrome was covering

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…w; notes cover

- object properties / scene settings (Inspector): on a narrow screen it is now a
  full-width bottom sheet with a top drag handle to adjust height, like the
  scene-notes sheet; wide stays the right drawer
- app root clips overflow so a floating window shoved off the right/bottom edge can
  no longer grow the page or spawn scrollbars (now matches the left edge)
- scene notes: on a wide/unfolded screen it sits above the top-right chrome
  (profile/peers/bell) so opening it covers those buttons

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- @threlte/xr: guard the controller/hand disconnected store access via a postinstall
  patch - a Cardboard/gaze session end hit stores[undefined].set and threw, aborting
  the teardown and wedging the viewport (dark blue, re-entry impossible)
- object/scene/mesh settings sheet slides UP from the bottom on narrow (was fly-right)
- both bottom sheets (settings + scene notes) cap their height so the top stays below
  the Connect bar + top-right chrome, like the Flow/Explorer dock limit
- both sheets' background now extends behind the Controls HUD while their content is
  padded to stay above it (no viewport gap under the sheet)
- keep overflow:hidden only on body/html (removed it from the canvas wrapper div)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… above controls

- @threlte/xr: the connected handler also indexed stores[handedness] unguarded (the
  handleConnected crash on onInputSourcesChange) - the patch now guards ALL four store
  accesses; exclude @threlte/xr from Vite optimizeDeps so dev serves the patched source
  (the cached optimized bundle kept crashing after the node_modules edit)
- only ONE bottom sheet open at a time on narrow: opening scene notes closes the
  object/scene/mesh settings sheet and vice versa
- Flow + Explorer docked: on narrow their content is inset above the Controls HUD (the
  panel bg still fills behind it) so items are no longer hidden behind the play button

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…over chrome

- Flow node palette + props panel and Explorer tree + grid get a bottom inset above
  the Controls HUD (padding = --controls-inset, 0 on desktop) so those fixed side
  lists clear the play/HUD buttons WITHOUT shrinking the pannable graph/grid
- mesh/object/scene properties side drawer (wide) and the scene-notes side drawer now
  sit just below the Connect bar and above the top-right chrome (z:1000), covering the
  profile/peers/bell buttons when a docked Connect has dropped them underneath

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rink

- side drawers (mesh/object/scene properties + scene notes) only COVER the top-right
  chrome when Connect is DOCKED (a .connect-docked root class published by Connect);
  when Connect is centred they stay below the profile icon (default top-16, lower z)
- Flow docked content insets above the Controls HUD only when the node palette is open
  (bound paletteOpen); Explorer docked insets on narrow - restores the shrink approach
  (panel bg fills behind the Controls HUD, items above) instead of per-list padding

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… to controls

The full --controls-inset left too much empty space above the Controls HUD; use half
of it so the node palette / folder tree come closer while still clearing the buttons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ll amount

- new --dock-inset var: the full --controls-inset below 500px, 0 above. So the docked
  content insets above the Controls only when they actually reach the node palette /
  folder tree (folded); at ~550px+ it stays flush with no wasted strip. Reverts the
  half-inset back to the full amount the user preferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…in horizontally

Gate the slide-up transition on the actual bottom-sheet breakpoint (max-width:640,
matching the CSS) instead of narrowDrawer (<=820), so the 641-820 side drawer flies in
from the right rather than up. Mutual exclusion also keyed to sheet mode.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
It is copied in by the cloud repo's link-to-app vstask and regenerated on demand; the
OSS app is inert without it, so it should never appear in git status or be committed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…I pass

- CLAUDE.md: Status entry for fix/ui-polish-connect-settings (Connect docking, role-pill
  portal, SettingRow 3-col + shared tp-modal fullscreen, bottom sheets, floating-window
  reveal, docked palette/tree inset, logo-closes-modal, cardboard @threlte/xr patch) +
  gotchas for the responsive CSS-var bus (--connect-bottom/--controls-inset/--dock-inset,
  .connect-docked), the off-right-edge overflow rule, and the threlte/xr postinstall patch
- e2e-verify skill: pointer:coarse / matchMedia gates can't be emulated headlessly
  (on-device check), but width-gated CSS vars + geometry are measurable

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eads

The disconnect fired at session end has event.data === undefined, so the dispatch
helper crashed on data.handedness (setupControllers:26 / setupHands:26) BEFORE the
already-guarded stores[...].set. Guard those reads too (controllerEvents[data?.handedness]
and handEvent.data?.handedness). Now every handedness access in both files is optional.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e composer

Outline.svelte disables autoRender and drives ALL rendering through the EffectComposer.
Its passes render to canvas-sized targets, not the XR framebuffer, so in WebXR the blit
mismatches sizes (glBlitFramebuffer GL_INVALID_FRAMEBUFFER_OPERATION) and nothing reaches
the headset (dark viewport). Render the scene directly through the XR cameras while
presenting; the AO/outline composer resumes on desktop.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, drop postinstall

Replace the node_modules postinstall patch with guardThrelteXr in vite.config.ts: it
rewrites the four unguarded handedness accesses (dispatch reads + connect/disconnect
store writes) at LOAD time, dev + build. A node_modules edit went stale (Vite caches the
transformed module; only a vite.config change forces the dev restart) - the plugin can't,
and it survives fresh installs. Keeps optimizeDeps.exclude:['@threlte/xr'] so the dep is
served as source for the transform to run. Removes the old postinstall +
scripts/patch-threlte-xr.cjs; CLAUDE.md gotcha/status updated to the plugin + the
Outline.svelte direct-XR-render fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AlexZ005
AlexZ005 merged commit f041504 into main Jul 26, 2026
@AlexZ005
AlexZ005 deleted the fix/ui-polish-connect-settings branch August 5, 2026 20:25
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.

1 participant