feat: Implement color theme persistence and toggle functionality in ThemeCustomizer and ThemeEditorWidget
This commit is contained in:
parent
d208648350
commit
3c89b4ddbb
@ -1,5 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marco/helpers/services/json_decoder.dart';
|
import 'package:marco/helpers/services/json_decoder.dart';
|
||||||
import 'package:marco/helpers/services/localizations/language.dart';
|
import 'package:marco/helpers/services/localizations/language.dart';
|
||||||
import 'package:marco/helpers/services/localizations/translator.dart';
|
import 'package:marco/helpers/services/localizations/translator.dart';
|
||||||
@ -7,8 +7,8 @@ import 'package:marco/helpers/services/navigation_services.dart';
|
|||||||
import 'package:marco/helpers/theme/admin_theme.dart';
|
import 'package:marco/helpers/theme/admin_theme.dart';
|
||||||
import 'package:marco/helpers/theme/app_notifier.dart';
|
import 'package:marco/helpers/theme/app_notifier.dart';
|
||||||
import 'package:marco/helpers/theme/app_theme.dart';
|
import 'package:marco/helpers/theme/app_theme.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
typedef ThemeChangeCallback = void Function(
|
typedef ThemeChangeCallback = void Function(
|
||||||
ThemeCustomizer oldVal, ThemeCustomizer newVal);
|
ThemeCustomizer oldVal, ThemeCustomizer newVal);
|
||||||
@ -33,6 +33,8 @@ class ThemeCustomizer {
|
|||||||
|
|
||||||
static Future<void> init() async {
|
static Future<void> init() async {
|
||||||
await initLanguage();
|
await initLanguage();
|
||||||
|
await _loadColorTheme();
|
||||||
|
_notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
static initLanguage() async {
|
static initLanguage() async {
|
||||||
@ -40,7 +42,7 @@ class ThemeCustomizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String toJSON() {
|
String toJSON() {
|
||||||
return jsonEncode({'theme': theme.name});
|
return jsonEncode({'theme': theme.name, 'colorTheme': colorTheme.name});
|
||||||
}
|
}
|
||||||
|
|
||||||
static ThemeCustomizer fromJSON(String? json) {
|
static ThemeCustomizer fromJSON(String? json) {
|
||||||
@ -49,6 +51,8 @@ class ThemeCustomizer {
|
|||||||
JSONDecoder decoder = JSONDecoder(json);
|
JSONDecoder decoder = JSONDecoder(json);
|
||||||
instance.theme =
|
instance.theme =
|
||||||
decoder.getEnum('theme', ThemeMode.values, ThemeMode.light);
|
decoder.getEnum('theme', ThemeMode.values, ThemeMode.light);
|
||||||
|
instance.colorTheme = decoder.getEnum(
|
||||||
|
'colorTheme', ColorThemeType.values, ColorThemeType.red);
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@ -117,12 +121,46 @@ class ThemeCustomizer {
|
|||||||
tc.topBarTheme = topBarTheme;
|
tc.topBarTheme = topBarTheme;
|
||||||
tc.rightBarOpen = rightBarOpen;
|
tc.rightBarOpen = rightBarOpen;
|
||||||
tc.leftBarCondensed = leftBarCondensed;
|
tc.leftBarCondensed = leftBarCondensed;
|
||||||
|
tc.colorTheme = colorTheme;
|
||||||
tc.currentLanguage = currentLanguage.clone();
|
tc.currentLanguage = currentLanguage.clone();
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'ThemeCustomizer{theme: $theme}';
|
return 'ThemeCustomizer{theme: $theme, colorTheme: $colorTheme}';
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// 🟢 Color Theme Persistence
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static const _colorThemeKey = 'color_theme_type';
|
||||||
|
|
||||||
|
/// Save selected color theme
|
||||||
|
static Future<void> saveColorTheme(ColorThemeType type) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setString(_colorThemeKey, type.name);
|
||||||
|
instance.colorTheme = type;
|
||||||
|
_notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load saved color theme (called at startup)
|
||||||
|
static Future<void> _loadColorTheme() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final savedType = prefs.getString(_colorThemeKey);
|
||||||
|
if (savedType != null) {
|
||||||
|
instance.colorTheme = ColorThemeType.values.firstWhere(
|
||||||
|
(e) => e.name == savedType,
|
||||||
|
orElse: () => ColorThemeType.red,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change color theme & persist
|
||||||
|
static Future<void> changeColorTheme(ColorThemeType type) async {
|
||||||
|
oldInstance = instance.clone();
|
||||||
|
instance.colorTheme = type;
|
||||||
|
await saveColorTheme(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'package:marco/helpers/widgets/my_text.dart';
|
|||||||
import 'package:marco/helpers/widgets/wave_background.dart';
|
import 'package:marco/helpers/widgets/wave_background.dart';
|
||||||
import 'package:marco/helpers/theme/admin_theme.dart';
|
import 'package:marco/helpers/theme/admin_theme.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:marco/helpers/theme/theme_customizer.dart';
|
||||||
|
import 'package:flutter_lucide/flutter_lucide.dart';
|
||||||
|
|
||||||
class ThemeOption {
|
class ThemeOption {
|
||||||
final String label;
|
final String label;
|
||||||
@ -105,7 +106,20 @@ class _ThemeEditorWidgetState extends State<ThemeEditorWidget> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
ThemeCustomizer.setTheme(
|
||||||
|
ThemeCustomizer.instance.theme == ThemeMode.dark
|
||||||
|
? ThemeMode.light
|
||||||
|
: ThemeMode.dark);
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
ThemeCustomizer.instance.theme == ThemeMode.dark
|
||||||
|
? LucideIcons.sun
|
||||||
|
: LucideIcons.moon,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
// Theme cards wrapped in reactive Obx widget
|
// Theme cards wrapped in reactive Obx widget
|
||||||
Center(
|
Center(
|
||||||
child: Obx(
|
child: Obx(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user