Skip to content

XERK-133: 4-line cue body + host-native scroll bar on the glasses lens - #85

Merged
xerhab merged 1 commit into
mainfrom
XERK-133
Jul 27, 2026
Merged

XERK-133: 4-line cue body + host-native scroll bar on the glasses lens#85
xerhab merged 1 commit into
mainfrom
XERK-133

Conversation

@xerhab

@xerhab xerhab commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Closes XERK-133.

What the ticket asked

In the glasses ui expand the body to 4 lines max. And fix the cue scroll bar. Right now it looks blocky and dumb, it should just be a native scroll bar.

What changed (even/ — the Even G2 glasses lens)

1. Body expands to 4 lines. CUE_BODY_LINES 3 → 4. The box still lands on whole caption-row boundaries (5 rows = 161px, inside the 6th transcript row's 162px boundary), so it never leaves a clipped half-line the host would grow a stray scroll bar into (the XERK-85 invariant).

2. The scroll bar is now the host's own native one. The old bar was drawn by hand out of box-drawing glyphs ( track, thumb — the "blocky and dumb" part, XERK-129). The lens SDK exposes no scrollbar property, so the only truly native scroll is to let a container's content overflow and have the host (LVGL) scroll it. The cue is now two containers:

  • a pinned title frame (bordered box, carries the title + live countdown), and
  • a scrolling body container inside it holding the whole body.

When the body wraps past the 4 visible rows its content overflows the fixed body-container height and the host scrolls it with its native scroll bar. That body container is the sole event-capture container while a cue is up (the invisible touch overlay yields for the cue page, so exactly one container still captures per page — the XERK-85 rule holds), so a swipe drives the host scroll directly. Splitting the title into its own container is what keeps the per-second countdown repaint from ever yanking the host's scroll back to the top.

Removed: manual swipe-windowing (cueScroll / scrollCue / cueMaxScroll) and the glyph bar (CUE_BAR_TRACK/THUMB, cueScrollBar). cueText split into cueTitleLine (pinned) + cueBodyText (scrolled). Tapping/swiping a live cue still resets the auto-dismiss countdown (XERK-129) and nothing else.

Docs (even/README.md, docs/cues.md) updated to match.

Verification

  • npm run typecheck — green across all workspaces (client-core, even, mobile, web).
  • even build — green.
  • even tests — 227 passing. Layout + controller suites reworked for the two-container model: pinned title vs whole-body scrolling container, the capture handoff (body captures, touch overlay yields), overflow geometry (long body's rendered height > container height), the 4-line/161px box geometry, and that a countdown tick repaints only the title (no rebuild/repaint of the body).

⚠️ Needs on-device validation (cannot be tested off the G2 hardware)

The native scroll itself is host/LVGL behaviour that no unit test or browser can exercise — there is no lens simulator. Please confirm on real glasses:

  1. A long-body cue's body container actually overflow-scrolls and the host draws its native scroll bar (a plain TextContainerProperty overflowing its height).
  2. Swiping the cue scrolls the body (the body container is now the capture target instead of the invisible touch overlay), and the per-second countdown repaint of the title leaves the body's scroll position untouched.
  3. Tap-to-reset-countdown and the double-tap menu still work with a cue up (gesture events still reach the controller via the captured body container).

If (2) shows the host resets scroll on any title repaint despite the split, the fallback is to also stop repainting the title while actively scrolling — but the container split should already isolate it.

…K-133)

The glasses-UI cue box got two changes the ticket asked for:

- Expand the body to four lines max. CUE_BODY_LINES 3 -> 4, so a cue reads
  more at a glance. The box still lands on whole caption-row boundaries
  (5 rows = 161px, inside the 6th row's 162px boundary), so it never grows a
  clipped half-line the host would scroll into (XERK-85).

- Replace the hand-drawn glyph scroll bar (the blocky |/# built out of box
  characters, XERK-129) with the host's own NATIVE scroll bar. The cue is now
  two containers: a pinned title frame (with its live countdown) over a
  separate scrolling body container. The body container holds the WHOLE body;
  when it wraps past the four visible rows its content overflows the fixed
  container height and the host scrolls it with its native scroll bar. That
  body container is the one event-capture container while a cue is up (the
  invisible touch overlay yields for the cue page, so exactly one container
  still captures per page, XERK-85), so a swipe drives the host's scroll
  directly. Splitting the title out keeps it — and its per-second countdown
  repaint — from ever disturbing the host's scroll position.

The manual swipe-windowing (cueScroll / scrollCue / cueMaxScroll) and the
glyph-bar layout (CUE_BAR_TRACK/THUMB, cueScrollBar) are gone; cueText splits
into cueTitleLine (pinned) + cueBodyText (scrolled). A tap or swipe on a live
cue still resets the auto-dismiss countdown (XERK-129) and nothing else.

Tests: layout + controller suites reworked for the two-container model
(pinned title, whole-body scrolling container, capture handoff, overflow
geometry, and that a countdown tick never rebuilds/repaints the body). All
227 even tests pass; typecheck + build green across workspaces.

NOTE: the native-scroll behaviour is host/LVGL device behaviour that cannot be
exercised off the physical G2 glasses — see the PR for the on-device checklist.
@xerhab
xerhab merged commit 5d2fff1 into main Jul 27, 2026
1 check passed
@xerhab
xerhab deleted the XERK-133 branch July 27, 2026 12:13
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