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>
This commit is contained in:
parent
59f5d2cb81
commit
96bce87a0e
19 changed files with 158 additions and 84 deletions
|
|
@ -164,20 +164,17 @@ class _MyAppState extends State<MyApp> {
|
|||
colorSchemeSeed: Color(settingsStore.accentColor),
|
||||
);
|
||||
|
||||
return Provider<FrostyThemes>(
|
||||
create: (_) => themes,
|
||||
child: MaterialApp(
|
||||
title: 'Frosty',
|
||||
theme: themes.light,
|
||||
darkTheme: themes.dark,
|
||||
themeMode: settingsStore.themeType == ThemeType.system
|
||||
? ThemeMode.system
|
||||
: settingsStore.themeType == ThemeType.light
|
||||
? ThemeMode.light
|
||||
: ThemeMode.dark,
|
||||
home: widget.firstRun ? const OnboardingIntro() : const Home(),
|
||||
navigatorKey: navigatorKey,
|
||||
),
|
||||
return MaterialApp(
|
||||
title: 'Frosty',
|
||||
theme: themes.light,
|
||||
darkTheme: themes.dark,
|
||||
themeMode: settingsStore.themeType == ThemeType.system
|
||||
? ThemeMode.system
|
||||
: settingsStore.themeType == ThemeType.light
|
||||
? ThemeMode.light
|
||||
: ThemeMode.dark,
|
||||
home: widget.firstRun ? const OnboardingIntro() : const Home(),
|
||||
navigatorKey: navigatorKey,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -442,8 +442,9 @@ class IRCMessage {
|
|||
bool launchExternal,
|
||||
TextStyle? textStyle,
|
||||
void Function(String)? onTapPingedUser,
|
||||
void Function()? onTapDeletedMessage,
|
||||
) {
|
||||
void Function()? onTapDeletedMessage, {
|
||||
Color? linkColor,
|
||||
}) {
|
||||
if (!showMessage) {
|
||||
span.add(
|
||||
TextSpan(
|
||||
|
|
@ -493,6 +494,7 @@ class IRCMessage {
|
|||
emoteScale,
|
||||
textStyle,
|
||||
launchExternal,
|
||||
linkColor: linkColor,
|
||||
);
|
||||
} else {
|
||||
localSpan.add(
|
||||
|
|
@ -524,6 +526,7 @@ class IRCMessage {
|
|||
_createTextSpan(
|
||||
text: word,
|
||||
style: textStyle,
|
||||
linkColor: linkColor,
|
||||
launchExternal: launchExternal,
|
||||
onTapPingedUser: onTapPingedUser,
|
||||
),
|
||||
|
|
@ -550,8 +553,9 @@ class IRCMessage {
|
|||
double emoteSize,
|
||||
double emoteScale,
|
||||
TextStyle? textStyle,
|
||||
bool launchExternal,
|
||||
) {
|
||||
bool launchExternal, {
|
||||
Color? linkColor,
|
||||
}) {
|
||||
final emoteStack = <Emote>[];
|
||||
var index = startIndex;
|
||||
|
||||
|
|
@ -631,6 +635,7 @@ class IRCMessage {
|
|||
_createTextSpan(
|
||||
text: words[index],
|
||||
style: textStyle,
|
||||
linkColor: linkColor,
|
||||
launchExternal: launchExternal,
|
||||
),
|
||||
);
|
||||
|
|
@ -661,6 +666,7 @@ class IRCMessage {
|
|||
final emoteToObject = assetsStore.emoteToObject;
|
||||
final badgeSize = defaultBadgeSize * badgeScale;
|
||||
final emoteSize = defaultEmoteSize * emoteScale;
|
||||
final linkColor = Theme.of(context).colorScheme.primary;
|
||||
|
||||
// The span list that will be used to render the chat message
|
||||
final span = <InlineSpan>[];
|
||||
|
|
@ -702,6 +708,7 @@ class IRCMessage {
|
|||
textStyle,
|
||||
onTapPingedUser,
|
||||
onTapDeletedMessage,
|
||||
linkColor: linkColor,
|
||||
);
|
||||
|
||||
return span;
|
||||
|
|
@ -810,6 +817,7 @@ class IRCMessage {
|
|||
required String text,
|
||||
required bool launchExternal,
|
||||
TextStyle? style,
|
||||
Color? linkColor,
|
||||
Function(String)? onTapPingedUser,
|
||||
}) {
|
||||
if (text.startsWith('@')) {
|
||||
|
|
@ -827,9 +835,9 @@ class IRCMessage {
|
|||
return TextSpan(
|
||||
text: text,
|
||||
style: style?.copyWith(
|
||||
color: Colors.blue,
|
||||
color: linkColor,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: Colors.blue,
|
||||
decorationColor: linkColor,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => launchUrl(
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import 'package:frosty/utils/context_extensions.dart';
|
|||
import 'package:frosty/widgets/blurred_container.dart';
|
||||
import 'package:frosty/widgets/draggable_divider.dart';
|
||||
import 'package:frosty/widgets/frosty_notification.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:simple_pip_mode/actions/pip_actions_layout.dart';
|
||||
import 'package:simple_pip_mode/pip_widget.dart';
|
||||
|
||||
|
|
@ -445,11 +444,7 @@ class _VideoChatState extends State<VideoChat>
|
|||
).dark,
|
||||
child: DefaultTextStyle(
|
||||
style: context.defaultTextStyle.copyWith(
|
||||
color: context
|
||||
.watch<FrostyThemes>()
|
||||
.dark
|
||||
.colorScheme
|
||||
.onSurface,
|
||||
color: context.frostyColors.overlayOnSurface,
|
||||
),
|
||||
child: landscapeChat,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:frosty/models/irc.dart';
|
||||
import 'package:frosty/utils/context_extensions.dart';
|
||||
|
||||
class ChatModes extends StatelessWidget {
|
||||
final ROOMSTATE roomState;
|
||||
|
|
@ -27,7 +28,7 @@ class ChatModes extends StatelessWidget {
|
|||
label: 'Emote only',
|
||||
activeLabel: 'Emote only',
|
||||
isActive: true,
|
||||
activeColor: const Color(0xFFFFB74D), // Slightly lighter orange
|
||||
activeColor: context.frostyColors.emoteOnly,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -44,7 +45,7 @@ class ChatModes extends StatelessWidget {
|
|||
label: 'Follower only',
|
||||
activeLabel: 'Follower only',
|
||||
isActive: true,
|
||||
activeColor: const Color(0xFFF44336), // Bright red
|
||||
activeColor: context.frostyColors.followersOnly,
|
||||
duration: _getFollowersDuration(),
|
||||
),
|
||||
),
|
||||
|
|
@ -62,7 +63,7 @@ class ChatModes extends StatelessWidget {
|
|||
label: 'Slow mode',
|
||||
activeLabel: 'Slow mode',
|
||||
isActive: true,
|
||||
activeColor: const Color(0xFF2196F3), // Bright blue
|
||||
activeColor: context.frostyColors.slowMode,
|
||||
duration: _getSlowModeDuration(),
|
||||
),
|
||||
),
|
||||
|
|
@ -80,7 +81,7 @@ class ChatModes extends StatelessWidget {
|
|||
label: 'Sub only',
|
||||
activeLabel: 'Sub only',
|
||||
isActive: true,
|
||||
activeColor: const Color(0xFF4CAF50), // Bright green
|
||||
activeColor: context.frostyColors.subOnly,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -97,7 +98,7 @@ class ChatModes extends StatelessWidget {
|
|||
label: 'Unique mode',
|
||||
activeLabel: 'Unique mode',
|
||||
isActive: true,
|
||||
activeColor: const Color(0xFFAB47BC), // Slightly lighter purple
|
||||
activeColor: context.frostyColors.uniqueMode,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -170,7 +171,7 @@ class ChatModes extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.6),
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import 'package:frosty/models/irc.dart';
|
|||
import 'package:frosty/screens/channel/chat/stores/chat_store.dart';
|
||||
import 'package:frosty/screens/channel/chat/widgets/chat_user_modal.dart';
|
||||
import 'package:frosty/screens/channel/chat/widgets/reply_thread.dart';
|
||||
import 'package:frosty/utils/context_extensions.dart';
|
||||
import 'package:frosty/utils/modal_bottom_sheet.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
@ -252,7 +253,7 @@ class ChatMessage extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
} else if (shouldHighlightFirstMessage) {
|
||||
highlightColor = Colors.purple;
|
||||
highlightColor = context.frostyColors.highlightedMessage;
|
||||
messageHeaderIcon = Icon(
|
||||
Icons.auto_awesome_rounded,
|
||||
size: messageHeaderIconSize,
|
||||
|
|
@ -266,7 +267,7 @@ class ChatMessage extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
} else if (shouldHighlightMessage) {
|
||||
highlightColor = const Color(0xff9146ff);
|
||||
highlightColor = context.frostyColors.highlightedMessage;
|
||||
messageHeader = Text(
|
||||
'Highlighted message',
|
||||
style: TextStyle(
|
||||
|
|
@ -277,7 +278,7 @@ class ChatMessage extends StatelessWidget {
|
|||
}
|
||||
|
||||
// If user is being mentioned in the message, highlight it red.
|
||||
if (ircMessage.mention == true) highlightColor = Colors.red;
|
||||
if (ircMessage.mention == true) highlightColor = context.colorScheme.error;
|
||||
|
||||
if (messageHeader != null) {
|
||||
renderMessage = Column(
|
||||
|
|
@ -401,7 +402,7 @@ class ChatMessage extends StatelessWidget {
|
|||
break;
|
||||
case Command.userNotice:
|
||||
if (chatStore.settings.showUserNotices) {
|
||||
highlightColor = const Color(0xff9146ff);
|
||||
highlightColor = context.frostyColors.highlightedMessage;
|
||||
Widget? messageHeaderIcon;
|
||||
Widget? messageHeader;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import 'package:frosty/widgets/section_header.dart';
|
|||
import 'package:frosty/widgets/uptime.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:native_device_orientation/native_device_orientation.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// Creates a widget containing controls which enable interactions with an underlying [Video] widget.
|
||||
|
|
@ -51,11 +50,7 @@ class VideoOverlay extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final surfaceColor = context
|
||||
.watch<FrostyThemes>()
|
||||
.dark
|
||||
.colorScheme
|
||||
.onSurface;
|
||||
final surfaceColor = context.frostyColors.overlayOnSurface;
|
||||
|
||||
final backButton = IconButton(
|
||||
tooltip: 'Back',
|
||||
|
|
|
|||
|
|
@ -165,9 +165,7 @@ class _HomeState extends State<Home> {
|
|||
Icons.favorite_border_rounded,
|
||||
color: _homeStore.selectedIndex == 0
|
||||
? theme.colorScheme.onSurface
|
||||
: theme.colorScheme.onSurfaceVariant.withValues(
|
||||
alpha: 0.6,
|
||||
),
|
||||
: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
selectedIcon: Icon(
|
||||
Icons.favorite_rounded,
|
||||
|
|
@ -183,9 +181,7 @@ class _HomeState extends State<Home> {
|
|||
_homeStore.selectedIndex ==
|
||||
(_authStore.isLoggedIn ? 1 : 0)
|
||||
? theme.colorScheme.onSurface
|
||||
: theme.colorScheme.onSurfaceVariant.withValues(
|
||||
alpha: 0.6,
|
||||
),
|
||||
: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
selectedIcon: Icon(
|
||||
Icons.arrow_upward_rounded,
|
||||
|
|
@ -201,9 +197,7 @@ class _HomeState extends State<Home> {
|
|||
_homeStore.selectedIndex ==
|
||||
(_authStore.isLoggedIn ? 2 : 1)
|
||||
? theme.colorScheme.onSurface
|
||||
: theme.colorScheme.onSurfaceVariant.withValues(
|
||||
alpha: 0.6,
|
||||
),
|
||||
: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
selectedIcon: Icon(
|
||||
Icons.search_rounded,
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import 'package:frosty/models/stream.dart';
|
|||
import 'package:frosty/screens/channel/channel.dart';
|
||||
import 'package:frosty/screens/home/top/categories/category_streams.dart';
|
||||
import 'package:frosty/screens/settings/stores/auth_store.dart';
|
||||
import 'package:frosty/theme.dart';
|
||||
import 'package:frosty/utils.dart';
|
||||
import 'package:frosty/utils/context_extensions.dart';
|
||||
import 'package:frosty/utils/modal_bottom_sheet.dart';
|
||||
import 'package:frosty/widgets/frosty_cached_network_image.dart';
|
||||
import 'package:frosty/widgets/frosty_photo_view_dialog.dart';
|
||||
|
|
@ -111,11 +111,7 @@ class StreamCard extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: context
|
||||
.watch<FrostyThemes>()
|
||||
.dark
|
||||
.colorScheme
|
||||
.onSurface,
|
||||
color: context.frostyColors.overlayOnSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:frosty/screens/onboarding/onboarding_scaffold.dart';
|
|||
import 'package:frosty/screens/onboarding/onboarding_welcome.dart';
|
||||
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
||||
import 'package:frosty/screens/settings/widgets/settings_list_switch.dart';
|
||||
import 'package:frosty/utils/context_extensions.dart';
|
||||
import 'package:frosty/widgets/accent_color_setting.dart';
|
||||
import 'package:frosty/widgets/theme_selection_setting.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
|
@ -40,10 +41,10 @@ class OnboardingSetup extends StatelessWidget {
|
|||
children: [
|
||||
TextSpan(
|
||||
text: 'https://recent-messages.robotty.de/',
|
||||
style: const TextStyle(
|
||||
color: Colors.blue,
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.primary,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: Colors.blue,
|
||||
decorationColor: context.colorScheme.primary,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => launchUrl(
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ class BlockedUsers extends StatelessWidget {
|
|||
return ListTile(
|
||||
title: Text(displayName),
|
||||
trailing: TextButton(
|
||||
style: TextButton.styleFrom(foregroundColor: Colors.red),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
onPressed: () => authStore.showBlockDialog(
|
||||
context,
|
||||
targetUser: displayName,
|
||||
|
|
|
|||
|
|
@ -320,10 +320,10 @@ class _ChatSettingsState extends State<ChatSettings> {
|
|||
children: [
|
||||
TextSpan(
|
||||
text: 'https://recent-messages.robotty.de/',
|
||||
style: const TextStyle(
|
||||
color: Colors.blue,
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.primary,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: Colors.blue,
|
||||
decorationColor: context.colorScheme.primary,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => launchUrl(
|
||||
|
|
|
|||
|
|
@ -11,6 +11,90 @@ const kOverlayShadow = [
|
|||
),
|
||||
];
|
||||
|
||||
/// App-specific semantic colors that extend Material's [ColorScheme].
|
||||
///
|
||||
/// Colors that map to Material 3 roles use [ColorScheme] directly:
|
||||
/// - Links → [ColorScheme.primary]
|
||||
/// - Mentions → [ColorScheme.error]
|
||||
/// - First-time chatters → [ColorScheme.tertiary]
|
||||
///
|
||||
/// Access via `Theme.of(context).extension<FrostyColors>()!` or the
|
||||
/// `context.frostyColors` convenience extension.
|
||||
class FrostyColors extends ThemeExtension<FrostyColors> {
|
||||
final Color highlightedMessage;
|
||||
final Color emoteOnly;
|
||||
final Color followersOnly;
|
||||
final Color slowMode;
|
||||
final Color subOnly;
|
||||
final Color uniqueMode;
|
||||
final Color overlayOnSurface;
|
||||
|
||||
const FrostyColors({
|
||||
required this.highlightedMessage,
|
||||
required this.emoteOnly,
|
||||
required this.followersOnly,
|
||||
required this.slowMode,
|
||||
required this.subOnly,
|
||||
required this.uniqueMode,
|
||||
required this.overlayOnSurface,
|
||||
});
|
||||
|
||||
static const light = FrostyColors(
|
||||
highlightedMessage: Color(0xff9146ff),
|
||||
emoteOnly: Color(0xFFFFB74D),
|
||||
followersOnly: Color(0xFFF44336),
|
||||
slowMode: Color(0xFF2196F3),
|
||||
subOnly: Color(0xFF4CAF50),
|
||||
uniqueMode: Color(0xFFAB47BC),
|
||||
overlayOnSurface: Colors.white,
|
||||
);
|
||||
|
||||
static const dark = FrostyColors(
|
||||
highlightedMessage: Color(0xff9146ff),
|
||||
emoteOnly: Color(0xFFFFCC80),
|
||||
followersOnly: Color(0xFFE57373),
|
||||
slowMode: Color(0xFF64B5F6),
|
||||
subOnly: Color(0xFF81C784),
|
||||
uniqueMode: Color(0xFFBA68C8),
|
||||
overlayOnSurface: Colors.white,
|
||||
);
|
||||
|
||||
@override
|
||||
FrostyColors copyWith({
|
||||
Color? highlightedMessage,
|
||||
Color? emoteOnly,
|
||||
Color? followersOnly,
|
||||
Color? slowMode,
|
||||
Color? subOnly,
|
||||
Color? uniqueMode,
|
||||
Color? overlayOnSurface,
|
||||
}) {
|
||||
return FrostyColors(
|
||||
highlightedMessage: highlightedMessage ?? this.highlightedMessage,
|
||||
emoteOnly: emoteOnly ?? this.emoteOnly,
|
||||
followersOnly: followersOnly ?? this.followersOnly,
|
||||
slowMode: slowMode ?? this.slowMode,
|
||||
subOnly: subOnly ?? this.subOnly,
|
||||
uniqueMode: uniqueMode ?? this.uniqueMode,
|
||||
overlayOnSurface: overlayOnSurface ?? this.overlayOnSurface,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FrostyColors lerp(FrostyColors? other, double t) {
|
||||
if (other is! FrostyColors) return this;
|
||||
return FrostyColors(
|
||||
highlightedMessage: Color.lerp(highlightedMessage, other.highlightedMessage, t)!,
|
||||
emoteOnly: Color.lerp(emoteOnly, other.emoteOnly, t)!,
|
||||
followersOnly: Color.lerp(followersOnly, other.followersOnly, t)!,
|
||||
slowMode: Color.lerp(slowMode, other.slowMode, t)!,
|
||||
subOnly: Color.lerp(subOnly, other.subOnly, t)!,
|
||||
uniqueMode: Color.lerp(uniqueMode, other.uniqueMode, t)!,
|
||||
overlayOnSurface: Color.lerp(overlayOnSurface, other.overlayOnSurface, t)!,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FrostyThemes {
|
||||
final Color colorSchemeSeed;
|
||||
|
||||
|
|
@ -38,6 +122,11 @@ class FrostyThemes {
|
|||
const borderWidth = 0.5;
|
||||
|
||||
return ThemeData(
|
||||
extensions: [
|
||||
colorScheme.brightness == Brightness.dark
|
||||
? FrostyColors.dark
|
||||
: FrostyColors.light,
|
||||
],
|
||||
colorScheme: colorScheme,
|
||||
fontFamily: 'Inter',
|
||||
splashFactory: Platform.isIOS ? NoSplash.splashFactory : null,
|
||||
|
|
@ -66,7 +155,7 @@ class FrostyThemes {
|
|||
filled: true,
|
||||
fillColor: colorScheme.surfaceContainerHighest.withValues(alpha: 0.6),
|
||||
hintStyle: TextStyle(
|
||||
color: colorScheme.onSurface.withValues(alpha: 0.6),
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ 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
|
||||
|
|
@ -45,6 +46,9 @@ extension ContextExtensions on BuildContext {
|
|||
/// 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ class AlertMessage extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final defaultColor = Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withValues(alpha: vertical ? 0.6 : 1);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final defaultColor =
|
||||
vertical ? colorScheme.onSurfaceVariant : colorScheme.onSurface;
|
||||
|
||||
final Widget widget;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class ExpandableSectionHeader extends StatelessWidget {
|
|||
duration: const Duration(milliseconds: 200),
|
||||
child: Icon(
|
||||
Icons.keyboard_arrow_down,
|
||||
color: context.colorScheme.onSurface.withValues(alpha: 0.6),
|
||||
color: context.colorScheme.onSurfaceVariant,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -44,9 +44,7 @@ class FrostyNotification extends StatelessWidget {
|
|||
icon: const Icon(Icons.close_rounded, size: 20),
|
||||
visualDensity: VisualDensity.compact,
|
||||
tooltip: 'Dismiss',
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant.withValues(alpha: 0.6),
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frosty/cache_manager.dart';
|
||||
import 'package:frosty/theme.dart';
|
||||
import 'package:frosty/utils/context_extensions.dart';
|
||||
import 'package:frosty/widgets/blurred_container.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class FrostyPhotoViewDialog extends StatefulWidget {
|
||||
final String imageUrl;
|
||||
|
|
@ -180,7 +179,7 @@ class _FrostyPhotoViewDialogState extends State<FrostyPhotoViewDialog>
|
|||
child: IconButton(
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
color: context.watch<FrostyThemes>().dark.colorScheme.onSurface,
|
||||
color: context.frostyColors.overlayOnSurface,
|
||||
),
|
||||
onPressed: Navigator.of(context).pop,
|
||||
),
|
||||
|
|
@ -205,11 +204,7 @@ class _FrostyPhotoViewDialogState extends State<FrostyPhotoViewDialog>
|
|||
child: Text(
|
||||
_isFullResolution ? 'View thumbnail' : 'View original',
|
||||
style: TextStyle(
|
||||
color: context
|
||||
.watch<FrostyThemes>()
|
||||
.dark
|
||||
.colorScheme
|
||||
.onSurface,
|
||||
color: context.frostyColors.overlayOnSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@ class LoadingIndicator extends StatelessWidget {
|
|||
Text(
|
||||
subtitle!,
|
||||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.5),
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class SectionHeader extends StatelessWidget {
|
|||
fontSize: fontSize ?? 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.5,
|
||||
color: context.colorScheme.onSurface.withValues(alpha: 0.6),
|
||||
color: context.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue