Implements VOD (past broadcast) browsing and chat replay that reuses
the existing live chat rendering pipeline in read-only mode.
Models & API:
- video.dart: Helix video model with duration parsing (3h26m15s → Duration)
- gql_chat_comment.dart: GQL VOD chat comment models (manual parsing)
- IRCMessage.fromGqlComment(): adapter mapping GQL comments → IRC format
so the existing chat rendering pipeline (generateSpan, badges, emotes)
works unchanged for VOD chat
- TwitchApi.getVideos(): Helix endpoint for user VOD list with pagination
- TwitchGqlApi.getVideoComments(): GQL persisted query using mobile
client ID (bypasses Client-Integrity) for VOD chat comments
Architecture:
- ChatRenderContext interface: minimal abstraction over ChatStore so
ChatMessage widget works with both live ChatStore and VodChatStore
- ChatStore now implements ChatRenderContext (one-line change)
- ChatMessage accepts ChatRenderContext instead of ChatStore, with
type guards for live-only actions (reply, paste, name tap navigation)
VOD stores:
- VodChatStore: MobX store implementing ChatRenderContext with identical
message batching (200ms timer, 5000 limit, 100 render limit, 20% trim),
scroll/autoscroll, playback position tracking, seek detection
(delta < -5 or > 10 triggers clear + re-fetch), comment buffer with
pre-fetching when < 50 comments remain
- VodListStore: standard paginated list store for VOD browsing
VOD UI:
- VodPlayer: matches live channel layout exactly (no AppBar, SafeArea,
16:9 WebView + expanded chat) with JS position polling every 1s +
seeked event listener via VodPosition JS channel
- VodList: paginated VOD list with scroll-based loading
- VodCard: thumbnail card with duration overlay and relative dates
- Entry point: "Past broadcasts" in chat details drawer
Tests (21 new):
- video_test.dart: VideoTwitch/VideosTwitch parsing, duration parsing
- gql_chat_comment_test.dart: comment parsing, response error handling,
IRCMessage.fromGqlComment adapter (tags, localEmotes, deleted user)
- twitch_gql_api_test.dart: getVideoComments mock tests
- twitch_api_test.dart: getVideos mock tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>