diff --git a/lib/screens/settings/logs_settings/config_widgets.dart b/lib/screens/settings/logs_settings/config_widgets.dart index 002fd96..16700a9 100644 --- a/lib/screens/settings/logs_settings/config_widgets.dart +++ b/lib/screens/settings/logs_settings/config_widgets.dart @@ -12,13 +12,16 @@ class LogsConfigOptions extends StatelessWidget { final void Function(bool) updateGeneralSwitch; final bool anonymizeClientIp; final void Function(bool) updateAnonymizeClientIp; - final List retentionItems; - final double? retentionTime; - final void Function(double?) updateRetentionTime; + final List retentionItems; + final String? retentionTime; + final void Function(String?) updateRetentionTime; final void Function() onClear; final void Function() onConfirm; final List ignoredDomainsControllers; final void Function(List) updateIgnoredDomainsControllers; + final TextEditingController customTimeController; + final String? customTimeError; + final void Function(String) validateCustomTime; const LogsConfigOptions({ super.key, @@ -32,7 +35,10 @@ class LogsConfigOptions extends StatelessWidget { required this.onClear, required this.onConfirm, required this.ignoredDomainsControllers, - required this.updateIgnoredDomainsControllers + required this.updateIgnoredDomainsControllers, + required this.customTimeController, + required this.customTimeError, + required this.validateCustomTime, }); @override @@ -40,6 +46,7 @@ class LogsConfigOptions extends StatelessWidget { const Uuid uuid = Uuid(); final List dropdownItemTranslation = [ + AppLocalizations.of(context)!.custom, AppLocalizations.of(context)!.hours6, AppLocalizations.of(context)!.hours24, AppLocalizations.of(context)!.days7, @@ -67,7 +74,7 @@ class LogsConfigOptions extends StatelessWidget { }).toList() ); } - +print(retentionTime); return ListView( children: [ const SizedBox(height: 16), @@ -92,7 +99,7 @@ class LogsConfigOptions extends StatelessWidget { child: Text(dropdownItemTranslation[item.key]), )).toList(), value: retentionTime, - onChanged: (value) => updateRetentionTime(double.tryParse(value.toString())), + onChanged: (value) => updateRetentionTime(value.toString()), decoration: InputDecoration( border: const OutlineInputBorder( borderRadius: BorderRadius.all( @@ -104,6 +111,24 @@ class LogsConfigOptions extends StatelessWidget { borderRadius: BorderRadius.circular(20), ), ), + if (retentionTime == "custom") Padding( + padding: const EdgeInsets.only(top: 24, left: 16, right: 16), + child: TextFormField( + controller: customTimeController, + onChanged: validateCustomTime, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.schedule_rounded), + border: const OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(10) + ) + ), + labelText: AppLocalizations.of(context)!.customTimeInHours, + errorText: customTimeError + ), + keyboardType: TextInputType.number, + ), + ), Padding( padding: const EdgeInsets.only(top: 24, bottom: 8), child: Row( diff --git a/lib/screens/settings/logs_settings/logs_settings.dart b/lib/screens/settings/logs_settings/logs_settings.dart index 0d55ce5..c31304f 100644 --- a/lib/screens/settings/logs_settings/logs_settings.dart +++ b/lib/screens/settings/logs_settings/logs_settings.dart @@ -37,15 +37,18 @@ class _LogsSettingsState extends State { bool generalSwitch = false; bool anonymizeClientIp = false; - double? retentionTime; + String? retentionTime; List _ignoredDomainsControllers = []; + final _customTimeController = TextEditingController(); + String? _customTimeError = null; - List retentionItems = [ - 21600000, - 86400000, - 604800000, - 2592000000, - 7776000000 + List retentionItems = [ + "custom", + "21600000", + "86400000", + "604800000", + "2592000000", + "7776000000" ]; LoadStatus loadStatus = LoadStatus.loading; @@ -61,9 +64,10 @@ class _LogsSettingsState extends State { setState(() { generalSwitch = data.enabled ?? false; anonymizeClientIp = data.anonymizeClientIp ?? false; - retentionTime = data.interval != null - ? double.parse(data.interval.toString()) - : null; + retentionTime = retentionItems.contains(data.interval.toString()) ? data.interval.toString() : "custom"; + if (data.interval != null && !retentionItems.contains(data.interval.toString())) { + _customTimeController.text = (data.interval!/3.6e+6).toInt().toString(); + } if (data.ignored != null) { _ignoredDomainsControllers = data.ignored!.map((e) => DomainListItemController( id: uuid.v4(), @@ -79,6 +83,34 @@ class _LogsSettingsState extends State { } } + void validateCustomTime(String value) { + try { + final regex = RegExp(r'^\d+$'); + final parsed = int.parse(value); + if (!regex.hasMatch(value)) { + setState(() => _customTimeError = AppLocalizations.of(context)!.invalidTime); + } + else if (parsed < 1) { + setState(() => _customTimeError = AppLocalizations.of(context)!.notLess1Hour); + } + else { + setState(() => _customTimeError = null); + } + } catch (_) { + setState(() => _customTimeError = AppLocalizations.of(context)!.invalidTime); + } + } + + bool checkValidValues() { + if (_ignoredDomainsControllers.where((d) => d.controller.text == "" || d.error == true).isNotEmpty) { + return false; + } + if (retentionTime == "custom" && (_customTimeError != null || _customTimeController.text == "")) { + return false; + } + return true; + } + @override void initState() { loadData(); @@ -90,9 +122,7 @@ class _LogsSettingsState extends State { final serversProvider = Provider.of(context); final appConfigProvider = Provider.of(context); - final validValues = _ignoredDomainsControllers.where( - (d) => d.controller.text == "" || d.error == true - ).isEmpty; + final validValues = checkValidValues(); void clearQueries() async { ProcessModal processModal = ProcessModal(); @@ -127,7 +157,7 @@ class _LogsSettingsState extends State { final result = await serversProvider.apiClient2!.updateQueryLogParameters( data: { "enabled": generalSwitch, - "interval": retentionTime, + "interval": retentionTime == "custom" ? int.parse(_customTimeController.text)*3.6e+6 : int.parse(retentionTime!) , "anonymize_client_ip": anonymizeClientIp, "ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList() } @@ -198,6 +228,9 @@ class _LogsSettingsState extends State { onConfirm: updateConfig, ignoredDomainsControllers: _ignoredDomainsControllers, updateIgnoredDomainsControllers: (v) => setState(() => _ignoredDomainsControllers = v), + customTimeController: _customTimeController, + customTimeError: _customTimeError, + validateCustomTime: validateCustomTime, ); case LoadStatus.error: