feat(ui): consolidate secondary controls in settings menu
This commit is contained in:
@@ -2960,7 +2960,7 @@ without automatically opening the optional player help overlay.
|
||||
|
||||
## Milestone 027 — Playful breakthrough movement and prominent hedge gaps
|
||||
|
||||
**Status:** `IN_PROGRESS`
|
||||
**Status:** `COMPLETE`
|
||||
|
||||
### Objective
|
||||
|
||||
@@ -3126,3 +3126,291 @@ passage on supported mobile and desktop screens.
|
||||
2,031,616 / 2,031,616 byte LittleFS image.
|
||||
- Mobile, desktop, observer, reduced-motion, and physical-device visual
|
||||
acceptance remain required before this milestone can be marked `COMPLETE`.
|
||||
|
||||
## Milestone 028 — Compact settings menu
|
||||
|
||||
**Status:** `COMPLETE`
|
||||
|
||||
### Objective
|
||||
|
||||
Reduce persistent browser-interface clutter on every supported viewport by
|
||||
consolidating secondary connection and player-preference controls into one
|
||||
compact settings menu opened by a gear button beside the Wi-Fi connection
|
||||
indicator.
|
||||
|
||||
### Scope
|
||||
|
||||
- Do not start implementation until every preceding milestone is `COMPLETE`.
|
||||
Milestone 027 is `COMPLETE` when this plan is created; this milestone remains
|
||||
`NOT_STARTED` because implementation was not requested.
|
||||
- Keep the Wi-Fi connection indicator visible and place one persistent
|
||||
gear-icon menu button next to it on welcome, lobby, active-player, observer,
|
||||
pause, and result screens where the corresponding secondary actions are
|
||||
available.
|
||||
- Remove the separate persistent buttons for connection details, sound,
|
||||
reduced motion, and help. Expose those actions as clearly labelled Russian
|
||||
items in the gear-button popover.
|
||||
- Move the Wi-Fi settings action out of the connection-details panel and into
|
||||
the same popover. Do not duplicate the Wi-Fi settings action elsewhere in
|
||||
the normal connected application flow.
|
||||
- Preserve the existing behavior and current state of connection details,
|
||||
sound, reduced motion, the optional help overlay, and Wi-Fi settings. The
|
||||
sound and reduced-motion items must visibly and accessibly communicate their
|
||||
current on/off state.
|
||||
- Keep primary gameplay actions outside the settings menu, including movement,
|
||||
avatar drag, key drop, lobby participation, match start, observer navigation,
|
||||
and result actions.
|
||||
- Make the popover usable with touch, pointer, and keyboard. Give its trigger
|
||||
an accessible Russian name and exposed open/closed state; provide predictable
|
||||
focus order; close it after an applicable navigation action, on outside
|
||||
activation, and with Escape; and restore focus to the trigger when
|
||||
appropriate.
|
||||
- Prevent the popover from covering essential controls or escaping the
|
||||
viewport. Anchor it to the top-right status area and allow it to reposition
|
||||
or constrain its height on narrow portrait, compact landscape, desktop, and
|
||||
safe-area-inset layouts.
|
||||
- Preserve Russian player-facing copy, offline operation, observer read-only
|
||||
behavior, server-authoritative game state, supported browser layouts, and
|
||||
firmware and LittleFS budgets.
|
||||
|
||||
### Deliverables
|
||||
|
||||
- Updated compact-settings-menu behavior and responsive-layout contracts in
|
||||
`docs/UI_STYLE.md` and any affected supporting UI documentation.
|
||||
- One reusable gear-triggered settings popover with connection details, sound,
|
||||
reduced motion, help, and Wi-Fi settings actions shown only when applicable.
|
||||
- Removal of the superseded standalone secondary-control buttons and of the
|
||||
duplicated Wi-Fi settings entry from the connection-details panel.
|
||||
- Deterministic browser tests for visibility, state reflection, action routing,
|
||||
keyboard and pointer dismissal, focus behavior, responsive placement, and
|
||||
absence of duplicate controls.
|
||||
- Browser, host-regression, compressed-web-asset, LittleFS, and representative
|
||||
mobile and desktop visual-verification evidence.
|
||||
|
||||
### Acceptance criteria
|
||||
|
||||
1. Every supported screen and viewport shows at most one persistent secondary
|
||||
settings control: a gear button beside the visible Wi-Fi connection
|
||||
indicator. The previous standalone connection-details, sound,
|
||||
reduced-motion, and help buttons are absent.
|
||||
2. Opening the gear button displays the applicable connection details, sound,
|
||||
reduced motion, help, and Wi-Fi settings actions with clear Russian labels.
|
||||
No primary gameplay or lobby action is moved into the menu.
|
||||
3. Connection details show the same live information as before, and their
|
||||
former standalone round button is not rendered.
|
||||
4. Sound and reduced-motion actions retain their existing behavior and reflect
|
||||
their current on/off state visually and through accessible state. Changing
|
||||
either setting updates the menu item without creating another persistent
|
||||
control.
|
||||
5. Help opens the existing optional help overlay without changing its content,
|
||||
navigation, close behavior, or the direct countdown-to-maze transition.
|
||||
6. Wi-Fi settings remain reachable from the menu through the existing
|
||||
configuration flow, and the action is not duplicated in the
|
||||
connection-details panel or elsewhere in the normal connected application
|
||||
flow.
|
||||
7. The trigger and popover work with touch, pointer, and keyboard. The trigger
|
||||
has an accessible Russian name and accurate expanded state; focus order is
|
||||
predictable; Escape and outside activation dismiss the popover; and focus
|
||||
returns safely without trapping the player.
|
||||
8. Opening, using, and closing the popover does not issue gameplay commands,
|
||||
change authoritative game state, enable observer input, or interfere with
|
||||
keyboard, swipe, directional-pad, avatar-drag, key-drop, pause, or result
|
||||
controls.
|
||||
9. At all supported mobile, compact-landscape, tablet, and desktop sizes, the
|
||||
closed layout is more compact than the current standalone-control layout.
|
||||
The open popover stays within safe areas and the viewport, remains readable,
|
||||
introduces no page or map overflow, and does not permanently cover
|
||||
essential controls.
|
||||
10. Automated tests cover screen applicability, absence of standalone and
|
||||
duplicate controls, state reflection, every routed action, dismissal,
|
||||
focus restoration, supported responsive layouts, and regression behavior.
|
||||
11. All host and browser tests pass; compressed-web-asset validation passes;
|
||||
the payload remains within the 1.5 MiB web budget and LittleFS partition;
|
||||
and firmware remains within the factory partition.
|
||||
12. Physical-device verification confirms that the menu and all five
|
||||
secondary actions work in the served application, and the project owner
|
||||
confirms on representative mobile and desktop browsers that the interface
|
||||
is less distracting and materially more compact.
|
||||
|
||||
### Evidence
|
||||
|
||||
- On 2026-09-13, planning-time inspection of the active game at
|
||||
`http://192.168.1.50/` identified the separate round connection-details
|
||||
button beside `ESP на связи` and the standalone sound, reduced-motion, and
|
||||
help controls in the active-player layout.
|
||||
- On 2026-09-13, the project owner chose a gear icon beside the connection
|
||||
indicator, required all referenced secondary controls and Wi-Fi settings to
|
||||
move into its popover without duplicating the Wi-Fi action, and required the
|
||||
compact layout on all screen sizes.
|
||||
- On 2026-09-13, implementation began with one header gear button, a bounded
|
||||
safe-area-aware settings popover, and the removal of the superseded details,
|
||||
sound, reduced-motion, and help buttons. The popover retains live connection
|
||||
information and Wi-Fi navigation on every screen, while player preferences
|
||||
and optional help appear only during an active player match.
|
||||
- On 2026-09-13, `node --test test/web/test_player_app.js
|
||||
test/web/test_hedge_svg.js` passed all 31 tests. The compact-settings test
|
||||
covers the sole trigger, removed standalone controls, state labels,
|
||||
player-screen applicability, Escape and outside dismissal, and safe-area
|
||||
constrained placement.
|
||||
- On 2026-09-13, `bash scripts/run_host_tests.sh` passed all host and bundled
|
||||
browser checks. `python3 scripts/verify_web_assets.py` passed with a
|
||||
deterministic 31,420 / 1,572,864 byte compressed payload, and
|
||||
`/home/sasa/.platformio/penv/bin/pio run --target buildfs` succeeded with a
|
||||
2,031,616 / 2,031,616 byte LittleFS image.
|
||||
- Mobile, desktop, and physical-device visual verification of all settings
|
||||
actions were pending until the project-owner check below.
|
||||
- On 2026-09-13, the project owner checked the UI in every available mode and
|
||||
confirmed that the settings menu is present and works as expected. This
|
||||
supplies the required visual and physical-device acceptance evidence.
|
||||
|
||||
## Milestone 029 — Low-overhead live connection quality
|
||||
|
||||
**Status:** `NOT_STARTED`
|
||||
|
||||
### Objective
|
||||
|
||||
Show a compact, continuously understandable indication of the browser's live
|
||||
round-trip response to the ESP on every application screen, with an honest
|
||||
breakdown between measured ESP handling time and the remaining communication
|
||||
delay, without reducing gameplay responsiveness or consuming unbounded device
|
||||
resources.
|
||||
|
||||
### Scope
|
||||
|
||||
- Do not start implementation until every preceding milestone is `COMPLETE`.
|
||||
Milestone 028 is `COMPLETE` when this plan is created; this milestone remains
|
||||
`NOT_STARTED` because implementation was not requested.
|
||||
- Reuse the existing versioned WebSocket heartbeat request and acknowledgement
|
||||
path. Correlate each probe with its unique request ID and use the browser's
|
||||
monotonic clock to measure complete application round-trip time.
|
||||
- Measure heartbeat handling duration only with the ESP's monotonic clock,
|
||||
from bounded request handling to acknowledgement preparation, and return
|
||||
that duration in the matching acknowledgement. Never subtract an ESP
|
||||
timestamp from a browser timestamp or require clock synchronization.
|
||||
- Derive the communication remainder as the non-negative difference between
|
||||
browser-measured round-trip time and ESP-measured handling time. Label it
|
||||
`Связь`, not pure `Wi-Fi`, because it can also include TCP/WebSocket
|
||||
transport, task scheduling, and outbound queueing. Label the measured device
|
||||
interval `ESP` and the full round trip `Отклик`.
|
||||
- Keep one compact persistent quality indicator beside the existing connection
|
||||
status and settings trigger. Show a connection-quality symbol and rounded
|
||||
total milliseconds without expanding the header or displacing primary
|
||||
content.
|
||||
- Make the `Связь` and `ESP` values available in the existing connection
|
||||
details reached through the settings menu and in the indicator's accessible
|
||||
Russian description. Do not expose developer diagnostics or misleading
|
||||
claims about which person or device is at fault.
|
||||
- Show the indicator on welcome, lobby, active-player, observer, countdown,
|
||||
pause, and result screens. Before the first valid sample, while a sample is
|
||||
stale, and while disconnected, show explicit compact unknown or offline
|
||||
states instead of retaining an old number as if it were current.
|
||||
- Define documented quality thresholds from representative physical-device
|
||||
measurements. Use stable good, delayed, and slow states with smoothing and
|
||||
hysteresis so normal jitter does not make the indicator flicker. State must
|
||||
not rely on color alone.
|
||||
- Keep probing strictly bounded and lower priority than gameplay: at most one
|
||||
heartbeat may be outstanding per browser, normal cadence may not exceed one
|
||||
probe every five seconds, no retry burst is allowed, and a probe or its
|
||||
response must be skipped or dropped rather than delay a move, projection,
|
||||
pause, resume, or result message.
|
||||
- Suspend probes while the WebSocket is closed and while the document is
|
||||
hidden. Clear pending measurements on disconnect, session reset, and socket
|
||||
replacement, then take one fresh sample after a successful connection before
|
||||
resuming the bounded cadence.
|
||||
- Keep a small fixed-size sample window in the browser only. Do not persist or
|
||||
transmit latency history, player names, session tokens, network names, or
|
||||
hidden game state as part of this feature.
|
||||
- Preserve observer read-only behavior, server-authoritative gameplay,
|
||||
existing connection-loss messaging, offline operation, Russian
|
||||
player-facing copy, responsive layouts, and firmware and LittleFS budgets.
|
||||
|
||||
### Deliverables
|
||||
|
||||
- Updated measurement, protocol, quality-state, copy, and responsive-placement
|
||||
contracts in `ARCHITECTURE.md`, `docs/UI_STYLE.md`, `docs/PLAYER_UI.md`, and
|
||||
the Milestone 016 latency procedure where applicable.
|
||||
- A bounded heartbeat round-trip sampler and ESP handling-duration field with
|
||||
documented units, range validation, correlation, timeout, and stale-sample
|
||||
behavior.
|
||||
- A compact always-applicable connection-quality indicator showing total
|
||||
milliseconds, plus `Связь` and `ESP` details integrated with the existing
|
||||
settings and connection-details interface.
|
||||
- Deterministic protocol, gateway, browser, accessibility, responsive-layout,
|
||||
scheduling, smoothing, timeout, reconnect, and backpressure tests.
|
||||
- Before-and-after maximum-session latency, queue, traffic, heap, web-asset,
|
||||
firmware, LittleFS, and physical-device visual-verification evidence.
|
||||
|
||||
### Acceptance criteria
|
||||
|
||||
1. On every supported application screen, the header contains one compact
|
||||
quality symbol and a rounded current total such as `85 мс` beside the
|
||||
existing connection status and gear trigger, without moving or obscuring
|
||||
primary game, lobby, observer, pause, or result controls.
|
||||
2. Each displayed total is calculated from the browser monotonic send and
|
||||
matching-heartbeat-acknowledgement times. Responses with a missing,
|
||||
duplicate, expired, malformed, or mismatched request ID cannot update the
|
||||
indicator.
|
||||
3. The matching heartbeat acknowledgement carries a bounded ESP handling
|
||||
duration measured solely with the ESP monotonic clock. The browser validates
|
||||
the field and derives `Связь = max(0, Отклик - ESP)` without comparing clocks
|
||||
from different devices.
|
||||
4. Connection details show the same sample as three Russian-labelled values:
|
||||
`Отклик`, `Связь`, and `ESP`. Supporting text explains that `Связь` is a
|
||||
transport remainder and cannot isolate radio-only Wi-Fi delay or assign
|
||||
blame with certainty.
|
||||
5. Before the first sample, after the documented stale timeout, and while
|
||||
disconnected, the indicator uses distinct unknown, stale, or offline text
|
||||
and shape states. It never presents an old millisecond value as current.
|
||||
6. Good, delayed, and slow thresholds, smoothing window, hysteresis, rounding,
|
||||
sample timeout, and stale timeout are fixed in canonical documentation and
|
||||
covered at every boundary by deterministic tests. Meaning remains clear in
|
||||
grayscale and without relying on animation or color alone.
|
||||
7. Each browser has at most one heartbeat in flight, sends no more than one
|
||||
normal probe per five seconds, keeps only the documented fixed number of
|
||||
recent samples, and produces no immediate retry loop after timeout,
|
||||
malformed input, disconnect, background suspension, or reconnect.
|
||||
8. Heartbeat work is constant and bounded on the ESP, causes no broadcast or
|
||||
authoritative-state mutation, and cannot occupy queue capacity needed by
|
||||
gameplay or lifecycle messages. Under backpressure its acknowledgement is
|
||||
discarded before any move, view, pause, resume, or result message.
|
||||
9. Pointer feedback, keyboard, swipe, directional-pad, avatar-drag, key-drop,
|
||||
rendering, and observer navigation remain responsive while sampling. The
|
||||
Milestone 017 controlled two-player and two-player/four-observer latency
|
||||
budgets continue to pass, with no increased dropped gameplay messages or
|
||||
queue high-water regression attributable to probes.
|
||||
10. Visibility changes, socket replacement, disconnect, reconnection, session
|
||||
reset, screen changes, and result transitions leave no orphan timer,
|
||||
duplicate probe, stale accessible label, or retained pending correlation.
|
||||
11. The indicator and its details remain readable and within the viewport on
|
||||
supported narrow portrait, compact-landscape, tablet, and desktop layouts,
|
||||
including safe-area insets and all player and observer states.
|
||||
12. Automated protocol, gateway, browser, host, and web-asset tests pass. The
|
||||
compressed payload remains within the 1.5 MiB web budget and LittleFS
|
||||
partition, and firmware remains within the factory partition.
|
||||
13. Physical-device testing with two players and four observers confirms the
|
||||
displayed total and split track controlled fast and delayed conditions,
|
||||
reconnect states recover correctly, and continuous sampling causes no
|
||||
perceptible input delay, animation stutter, disconnect, or gameplay
|
||||
regression.
|
||||
14. The project owner confirms on representative mobile and desktop browsers
|
||||
that the indicator is compact, understandable in every application state,
|
||||
and useful for recognizing a delayed ESP response without distracting from
|
||||
play, or explicitly approves a documented evidence deviation.
|
||||
|
||||
### Evidence
|
||||
|
||||
- On 2026-09-13, planning inspection confirmed that the protocol already
|
||||
supports a correlated `heartbeat` acknowledgement and that the browser uses
|
||||
monotonic timing with a bounded 256-sample diagnostic tracker for accepted
|
||||
movement acknowledgements and painted projections.
|
||||
- On 2026-09-13, the project owner requested a compact icon with a millisecond
|
||||
value in every application state and asked to separate communication delay
|
||||
from ESP processing when this can be done without complicating or slowing
|
||||
gameplay.
|
||||
- Planning analysis established that a single round trip cannot measure pure
|
||||
radio-only Wi-Fi latency. This milestone therefore specifies a directly
|
||||
measured ESP handling interval and an honestly labelled communication
|
||||
remainder, while keeping the displayed headline value equal to the complete
|
||||
browser-to-ESP application round trip.
|
||||
- Implementation and verification have not started, as requested by the
|
||||
project owner.
|
||||
|
||||
Reference in New Issue
Block a user