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

@ -726,5 +726,6 @@
"oneIdentifierRequired": "At least one identifier is required", "oneIdentifierRequired": "At least one identifier is required",
"dnsCacheNumber": "DNS cache size must be a number", "dnsCacheNumber": "DNS cache size must be a number",
"errors": "Errors", "errors": "Errors",
"redirectHttpsWarning": "If you have enabled \"Redirect to HTTPS automatically\" on your AdGuard Home server, you must select an HTTPS connection and use the HTTPS port of your server." "redirectHttpsWarning": "If you have enabled \"Redirect to HTTPS automatically\" on your AdGuard Home server, you must select an HTTPS connection and use the HTTPS port of your server.",
"logsSettingsDescription": "Configure query logs"
} }

View file

@ -726,5 +726,6 @@
"oneIdentifierRequired": "Se require al menos un identificador", "oneIdentifierRequired": "Se require al menos un identificador",
"dnsCacheNumber": "El tamaño de caché de DNS debe ser un número", "dnsCacheNumber": "El tamaño de caché de DNS debe ser un número",
"errors": "Errores", "errors": "Errores",
"redirectHttpsWarning": "Si tienes activado \"Redireccionar a HTTPS automáticamente\" en tu servidor AdGuard Home, debes seleccionar una conexión HTTPS y utilizar el puerto de HTTPS de tu servidor." "redirectHttpsWarning": "Si tienes activado \"Redireccionar a HTTPS automáticamente\" en tu servidor AdGuard Home, debes seleccionar una conexión HTTPS y utilizar el puerto de HTTPS de tu servidor.",
"logsSettingsDescription": "Configura los registros de peticiones"
} }

View file

@ -1,276 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/screens/logs/configuration/logs_config_modal.dart';
class LogsConfigOptions extends StatelessWidget {
final bool generalSwitch;
final void Function(bool) updateGeneralSwitch;
final bool anonymizeClientIp;
final void Function(bool) updateAnonymizeClientIp;
final List<RetentionItem> 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 width = MediaQuery.of(context).size.width;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: SingleChildScrollView(
child: Wrap(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
child: Icon(
Icons.settings,
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
),
const SizedBox(height: 16),
Text(
AppLocalizations.of(context)!.logsSettings,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Theme.of(context).colorScheme.onSurface
),
),
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,
)
],
),
),
),
),
),
Container(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 14),
child: Column(
children: [
Material(
color: Colors.transparent,
child: InkWell(
onTap: () => updateAnonymizeClientIp(!anonymizeClientIp),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
AppLocalizations.of(context)!.anonymizeClientIp,
style: const TextStyle(
fontSize: 16
),
),
),
Switch(
value: anonymizeClientIp,
onChanged: updateAnonymizeClientIp,
)
],
),
),
),
),
Container(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: DropdownButtonFormField(
items: retentionItems.map((item) => DropdownMenuItem(
value: item.value,
child: Text(item.label),
)).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),
),
),
],
),
)
],
),
),
),
Padding(
padding: const EdgeInsets.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (width > 500) TextButton(
onPressed: () {
Navigator.pop(context);
onClear();
},
child: Text(AppLocalizations.of(context)!.clearLogs)
),
if (width <= 500) IconButton(
onPressed: () {
Navigator.pop(context);
onClear();
},
icon: const Icon(Icons.delete_rounded),
tooltip: AppLocalizations.of(context)!.clearLogs,
),
Row(
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.cancel)
),
const SizedBox(width: 20),
TextButton(
onPressed: retentionTime != null
? () {
Navigator.pop(context);
onConfirm();
}
: null,
child: Text(
AppLocalizations.of(context)!.confirm,
style: TextStyle(
color: retentionTime != null
? Theme.of(context).colorScheme.primary
: Colors.grey
),
)
),
],
)
],
),
),
if (Platform.isIOS) const SizedBox(height: 16)
],
);
}
}
class ConfigLogsLoading extends StatelessWidget {
const ConfigLogsLoading({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
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 Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
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

@ -1,187 +0,0 @@
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/logs/configuration/config_widgets.dart';
import 'package:adguard_home_manager/constants/enums.dart';
import 'package:adguard_home_manager/providers/servers_provider.dart';
class RetentionItem {
final String label;
final double value;
const RetentionItem({
required this.label,
required this.value,
});
}
class LogsConfigModal extends StatefulWidget {
final BuildContext context;
final void Function(Map<String, dynamic>) onConfirm;
final void Function() onClear;
final bool dialog;
final String serverVersion;
const LogsConfigModal({
super.key,
required this.context,
required this.onConfirm,
required this.onClear,
required this.dialog,
required this.serverVersion
});
@override
State<LogsConfigModal> createState() => _LogsConfigModalState();
}
class _LogsConfigModalState extends State<LogsConfigModal> {
bool generalSwitch = false;
bool anonymizeClientIp = false;
double? retentionTime;
List<RetentionItem> retentionItems = [];
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() {
retentionItems = [
RetentionItem(
label: AppLocalizations.of(widget.context)!.hours6,
value: 21600000
),
RetentionItem(
label: AppLocalizations.of(widget.context)!.hours24,
value: 86400000
),
RetentionItem(
label: AppLocalizations.of(widget.context)!.days7,
value: 604800000
),
RetentionItem(
label: AppLocalizations.of(widget.context)!.days30,
value: 2592000000
),
RetentionItem(
label: AppLocalizations.of(widget.context)!.days90,
value: 7776000000
),
];
loadData();
super.initState();
}
@override
Widget build(BuildContext context) {
if (widget.dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 500
),
child: 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: () => widget.onClear(),
onConfirm: () => widget.onConfirm({
"enabled": generalSwitch,
"interval": retentionTime,
"anonymize_client_ip": anonymizeClientIp
})
);
case LoadStatus.error:
return const ConfigLogsError();
default:
return const SizedBox();
}
},
)
),
);
}
else {
return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
),
color: Theme.of(context).dialogBackgroundColor
),
child: SafeArea(
child: 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: () => widget.onClear(),
onConfirm: () => widget.onConfirm({
"enabled": generalSwitch,
"interval": retentionTime,
"anonymize_client_ip": anonymizeClientIp
})
);
case LoadStatus.error:
return const ConfigLogsError();
default:
return const SizedBox();
}
},
),
)
);
}
}
}

View file

@ -7,16 +7,10 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/screens/logs/filters/logs_filters_modal.dart'; import 'package:adguard_home_manager/screens/logs/filters/logs_filters_modal.dart';
import 'package:adguard_home_manager/screens/logs/configuration/logs_config_modal.dart';
import 'package:adguard_home_manager/classes/process_modal.dart';
import 'package:adguard_home_manager/constants/enums.dart'; import 'package:adguard_home_manager/constants/enums.dart';
import 'package:adguard_home_manager/functions/desktop_mode.dart'; import 'package:adguard_home_manager/functions/desktop_mode.dart';
import 'package:adguard_home_manager/functions/snackbar.dart';
import 'package:adguard_home_manager/models/applied_filters.dart'; import 'package:adguard_home_manager/models/applied_filters.dart';
import 'package:adguard_home_manager/providers/app_config_provider.dart';
import 'package:adguard_home_manager/providers/servers_provider.dart';
import 'package:adguard_home_manager/providers/status_provider.dart';
import 'package:adguard_home_manager/providers/logs_provider.dart'; import 'package:adguard_home_manager/providers/logs_provider.dart';
class LogsListAppBar extends StatelessWidget { class LogsListAppBar extends StatelessWidget {
@ -32,61 +26,9 @@ class LogsListAppBar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final logsProvider = Provider.of<LogsProvider>(context); final logsProvider = Provider.of<LogsProvider>(context);
final statusProvider = Provider.of<StatusProvider>(context);
final serversProvider = Provider.of<ServersProvider>(context);
final appConfigProvider = Provider.of<AppConfigProvider>(context);
final width = MediaQuery.of(context).size.width; final width = MediaQuery.of(context).size.width;
void updateConfig(Map<String, dynamic> data) async {
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.updatingSettings);
final result = await serversProvider.apiClient2!.updateQueryLogParameters(data: data);
processModal.close();
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
);
}
}
void clearQueries() async {
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.updatingSettings);
final result = await serversProvider.apiClient2!.clearLogs();
processModal.close();
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 openFilersModal() { void openFilersModal() {
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) { if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog( showDialog(
@ -143,40 +85,6 @@ class LogsListAppBar extends StatelessWidget {
tooltip: AppLocalizations.of(context)!.filters, tooltip: AppLocalizations.of(context)!.filters,
) )
: const SizedBox(), : const SizedBox(),
if (statusProvider.serverStatus != null) IconButton(
tooltip: AppLocalizations.of(context)!.settings,
onPressed: () => {
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (context) => LogsConfigModal(
context: context,
onConfirm: updateConfig,
onClear: clearQueries,
dialog: true,
serverVersion: statusProvider.serverStatus!.serverVersion,
),
barrierDismissible: false
)
}
else {
showModalBottomSheet(
context: context,
useRootNavigator: true,
builder: (context) => LogsConfigModal(
context: context,
onConfirm: updateConfig,
onClear: clearQueries,
dialog: false,
serverVersion: statusProvider.serverStatus!.serverVersion,
),
backgroundColor: Colors.transparent,
isScrollControlled: true
)
}
},
icon: const Icon(Icons.settings)
),
const SizedBox(width: 5), const SizedBox(width: 5),
], ],
bottom: logsProvider.appliedFilters.searchText != null || logsProvider.appliedFilters.selectedResultStatus != 'all' || logsProvider.appliedFilters.clients != null bottom: logsProvider.appliedFilters.searchText != null || logsProvider.appliedFilters.selectedResultStatus != 'all' || logsProvider.appliedFilters.clients != null

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

View file

@ -649,7 +649,7 @@ class ApiClientV2 {
} }
Future<ApiResponse> clearLogs() async { Future<ApiResponse> clearLogs() async {
final result = await HttpRequestClient.put( final result = await HttpRequestClient.post(
urlPath: '/querylog_clear', urlPath: '/querylog_clear',
server: server, server: server,
body: {}, body: {},