frosty/lib/widgets/frosty_notification.dart
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

65 lines
1.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:frosty/widgets/blurred_container.dart';
class FrostyNotification extends StatelessWidget {
final String message;
final VoidCallback? onDismissed;
final bool showGradient;
const FrostyNotification({
super.key,
required this.message,
this.onDismissed,
this.showGradient = true,
});
@override
Widget build(BuildContext context) {
final Widget notificationContent = BlurredContainer(
gradientDirection: showGradient
? GradientDirection.up
: GradientDirection.none,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Row(
children: [
Expanded(
child: Row(
spacing: 8,
children: [
Icon(Icons.info_outline_rounded, size: 20),
Expanded(
child: Text(
message,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.w500),
),
),
],
),
),
if (onDismissed != null)
IconButton(
onPressed: onDismissed,
icon: const Icon(Icons.close_rounded, size: 20),
visualDensity: VisualDensity.compact,
tooltip: 'Dismiss',
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
],
),
);
// Make it dismissible with swipe gesture if onDismissed is provided
if (onDismissed != null) {
return Dismissible(
key: ValueKey(message),
onDismissed: (_) => onDismissed!(),
direction: DismissDirection.up,
child: notificationContent,
);
}
return notificationContent;
}
}