diff --git a/lib/screens/channel/video/native_video_store.dart b/lib/screens/channel/video/native_video_store.dart index 0d5a29bd..0ef29efd 100644 --- a/lib/screens/channel/video/native_video_store.dart +++ b/lib/screens/channel/video/native_video_store.dart @@ -11,7 +11,6 @@ import 'package:frosty/models/stream.dart'; import 'package:frosty/screens/channel/video/video_player_interface.dart'; import 'package:frosty/screens/settings/stores/auth_store.dart'; import 'package:frosty/screens/settings/stores/settings_store.dart'; -import 'package:frosty/services/cookie_extractor.dart'; import 'package:mobx/mobx.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -102,10 +101,8 @@ abstract class NativeVideoStoreBase with Store implements VideoPlayerInterface { @action Future _initPlayer() async { try { - // Prefer web cookie token (works with web Client-ID) for ad-free playback. - // Fall back to direct cookie extraction if AuthStore hasn't resolved it yet. - var authToken = authStore.gqlToken; - authToken ??= await CookieExtractor.extractTwitchAuthToken(); + // Use web cookie token (works with web Client-ID) for ad-free playback. + final authToken = authStore.gqlToken; late final PlaybackAccessToken token; try { token = await twitchGqlApi.getPlaybackAccessToken( diff --git a/lib/screens/settings/account/widgets/profile_card.dart b/lib/screens/settings/account/widgets/profile_card.dart index 7a55c3a5..169c2c71 100644 --- a/lib/screens/settings/account/widgets/profile_card.dart +++ b/lib/screens/settings/account/widgets/profile_card.dart @@ -39,13 +39,63 @@ class ProfileCard extends StatelessWidget { ); } if (authStore.isLoggedIn && authStore.user.details != null) { + final hasToken = authStore.gqlToken != null; return ListTile( leading: ProfilePicture( userLogin: authStore.user.details!.login, radius: 12, ), title: Text(authStore.user.details!.displayName), - trailing: const Icon(Icons.chevron_right_rounded), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + tooltip: hasToken + ? 'Web session linked' + : 'Web session not linked', + icon: Icon( + hasToken + ? Icons.check_circle_outline_rounded + : Icons.link_off_rounded, + size: 20, + color: hasToken ? Colors.green : null, + ), + onPressed: () { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Web session'), + content: Text( + hasToken + ? 'Your Twitch web session is linked. When using the native player, ads will be avoided on channels where you have a subscription or Twitch Turbo.' + : 'Your Twitch web session is not linked. Log in again to avoid ads when using the native player on channels where you have a subscription or Twitch Turbo.', + ), + actions: [ + if (!hasToken) + TextButton( + onPressed: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => LoginWebView(), + ), + ); + }, + child: const Text('Log in'), + ), + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('OK'), + ), + ], + ), + ); + }, + ), + const Icon(Icons.chevron_right_rounded), + ], + ), onTap: () => _showAccountOptionsModalBottomSheet(context), ); } diff --git a/lib/screens/settings/stores/auth_store.dart b/lib/screens/settings/stores/auth_store.dart index a302f7a8..2f985eab 100644 --- a/lib/screens/settings/stores/auth_store.dart +++ b/lib/screens/settings/stores/auth_store.dart @@ -275,9 +275,6 @@ abstract class AuthBase with Store { } } - // Try extracting a fresh GQL token from the WebView cookie store. - if (_isLoggedIn) await _extractGqlToken(); - FirebaseCrashlytics.instance.setCustomKey('is_logged_in', _isLoggedIn); _error = null; } catch (e) { diff --git a/lib/screens/settings/video_settings.dart b/lib/screens/settings/video_settings.dart index e54fec02..f7928a36 100644 --- a/lib/screens/settings/video_settings.dart +++ b/lib/screens/settings/video_settings.dart @@ -28,7 +28,7 @@ class VideoSettings extends StatelessWidget { SettingsListSwitch( title: 'Native player (experimental)', subtitle: const Text( - 'Uses a native video player with improved picture-in-picture.', + 'Native video player with auto picture-in-picture and quality selection.', ), value: settingsStore.useNativePlayer, onChanged: (newValue) =>