diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 6850c31d00..5d632ca78a 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:device_apps/device_apps.dart'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_i18n/widgets/I18nText.dart'; @@ -33,6 +34,7 @@ class ManagerAPI { Patch? selectedPatch; BuildContext? ctx; bool isRooted = false; + bool isDynamicThemeAvailable = false; String storedPatchesFile = '/selected-patches.json'; String keystoreFile = '/sdcard/Android/data/app.revanced.manager.flutter/files/revanced-manager.keystore'; @@ -59,10 +61,16 @@ class ManagerAPI { Future initialize() async { _prefs = await SharedPreferences.getInstance(); isRooted = await _rootAPI.isRooted(); + isDynamicThemeAvailable = (await getSdkVersion()) >= 31; // ANDROID_12_SDK_VERSION = 31 storedPatchesFile = (await getApplicationDocumentsDirectory()).path + storedPatchesFile; } + Future getSdkVersion() async { + final AndroidDeviceInfo info = await DeviceInfoPlugin().androidInfo; + return info.version.sdkInt; + } + String getApiUrl() { return _prefs.getString('apiUrl') ?? defaultApiUrl; } diff --git a/lib/ui/views/settings/settingsFragment/settings_update_theme.dart b/lib/ui/views/settings/settingsFragment/settings_update_theme.dart index 1d15a1680f..66fa683094 100644 --- a/lib/ui/views/settings/settingsFragment/settings_update_theme.dart +++ b/lib/ui/views/settings/settingsFragment/settings_update_theme.dart @@ -6,46 +6,98 @@ import 'package:flutter/services.dart'; import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/services/manager_api.dart'; -import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; -import 'package:stacked/stacked.dart'; -final _settingViewModel = SettingsViewModel(); +class SUpdateThemeUI extends StatefulWidget { + const SUpdateThemeUI({super.key}); -// ignore: constant_identifier_names -const int ANDROID_12_SDK_VERSION = 31; + @override + State createState() => _SUpdateThemeUIState(); +} -class SUpdateTheme extends BaseViewModel { - final ManagerAPI _managerAPI = locator(); +class _SUpdateThemeUIState extends State { + final ManagerAPI managerAPI = locator(); + + @override + Widget build(BuildContext context) { + return SettingsSection( + title: 'settingsView.appearanceSectionTitle', + children: [ + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), + title: I18nText( + 'settingsView.themeModeLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + ), + trailing: CustomMaterialButton( + label: getThemeModeName(), + onPressed: () => {showThemeDialog(context)}, + ), + onTap: () => {showThemeDialog(context)}, + ), + if (managerAPI.isDynamicThemeAvailable) + SwitchListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), + title: I18nText( + 'settingsView.dynamicThemeLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + ), + subtitle: I18nText('settingsView.dynamicThemeHint'), + value: getDynamicThemeStatus(), + onChanged: (value) => { + setUseDynamicTheme( + context, + value, + ), + }, + ), + ], + ); + } bool getDynamicThemeStatus() { - return _managerAPI.getUseDynamicTheme(); + return managerAPI.getUseDynamicTheme(); } Future setUseDynamicTheme(BuildContext context, bool value) async { - await _managerAPI.setUseDynamicTheme(value); + await managerAPI.setUseDynamicTheme(value); final int currentTheme = (DynamicTheme.of(context)!.themeId ~/ 2) * 2; await DynamicTheme.of(context)!.setTheme(currentTheme + (value ? 1 : 0)); - notifyListeners(); + setState(() {}); } int getThemeMode() { - return _managerAPI.getThemeMode(); + return managerAPI.getThemeMode(); } Future setThemeMode(BuildContext context, int value) async { - await _managerAPI.setThemeMode(value); + await managerAPI.setThemeMode(value); final bool isDynamicTheme = DynamicTheme.of(context)!.themeId.isEven; - await DynamicTheme.of(context)!.setTheme(value * 2 + (isDynamicTheme ? 0 : 1)); - final bool isLight = value != 2 && (value == 1 || DynamicTheme.of(context)!.theme.brightness == Brightness.light); + await DynamicTheme.of(context)! + .setTheme(value * 2 + (isDynamicTheme ? 0 : 1)); + final bool isLight = value != 2 && + (value == 1 || + DynamicTheme.of(context)!.theme.brightness == Brightness.light); SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( systemNavigationBarIconBrightness: - isLight ? Brightness.dark : Brightness.light, + isLight ? Brightness.dark : Brightness.light, ), ); - notifyListeners(); + setState(() {}); } I18nText getThemeModeName() { @@ -131,63 +183,3 @@ class SUpdateTheme extends BaseViewModel { ); } } - -final sUpdateTheme = SUpdateTheme(); -class SUpdateThemeUI extends StatelessWidget { - const SUpdateThemeUI({super.key}); - - @override - Widget build(BuildContext context) { - return SettingsSection( - title: 'settingsView.appearanceSectionTitle', - children: [ - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.themeModeLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - trailing: CustomMaterialButton( - label: sUpdateTheme.getThemeModeName(), - onPressed: () => { sUpdateTheme.showThemeDialog(context) }, - ), - onTap: () => { sUpdateTheme.showThemeDialog(context) }, - ), - FutureBuilder( - future: _settingViewModel.getSdkVersion(), - builder: (context, snapshot) => Visibility( - visible: - snapshot.hasData && snapshot.data! >= ANDROID_12_SDK_VERSION, - child: SwitchListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.dynamicThemeLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - subtitle: I18nText('settingsView.dynamicThemeHint'), - value: _settingViewModel.sUpdateTheme.getDynamicThemeStatus(), - onChanged: (value) => { - _settingViewModel.sUpdateTheme.setUseDynamicTheme( - context, - value, - ), - }, - ), - ), - ), - ], - ); - } -} diff --git a/lib/ui/views/settings/settings_viewmodel.dart b/lib/ui/views/settings/settings_viewmodel.dart index 409d44ce3d..bc3988e646 100644 --- a/lib/ui/views/settings/settings_viewmodel.dart +++ b/lib/ui/views/settings/settings_viewmodel.dart @@ -1,6 +1,5 @@ import 'dart:io'; import 'package:cr_file_saver/file_saver.dart'; -import 'package:device_info_plus/device_info_plus.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -14,7 +13,6 @@ import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_language.dart'; -import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_theme.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; import 'package:share_extend/share_extend.dart'; import 'package:stacked/stacked.dart'; @@ -29,7 +27,6 @@ class SettingsViewModel extends BaseViewModel { final Toast _toast = locator(); final SUpdateLanguage sUpdateLanguage = SUpdateLanguage(); - final SUpdateTheme sUpdateTheme = SUpdateTheme(); void navigateToContributors() { _navigationService.navigateTo(Routes.contributorsView); @@ -256,11 +253,6 @@ class SettingsViewModel extends BaseViewModel { _toast.showBottom('settingsView.resetStoredPatches'); } - Future getSdkVersion() async { - final AndroidDeviceInfo info = await DeviceInfoPlugin().androidInfo; - return info.version.sdkInt; - } - Future deleteLogs() async { final Directory appCacheDir = await getTemporaryDirectory(); final Directory logsDir = Directory('${appCacheDir.path}/logs');