Fork of tommyxchow/frosty with TwitchAdSolutions (vaft) adblock https://frostyapp.io
Find a file
Tommy Chow e73d9b255f add VOD browsing with synchronized chat replay
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>
2026-03-09 01:47:14 -07:00
.claude update plugin settings and add testing section to AGENTS.md 2026-03-07 00:32:04 -08:00
.github merge instructions into AGENTS.md 2026-01-11 16:59:33 -08:00
.vscode add .env-based config, token script, and VS Code launch configs 2026-03-01 20:09:39 -08:00
android enable native video player on Android 2026-03-08 22:34:05 -07:00
assets release v5.0.5 2026-01-09 02:32:59 -05:00
ios use forked plugin for seamless quality switching, add latency tracking and cookie auth 2026-03-08 22:34:05 -07:00
lib add VOD browsing with synchronized chat replay 2026-03-09 01:47:14 -07:00
scripts switch token script to implicit flow and fix interceptor hanging Future 2026-03-07 20:37:23 -08:00
test add VOD browsing with synchronized chat replay 2026-03-09 01:47:14 -07:00
web enlarge mobile carousel phones and tighten description spacing 2026-02-19 02:50:21 -08:00
.env.example add .env-based config, token script, and VS Code launch configs 2026-03-01 20:09:39 -08:00
.gitignore add .env-based config, token script, and VS Code launch configs 2026-03-01 20:09:39 -08:00
.mcp.json migrate web to next 16 template and redesign landing page (#526) 2026-02-17 19:53:43 -08:00
.metadata Upgrade Flutter/Dart and dependencies (#265) 2023-05-30 21:10:04 -04:00
AGENTS.md update plugin settings and add testing section to AGENTS.md 2026-03-07 00:32:04 -08:00
analysis_options.yaml v5 (#463) 2026-01-01 22:28:17 -05:00
firebase.json Re-run flutterfire configure and fix plugin versions 2024-08-13 00:03:53 -07:00
LICENSE Create LICENSE 2022-01-11 15:29:38 -05:00
pubspec.lock add VOD browsing with synchronized chat replay 2026-03-09 01:47:14 -07:00
pubspec.yaml use forked plugin for seamless quality switching, add latency tracking and cookie auth 2026-03-08 22:34:05 -07:00
README.md replace get-twitch-token bash script with cross-platform Dart script 2026-03-07 16:59:31 -08:00

Showcase of the Frosty app with screenshots in a masonry grid

Badge showing the CI status. Badge showing the number of open issues. Badge showing the date of the last commit. Badge showing the current license of the repo. Badge showing the version of the latest release.

Download

Apple App Store badge. Google Play Store badge.

Why

The official Twitch mobile app doesn't support emotes from 7TV, BetterTTV (BTTV), and FrankerFaceZ (FFZ) — third-party extensions for Twitch used by millions. As a result, only emote text names are rendered rather than their actual image or GIF, making the chat unreadable in many channels.

Features

  • Support for 7TV, BetterTTV, and FrankerFaceZ emotes and badges
  • Browse followed streams, top streams, and top categories
  • Autocomplete for emotes and user mentions
  • Light, dark, and black (OLED) themes
  • Search for channels and categories
  • See and filter chatters in a channel
  • Local chat user message history
  • Theater and fullscreen mode
  • Watch live streams with chat
  • Picture-in-picture mode
  • Block and report users
  • Emote menu
  • Sleep timer
  • And more...

For a more detailed overview, visit frostyapp.io.

Development setup

  1. Install Flutter.

  2. Clone this repo (e.g., git clone https://github.com/tommyxchow/frosty.git).

  3. Go to the Twitch dev console and register a new application to retrieve a Client ID and Client Secret.

  4. Copy .env.example to .env and fill in your credentials:

    cp .env.example .env
    
  5. Run flutter pub get to fetch all the dependencies.

  6. Choose an emulator or device and run the app! The included VS Code launch configurations will automatically read your .env file.

  7. (Optional) Run dart run scripts/get_twitch_token.dart to quickly get a user auth token. Long-press the Anonymous account tile in the app to log in.

Important

Frosty uses MobX for state management. Please refer to the documentation about code generation, otherwise your changes within MobX stores may not be applied.

Donate

If you appreciate my work and would like to donate/tip, you can through:

Otherwise, downloading Frosty, leaving a review, or starring this repository is more than enough to show support. Thank you!

License

Frosty is licensed under AGPL-3.0-or-later.