fix(#1065): first-visit gesture discoverability hints#1186
Merged
Kpa-clawbot merged 4 commits intomasterfrom May 10, 2026
Merged
fix(#1065): first-visit gesture discoverability hints#1186Kpa-clawbot merged 4 commits intomasterfrom
Kpa-clawbot merged 4 commits intomasterfrom
Conversation
Adds Playwright E2E covering: - first-visit row-swipe hint shown at 360x800 /#/packets - aria-live=polite, role=status, pointer-events:none - 'Got it' button dismisses + persists meshcore-gesture-hints-* flag - reload does not re-show - Settings 'Reset gesture hints' button restores - 1024x800 edge-drawer hint visible - prefers-reduced-motion → animation-name: none - focus not stolen - 5 SPA round-trips don't re-show after dismiss Wired into .github/workflows/deploy.yml. Will FAIL on assertion until public/gesture-hints.js + Settings reset button + CSS land in the green commit.
Implements gesture discoverability hints per AC: - Hints: row-swipe, tab-swipe, edge-drawer, pull-refresh - localStorage namespace: meshcore-gesture-hints-<id> = 'seen' - Show 800ms after page settle; auto-fade after 8s; 'Got it' marks seen - aria-live=polite + role=status + aria-atomic=true - pointer-events:none on wrapper (inner balloon clickable, row stays usable) - Singleton guard via window.__gestureHints1065Init - prefers-reduced-motion: animation-name:none, opacity-only fade - Pull-to-refresh hint conditional on .pull-to-reconnect element presence - Edge-drawer hint conditional on viewport > 768px - Row-swipe hint scoped to /#/packets, /#/nodes, /#/live - 'Reset gesture hints' button added to Customize > Display panel - hashchange listener removes irrelevant hints + re-evaluates on route change Files: - NEW public/gesture-hints.js (module-scoped singleton) - NEW CSS section in public/style.css (#1065 fence) - public/index.html: script tag after touch-gestures.js - public/customize-v2.js: 'Reset gesture hints' button + handler
CI test (a) reported computed pointer-events='auto' on the wrapper
despite .gesture-hint { pointer-events: none } — likely a cascade
collision (e.g. .gesture-hint-inner sibling rule, or a future overlay
class). Force it with !important. Inner balloon + button retain
pointer-events:auto so 'Got it' still works.
CSS rule + !important alone didn't satisfy the E2E (Chromium reported
computed pointer-events=auto despite '.gesture-hint { pointer-events:
none !important }'). Most likely: cached page state during test, or a
sibling rule we haven't identified. Inline style.pointerEvents='none'
on the wrapper at creation time bypasses the entire CSS cascade — the
hint provably cannot capture clicks. Inner balloon + button keep their
own pointer-events:auto via separate elements.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Red commit: 4e0a168 (CI run: see Checks tab — branch pushes don't trigger CI on this repo; first CI is on this PR)
Fixes #1065. Parent: #1052.
What
First-visit gesture discoverability hints. Brief animated balloons appear 800ms after page settle on first visit, announcing each gesture: swipe-row-action, swipe-between-tabs, edge-swipe-drawer, pull-to-refresh. Each hint dismisses individually via "Got it"; dismissed hints persist across sessions; "Reset gesture hints" in Customize → Display restores them.
Decisions
meshcore-gesture-hints-<id>with keysrow-swipe,tab-swipe,edge-drawer,pull-refresh. Value:"seen".↺ Reset gesture hintsbutton. Callswindow.GestureHints.reset()which clears all four keys + removes any visible balloons..pull-to-reconnectelement exists in DOM (per [#1052] Task 4: Pull-to-reconnect on data pages #1063). If absent, the hint is silently skipped — other 3 still show.animation-name: none !importantunder the media query; only opacity transition remains.autofocus, no.focus()calls. Wrapper haspointer-events: none; only the inner balloon + dismiss button capture pointer, so the row underneath stays interactive (no conflict with fix(#1062): gesture system — swipe rows, tabs, slide-over dismiss #1185 row-swipe).window.__gestureHints1065Initcounter;hashchangelistener bound exactly once across SPA mounts; dismissed hints don't re-show on route change (gated bylocalStorage)./#/packets|nodes|live; edge-drawer only at viewport > 768px (matches [#1052] Task 5: Edge-swipe nav drawer #1064 drawer scope).E2E
test-gesture-hints-1065-e2e.js— Playwright covering first-visit show, "Got it" dismiss + flag persistence, reload-no-show, Settings reset → reload → re-show, edge-drawer at 1024x800, prefers-reduced-motion → animation-name: none, focus not stolen, singleton across 5 SPA round-trips.E2E assertion added: test-gesture-hints-1065-e2e.js:90
Browser verified: pending CI run.