From 69fdd3d3d64e37db198208b0864a7d48d26649ec Mon Sep 17 00:00:00 2001 From: nahnah Date: Wed, 11 Feb 2026 19:28:56 +0000 Subject: [PATCH] [imp]: Improvement in settings's architecture --- ...screen.dart => app_management_screen.dart} | 142 ++++++++++++++++-- lib/screens/settings_screen.dart | 133 +++------------- 2 files changed, 147 insertions(+), 128 deletions(-) rename lib/screens/{update_settings_screen.dart => app_management_screen.dart} (66%) diff --git a/lib/screens/update_settings_screen.dart b/lib/screens/app_management_screen.dart similarity index 66% rename from lib/screens/update_settings_screen.dart rename to lib/screens/app_management_screen.dart index 7351cb2..9418714 100644 --- a/lib/screens/update_settings_screen.dart +++ b/lib/screens/app_management_screen.dart @@ -1,6 +1,9 @@ import 'dart:io'; import 'package:android_intent_plus/android_intent.dart'; +import 'package:florid/providers/settings_provider.dart'; +import 'package:florid/services/update_check_service.dart'; +import 'package:florid/widgets/m_list.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -8,22 +11,18 @@ import 'package:material_symbols_icons/symbols.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:provider/provider.dart'; -import '../providers/settings_provider.dart'; -import '../services/update_check_service.dart'; -import '../widgets/m_list.dart'; +class AppManagementScreen extends StatefulWidget { + const AppManagementScreen({super.key}); -class UpdateSettingsScreen extends StatefulWidget { - const UpdateSettingsScreen({super.key}); - - @override - State createState() => _UpdateSettingsScreenState(); -} - -class _UpdateSettingsScreenState extends State { static const MethodChannel _batteryChannel = MethodChannel( 'florid/battery_optimizations', ); + @override + State createState() => _AppManagementScreenState(); +} + +class _AppManagementScreenState extends State { bool? _isIgnoringBatteryOptimizations; @override @@ -32,12 +31,59 @@ class _UpdateSettingsScreenState extends State { _loadBatteryOptimizationStatus(); } + String _installMethodLabel(InstallMethod method) { + switch (method) { + case InstallMethod.shizuku: + return 'Shizuku'; + case InstallMethod.system: + return 'System installer'; + } + } + + Future _showInstallMethodDialog( + BuildContext context, + SettingsProvider settings, + ) async { + await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Installation method'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: InstallMethod.values + .map( + (method) => RadioListTile( + value: method, + groupValue: settings.installMethod, + title: Text(_installMethodLabel(method)), + subtitle: method == InstallMethod.shizuku + ? const Text('Requires Shizuku to be running') + : const Text('Uses the standard system installer'), + onChanged: (value) async { + if (value == null) return; + await settings.setInstallMethod(value); + if (!context.mounted) return; + Navigator.of(context).pop(); + }, + ), + ) + .toList(), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Close'), + ), + ], + ), + ); + } + Future _loadBatteryOptimizationStatus() async { if (!Platform.isAndroid) return; try { - final isIgnoring = await _batteryChannel.invokeMethod( - 'isIgnoringBatteryOptimizations', - ); + final isIgnoring = await AppManagementScreen._batteryChannel + .invokeMethod('isIgnoringBatteryOptimizations'); if (!mounted) return; setState(() { _isIgnoringBatteryOptimizations = isIgnoring ?? false; @@ -173,7 +219,7 @@ class _UpdateSettingsScreenState extends State { return Consumer( builder: (context, settings, _) { return Scaffold( - appBar: AppBar(title: const Text('Update settings')), + appBar: AppBar(title: const Text('App Management')), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), @@ -181,6 +227,72 @@ class _UpdateSettingsScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, spacing: 16, children: [ + Column( + spacing: 4, + children: [ + MListHeader(title: 'Installation method'), + MRadioListView( + items: InstallMethod.values + .map( + (method) => MRadioListItemData( + title: _installMethodLabel(method), + subtitle: method == InstallMethod.shizuku + ? 'Requires Shizuku to be running' + : 'Uses the standard system installer', + value: method, + ), + ) + .toList(), + groupValue: settings.installMethod, + onChanged: (value) async { + await settings.setInstallMethod(value); + }, + ), + ], + ), + + Column( + spacing: 4, + children: [ + MListHeader(title: 'Downloads & Storage'), + MListView( + items: [ + MListItemData( + title: 'Auto-install after download', + onTap: () { + settings.setAutoInstallApk( + !settings.autoInstallApk, + ); + }, + subtitle: + 'Install APKs automatically once download finishes', + suffix: Switch( + value: settings.autoInstallApk, + onChanged: (value) { + settings.setAutoInstallApk(value); + }, + ), + ), + MListItemData( + title: 'Delete APK after install', + onTap: () { + settings.setAutoInstallApk( + !settings.autoInstallApk, + ); + }, + subtitle: + 'Remove installer files after successful installation', + suffix: Switch( + value: settings.autoDeleteApk, + onChanged: (value) { + settings.setAutoDeleteApk(value); + }, + ), + ), + ], + ), + ], + ), Column( spacing: 4, children: [ diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 329c6da..8499c6c 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:florid/l10n/app_localizations.dart'; +import 'package:florid/screens/app_management_screen.dart'; import 'package:florid/widgets/m_list.dart'; import 'package:flutter/material.dart'; import 'package:material_symbols_icons/symbols.dart'; @@ -18,9 +19,7 @@ import '../providers/settings_provider.dart'; import '../screens/appearance_screen.dart'; import '../screens/repositories_screen.dart'; import '../screens/troubleshooting_screen.dart'; -import '../screens/update_settings_screen.dart'; import '../services/fdroid_api_service.dart'; -import '../services/update_check_service.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({super.key}); @@ -182,112 +181,6 @@ class _SettingsScreenState extends State { ); } - String _updateNetworkPolicyLabel(UpdateNetworkPolicy policy) { - switch (policy) { - case UpdateNetworkPolicy.wifiOnly: - return 'Wi-Fi only'; - case UpdateNetworkPolicy.wifiAndCharging: - return 'Wi-Fi + charging'; - case UpdateNetworkPolicy.any: - default: - return 'Mobile data or Wi-Fi'; - } - } - - Future _showUpdateNetworkPolicyDialog( - BuildContext context, - SettingsProvider settings, - ) async { - await showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text('Update network'), - content: Column( - mainAxisSize: MainAxisSize.min, - children: UpdateNetworkPolicy.values - .map( - (policy) => RadioListTile( - value: policy, - groupValue: settings.updateNetworkPolicy, - title: Text(_updateNetworkPolicyLabel(policy)), - onChanged: (value) async { - if (value == null) return; - await settings.setUpdateNetworkPolicy(value); - await UpdateCheckService.scheduleFromPrefs(); - if (!context.mounted) return; - Navigator.of(context).pop(); - }, - ), - ) - .toList(), - ), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(), - child: const Text('Close'), - ), - ], - ), - ); - } - - String _updateIntervalLabel(int hours) { - switch (hours) { - case 1: - return 'Every 1 hour'; - case 2: - return 'Every 2 hours'; - case 3: - return 'Every 3 hours'; - case 6: - return 'Every 6 hours'; - case 12: - return 'Every 12 hours'; - case 24: - return 'Daily'; - default: - return 'Every $hours hours'; - } - } - - Future _showUpdateIntervalDialog( - BuildContext context, - SettingsProvider settings, - ) async { - const intervals = [1, 2, 3, 6, 12, 24]; - await showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text('Update interval'), - content: Column( - mainAxisSize: MainAxisSize.min, - children: intervals - .map( - (hours) => RadioListTile( - value: hours, - groupValue: settings.updateIntervalHours, - title: Text(_updateIntervalLabel(hours)), - onChanged: (value) async { - if (value == null) return; - await settings.setUpdateIntervalHours(value); - await UpdateCheckService.scheduleFromPrefs(); - if (!context.mounted) return; - Navigator.of(context).pop(); - }, - ), - ) - .toList(), - ), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(), - child: const Text('Close'), - ), - ], - ), - ); - } - @override Widget build(BuildContext context) { return Consumer( @@ -306,7 +199,7 @@ class _SettingsScreenState extends State { children: [ MListHeader( title: 'General Settings', - icon: Symbols.settings, + icon: Symbols.mobile, ), MListView( items: [ @@ -334,6 +227,19 @@ class _SettingsScreenState extends State { ), suffix: Icon(Symbols.chevron_right), ), + ], + ), + ], + ), + Column( + spacing: 4, + children: [ + MListHeader( + title: 'Repositories & Management', + icon: Symbols.settings, + ), + MListView( + items: [ MListItemData( leading: Icon(Symbols.cloud), title: 'Manage repositories', @@ -350,15 +256,16 @@ class _SettingsScreenState extends State { suffix: Icon(Symbols.chevron_right), ), MListItemData( - leading: Icon(Symbols.update), - title: 'Update settings', - subtitle: 'Manage background updates', + leading: Icon(Symbols.discover_tune), + title: 'App Management', + subtitle: + 'Manage settings regarding installs and updates', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => - const UpdateSettingsScreen(), + const AppManagementScreen(), ), ); },