[imp]: Improvement in settings's architecture

This commit is contained in:
nahnah
2026-02-11 20:46:02 +00:00
parent f873374f30
commit 69fdd3d3d6
2 changed files with 147 additions and 128 deletions
@@ -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<UpdateSettingsScreen> createState() => _UpdateSettingsScreenState();
}
class _UpdateSettingsScreenState extends State<UpdateSettingsScreen> {
static const MethodChannel _batteryChannel = MethodChannel(
'florid/battery_optimizations',
);
@override
State<AppManagementScreen> createState() => _AppManagementScreenState();
}
class _AppManagementScreenState extends State<AppManagementScreen> {
bool? _isIgnoringBatteryOptimizations;
@override
@@ -32,12 +31,59 @@ class _UpdateSettingsScreenState extends State<UpdateSettingsScreen> {
_loadBatteryOptimizationStatus();
}
String _installMethodLabel(InstallMethod method) {
switch (method) {
case InstallMethod.shizuku:
return 'Shizuku';
case InstallMethod.system:
return 'System installer';
}
}
Future<void> _showInstallMethodDialog(
BuildContext context,
SettingsProvider settings,
) async {
await showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Installation method'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: InstallMethod.values
.map(
(method) => RadioListTile<InstallMethod>(
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<void> _loadBatteryOptimizationStatus() async {
if (!Platform.isAndroid) return;
try {
final isIgnoring = await _batteryChannel.invokeMethod<bool>(
'isIgnoringBatteryOptimizations',
);
final isIgnoring = await AppManagementScreen._batteryChannel
.invokeMethod<bool>('isIgnoringBatteryOptimizations');
if (!mounted) return;
setState(() {
_isIgnoringBatteryOptimizations = isIgnoring ?? false;
@@ -173,7 +219,7 @@ class _UpdateSettingsScreenState extends State<UpdateSettingsScreen> {
return Consumer<SettingsProvider>(
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<UpdateSettingsScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 16,
children: [
Column(
spacing: 4,
children: [
MListHeader(title: 'Installation method'),
MRadioListView<InstallMethod>(
items: InstallMethod.values
.map(
(method) => MRadioListItemData<InstallMethod>(
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: [
+20 -113
View File
@@ -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<SettingsScreen> {
);
}
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<void> _showUpdateNetworkPolicyDialog(
BuildContext context,
SettingsProvider settings,
) async {
await showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Update network'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: UpdateNetworkPolicy.values
.map(
(policy) => RadioListTile<UpdateNetworkPolicy>(
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<void> _showUpdateIntervalDialog(
BuildContext context,
SettingsProvider settings,
) async {
const intervals = [1, 2, 3, 6, 12, 24];
await showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Update interval'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: intervals
.map(
(hours) => RadioListTile<int>(
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<SettingsProvider>(
@@ -306,7 +199,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
children: [
MListHeader(
title: 'General Settings',
icon: Symbols.settings,
icon: Symbols.mobile,
),
MListView(
items: [
@@ -334,6 +227,19 @@ class _SettingsScreenState extends State<SettingsScreen> {
),
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<SettingsScreen> {
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(),
),
);
},