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>
105 lines
3.5 KiB
Dart
105 lines
3.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:frosty/apis/bttv_api.dart';
|
|
import 'package:frosty/apis/ffz_api.dart';
|
|
import 'package:frosty/apis/seventv_api.dart';
|
|
import 'package:frosty/apis/twitch_api.dart';
|
|
import 'package:frosty/screens/settings/stores/auth_store.dart';
|
|
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
|
import 'package:frosty/stores/global_assets_store.dart';
|
|
import 'package:frosty/theme.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
/// Static utility class for orientation-related operations
|
|
class OrientationUtils {
|
|
/// Gets the current orientation from the given context
|
|
static Orientation getCurrentOrientation(BuildContext context) {
|
|
return MediaQuery.of(context).orientation;
|
|
}
|
|
|
|
/// Returns true if the current orientation is portrait
|
|
static bool isPortrait(BuildContext context) {
|
|
return MediaQuery.of(context).orientation == Orientation.portrait;
|
|
}
|
|
|
|
/// Returns true if the current orientation is landscape
|
|
static bool isLandscape(BuildContext context) {
|
|
return MediaQuery.of(context).orientation == Orientation.landscape;
|
|
}
|
|
}
|
|
|
|
/// Comprehensive context extensions for common Flutter patterns
|
|
extension ContextExtensions on BuildContext {
|
|
// ===== THEME & STYLING =====
|
|
|
|
/// Gets the current theme
|
|
ThemeData get theme => Theme.of(this);
|
|
|
|
/// Gets the current color scheme
|
|
ColorScheme get colorScheme => Theme.of(this).colorScheme;
|
|
|
|
/// Gets the current text theme
|
|
TextTheme get textTheme => Theme.of(this).textTheme;
|
|
|
|
/// Gets the scaffold background color
|
|
Color get scaffoldColor => Theme.of(this).scaffoldBackgroundColor;
|
|
|
|
/// Gets body small text color (commonly used for secondary text)
|
|
Color? get bodySmallColor => Theme.of(this).textTheme.bodySmall?.color;
|
|
|
|
/// Gets the app's custom semantic colors
|
|
FrostyColors get frostyColors => Theme.of(this).extension<FrostyColors>()!;
|
|
|
|
/// Gets the default text style
|
|
TextStyle get defaultTextStyle => DefaultTextStyle.of(this).style;
|
|
|
|
// ===== SCREEN & LAYOUT =====
|
|
|
|
/// Gets the screen width
|
|
double get screenWidth => MediaQuery.of(this).size.width;
|
|
|
|
/// Gets the screen height
|
|
double get screenHeight => MediaQuery.of(this).size.height;
|
|
|
|
/// Gets the safe area padding top (commonly used)
|
|
double get safePaddingTop => MediaQuery.of(this).padding.top;
|
|
|
|
/// Gets the safe area padding bottom (commonly used)
|
|
double get safePaddingBottom => MediaQuery.of(this).padding.bottom;
|
|
|
|
// ===== PROVIDER ACCESS =====
|
|
|
|
/// Gets TwitchApi from provider
|
|
TwitchApi get twitchApi => read<TwitchApi>();
|
|
|
|
/// Gets AuthStore from provider
|
|
AuthStore get authStore => read<AuthStore>();
|
|
|
|
/// Gets SettingsStore from provider
|
|
SettingsStore get settingsStore => read<SettingsStore>();
|
|
|
|
/// Gets FFZApi from provider
|
|
FFZApi get ffzApi => read<FFZApi>();
|
|
|
|
/// Gets BTTVApi from provider
|
|
BTTVApi get bttvApi => read<BTTVApi>();
|
|
|
|
/// Gets SevenTVApi from provider
|
|
SevenTVApi get sevenTVApi => read<SevenTVApi>();
|
|
|
|
/// Gets GlobalAssetsStore from provider
|
|
GlobalAssetsStore get globalAssetsStore => read<GlobalAssetsStore>();
|
|
|
|
// ===== ORIENTATION =====
|
|
|
|
/// Returns true if currently in portrait orientation
|
|
bool get isPortrait => OrientationUtils.isPortrait(this);
|
|
|
|
/// Returns true if currently in landscape orientation
|
|
bool get isLandscape => OrientationUtils.isLandscape(this);
|
|
}
|
|
|
|
/// TextScaler extensions for common scaling operations
|
|
extension TextScalerExtensions on double {
|
|
/// Creates a linear text scaler with this scale factor
|
|
TextScaler get textScaler => TextScaler.linear(this);
|
|
}
|