You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			105 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Dart
		
	
import 'package:flutter/material.dart';
 | 
						|
 | 
						|
import 'package:collection/collection.dart';
 | 
						|
import 'package:dynamic_color/dynamic_color.dart';
 | 
						|
import 'package:provider/provider.dart';
 | 
						|
import 'package:shared_preferences/shared_preferences.dart';
 | 
						|
 | 
						|
import 'package:fluffychat/utils/color_value.dart';
 | 
						|
 | 
						|
class ThemeBuilder extends StatefulWidget {
 | 
						|
  final Widget Function(
 | 
						|
    BuildContext context,
 | 
						|
    ThemeMode themeMode,
 | 
						|
    Color? primaryColor,
 | 
						|
  ) builder;
 | 
						|
 | 
						|
  final String themeModeSettingsKey;
 | 
						|
  final String primaryColorSettingsKey;
 | 
						|
 | 
						|
  const ThemeBuilder({
 | 
						|
    required this.builder,
 | 
						|
    this.themeModeSettingsKey = 'theme_mode',
 | 
						|
    this.primaryColorSettingsKey = 'primary_color',
 | 
						|
    super.key,
 | 
						|
  });
 | 
						|
 | 
						|
  @override
 | 
						|
  State<ThemeBuilder> createState() => ThemeController();
 | 
						|
}
 | 
						|
 | 
						|
class ThemeController extends State<ThemeBuilder> {
 | 
						|
  SharedPreferences? _sharedPreferences;
 | 
						|
  ThemeMode? _themeMode;
 | 
						|
  Color? _primaryColor;
 | 
						|
 | 
						|
  ThemeMode get themeMode => _themeMode ?? ThemeMode.system;
 | 
						|
 | 
						|
  Color? get primaryColor => _primaryColor;
 | 
						|
 | 
						|
  static ThemeController of(BuildContext context) =>
 | 
						|
      Provider.of<ThemeController>(
 | 
						|
        context,
 | 
						|
        listen: false,
 | 
						|
      );
 | 
						|
 | 
						|
  void _loadData(_) async {
 | 
						|
    final preferences =
 | 
						|
        _sharedPreferences ??= await SharedPreferences.getInstance();
 | 
						|
 | 
						|
    final rawThemeMode = preferences.getString(widget.themeModeSettingsKey);
 | 
						|
    final rawColor = preferences.getInt(widget.primaryColorSettingsKey);
 | 
						|
 | 
						|
    setState(() {
 | 
						|
      _themeMode = ThemeMode.values
 | 
						|
          .singleWhereOrNull((value) => value.name == rawThemeMode);
 | 
						|
      _primaryColor = rawColor == null ? null : Color(rawColor);
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> setThemeMode(ThemeMode newThemeMode) async {
 | 
						|
    final preferences =
 | 
						|
        _sharedPreferences ??= await SharedPreferences.getInstance();
 | 
						|
    await preferences.setString(widget.themeModeSettingsKey, newThemeMode.name);
 | 
						|
    setState(() {
 | 
						|
      _themeMode = newThemeMode;
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> setPrimaryColor(Color? newPrimaryColor) async {
 | 
						|
    final preferences =
 | 
						|
        _sharedPreferences ??= await SharedPreferences.getInstance();
 | 
						|
    if (newPrimaryColor == null) {
 | 
						|
      await preferences.remove(widget.primaryColorSettingsKey);
 | 
						|
    } else {
 | 
						|
      await preferences.setInt(
 | 
						|
        widget.primaryColorSettingsKey,
 | 
						|
        newPrimaryColor.hexValue,
 | 
						|
      );
 | 
						|
    }
 | 
						|
    setState(() {
 | 
						|
      _primaryColor = newPrimaryColor;
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void initState() {
 | 
						|
    WidgetsBinding.instance.addPostFrameCallback(_loadData);
 | 
						|
    super.initState();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    return Provider(
 | 
						|
      create: (_) => this,
 | 
						|
      child: DynamicColorBuilder(
 | 
						|
        builder: (light, _) => widget.builder(
 | 
						|
          context,
 | 
						|
          themeMode,
 | 
						|
          primaryColor ?? light?.primary,
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |