diff --git a/lib/app/data/providers/secure_storage_provider.dart b/lib/app/data/providers/secure_storage_provider.dart index 3e8ea00f..27c36e8e 100644 --- a/lib/app/data/providers/secure_storage_provider.dart +++ b/lib/app/data/providers/secure_storage_provider.dart @@ -95,7 +95,9 @@ class SecureStorageProvider { Future readThemeValue() async { String themeValue = await _secureStorage.read(key: 'theme_value') ?? 'AppTheme.dark'; - return themeValue == 'AppTheme.dark' ? AppTheme.dark : AppTheme.light; + return themeValue == 'AppTheme.dark' ? AppTheme.dark + : themeValue == 'AppTheme.light' ? AppTheme.light + : AppTheme.system; } Future writeThemeValue({ diff --git a/lib/app/modules/settings/controllers/theme_controller.dart b/lib/app/modules/settings/controllers/theme_controller.dart index 5774e31d..72f25a27 100644 --- a/lib/app/modules/settings/controllers/theme_controller.dart +++ b/lib/app/modules/settings/controllers/theme_controller.dart @@ -1,3 +1,5 @@ +import 'dart:ui'; + import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:ultimate_alarm_clock/app/data/providers/secure_storage_provider.dart'; @@ -5,23 +7,17 @@ import 'package:ultimate_alarm_clock/app/utils/constants.dart'; class ThemeController extends GetxController { final _secureStorageProvider = SecureStorageProvider(); + Brightness platformBrightness = Brightness.dark; + bool isSystemTheme = false; @override void onInit() { _loadThemeValue(); - updateThemeColors(); super.onInit(); } Rx currentTheme = ThemeMode.system.obs; - void switchTheme() { - currentTheme.value = currentTheme.value == ThemeMode.light - ? ThemeMode.dark - : ThemeMode.light; - updateThemeColors(); - } - Rx primaryColor = kprimaryColor.obs; Rx secondaryColor = kLightSecondaryColor.obs; Rx primaryBackgroundColor = kLightPrimaryBackgroundColor.obs; @@ -51,25 +47,41 @@ class ThemeController extends GetxController { } void _loadThemeValue() async { - currentTheme.value = - await _secureStorageProvider.readThemeValue() == AppTheme.light - ? ThemeMode.light - : ThemeMode.dark; + AppTheme theme = await _secureStorageProvider.readThemeValue(); + currentTheme.value = getCurrentTheme(theme == AppTheme.light ? ThemeMode.light + : theme == AppTheme.dark ? ThemeMode.dark + : ThemeMode.system, + ); updateThemeColors(); Get.changeThemeMode(currentTheme.value); } void _saveThemeValuePreference() async { await _secureStorageProvider.writeThemeValue( - theme: currentTheme.value == ThemeMode.light - ? AppTheme.light + theme: isSystemTheme ? AppTheme.system + : currentTheme.value == ThemeMode.light ? AppTheme.light : AppTheme.dark, ); } - void toggleThemeValue(bool enabled) { - currentTheme.value = enabled ? ThemeMode.light : ThemeMode.dark; + void toggleThemeValue(ThemeMode mode) { + currentTheme.value = getCurrentTheme(mode); updateThemeColors(); _saveThemeValuePreference(); + Get.changeThemeMode(currentTheme.value); + } + + getCurrentTheme(ThemeMode mode){ + ThemeMode theme; + if (mode == ThemeMode.system){ + isSystemTheme = true; + platformBrightness = Get.mediaQuery.platformBrightness; + theme = platformBrightness == Brightness.light ? ThemeMode.light + : ThemeMode.dark; + }else{ + isSystemTheme = false; + theme = mode; + } + return theme; } } diff --git a/lib/app/modules/settings/views/theme_value_tile.dart b/lib/app/modules/settings/views/theme_value_tile.dart index 589daf24..c3c6a5b0 100644 --- a/lib/app/modules/settings/views/theme_value_tile.dart +++ b/lib/app/modules/settings/views/theme_value_tile.dart @@ -5,7 +5,7 @@ import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_cont import 'package:ultimate_alarm_clock/app/utils/constants.dart'; import 'package:ultimate_alarm_clock/app/utils/utils.dart'; -class ThemeValueTile extends StatefulWidget { +class ThemeValueTile extends StatelessWidget { const ThemeValueTile({ super.key, required this.controller, @@ -20,52 +20,65 @@ class ThemeValueTile extends StatefulWidget { final double height; final double width; - @override - State createState() => _ThemeValueTileState(); -} - -class _ThemeValueTileState extends State { - @override - void initState() { - super.initState(); - } + final themes = const [MapEntry('dark', 'Dark Theme'), + MapEntry('light', 'Light Theme'), + MapEntry('system', 'System Theme'),]; @override Widget build(BuildContext context) { + ThemeMode theme = themeController.currentTheme.value; return Obx( () => Container( - width: widget.width * 0.91, - height: widget.height * 0.1, + width: width * 0.91, + height: height * 0.1, decoration: Utils.getCustomTileBoxDecoration( isLightMode: - widget.themeController.currentTheme.value == ThemeMode.light, + themeController.currentTheme.value == ThemeMode.light, ), child: Padding( padding: EdgeInsets.only(left: 30, right: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - 'Enable Light Mode'.tr, - style: Theme.of(context).textTheme.bodyLarge, + child: Obx( + () => DropdownMenu( + menuStyle: MenuStyle( + backgroundColor: MaterialStatePropertyAll( + themeController.secondaryBackgroundColor.value, ), ), - Obx( - () => Switch.adaptive( - value: widget.themeController.currentTheme.value == - ThemeMode.light, - activeColor: ksecondaryColor, - onChanged: (bool value) async { - widget.themeController.toggleThemeValue(value); - Get.changeThemeMode( - widget.themeController.currentTheme.value, - ); - Utils.hapticFeedback(); - }, - ), + inputDecorationTheme: + const InputDecorationTheme(enabledBorder: InputBorder.none), + trailingIcon: Icon( + Icons.arrow_drop_down_outlined, + size: 40.0, + color: themeController.primaryTextColor.value + .withOpacity(0.8), ), - ], + width: width * 0.78, + initialSelection: themeController.isSystemTheme ? themes[2].key + : theme == ThemeMode.dark ? themes[0].key + : themes[1].key, + label: const Text('Select Theme'), + dropdownMenuEntries: themes.map((e) { + return DropdownMenuEntry( + value: e.key, + label: e.value, + style: ButtonStyle( + foregroundColor: MaterialStatePropertyAll( + themeController.primaryTextColor.value, + ), + ), + ); + }).toList(), + onSelected: (newValue) { + if (newValue == themes[0].key) { + themeController.toggleThemeValue(ThemeMode.dark); + } else if (newValue == themes[1].key) { + themeController.toggleThemeValue(ThemeMode.light); + } else { + themeController.toggleThemeValue(ThemeMode.system); + } + Utils.hapticFeedback(); + }, + ), ), ), ), diff --git a/lib/app/utils/constants.dart b/lib/app/utils/constants.dart index 6e203ef5..de0d0e80 100644 --- a/lib/app/utils/constants.dart +++ b/lib/app/utils/constants.dart @@ -4,7 +4,7 @@ enum ApiKeys { openWeatherMap, } -enum AppTheme { light, dark } +enum AppTheme { light, dark, system } enum Status { initialized, ongoing, completed }