mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-06 04:42:57 +00:00
[docs] Refine shorts/live plans: portrait card design + committed VOD & chat phases
Shorts (docs/shorts-plan.md): - Add DECISION 6 + architecture/phase items for a NEW portrait 9:16 card design. The existing VideoCard.js is hardcoded 16:9 (ratio-16-9), so shorts need either a "short" variant of VideoCard or a dedicated ShortCard — a first-class Phase 1 deliverable, not an afterthought. Live ingest (docs/live-ingest-plan.md): - Reframe past streams (VOD) and chat from "deferred/maybe" to committed phases: Phase 3 read-only chat (+ optional 3b post), Phase 4 ended/recording VOD playback through the same HLS path. So the plan's phases fully account for live AND past zap.stream streams AND chat. - Add a distinct LiveCard design (LIVE badge, viewer count, ended state). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
163f7e11d5
commit
8e76f0d7a8
2 files changed
+50
-16
No files matched your search
+25
-12
@@ -24,10 +24,12 @@ a config flag that leaves **no trace** when off.
|
||||
> *Recommendation: whitelisted hosts for v1 — consistent with the rest of bitvid's
|
||||
> trust model and avoids surfacing arbitrary/abusive streams.*
|
||||
|
||||
> **DECISION 2 — Live chat in v1?** Read-only kind-1311 chat alongside the player,
|
||||
> or playback-only for v1 (chat later)?
|
||||
> *Recommendation: playback-only v1; add read-only chat in a later phase. Chat is
|
||||
> a live subscription with its own moderation questions.*
|
||||
> **DECISION 2 — Chat level (read-only vs read + post).** Chat is **committed to
|
||||
> the roadmap** (Phase 3), the only open question is how far: **read-only** (kind
|
||||
> 1311 ingest — stays cleanly inside "ingest"), or **read + post** (signing/
|
||||
> publishing 1311 events — a write path, likely its own sub-flag + moderation
|
||||
> stance). *Recommendation: read-only in Phase 3, then read + post as Phase 3b if
|
||||
> wanted. Playback (Phases 1–2) ships before chat regardless.*
|
||||
|
||||
> **DECISION 3 — HLS playback dependency.** OK to lazy-load a small HLS library
|
||||
> (**hls.js**, ~cdn/vendored) ONLY when the flag is on, or must playback stay
|
||||
@@ -35,10 +37,13 @@ a config flag that leaves **no trace** when off.
|
||||
> *Recommendation: allow hls.js, lazy-imported behind the flag (native HLS alone
|
||||
> won't play `.m3u8` in Chrome/Firefox). It never loads when the flag is off.*
|
||||
|
||||
> **DECISION 4 — Ended streams / VOD.** When `status=ended`, some events carry a
|
||||
> `recording` URL (a VOD). Show ended streams with playback of the recording,
|
||||
> hide them, or list-but-mark-ended? *Recommendation: v1 shows only `status=live`;
|
||||
> treat recordings as a later enhancement.*
|
||||
> **DECISION 4 — Past streams / VOD presentation.** Past (ended) streams are
|
||||
> **committed to the roadmap** (Phase 4): a `status=ended` event carries a
|
||||
> `recording` URL (a VOD, usually `.m3u8`/mp4) which plays through the same HLS
|
||||
> path as live. Open question is only *presentation*: mix ended streams into the
|
||||
> Live tab (marked "ended"), or give them a separate "Past streams" section/sort?
|
||||
> *Recommendation: one Live tab that lists live first, then recent ended streams
|
||||
> marked accordingly; a dedicated section only if it gets crowded.*
|
||||
|
||||
> **DECISION 5 — Discovery relays.** Use the user's normal read relays, or add
|
||||
> stream-heavy relays (zap.stream's relay etc.) for discovery? *Recommendation:
|
||||
@@ -102,6 +107,10 @@ chat message. Read-only ingest = subscribe by `#a`, render newest.
|
||||
`nip71IngestService` so it stays off the cold-start critical path.
|
||||
- **Sidebar tab + view:** "Live" link in `components/sidebar.html` (flag-gated) +
|
||||
`views/live.html` (grid of live cards).
|
||||
- **Card design (new):** a **live card** distinct from `VideoCard.js` — a **LIVE
|
||||
badge**, viewer count, host name/avatar, and an "ended" state for past streams
|
||||
(Phase 4). Likely a dedicated `LiveCard` (the live/ended metadata differs enough
|
||||
from a video card that a variant is awkward). New `data-testid` for e2e.
|
||||
- **Player:** a live player path. The current player
|
||||
(`js/services/playbackService.js`) sets `videoEl.src` for URL/WebTorrent; HLS
|
||||
needs hls.js attached to the `<video>` element when the source is `.m3u8`
|
||||
@@ -126,10 +135,14 @@ chat message. Read-only ingest = subscribe by `#a`, render newest.
|
||||
live cards, route gated by flag. Clicking a card opens… (Phase 2).
|
||||
- **Phase 2 — HLS playback (medium).** Live player path + lazy hls.js; play the
|
||||
`streaming` URL; graceful error when the stream is down.
|
||||
- **Phase 3 — Read-only chat (medium, DECISION 2).** kind-1311 subscription +
|
||||
render + teardown.
|
||||
- **Phase 4 — Polish.** Viewer counts, ended/recording handling (DECISION 4),
|
||||
optional extra discovery relays (DECISION 5), poster/skeleton states.
|
||||
- **Phase 3 — Chat (medium, DECISION 2).** Read-only kind-1311 subscription by
|
||||
`#a` + render + teardown. Optional **Phase 3b — post chat** (sign/publish 1311,
|
||||
its own sub-flag + moderation stance) if read+post is chosen.
|
||||
- **Phase 4 — Past streams / VOD (medium, DECISION 4).** List `status=ended`
|
||||
events and play their `recording` URL through the same HLS player; mark ended
|
||||
vs live in the UI. This is the "past zap.stream streams" capability.
|
||||
- **Phase 5 — Polish.** Viewer counts, optional extra discovery relays
|
||||
(DECISION 5), poster/skeleton states, liveness de-emphasis for stale events.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+25
-4
@@ -46,6 +46,19 @@ source that lists only shorts. Everything ships behind a config flag that leaves
|
||||
> *Recommendation: ship the grid + portrait player first (small), then layer the
|
||||
> swipe feed as a phase 2 — keeps the first release cheap.*
|
||||
|
||||
> **DECISION 6 — Card design.** Shorts need a **new portrait (9:16) card** — the
|
||||
> existing `js/ui/components/VideoCard.js` hardcodes a **16:9 landscape** media
|
||||
> ratio (`ratio-16-9`), so it can't render shorts correctly as-is. Two options:
|
||||
> (a) a **new `ShortCard` component** (portrait thumbnail, compact meta, its own
|
||||
> `data-testid`); or (b) a **portrait "mode"/variant of `VideoCard`** driven by a
|
||||
> flag (e.g. `variant: "short"` swapping the ratio class + layout).
|
||||
> *Recommendation: (b) a portrait variant of `VideoCard` if the internals are
|
||||
> clean enough to parameterize the ratio + layout — it inherits thumbnail
|
||||
> binding, moderation badges, engagement controls, and the ⋯ menu for free;
|
||||
> fall back to (a) a dedicated `ShortCard` only if forcing a variant makes
|
||||
> `VideoCard` unwieldy or pushes it past its size cap.* Either way this is a
|
||||
> **first-class deliverable**, not an afterthought — the grid can't ship without it.
|
||||
|
||||
---
|
||||
|
||||
## Config flag (off = no trace)
|
||||
@@ -97,6 +110,12 @@ Reuses the existing feed engine + ingest; new pieces are thin.
|
||||
- **Sidebar tab:** add a Shorts link in `components/sidebar.html`, rendered only
|
||||
when the flag is on.
|
||||
- **View:** `views/shorts.html` (a portrait-oriented grid container).
|
||||
- **Card design (new):** a portrait **9:16** card — either a `variant: "short"`
|
||||
mode of `js/ui/components/VideoCard.js` (which is currently 16:9 / `ratio-16-9`)
|
||||
or a dedicated `ShortCard` (DECISION 6). Portrait thumbnail, compact title +
|
||||
author, reuse of thumbnail binding, moderation badges, engagement + ⋯ menu. New
|
||||
design tokens if needed (existing `--video-card-*` tokens live in
|
||||
`css/tokens.css`). A distinct `data-testid` for e2e selectors.
|
||||
- **Player UI:** v1 opens a short in the existing player modal with a portrait
|
||||
layout; v2 adds a full-screen vertical swipe/next feed.
|
||||
- **Diversity:** apply the existing `spreadAuthors` pass (feed sorters) so the
|
||||
@@ -108,10 +127,12 @@ Reuses the existing feed engine + ingest; new pieces are thin.
|
||||
|
||||
- **Phase 0 — Detection + flag (small).** Add `FEATURE_SHORTS` (off), `isShort`
|
||||
derivation in the ingest adapter + mirror, unit tests for detection. No UI.
|
||||
- **Phase 1 — Tab + feed (small–medium).** `FEED_TYPES.SHORTS`, sidebar link,
|
||||
`views/shorts.html`, feed registration filtered to `isShort`, route gated by
|
||||
flag. Grid renders; opens in the standard player.
|
||||
- **Phase 2 — Vertical UX (medium).** Portrait player layout + swipe/next feel.
|
||||
- **Phase 1 — Tab + feed + portrait card (medium).** `FEED_TYPES.SHORTS`, sidebar
|
||||
link, `views/shorts.html`, feed registration filtered to `isShort`, route gated
|
||||
by flag, and the **new portrait 9:16 card** (DECISION 6) so the grid renders
|
||||
shorts correctly. Opens in the standard player for now.
|
||||
- **Phase 2 — Vertical UX (medium).** Portrait player layout + full-screen
|
||||
swipe/next feed.
|
||||
- **Phase 3 — Polish.** Autoplay-on-scroll, mute toggle, per-tab empty states,
|
||||
optional exclusion from the main feed (DECISION 3 revisit).
|
||||
|
||||
|
||||
Reference in new issue
Block a user