Commit graph

152 commits

Author SHA1 Message Date
Tommy Chow
abb6cbc446
feat(chat): add bubbles for shared chat participant channels (#581)
* feat(chat): add bubbles for shared chat participant channels

Twitch's native shared chat previously had no way to interact with
participant channels the way manually-added chats work. Adds
per-participant bubbles alongside manual tabs: tapping one spotlights
that channel (fading the rest), hiding one filters its messages from
the feed entirely. Defaults to unfaded, resets on rejoin (fresh
ChatStore per connect).

Manual "merged mode" fading is untouched and unaffected.

* refactor(chat): dedup shared-chat tag lookup and extract fade policy

- add IRCMessage.sourceChannelId, replacing three copies of the same
  source-room-id/room-id tag lookup
- move the shared-chat spotlight/merged-mode fade decision out of
  ChatMessage's build into ChatStore.shouldFadeMessage, matching the
  extract-into-store convention already used for SharedChatBubbleState
- factor the tab-bar item's Padding/Center wrapper into a shared
  _wrapItem helper instead of duplicating it per branch

* fix(chat): don't spotlight a hidden shared-chat bubble

toggleFocus didn't check hiddenChannelIds, so tapping a hidden
bubble's chip added it to the spotlight set — fading every other
participant to showcase a channel whose own messages were already
filtered out of the feed.

* fix(chat): stop shared-chat detection flapping on system messages

_isInSharedChatMode was recomputed from every PRIVMSG/NOTICE/USERNOTICE,
but only PRIVMSG reliably carries source-room-id for a session's
duration. A sub/raid/announcement without the tag would flip the flag
off and back on within a single live session. Previously this only
risked a redundant asset refetch (already guarded); now the shared
chat bubble bar reads the flag directly, so a flap would visibly
collapse and reopen it. Scope detection to PRIVMSG only.
2026-07-03 00:16:49 -04:00
Tommy Chow
ef1b1ded5d fix: reclassify transient errors as non-fatal and fix top crashes
- main: record transient I/O, plugin-teardown, and non-crashing UI errors
  (network/websocket/timeout, MissingPluginException, image-load, layout
  overflow) as non-fatal, and add a grouping reason to async errors so
  distinct errors stop collapsing into one catch-all Crashlytics issue
- irc: guard IRCMessage.fromString against malformed/truncated lines that
  threw RangeError, with regression tests
- chat: wrap the emote menu in OverflowBox so it no longer overflows
  (RenderFlex) while the panel collapses
- chat: fix onBadgeError returning a List instead of a Map, which threw a
  Future.catchError type error during channel asset loads
- video: skip setAutoPipMode on Android < 12 where it isn't implemented

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 15:04:11 -04:00
Tommy Chow
f2b932bc93
feat(video,chat): native player, ad-break awareness, chat send/delay reliability, and tab redesign (#567)
Squash-merge commit. Covers four areas: native video player, chat reliability, multi-tab, and hardening.

## Native video player
- Direct HLS playback via `better_native_video_player` (forked from `plug-and-pay/flutter-native-video-player`, patched on `frosty-patches` branch)
- Twitch GQL playback token fetching with platform cookie extraction (iOS Swift + Android Kotlin plugins) for authenticated streams
- Quality selection (source, 720p, 480p, 360p, 160p, audio-only) persisted per channel
- Picture-in-picture: iOS automatic inline PiP, Android auto-PiP on API 31+ guarded against older devices
- Latency polling, chat latency sync, stall detection/recovery, startup auto-pause recovery, watchdog timers
- **Twitch stitched-ad break detection** (HLS `EXT-X-DATERANGE`) on both platforms, emitting `adBreakChanged` so the host suspends latency/stall recovery and chat sync during ads (program-date-time is unreliable then). Matches `CLASS="twitch-stitched-ad"` / `ID="stitched-ad-"` **and** the `X-TV-TWITCH-AD-*` attribute prefix (the durable signal streamlink/yt-dlp use)
- Shared `VideoPlayerInterface` so WebView and native paths are interchangeable via settings toggle
- `PlaybackAccessToken` model, `TwitchGqlApi` client

## Chat delay & send reliability
- **Optimistic send-finalize**: Twitch acks a sent message with a per-PRIVMSG USERSTATE (not an echo), which it can intermittently drop — more so under a long chat delay. A missing ack no longer shows a false "message may not have been sent" error; the send is finalized optimistically (local echo rendered), and only genuine rejection NOTICEs surface an error. Ack timeout scaled by the chat delay.
- **Per-line chat-delay bypass**: control/state lines (USERSTATE/ROOMSTATE/GLOBALUSERSTATE), rejection NOTICEs, the reconnect notice, and untagged server lines bypass the delay so send-acks and PONGs aren't stalled; only displayable chat content is delayed, staying in sync with delayed video.
- **Measured chat bottom-bar height**: the message list reflows to the composer's real measured height, fixing the input overlapping messages when a long message expands it (replaces a fixed-constant estimate).
- IRC tag parsing handles valueless and escaped tags per the IRCv3 message-tags spec (fixes a recent-messages RangeError on certain tags).

## Chat / multi-tab
- Redesigned tab chips: unread dot indicator, chips dim until WebSocket connects
- Animated tab options popover replacing `MenuAnchor` (no animation hook in Flutter 3.44)
- Simplified `ChatTabs` from `StatefulWidget` to `StatelessWidget`
- Focus-current-channel fade bump to 0.55; section-header alpha lifted to match the muted-label tier
- `addTab` now calls `setActiveTab` to snapshot outgoing tab's `lastSeenMessageId` — fixes spurious unread dots after adding a tab
- `onActivateSourceTab` threaded into `ChatUserModal` so Reply in merged mode switches to the correct source tab's composer

## Bug fixes and hardening
- **Reverted the experimental iOS low-latency mode** (5s live-edge join + 1.05x catch-up): AVPlayer can't sustain <~18s on Twitch (declared `TARGETDURATION:6` paces playlist refreshes), and the offset starved the buffer into pause-on-launch. Default join distance restored.
- Fork (Android): **cap `BEHIND_LIVE_WINDOW` recovery** so a stream repeatedly falling off the live window can't silently re-prepare forever; emits `error` on exhaustion so the host recovery ladder takes over
- Guard all Android `setAutoPipMode` calls with `_autoPipAvailable` — prevents `PlatformException` on Android 8–11; check `_disposed` after `isAutoPipAvailable` await to prevent post-dispose auto-PiP re-enable
- Remove `_isInPipMode` guard from `_onPaused` so `_paused` tracks actual state, fixing PiP play/pause toggle getting stuck
- Tighten iOS cookie domain check to exact `twitch.tv` / `.twitch.tv` suffix
- Invalidate the stored web session token when Twitch rejects it with a 401 (profile card flips back to unlinked; future loads skip the doomed authenticated request), and re-extract the cookie on launch when logged in without a linked session
- Send `play_session_id` and `player_backend=mediaplayer` to Usher, matching the web client / streamlink
- Fork (iOS): restore program-date-time latency measurement (a prior rev measured distance to the manifest edge, reading ~0s and silently disabling high-latency recovery / chat-delay auto-sync); release platform views on dispose (per-stream view + AVPlayerViewController leak), track the observed AVPlayerItem for KVO removal (sibling-view crash), main-thread seek results, resolve superseded load futures
- Fork (Android): clean up method handlers orphaned by PiP-time view disposal (leaked audio-focus listeners), drop the live-offset re-anchoring seekTo on metadata updates (latency creep), restore pre-duck volume, respect user pause in the stall watchdog, resolve superseded load futures
- Deep review pass: expire the quality-switch flag so stall recovery isn't disabled for the session, cap latency-driven recovery (clock-skew loop), generation-guard the error overlay, two-strike offline confirmation, controller null-safety on quality switch
- Tighten `/me` local-echo match (no longer renders `/meow ...` as an action); clear pending send text on disconnect

## Web / docs
- Remove stale Cloudflare Images binding from `wrangler.jsonc` (covered by `images.unoptimized: true`)
- Correct `web/AGENTS.md` Cache Components claim (feature not enabled)
- Repo and agent config cleanup

## Test plan
- [x] `flutter analyze` — clean (frosty + plugin lib)
- [x] `flutter test` — 319/319 pass (adds `ChatLatencySync`, `StreamInfoPoller`, video timing invariants, `PlaybackAccessToken`, IRC tag parsing)
- [x] Android plugin Kotlin compiles against the bumped fork rev
- [ ] Native player plays live streams on iOS and Android
- [ ] Quality switching works and persists across channel reopens
- [ ] PiP enters/exits correctly; pause/resume toggle in PiP window works
- [ ] Audio-only mode does not crash on Android < API 31
- [ ] Sending under a long synced chat delay no longer shows a false "may not have been sent" error
- [ ] Long composer text reflows the message list (no input/message overlap)
- [ ] Multi-tab: adding a tab does not mark previous tab as unread
- [ ] Merged chat: Reply from user modal targets the correct tab's composer

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-13 17:06:24 -04:00
Tommy Chow
c27a37d52f fix recent messages by handling valueless and escaped irc tags
The recent-messages API now serializes empty IRCv3 tags as bare keys
(e.g. `emotes`) instead of `emotes=`, which threw a RangeError in the
tag parser and silently dropped every recent message. Parse tags per the
IRCv3 spec: treat bare and empty values as equivalent, split on the first
`=` so values may contain `=`, and unescape values in a single pass
(\: \s \ \r \n). Also guard user extraction against prefixes without
`!`, and isolate per-message parse failures in _handleIRCData so one bad
message can no longer abort an entire batch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 21:53:53 -07:00
Tommy Chow
89f8859ba3 add merged chat mode for multi-tab view
Merge only already-activated tabs; lazy tabs join when tapped. Dedup
messages by IRC id for Twitch shared chat overlap. Preserve draft and
reply state when switching tabs in merged mode. Merge button appears
only when 2+ tabs are loaded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:00:03 -08:00
Tommy Chow
96bce87a0e add FrostyColors ThemeExtension, align hardcoded colors with M3 roles
Introduce FrostyColors ThemeExtension with 7 semantic color fields
(highlightedMessage, emoteOnly, followersOnly, slowMode, subOnly,
uniqueMode, overlayOnSurface) and brightness-aware light/dark variants.

Replace hardcoded colors across 15 files:
- Links use colorScheme.primary instead of Colors.blue
- Mentions use colorScheme.error instead of Colors.red
- First-time chatters share highlightedMessage (Twitch purple)
- Chat mode indicators use frostyColors fields
- Overlay text uses frostyColors.overlayOnSurface

Remove Provider<FrostyThemes> pattern from main.dart, channel.dart,
video_overlay.dart, and frosty_photo_view_dialog.dart.

Replace manual onSurface.withValues(alpha: 0.6) with M3's built-in
onSurfaceVariant for secondary text in section headers, chat modes,
alerts, loading indicators, and input hints. Fix double-muted
onSurfaceVariant.withValues(alpha: 0.6) in navigation icons and
notification dismiss button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:01:44 -08:00
Tommy Chow
8f4ebde155
v5 (#463)
* migrate to dio

* ignore folders

* simplify twitch api headers handling

* clean up main

* simplify logs

* optimize profile picture fetching
fixes refetches on tab switch

* update claude md

* refactor irc.dart

* update copilot instructions with essential commands and project structure details

* implement message sending state management and UI updates

* refactor notification handling and add copy-paste functionality in chat

* refactor AlertMessage to support vertical layout and optional padding

* refactor error messages for consistency and clarity across various components

* refactor chat layout to use draggable divider and improve chat width settings

* refactor Uptime widget to use SharedTimerService for synchronized updates

* refactor search results components to handle null future states gracefully

* refactor loading indicators to use skeleton loaders for improved user experience

* refactor UI components for improved layout and responsiveness, enhance skeleton loaders, and streamline padding adjustments

* refactor: replace manual blur effects with BlurredContainer for consistency and reusability

* refactor: enhance JavaScript execution and error handling in WebView components

* refactor: replace app bar with blurred container for improved UI consistency across screens

* refactor: streamline video chat layout and enhance PiP drag gesture functionality

* revert some app bar changes

* refactor: implement Picture-in-Picture drag functionality in VideoChat

* refactor: pass currentChannelId to IRCMessage and ChatMessage for improved context

* fix large thubmnail width

* chore: update Gradle and Kotlin plugin versions for improved compatibility

* changes from v4.10.0 branch

* feat: integrate AnimatedScrollBorder for improved UI responsiveness across various screens

* refactor: update SectionHeader styling and improve theme management

* feat: add pinned section to StreamsList and enhance skeleton loader padding

* feat: add repository guidelines for project structure, coding style, testing, and security

* feat: enhance StreamCard UI with BlurredContainer and adjust border width in theme

* feat: implement unfocusInput and safeRequestFocus methods to manage text field focus behavior

* feat: enhance Picture-in-Picture drag interactions with haptic feedback and smooth animations

* refactor: improve code formatting and readability across multiple files

* feat: implement picture-in-picture mode toggle and state management for video playback

* feat: reset PiP mode state when pausing video playback

* feat: add custom app bar with profile picture and stream info for video chat

* feat: convert multiple settings screens to use StatefulWidget and add animated scroll borders

* feat: update blur configuration for adaptive alpha based on theme

* fix: adjust default font size in SectionHeader widget

* feat: enhance PiP mode with drag overlay instruction and UI improvements

* fix: improve badge rendering with consistent margin and border for current channel

* refactor: replace BackdropFilter with BlurredContainer for improved clarity and maintainability

* fix: reduce background transparency in Uptime widget for better visibility

* feat: enhance photo view dialog with full resolution toggle and blurred background

* fix: reset chat delay to 0 when auto sync is enabled and update settings title for clarity

* fix: adjust border width in theme to improve consistency

* feat: add forceDarkMode option to BlurredContainer for improved theme adaptability

* feat: implement offline followed channels feature with UI integration and settings option

* fix: increase font size and weight for offline status text for better readability

* feat: remove offline pinned channels feature and update related UI components

* feat: optimize offline channels loading behavior based on expansion state

* fix: improve clarity and consistency in repository guidelines formatting

* feat: update full resolution URL handling and button visibility logic

* feat: replace app bar with blurred version in chat-only mode and add animated scroll border

* feat: refactor video chat layout for improved chat and video display in landscape mode

* feat: remove bottom bar visibility setting and adjust chat layout accordingly

* fix: simplify condition for displaying offline channels section in following tab

* feat: enhance reply thread display with indentation and reply icon

* feat: implement showModalBottomSheetWithProperFocus for improved focus handling

* feat: add gradient direction support to BlurredContainer for enhanced visual effects

* feat: enhance NavigationBar and Theme settings for improved visual consistency

* feat: add gradient direction support to BlurredContainer in VideoChat for enhanced visual effects

* chore: update .gitignore to include .cursor file for better environment management

* fix: update PiP drag gesture conditions to include video paused state for better user experience

* refactor: replace ScrollController with SettingsPageLayout in settings screens for improved layout management

* refactor: centralize orientation handling by introducing OrientationUtils for improved readability and maintainability

* refactor: replace OrientationUtils with ContextExtensions for streamlined context-based access to theme, layout, and API dependencies

* refactor: improve video chat UI by adjusting title layout and adding stream info tooltips for better user experience

* refactor: adjust titleSpacing in theme and navigation components for improved layout consistency

* refactor: update stream info timer handling and overlay management for improved UI responsiveness

* refactor: enhance stream info timer logic and overlay visibility management for chat-only mode

* refactor: enhance input decoration theme in FrostyThemes for improved visual consistency and responsiveness

* refactor: adjust inputDecorationTheme padding in FrostyThemes for improved visual consistency

* refactor: enhance video overlay management by including video preview overlay in hideElements for improved UI consistency

* refactor: improve chat bottom bar padding and video chat layout for enhanced UI consistency

* refactor: adjust chat padding to account for device bottom insets for improved layout consistency

* refactor: update text styles in FrostyThemes for improved visual consistency across UI components

* refactor: update iOS minimum deployment target to 13.0 for improved compatibility

* refactor: adjust chat bottom padding based on emote menu visibility for improved layout consistency

* refactor: adjust padding values in StreamsList for improved layout consistency

* refactor: replace Padding with AnimatedPadding in Chat for smoother layout transitions
refactor: replace Container with AnimatedContainer in BlurredContainer for smoother animations

* refactor: remove unnecessary radius property from ProfilePicture in OfflineChannelCard for cleaner code

* refactor: enhance chat bottom bar suffix icon to display message delay with tooltip for improved user experience

* refactor: update hint text and tooltips in chat bottom bar and search for improved clarity

* refactor: simplify notification display logic and enhance chat input behavior for improved user experience

* refactor: enhance layout consistency by adjusting spacing in various components across the channel and home screens

* refactor: introduce LiveIndicator widget and adjust spacing in channel and video components for improved layout consistency

* refactor: remove monospace font family from chat bottom bar for improved text rendering

* refactor: reduce notification animation duration and change dismiss direction for improved user experience

* refactor: replace VideoBar with StreamInfoBar in video components for improved layout and consistency

* refactor: adjust font sizes and spacing in StreamInfoBar for improved layout consistency

* refactor: standardize font sizes and update gradient stops in video components for improved visual consistency

* refactor: update tooltip padding and background color in theme for improved visual consistency

* refactor: enhance tooltip behavior and standardize font sizes in StreamInfoBar and related components for improved visual consistency

* refactor: add showThumbnail option to LargeStreamCardSkeletonLoader for improved layout flexibility

* refactor: add StreamInfoBarSkeletonLoader for improved layout consistency in stream components

* refactor: add shadow effects to icons and text in StreamInfoBar and VideoOverlay for improved visual depth

* refactor: update defaultOverlayOpacity to 0.0 for improved overlay behavior

* fix: correct stream info text color on overlay

* refactor: implement a new color picker dialog with random color generation for enhanced user experience

* refactor: adjust gradient colors and stops in VideoOverlay for improved visual consistency

* refactor: refine gradient colors and stops in VideoOverlay for enhanced visual clarity

* refactor: add isCompact parameter to StreamInfoBar for responsive text sizing

* fix: update tooltip background color to use surface color for better contrast

* feat: add shared chat mode support in chat store and update StreamInfoBar for visual indication

* refactor: disable debug print for IRC messages to reduce log clutter

* feat: implement chat color selection feature with user color management in chat settings

* refactor: replace color adjustment logic with new contrast-aware utility for chat names

* refactor: simplify chat details UI by replacing list tiles with action cards and removing unused clear dialog

* refactor: enhance chat details UI by improving time formatting and adding label styling to action cards

* refactor: update chat color terminology to 'Username color' for clarity in UI

* refactor: enhance chat details UI by introducing active chat modes display and improving layout structure

* refactor: improve chat details layout by replacing ListTile with Padding and adding a Divider for better visual separation

* refactor: remove chat notifications positioning setting and adjust notification alignment in video chat

* refactor: streamline StreamInfoBar component by consolidating offline handling and improving layout for better readability

* refactor: enhance StreamInfoBar by adding tooltip for streamer name and improving text overflow handling

* refactor: adjust tooltip display duration in StreamInfoBar and update theme configuration

* refactor: adjust margin and padding in StreamCard for improved layout consistency

* chore: update dependencies in pubspec.yaml and pubspec.lock for Firebase and other packages

* template

* chore: update iOS platform version to 15.0 and Firebase dependencies to 12.2.0

* refactor: simplify StreamInfoBar layout by reducing nested widgets and improving text color handling

* format

* feat: enhance Channel model and StreamInfoBar to support offline channel details

* feat: add offline indicator and improve StreamInfoBar layout for better offline channel display

* fix: adjust icon color opacity in StreamInfoBar for improved visibility

* feat: enhance dismissal animation in FrostyPhotoViewDialog to track swipe direction

* docs: update copilot instructions for clarity and additional error handling details

* refactor: optimize latency tooltip layout and improve offline indicator styling in VideoOverlay

* feat: implement shared chat asset fetching and participant management in ChatAssetsStore

* refactor: replace Observer with Builder for improved widget rebuilding in VideoOverlay

* refactor: update StreamInfoBar border styling and adjust layout in VideoOverlay for improved visual consistency

* feat: add showTextShadows property to StreamInfoBar for customizable text shadow display

* refactor: adjust layout in VideoOverlay by adding padding to improve spacing and visual consistency

* refactor: enhance VideoOverlay gradients and layout for improved visual hierarchy and user experience

* refactor: reduce vertical padding in VideoOverlay for improved layout consistency

* refactor: remove overlay opacity settings from VideoSettings and SettingsStore for simplification

* refactor: improve text overlay transition in VideoChat for better user experience

* Revert "refactor: improve text overlay transition in VideoChat for better user experience"

This reverts commit fd16ff5ec3.

* refactor: wrap videoOverlay in ColoredBox for improved layout handling

* refactor: optimize animation duration and transition curves in VideoChat for smoother interactions

* refactor: dispose searchScrollController in HomeStoreBase to prevent memory leaks

* refactor: simplify gradient definitions in VideoOverlay for improved readability and maintainability

* refactor: remove 'Offline' text overlay from VideoOverlay for cleaner UI

* refactor: add refresh functionality for assets in ChatDetails with loading indicators

* refactor: update visibility conditions for uptime, viewer count, and category display in StreamInfoBar

* refactor: replace AlertDialog with FrostyDialog for consistent dialog styling across the application

* refactor: enhance layout handling in FrostyPageView to prevent overflow during height transitions

* refactor: replace ColorPickerDialog with AccentColorPickerDialog for improved color selection experience

* refactor: replace theme and accent color settings with dedicated components for improved modularity and readability

* refactor: replace ElevatedButton with TextButton for consistent button styling across dialogs

* refactor: integrate MobX Observer for reactive state management in settings widgets

* refactor: update theme and dialog components for improved styling and consistency

* refactor: enhance dialog styling with rounded corners and border in theme configuration

* refactor: improve dialog messages for unauthorized access handling

* refactor: update bodyLarge text style in theme configuration to include font weight

* refactor: standardize Divider usage and adjust theme styles for improved consistency

* refactor: adjust Divider properties and theme styles for enhanced visual consistency

* chore: remove GEMINI.md file as it is no longer needed for project documentation

* refactor: enhance token validation and reconnect logic in AuthBase for improved error handling

* format

* refactor: integrate landscape cutout settings into VideoChat layout for improved responsiveness

* refactor: implement app lifecycle handling in VideoChat and enhance stream info update logic in VideoStore

* refactor: update landscape cutout conditionals in VideoChat layout for improved responsiveness

* update AGENTS.md

* add scrollbar to search

* fix scrolling exception

* update CLAUDE.md

* 5 auth reconnect attemps then log out

* increase reply max lines to 2

* simplify and improve reply formatting

* add prime icon

* better draggable divider

* support draggable divider in fullscreen overlay chat

* add text shadow in fullscreen chat overlay mode

* format

* add landscape checks

* video store optimization attempts
* Dispose WebViewController and remove JavaScript channels properly
  * Track and cleanup all MutationObservers to prevent accumulation
  * Throttle latency updates to once per 5 seconds (reduces CPU load)
  * Add timeout protection and null checks for robustness
  * Prevent duplicate event listeners on page reloads

* double tap divider to reset

* Revert "video store optimization attempts"

This reverts commit b1df7b0de4.

* optimize video store attempt 2

* Revert "double tap divider to reset"

This reverts commit aeb26a4335.

* optimize latency listener to open the menu and check every 20 secconds

* more optimizations

* hard refresh

* abbreviate latency

* fix lint

* improve hide default overlay

* fix chat no longer reconnecting with chat delay

* refine chat alerts

* fix historical message missing badges and emotes on initial connection

* parallelize

* revert

* add reconnect button inline action

* refactor: replace Scrollbar with FrostyScrollbar across chat and settings screens for consistent styling

* tweak chat details menu

* add scrollbar to release notes, renames for consistency

* fix duplicate message case

* fix chat delay alerts in auto sync mode

* add regex for numeric strings and enhance display name formatting logic

* exterminate borders

* refactor: simplify active chat modes display in chat details screen

* feat: enhance chat input button with delay notification and disable state

* fix: wrap chat in SafeArea to prevent UI overflow issues

* refactor: remove divider line from video chat and update draggable divider visibility logic

* persist overlay in pip mode

* fix: update chat delay handling and notifications in chat bottom bar

* fix: update chat overlay visibility logic to respect fullscreen settings

* tap to show deleted message

* fix: prevent accidental chat scrolling when accessing system UI in landscape mode

* show latency in portrait

* fix: enhance chat delay notifications with dynamic delay time

* docs: update CLAUDE.md for improved environment variable instructions and architecture overview

* fix: improve chat delay countdown management and message handling

* add preliminary release notes

* remove agents.md

* update lockfile

* add initial multi chat feature

* add option to persist multi chat tabs

* add remove confirmation dialog

* improve add chat design

* lazy-load tabs

* create global assets store to dedupe global asset fetching

* improve tab design/styles

* update notes

* use frosty dialog

* update claude md

* tweak

* add ability to reorder tabs

* resolve conflict

* merge cleanup

* format

* update release notes

* add chat delay sync completion tracking to prevent countdown re-appearance

* add tests

* fix

* update release notes

* bump
2026-01-01 22:28:17 -05:00
Tommy Chow
224be878c6 gen file 2025-08-22 21:32:30 -07:00
Tommy Chow
6d15de707a
fix some channels missing 7tv emotes (#444)
* remove bang operator

* handle 7tv emotes that are being processed
2025-05-25 19:07:57 -07:00
Artiu
f72614afa7
Fix large cache size (#437)
* Add custom cache manager

* Fix

* Add cleanup

* Remove prints for debugging

* Remove unnecessary code

* Change nr of max cache objects
2025-04-06 19:58:37 -07:00
Tommy Chow
c7c85af6b4 improve link regex 2025-03-23 21:53:47 -07:00
Tommy Chow
1238867802 tweak shared chat source tooltip 2024-12-27 04:48:07 -05:00
Tommy Chow
045bb775ee fix incorrect badge order and spacing for ffz bots 2024-12-27 04:46:27 -05:00
Tommy Chow
f7f0f22bb5 middle-align new badges 2024-12-23 22:04:24 -05:00
Tommy Chow
80837beaa8 use badge for historical message indicator 2024-12-23 17:40:00 -05:00
Tommy Chow
817289a01d
add shared chat session support (#424)
* dispose overlay timer

* fix pip

* add channel indicators to messages for shared chat sessions

* add tooltip to chat message pfp

* remove tooltip marign/padding

* return null instead of throwing error

* fix build error
2024-12-23 16:05:07 -05:00
Tommy Chow
4f28408be6 use tabular figures for chat message timestamps 2024-12-23 15:28:38 -05:00
Tommy Chow
b9dae5df88 fix deprecated and lint warnings 2024-12-23 15:09:28 -05:00
Tommy Chow
ea8849a782 Switch to LaunchMode.inAppBrowserView
Uses Chrome Custom Tabs which has a better navigation menu.
2024-08-12 21:55:28 -07:00
Tommy Chow
1594d40f48
Add option to enable historical recent messages in chat (#374)
* Add initial support for recent messages

* Add setting for recent messages

* Add setting to onboarding

* Activate buffer after connecting

* Update copy

* Remove unnecessay future delayed

* Remove old line

* Prefer message buffer
2024-08-12 00:01:45 -07:00
Tommy Chow
a5cc7d8f3f
Add photo view for thumbnails, emotes, and badges (#372)
* Add photo view for emotes and badges

* Add photo view to stream thumbnails

* Remove dismissable and use close button

* Use cached network image provider

* Add dismissible
2024-08-11 12:57:24 -07:00
Tommy Chow
630a6725d1
Fix animated FFZ emotes not animating (#370)
Support animated FFZ emotes
2024-08-09 21:23:34 -07:00
Tommy Chow
387246635f
Add option to sync message delay with stream latency (#364)
* Run build_runner

* Add option to sync messsage delay with stream latency

* Add experimental labbel

* Hide seconds indicator in chat only mode

* Consistent casing
2024-08-03 15:00:31 -07:00
Tommy Chow
8fcb52f926 Fix onTapPingedUser not triggering due to commas 2023-12-20 23:45:31 -05:00
Tommy Chow
d61b938cbe Underline links in chat 2023-12-17 23:16:31 -05:00
Artiu
663b32b945
Add user mention clickability (#314)
* Add handle for clicking on user ping

* Add trailing coma
2023-12-17 21:47:44 -05:00
Tommy Chow
364b94411d Fix rare case where 7TV emotes don't show
7TV emotes are locked to 4x size, but if that doesn't exist an exception
is thrown. The lack of 4x size seems to
be caused by a new emote still in processing.
2023-11-30 17:59:43 -05:00
Tommy Chow
1a55bd2e63
Fix own display name not showing in chat (#309) 2023-11-30 17:23:09 -05:00
Tommy Chow
2801c6405b Fix missing username in sub notices 2023-11-28 14:41:02 -05:00
Tommy Chow
bdba3c08d2 Make Owner7TV nullable
Some emotes don't have an owner, causing parsing errors and resulting in
emotes not showing in chat.
2023-11-28 06:15:00 -05:00
Tommy Chow
04ac5346a6 Remove avatarUrl field from Owner7TV 2023-11-28 05:53:11 -05:00
Tommy Chow
9e91208555
Add support for 7TV and FFZ emote authors (#306) 2023-11-28 03:58:07 -05:00
Tommy Chow
8fab6bdbc9
Add support for 7TV emote update events (#305)
* Get 7TV emote set id

* Add initial support for 7TV emote set events in chat

* Add 7TV emote add/remove alerts in chat

* Add author to 7TV events
2023-11-28 03:21:05 -05:00
Tommy Chow
da491bdc50 Infer isLightTheme from provided context 2023-11-24 16:25:15 -05:00
Tommy Chow
b15ee89307 Use DefaultTextStyle & ListTile for reply box 2023-11-24 15:58:51 -05:00
Tommy Chow
b238e35b4c Fix emote copy name using full name 2023-11-21 01:42:32 -05:00
Tommy Chow
86324a4b22 Check and use proper flag for 7TV zero-width 2023-11-01 22:38:16 -04:00
Tommy Chow
1cb04bed2d
Fix 7TV zero-width emotes not working (#292)
Use flags to determine 7TV zero width emote
2023-11-01 18:16:57 -04:00
Tommy Chow
bc67aad670
Fix 7TV emotes not using custom names (#291)
* Fix 7TV emotes not using custom set names

* Show real name in emote details
2023-11-01 17:55:49 -04:00
Tommy Chow
a981cec250
Migrate 7TV emotes to V3 API (#287)
* Migrate 7TV global emotes to V3 API

* Migrate 7TV channel emotes to V3 API
2023-11-01 13:34:21 -04:00
Tommy Chow
00678129a8 Constrain badge details size 2023-10-23 22:33:14 -04:00
Tommy Chow
cba6600d5f
Add Twitch sub emotes to emote menu (#281)
* Fix subbed emotes not showing when enabling turbo emotes

* Add twitch channel emotes to emote menu

* Add ability to show emote details in emote menu

* Add haptic feedback

* Add emote details sheet to recent emotes

* Diisable chat logs
2023-10-23 11:52:04 -04:00
Tommy Chow
9a6892746d
Update to Material 3/You and other changes/fixes (#280)
* Use adaptive refresh indicators

* Add new message count indicator in chat

* Sync pubspec.lock

* Initial migration to material 3

* Restore default bottom sheet style

* Remove FrostyListTile and reset styles

* Use "Clear" button for all search history

* Add `require_trailing_commas` lint rule

* Exclude generated files from linter

* Use ListView for safe area support in bottom sheet

* Add initial dark theme

* Make sizing and units consistent

* Update onbaording spacings & copy

* Migrate to default material 3 buttons

* Add headers to chat details bottom sheet

* Simplify token log in method

* Use bottom sheet for account options

* Remove `AnimateScale` widget

* Tweak search paddings

* Update message spacing divisions

* Upgrade packages

* Update message spacing divisions

* Regenerate splash screens

* Update Inter & add google fonts

* Add initial material 3 themes

* Use adaptive alert dialogs

* Revert to oultined inputs

* Fix tooltip message

* Revert add google_fonts

* Improve themes and various styling

* Convert categories grid to list

* Tweak stream card thumbnail radii

* Tweak settings headers

* Left align floating snackbars

* Tweak search header padding

* Fix profile pics occasionally not rounded

* Use profile pic for settings button if logged in

* Redesign sleep timer

* Use divider theme and reduce thickness

* Use 0 letter spacing for tab bar titles

* Redesign category streams list

* Add border to tooltips

* Increase category card font weight

* Use outlined icon btton for chat user modal

* Reduce profile pic radius in search results

* Fix scrolll to top button safe area

* Add support for reply threads

* Reduce tooltip and snackbar border thickness

* Rebuild reply threads on new messages

* Upgrade packages (iOS)

* Reduce font weight for all chat alerts

* Use tabbars for pageview

* Add dividers everywhere

* Revert "Add dividers everywhere"

This reverts commit 5f0d349fdb.

* Remove fill from inputs

* Add dividers to settings

* Use segmented button for settings list

* Add scrollbar to lists with scrollcontroller

* Redesign badge/emote tooltip

* Remove outline from chat user modal buttons

* Remove divider from reply thread

* Use tap for chatters list and increase font weight

* Constrain emote tooltip width
2023-10-22 18:38:32 -04:00
Tommy
3af5406f60
Update linting and formatting rules (#261)
* Add new linting rules

* Apply new linting rules

* Fix dart sdk version

* Format code to 80 lines
2023-04-29 11:34:28 -04:00
Tommy
f17cef9523
Migrate to new Twitch badges endpoint (#256) 2023-04-11 08:52:18 -04:00
Tommy Chow
10a596a247 Fix FFZ emotes and badges no longer showing
Previously, emote and badge URLs from FFZ's API had the scheme
omitted. A recent update to the API has added these schemes, so we no
longer need to prepend it.
2023-03-05 05:23:06 -05:00
Tommy Chow
5d95843de8
Upgrade to Flutter 3.7.0 (#233)
* Rename `Badge` to `ChatBadge`
Flutter 3.7.0 adds a new `Badge` component that conflicts with the
existing badge widget.

* Fix new linting errors

* Upgrade packages
2023-01-26 23:56:16 -05:00
Tommy Chow
7881ce22b4
Improve design and usability, general tweaks and fixes (#226)
See #226 for more details.
2023-01-18 05:34:54 -05:00
Tommy Chow
d5e8d0c6c5 Enable zero width emotes by default 2022-09-08 16:04:13 -04:00
Tommy Chow
d4e9d82ee2 Simplify reply null check 2022-09-03 15:25:52 -04:00