Moved logs settings to settings screen

This commit is contained in:
Juan Gilsanz Polo 2024-01-24 13:55:15 +01:00
parent 65ee702b89
commit 211eab9f44
9 changed files with 369 additions and 569 deletions

View file

@ -0,0 +1,177 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/widgets/custom_checkbox_list_tile.dart';
class LogsConfigOptions extends StatelessWidget {
final bool generalSwitch;
final void Function(bool) updateGeneralSwitch;
final bool anonymizeClientIp;
final void Function(bool) updateAnonymizeClientIp;
final List<int> retentionItems;
final double? retentionTime;
final void Function(double?) updateRetentionTime;
final void Function() onClear;
final void Function() onConfirm;
const LogsConfigOptions({
super.key,
required this.generalSwitch,
required this.updateGeneralSwitch,
required this.anonymizeClientIp,
required this.updateAnonymizeClientIp,
required this.retentionItems,
required this.retentionTime,
required this.updateRetentionTime,
required this.onClear,
required this.onConfirm
});
@override
Widget build(BuildContext context) {
final List<String> dropdownItemTranslation = [
AppLocalizations.of(context)!.hours6,
AppLocalizations.of(context)!.hours24,
AppLocalizations.of(context)!.days7,
AppLocalizations.of(context)!.days30,
AppLocalizations.of(context)!.days90,
];
return Column(
children: [
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Material(
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(28),
child: InkWell(
onTap: () => updateGeneralSwitch(!generalSwitch),
borderRadius: BorderRadius.circular(28),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 8
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.enableLog,
style: const TextStyle(
fontSize: 18,
),
),
Switch(
value: generalSwitch,
onChanged: updateGeneralSwitch,
)
],
),
),
),
),
),
const SizedBox(height: 16),
CustomCheckboxListTile(
value: anonymizeClientIp,
onChanged: (_) => updateAnonymizeClientIp(!anonymizeClientIp),
title: AppLocalizations.of(context)!.anonymizeClientIp,
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
),
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 22),
child: DropdownButtonFormField(
items: retentionItems.asMap().entries.map((item) => DropdownMenuItem(
value: item.value,
child: Text(dropdownItemTranslation[item.key]),
)).toList(),
value: retentionTime,
onChanged: (value) => updateRetentionTime(value as double),
decoration: InputDecoration(
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(10)
)
),
label: Text(AppLocalizations.of(context)!.retentionTime)
),
borderRadius: BorderRadius.circular(20),
),
),
const SizedBox(height: 24),
ElevatedButton.icon(
onPressed: onClear,
icon: const Icon(Icons.delete_rounded),
label: Text(AppLocalizations.of(context)!.clearLogs),
)
],
);
}
}
class ConfigLogsLoading extends StatelessWidget {
const ConfigLogsLoading({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Text(
AppLocalizations.of(context)!.loadingLogsSettings,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant
),
),
)
],
),
),
);
}
}
class ConfigLogsError extends StatelessWidget {
const ConfigLogsError({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.error,
color: Colors.red,
size: 50,
),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Text(
AppLocalizations.of(context)!.logSettingsNotLoaded,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant
),
),
)
],
),
);
}
}

View file

@ -0,0 +1,167 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/screens/settings/logs_settings/config_widgets.dart';
import 'package:adguard_home_manager/classes/process_modal.dart';
import 'package:adguard_home_manager/functions/snackbar.dart';
import 'package:adguard_home_manager/providers/app_config_provider.dart';
import 'package:adguard_home_manager/constants/enums.dart';
import 'package:adguard_home_manager/providers/servers_provider.dart';
class LogsSettings extends StatefulWidget {
const LogsSettings({super.key});
@override
State<LogsSettings> createState() => _LogsSettingsState();
}
class _LogsSettingsState extends State<LogsSettings> {
bool generalSwitch = false;
bool anonymizeClientIp = false;
double? retentionTime;
List<int> retentionItems = [
21600000,
86400000,
604800000,
2592000000,
7776000000
];
LoadStatus loadStatus = LoadStatus.loading;
void loadData() async {
final serversProvider = Provider.of<ServersProvider>(context, listen: false);
final result = await serversProvider.apiClient2!.getQueryLogInfo();
if (mounted) {
if (result.successful == true) {
setState(() {
generalSwitch = result.content['enabled'];
anonymizeClientIp = result.content['anonymize_client_ip'];
retentionTime = result.content['interval'] != null
? double.parse(result.content['interval'].toString())
: null;
loadStatus = LoadStatus.loaded;
});
}
else {
setState(() => loadStatus = LoadStatus.error);
}
}
}
@override
void initState() {
loadData();
super.initState();
}
@override
Widget build(BuildContext context) {
final serversProvider = Provider.of<ServersProvider>(context);
final appConfigProvider = Provider.of<AppConfigProvider>(context);
void clearQueries() async {
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.updatingSettings);
final result = await serversProvider.apiClient2!.clearLogs();
processModal.close();
if (!mounted) return;
if (result.successful == true) {
showSnacbkar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.logsCleared,
color: Colors.green
);
}
else {
showSnacbkar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.logsNotCleared,
color: Colors.red
);
}
}
void updateConfig() async {
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.updatingSettings);
final result = await serversProvider.apiClient2!.updateQueryLogParameters(
data: {
"enabled": generalSwitch,
"interval": retentionTime,
"anonymize_client_ip": anonymizeClientIp
}
);
processModal.close();
if (!mounted) return;
if (result.successful == true) {
showSnacbkar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.logsConfigUpdated,
color: Colors.green
);
}
else {
showSnacbkar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.logsConfigNotUpdated,
color: Colors.red
);
}
}
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.logsSettings),
actions: [
if (loadStatus == LoadStatus.loaded) IconButton(
onPressed: updateConfig,
icon: const Icon(Icons.save_rounded),
tooltip: AppLocalizations.of(context)!.save,
),
const SizedBox(width: 8)
],
),
body: Builder(
builder: (context) {
switch (loadStatus) {
case LoadStatus.loading:
return const ConfigLogsLoading();
case LoadStatus.loaded:
return LogsConfigOptions(
generalSwitch: generalSwitch,
updateGeneralSwitch: (v) => setState(() => generalSwitch = v),
anonymizeClientIp: anonymizeClientIp,
updateAnonymizeClientIp: (v) => setState(() => anonymizeClientIp = v),
retentionItems: retentionItems,
retentionTime: retentionTime,
updateRetentionTime: (v) => setState(() => retentionTime = v),
onClear: clearQueries,
onConfirm: updateConfig
);
case LoadStatus.error:
return const ConfigLogsError();
default:
return const SizedBox();
}
},
),
);
}
}

View file

@ -8,6 +8,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/screens/settings/server_info/server_info.dart';
import 'package:adguard_home_manager/screens/settings/encryption/encryption.dart';
import 'package:adguard_home_manager/screens/settings/logs_settings/logs_settings.dart';
import 'package:adguard_home_manager/screens/settings/access_settings/access_settings.dart';
import 'package:adguard_home_manager/screens/settings/customization/customization.dart';
import 'package:adguard_home_manager/screens/settings/dhcp/dhcp.dart';
@ -139,11 +140,19 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
screenToNavigate: const SafeSearchSettingsScreen(),
twoColumns: widget.twoColumns,
),
_SettingsTile(
icon: Icons.list_alt_rounded,
title: AppLocalizations.of(context)!.logsSettings,
subtitle: AppLocalizations.of(context)!.logsSettingsDescription,
thisItem: 1,
screenToNavigate: const LogsSettings(),
twoColumns: widget.twoColumns,
),
_SettingsTile(
icon: Icons.lock_rounded,
title: AppLocalizations.of(context)!.accessSettings,
subtitle: AppLocalizations.of(context)!.accessSettingsDescription,
thisItem: 1,
thisItem: 2,
screenToNavigate: const AccessSettings(),
twoColumns: widget.twoColumns,
),
@ -151,7 +160,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.install_desktop_rounded,
title: AppLocalizations.of(context)!.dhcpSettings,
subtitle: AppLocalizations.of(context)!.dhcpSettingsDescription,
thisItem: 2,
thisItem: 3,
screenToNavigate: const DhcpScreen(),
twoColumns: widget.twoColumns,
),
@ -159,7 +168,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.dns_rounded,
title: AppLocalizations.of(context)!.dnsSettings,
subtitle: AppLocalizations.of(context)!.dnsSettingsDescription,
thisItem: 3,
thisItem: 4,
screenToNavigate: DnsSettings(
splitView: widget.twoColumns,
),
@ -169,7 +178,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.security_rounded,
title: AppLocalizations.of(context)!.encryptionSettings,
subtitle: AppLocalizations.of(context)!.encryptionSettingsDescription,
thisItem: 4,
thisItem: 5,
screenToNavigate: const EncryptionSettings(),
twoColumns: widget.twoColumns,
),
@ -177,7 +186,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.route_rounded,
title: AppLocalizations.of(context)!.dnsRewrites,
subtitle: AppLocalizations.of(context)!.dnsRewritesDescription,
thisItem: 5,
thisItem: 6,
screenToNavigate: const DnsRewritesScreen(),
twoColumns: widget.twoColumns,
),
@ -197,7 +206,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
),
)
: null,
thisItem: 6,
thisItem: 7,
screenToNavigate: const UpdateScreen(),
twoColumns: widget.twoColumns,
),
@ -205,7 +214,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.info_rounded,
title: AppLocalizations.of(context)!.serverInformation,
subtitle: AppLocalizations.of(context)!.serverInformationDescription,
thisItem: 7,
thisItem: 8,
screenToNavigate: const ServerInformation(),
twoColumns: widget.twoColumns,
),
@ -215,7 +224,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.palette_rounded,
title: AppLocalizations.of(context)!.customization,
subtitle: AppLocalizations.of(context)!.customizationDescription,
thisItem: 8,
thisItem: 9,
screenToNavigate: const Customization(),
twoColumns: widget.twoColumns,
),
@ -227,7 +236,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
? "${AppLocalizations.of(context)!.connectedTo} ${serversProvider.selectedServer!.name}"
: "${AppLocalizations.of(context)!.selectedServer} ${serversProvider.selectedServer!.name}"
: AppLocalizations.of(context)!.noServerSelected,
thisItem: 9,
thisItem: 10,
screenToNavigate: const Servers(),
twoColumns: widget.twoColumns,
),
@ -235,7 +244,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.settings,
title: AppLocalizations.of(context)!.generalSettings,
subtitle: AppLocalizations.of(context)!.generalSettingsDescription,
thisItem: 10,
thisItem: 11,
screenToNavigate: GeneralSettings(splitView: widget.twoColumns),
twoColumns: widget.twoColumns,
),
@ -243,7 +252,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> {
icon: Icons.build_outlined,
title: AppLocalizations.of(context)!.advancedSettings,
subtitle: AppLocalizations.of(context)!.advancedSetupDescription,
thisItem: 11,
thisItem: 12,
screenToNavigate: const AdvancedSettings(),
twoColumns: widget.twoColumns,
),