Files
Piik/docs/design/media-status.md
T
AAA 322e5d91b2 feat(ui): add illustrated hints and playback gestures
## Problem and outcome / 问题与结果

App startup rejected short or non-ASCII site passwords, viewers lacked picture-click playback gestures, and text-mode hints hid the existing illustrations. This phase accepts site passwords verbatim, combines shared illustrations with localized captions in tooltips and stage overlays, and adds desktop single-click play/pause and double-click fullscreen through the existing playback owner. Pure-visual mode remains available.

App ZIP names are now stable per platform, allowing the website to use GitHub's native latest-download URLs. The App update link selects the ZIP matching its compiled OS and architecture from the checked release metadata, falling back to the release page if the package is unavailable. Verified Gitee links retain their explicit release version. The Windows packaging workflow also stops restoring a redundant Go toolchain cache that caused setup-go to fail.

## Release notes

### 中文

- 中英文操作提示和画面状态覆盖层加入动态漫画,说明更直观;纯视觉模式继续保留。
- 观众可单击画面暂停或继续播放,双击进入或退出全屏;触屏仍通过单击显示或隐藏播放栏。
- 修复设置短密码、中文密码时 App 或 Server 无法启动的问题。站点密码仍可留空。
- 官网各系统的 GitHub 下载按钮直接获取最新 ZIP 包,并保留 Gitee 备用下载线路。
- App 内的更新入口直接下载对应系统和架构的 ZIP 包。

### English

- Chinese and English tooltips and picture status overlays now pair concise explanations with animated illustrations. Pure-visual mode remains available.
- Viewers can click the picture to pause or resume and double-click to enter or exit fullscreen. Touch taps continue to show or hide playback controls.
- Fixed App and Server startup rejecting short or non-ASCII site passwords. Site passwords remain optional.
- Each platform's GitHub download button now fetches the latest ZIP package, with Gitee retained as an alternative download source.
- App update links download the ZIP matching the installed platform and architecture.

## Verification / 验证

- `npm run check`: 59 test files / 774 tests, TypeScript and production build passed.
- `npm run check:client-core`: Go tests, formatting, vet and supported local target builds passed for the included runtime changes. Native macOS packaging remains on its macOS runner.
- Desktop and 390px touch playback checks passed, including double-click without an intermediate pause and control/keyboard interaction.
- Illustrated tooltip checks passed in Chinese, English and pure-visual modes, light/dark themes, 260/360/390px layouts, keyboard, touch hold and reduced motion. User accepted the resulting UI.
- Real stage overlay components passed 46 checks across the three modes and 260/390/1280px layouts, including keyboard play activation, reduced motion, and no overlay over healthy playback with a quality limitation.
- Bounded release review confirmed JSON password authentication retains old bodyless Bearer compatibility and ZIP names match packaging, publisher, mirror and website consumers.
- After checking both providers' real API shapes, 27 focused update tests and type-checking passed; anonymous GitHub and Gitee metadata each selected all three actual platform ZIPs without downloading them.
- Documentation, repository hygiene and diff checks passed.

## Impact / 影响

Compatible feature release. Signaling, Native control, capture protocol and persistent room schema are unchanged. The new latest-download filenames must be published before the matching website deploys; the existing CI-to-Website sequence provides that order. Production service updates use the immutable Server artifact and bounded rollback. Broader physical macOS/Linux, network and endurance acceptance stays under the existing documented deferrals.
2026-09-13 01:04:13 +08:00

6.8 KiB

Media Status

src/client/ui/media-status.ts owns the shared visual projection, demonstrated by /__status-preview. It is not a routing or quality controller. The existing presentation reducer continues to own playback facts; roster and quality evidence retain their own authority. Overlay, indicators, notices and title are consumers, not truth sources.

Frontend controls, names and details share Tooltip, following the visual language. Its native Popover top layer escapes scrolling containers, with viewport-relative placement. Hover, keyboard focus and touch hold share one visibility owner; Escape dismisses even a mouse-only hint. /__tooltip-preview shows the catalogue. Playback actions and their local audio ownership are defined in presentation lifecycle; /__playback-preview exercises the actual control bar with generated local media.

Status Meaning

Keep three questions separate: is the media path available, is this picture playing, and is this particular stream limited? An available path does not prove excellent quality. One weak child does not make its parent's received picture or a healthy sibling unhealthy.

The shared visual language owns colours, cast, shapes, panel accents and motion. This document owns the evidence and scope that select those meanings. Current StatusDescriptor tone and progress take precedence over a reused comic's default; text and pure-visual tooltips retain that context.

Projection Rules

  • Overlay: appears when there is no usable picture, an intentional Host pause, or a required user action. Ordinary quality warnings never cover playback. Initial connection guidance is not an error even though it occupies the stage.
  • Television: one media-status icon sits inside the lower television frame (lr-tv-chin). Every mode explains it with the same comic tooltip; text modes add the specific localized status beneath the scene. Both reuse Tooltip for hover, keyboard focus, touch hold and viewport placement; no native title competes with the custom status hint. There is no permanent text bubble, additional round lamp, or repeated control-menu caption. The Host television describes its local source, not an arbitrary outbound child. A confirmed limitation may colour the relevant icon amber while the page title still says watching.
  • Host couch: each Viewer has one round lamp. Grey means waiting for the share, blue means waiting for the media path, green means committed mediaReady, and amber means a recent receive freeze. The Host's own pawn has no duplicate lamp. deriveParticipantStatus supplies both the couch and Host overview; neither stores another copy of the status.
  • Viewer couch: pawns have no round lamps. While awaiting media readiness a pawn's body breathes gently; it becomes still when ready. This expresses the same roster fact without claiming to know other Viewers' quality.
  • Header: the page's connection to the room server. Its control-link comics show a Browser and server, not a failed video path. A media-route failure can coexist with a healthy server connection, and vice versa.
  • Connection notice: signaling recovery may coexist with healthy media. It cannot convert proved playback into waiting.
  • Notices: necessary coexisting issues and operation feedback use the existing pills near the stage; they are not another primary media status. Raw PeerConnection errors remain diagnostic observations, not persistent red warnings after media recovers. The control menu does not repeat the television status or aggregate the first weak outbound edge into a global quality warning.
  • Title: keeps the primary activity, with a compact warning for an applicable problem. Losing focus alone never means waiting for media.
  • Recovery: every projection is recomputed from current facts. A warning requires current evidence; an expired or mismatched sample becomes unknown, not healthy or disconnected. A ready participant can therefore return to a green readiness lamp without claiming that its quality has recovered. No warning latch or additional timer is needed.

Evidence And Integration Boundary

Use WebRTC connectionState for transport explanation, not first-frame proof. disconnected may recover; failed is terminal for that connection. Closing a retired connection is not an error in the replacement connection. qualityLimitationReason describes an outbound encoder. A relay's sender warning must never become a warning about its own inbound picture. Low FPS, resolution or bitrate alone does not prove poor quality; a static screen or a small source can legitimately need little data. Do not introduce UI thresholds or a new quality score.

Current roster messages expose committed mediaReady to both roles, not a complete remote quality/failure state. Missing readiness means waiting or recovery, not confirmed disconnection; departed participants leave the roster. Viewer receive evidence is shared with its parent and the Host, not with every other Viewer. No additional remote-quality broadcast is needed.

The Host's amber participant lamp requires an active share, committed readiness, fresh receive evidence for the current upstream, and a positive freezeCountDelta or freezeDurationMsDelta. The existing evidence-expiry path clears stale warnings. Hidden, paused and other diagnostic-only windows provide no freeze proof; low FPS, resolution or bitrate is not a substitute.

All *Delta metrics describe one observation window and never inherit an older non-null value. Non-window fields retain the existing details-display cache. Participant status reads the current evidence directly; it adds no stored status, timer, threshold or score. Detailed sender/receiver metrics remain available in connection details and Debug with their original scope.

The preview labels supplied example quality facts for the displayed stream. Examples do not authorize guessing unavailable production facts.

References

We reuse these distinctions and the existing Piik owners, not a new SDK, scoring algorithm or transport policy.