| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- import 'package:flutter/foundation.dart';
- import 'package:flutter/material.dart';
- import 'package:shared_preferences/shared_preferences.dart';
- import 'theme_notifier.dart';
- import '../l10n/app_localizations.dart';
- /// Seasonal theme system for ZenTap
- enum SeasonalTheme {
- automatic('automatic'),
- default_('default'),
- spring('spring'),
- summer('summer'),
- autumn('autumn'),
- winter('winter');
- const SeasonalTheme(this.id);
- final String id;
- static SeasonalTheme fromId(String id) {
- return SeasonalTheme.values.firstWhere(
- (theme) => theme.id == id,
- orElse: () => SeasonalTheme.automatic,
- );
- }
- }
- /// Theme color scheme for each season
- class SeasonalColors {
- final Color appBackground;
- final Color secondaryBackground;
- final Color primaryText;
- final Color secondaryText;
- final Color mutedText;
- final Color buttonBackground;
- final Color buttonText;
- final Color uiElements;
- final Color gameBoardBorder;
- final Color bubbleDefault;
- final Color bubblePopEffect;
- final Color scoreText;
- final Color timerText;
- final Color links;
- final Color linkHover;
- final Color selectedMenuItem;
- // Animation colors
- final List<Color> animationLayer1;
- final List<Color> animationLayer2;
- final List<Color> animationLayer3;
- final List<Color> zenModeColors;
- const SeasonalColors({
- required this.appBackground,
- required this.secondaryBackground,
- required this.primaryText,
- required this.secondaryText,
- required this.mutedText,
- required this.buttonBackground,
- required this.buttonText,
- required this.uiElements,
- required this.gameBoardBorder,
- required this.bubbleDefault,
- required this.bubblePopEffect,
- required this.scoreText,
- required this.timerText,
- required this.links,
- required this.linkHover,
- required this.selectedMenuItem,
- required this.animationLayer1,
- required this.animationLayer2,
- required this.animationLayer3,
- required this.zenModeColors,
- });
- }
- class ThemeManager {
- static const String _keySelectedTheme = 'selected_theme';
- static SharedPreferences? _prefs;
- static SeasonalTheme _currentTheme = SeasonalTheme.automatic;
- static Future<void> init() async {
- _prefs = await SharedPreferences.getInstance();
- final themeId = _prefs?.getString(_keySelectedTheme) ?? 'automatic';
- _currentTheme = SeasonalTheme.fromId(themeId);
- ThemeNotifier().initFromManager();
- }
- static SeasonalTheme get currentTheme => _currentTheme;
- static Future<void> setTheme(SeasonalTheme theme) async {
- _currentTheme = theme;
- await _prefs?.setString(_keySelectedTheme, theme.id);
- ThemeNotifier().setTheme(theme);
- }
- /// Detect current season based on date
- static SeasonalTheme _detectCurrentSeason() {
- final now = DateTime.now();
- final month = now.month;
- final day = now.day;
- // Northern hemisphere seasons
- if ((month == 3 && day >= 20) ||
- month == 4 ||
- month == 5 ||
- (month == 6 && day < 21)) {
- return SeasonalTheme.spring; // March 20 - June 20
- } else if ((month == 6 && day >= 21) ||
- month == 7 ||
- month == 8 ||
- (month == 9 && day < 22)) {
- return SeasonalTheme.summer; // June 21 - September 21
- } else if ((month == 9 && day >= 22) ||
- month == 10 ||
- month == 11 ||
- (month == 12 && day < 21)) {
- return SeasonalTheme.autumn; // September 22 - December 20
- } else {
- return SeasonalTheme.winter; // December 21 - March 19
- }
- }
- /// Get the effective theme (resolves automatic to actual season)
- static SeasonalTheme get effectiveTheme {
- if (_currentTheme == SeasonalTheme.automatic) {
- return _detectCurrentSeason();
- }
- return _currentTheme;
- }
- /// Get the auto-detected season (regardless of current theme setting)
- static SeasonalTheme get autoDetectedSeason {
- return _detectCurrentSeason();
- }
- /// Get the current theme's color scheme
- static SeasonalColors get colors {
- final theme = effectiveTheme;
- switch (theme) {
- case SeasonalTheme.spring:
- return _springColors;
- case SeasonalTheme.summer:
- return _summerColors;
- case SeasonalTheme.autumn:
- return _autumnColors;
- case SeasonalTheme.winter:
- return _winterColors;
- case SeasonalTheme.default_:
- return _defaultColors;
- case SeasonalTheme.automatic:
- // This should never happen since effectiveTheme resolves it
- return _detectCurrentSeason() == SeasonalTheme.spring
- ? _springColors
- : _detectCurrentSeason() == SeasonalTheme.summer
- ? _summerColors
- : _detectCurrentSeason() == SeasonalTheme.autumn
- ? _autumnColors
- : _winterColors;
- }
- }
- /// Get theme display name
- static String getThemeDisplayName(SeasonalTheme theme, BuildContext context) {
- final l10n = AppLocalizations.of(context)!;
- switch (theme) {
- case SeasonalTheme.automatic:
- return l10n.automaticTheme;
- case SeasonalTheme.default_:
- return l10n.defaultTheme;
- case SeasonalTheme.spring:
- return l10n.springTheme;
- case SeasonalTheme.summer:
- return l10n.summerTheme;
- case SeasonalTheme.autumn:
- return l10n.autumnTheme;
- case SeasonalTheme.winter:
- return l10n.winterTheme;
- }
- }
- /// Get theme icon
- static IconData getThemeIcon(SeasonalTheme theme) {
- switch (theme) {
- case SeasonalTheme.automatic:
- return Icons.auto_mode;
- case SeasonalTheme.default_:
- return Icons.contrast;
- case SeasonalTheme.spring:
- return Icons.local_florist;
- case SeasonalTheme.summer:
- return Icons.wb_sunny;
- case SeasonalTheme.autumn:
- return Icons.park;
- case SeasonalTheme.winter:
- return Icons.ac_unit;
- }
- }
- /// Get available themes for selection (excluding default in release mode)
- static List<SeasonalTheme> get availableThemes {
- return SeasonalTheme.values.where((theme) {
- // Hide default theme in release builds
- if (!kDebugMode && theme == SeasonalTheme.default_) {
- return false;
- }
- return true;
- }).toList();
- }
- /// Default fSociety theme (current colors)
- static const SeasonalColors _defaultColors = SeasonalColors(
- appBackground: Color(0xFF000000),
- secondaryBackground: Color(0xFF0A0A0A),
- primaryText: Color(0xFFFFFFFF),
- secondaryText: Color(0xDEFFFFFF),
- mutedText: Color(0xFF808080),
- buttonBackground: Color(0xFF0BC2F9),
- buttonText: Color(0xFFFFFFFF),
- uiElements: Color(0xFF808080),
- gameBoardBorder: Color(0xFF808080),
- bubbleDefault: Color(0xFF646CFF),
- bubblePopEffect: Color(0xFFFF0000),
- scoreText: Color(0xFFFFFFFF),
- timerText: Color(0xDEFFFFFF),
- links: Color(0xFF000080),
- linkHover: Color(0xFFFF0000),
- selectedMenuItem: Color(0xFFFFFFFF),
- animationLayer1: [Color(0x33808080), Colors.transparent],
- animationLayer2: [Color(0x1AFF0000), Colors.transparent],
- animationLayer3: [Color(0x0D0BC2F9), Colors.transparent],
- zenModeColors: [Color(0x4D000080), Colors.transparent],
- );
- /// Spring theme - Fresh greens and soft pastels
- static const SeasonalColors _springColors = SeasonalColors(
- appBackground: Color(0xFF0A1A0A), // Dark forest green
- secondaryBackground: Color(0xFF1A2A1A),
- primaryText: Color(0xFFE8F5E8), // Light mint
- secondaryText: Color(0xDEE8F5E8),
- mutedText: Color(0xFF7FB069), // Soft green
- buttonBackground: Color(0xFF8FBC8F), // Dark sea green
- buttonText: Color(0xFF0A1A0A),
- uiElements: Color(0xFF556B2F), // Dark olive green
- gameBoardBorder: Color(0xFF6B8E23),
- bubbleDefault: Color(0xFF98FB98), // Pale green
- bubblePopEffect: Color(0xFFFFB6C1), // Light pink
- scoreText: Color(0xFFE8F5E8),
- timerText: Color(0xDEE8F5E8),
- links: Color(0xFF228B22), // Forest green
- linkHover: Color(0xFFFF69B4), // Hot pink
- selectedMenuItem: Color(0xFFE8F5E8),
- animationLayer1: [Color(0x3398FB98), Colors.transparent], // Pale green
- animationLayer2: [Color(0x1AFFB6C1), Colors.transparent], // Light pink
- animationLayer3: [Color(0x0D7FB069), Colors.transparent], // Soft green
- zenModeColors: [Color(0x4D228B22), Colors.transparent], // Forest green
- );
- /// Summer theme - Bright blues and warm yellows
- static const SeasonalColors _summerColors = SeasonalColors(
- appBackground: Color(0xFF0A0A2A), // Deep navy
- secondaryBackground: Color(0xFF1A1A3A),
- primaryText: Color(0xFFF0F8FF), // Alice blue
- secondaryText: Color(0xDEF0F8FF),
- mutedText: Color(0xFF87CEEB), // Sky blue
- buttonBackground: Color(0xFFFFD700), // Gold
- buttonText: Color(0xFF0A0A2A),
- uiElements: Color(0xFF4682B4), // Steel blue
- gameBoardBorder: Color(0xFF5F9EA0),
- bubbleDefault: Color(0xFF00BFFF), // Deep sky blue
- bubblePopEffect: Color(0xFFFF6347), // Tomato
- scoreText: Color(0xFFF0F8FF),
- timerText: Color(0xDEF0F8FF),
- links: Color(0xFF1E90FF), // Dodger blue
- linkHover: Color(0xFFFF4500), // Orange red
- selectedMenuItem: Color(0xFFF0F8FF),
- animationLayer1: [Color(0x33FFD700), Colors.transparent], // Gold
- animationLayer2: [Color(0x1AFFFF00), Colors.transparent], // Yellow
- animationLayer3: [Color(0x0DFFA500), Colors.transparent], // Orange
- zenModeColors: [Color(0x4D1E90FF), Colors.transparent], // Dodger blue
- );
- /// Autumn theme - Warm oranges, reds, and browns
- static const SeasonalColors _autumnColors = SeasonalColors(
- appBackground: Color(0xFF2A1A0A), // Dark brown
- secondaryBackground: Color(0xFF3A2A1A),
- primaryText: Color(0xFFFFF8DC), // Cornsilk
- secondaryText: Color(0xDEFFF8DC),
- mutedText: Color(0xFFDEB887), // Burlywood
- buttonBackground: Color(0xFFD2691E), // Chocolate
- buttonText: Color(0xFFFFF8DC),
- uiElements: Color(0xFF8B4513), // Saddle brown
- gameBoardBorder: Color(0xFFA0522D),
- bubbleDefault: Color(0xFFFF7F50), // Coral
- bubblePopEffect: Color(0xFFDC143C), // Crimson
- scoreText: Color(0xFFFFF8DC),
- timerText: Color(0xDEFFF8DC),
- links: Color(0xFFB22222), // Fire brick
- linkHover: Color(0xFFFF4500), // Orange red
- selectedMenuItem: Color(0xFFFFF8DC),
- animationLayer1: [Color(0x33FF7F50), Colors.transparent], // Coral
- animationLayer2: [Color(0x1ADC143C), Colors.transparent], // Crimson
- animationLayer3: [Color(0x0DDEB887), Colors.transparent], // Burlywood
- zenModeColors: [Color(0x4DB22222), Colors.transparent], // Fire brick
- );
- /// Winter theme - Cool blues and icy whites
- static const SeasonalColors _winterColors = SeasonalColors(
- appBackground: Color(0xFF0A1A2A), // Dark slate blue
- secondaryBackground: Color(0xFF1A2A3A),
- primaryText: Color(0xFFF0F8FF), // Alice blue
- secondaryText: Color(0xDEF0F8FF),
- mutedText: Color(0xFFB0C4DE), // Light steel blue
- buttonBackground: Color(0xFF6495ED), // Cornflower blue
- buttonText: Color(0xFF0A1A2A),
- uiElements: Color(0xFF708090), // Slate gray
- gameBoardBorder: Color(0xFF778899),
- bubbleDefault: Color(0xFF87CEFA), // Light sky blue
- bubblePopEffect: Color(0xFFFFFFFF), // White
- scoreText: Color(0xFFF0F8FF),
- timerText: Color(0xDEF0F8FF),
- links: Color(0xFF4169E1), // Royal blue
- linkHover: Color(0xFF00CED1), // Dark turquoise
- selectedMenuItem: Color(0xFFF0F8FF),
- animationLayer1: [Color(0x3387CEFA), Colors.transparent], // Light sky blue
- animationLayer2: [Color(0x1AFFFFFF), Colors.transparent], // White
- animationLayer3: [
- Color(0x0DB0C4DE),
- Colors.transparent,
- ], // Light steel blue
- zenModeColors: [Color(0x4D4169E1), Colors.transparent], // Royal blue
- );
- }
|