From 19ae91905f7bcbb3f9a2e97ce816f9ef2a497be6 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 14:43:25 +0100 Subject: [PATCH 01/11] Added project specific vscode settings --- .vscode/settings.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9ad1ad1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "editor.formatOnSave": false, + "editor.defaultFormatter": "Dart-Code.flutter", + "dart.lineLength": 120, + "[dart]": { + "editor.rulers": [ + 120 + ], + "editor.defaultFormatter": "Dart-Code.dart-code", + "editor.formatOnSave": false, + } +} \ No newline at end of file From 8859468a660418160b791371a8f7391536187d16 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 14:44:00 +0100 Subject: [PATCH 02/11] Updated libraries --- pubspec.lock | 120 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index c1c90ca..38751b2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -189,10 +189,10 @@ packages: dependency: transitive description: name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" file: dependency: transitive description: @@ -213,10 +213,10 @@ packages: dependency: "direct main" description: name: fl_chart - sha256: b5e2b0f13d93f8c532b5a2786bfb44580de1f50b927bf95813fa1af617e9caf8 + sha256: "00b74ae680df6b1135bdbea00a7d1fc072a9180b7c3f3702e4b19a9943f5ed7d" url: "https://pub.dev" source: hosted - version: "0.66.1" + version: "0.66.2" flutter: dependency: "direct main" description: flutter @@ -311,10 +311,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "30088ce826b5b9cfbf9e8bece34c716c8a59fa54461dcae1e4ac01a94639e762" + sha256: a64c5323ac83ed2b7940d2b6288d160aa1753ff271ba9d9b2a86770414aa3eab url: "https://pub.dev" source: hosted - version: "0.6.18+3" + version: "0.6.20+1" flutter_native_splash: dependency: "direct dev" description: @@ -344,10 +344,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c + sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" url: "https://pub.dev" source: hosted - version: "2.0.9" + version: "2.0.10+1" flutter_test: dependency: "direct dev" description: flutter @@ -386,10 +386,10 @@ packages: dependency: transitive description: name: image - sha256: "49a0d4b0c12402853d3f227fe7c315601b238d126aa4caa5dbb2dcf99421aa4a" + sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" url: "https://pub.dev" source: hosted - version: "4.1.6" + version: "4.1.7" intl: dependency: "direct main" description: @@ -414,6 +414,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -442,26 +466,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" nested: dependency: transitive description: @@ -490,10 +514,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -578,10 +602,10 @@ packages: dependency: "direct main" description: name: provider - sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c url: "https://pub.dev" source: hosted - version: "6.1.1" + version: "6.1.2" segmented_button_slide: dependency: "direct main" description: @@ -594,18 +618,18 @@ packages: dependency: transitive description: name: sentry - sha256: a7946f4a90b0feb47214981d881b98149e05f6c576da9f2a2f33945bf561de25 + sha256: d2ee9c850d876d285f22e2e662f400ec2438df9939fe4acd5d780df9841794ce url: "https://pub.dev" source: hosted - version: "7.16.0" + version: "7.16.1" sentry_flutter: dependency: "direct main" description: name: sentry_flutter - sha256: "6db7fa1b076faf2f5dd77d8cc9ef206171f32a290cc638842d78e5d62b441a27" + sha256: "5b428c189c825f16fb14e9166529043f06b965d5b59bfc3a1415e39c082398c0" url: "https://pub.dev" source: hosted - version: "7.16.0" + version: "7.16.1" shared_preferences: dependency: "direct main" description: @@ -711,10 +735,10 @@ packages: dependency: transitive description: name: sqlite3 - sha256: c4a4c5a4b2a32e2d0f6837b33d7c91a67903891a5b7dbe706cf4b1f6b0c798c5 + sha256: "072128763f1547e3e9b4735ce846bfd226d68019ccda54db4cd427b12dfdedc9" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.0" sqlite3_flutter_libs: dependency: "direct main" description: @@ -807,26 +831,26 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c + sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e" url: "https://pub.dev" source: hosted - version: "6.2.4" + version: "6.2.5" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" + sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745 url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.3.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" + sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5" url: "https://pub.dev" source: hosted - version: "6.2.4" + version: "6.2.5" url_launcher_linux: dependency: transitive description: @@ -847,10 +871,10 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" url_launcher_web: dependency: transitive description: @@ -879,26 +903,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752" + sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" url: "https://pub.dev" source: hosted - version: "1.1.10+1" + version: "1.1.11+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33 + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da url: "https://pub.dev" source: hosted - version: "1.1.10+1" + version: "1.1.11+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a" + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" url: "https://pub.dev" source: hosted - version: "1.1.10+1" + version: "1.1.11+1" vector_math: dependency: transitive description: @@ -907,14 +931,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" web: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.4.2" win32: dependency: transitive description: @@ -965,5 +997,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" From 0821fd4e0e442565ed13fd8b66e877976195e7a5 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 14:44:10 +0100 Subject: [PATCH 03/11] Fix duplicated snackbars logs --- lib/screens/logs/logs_list.dart | 354 +++++++++++++++-------------- lib/screens/settings/settings.dart | 4 +- 2 files changed, 181 insertions(+), 177 deletions(-) diff --git a/lib/screens/logs/logs_list.dart b/lib/screens/logs/logs_list.dart index ced94ca..6036f77 100644 --- a/lib/screens/logs/logs_list.dart +++ b/lib/screens/logs/logs_list.dart @@ -33,6 +33,7 @@ class LogsListWidget extends StatefulWidget { } class _LogsListWidgetState extends State { + final _scaffoldMessengerKey = GlobalKey(); bool showDivider = true; void fetchFilteringRules() async { @@ -93,194 +94,197 @@ class _LogsListWidgetState extends State { Widget build(BuildContext context) { final logsProvider = Provider.of(context); - return Scaffold( - body: NestedScrollView( - headerSliverBuilder: (context, innerBoxIsScrolled) => [ - SliverOverlapAbsorber( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), - sliver: LogsListAppBar( - innerBoxIsScrolled: innerBoxIsScrolled, - showDivider: showDivider, + return ScaffoldMessenger( + key: widget.twoColumns ? _scaffoldMessengerKey : null, + child: Scaffold( + body: NestedScrollView( + headerSliverBuilder: (context, innerBoxIsScrolled) => [ + SliverOverlapAbsorber( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + sliver: LogsListAppBar( + innerBoxIsScrolled: innerBoxIsScrolled, + showDivider: showDivider, + ) ) - ) - ], - body: Builder( - builder: (context) { - switch (logsProvider.loadStatus) { - case LoadStatus.loading: - return SafeArea( - top: false, - bottom: false, - child: Builder( - builder: (context) => CustomScrollView( - slivers: [ - SliverOverlapInjector( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), - ), - SliverFillRemaining( - child: SizedBox( - width: double.maxFinite, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const CircularProgressIndicator(), - const SizedBox(height: 30), - Text( - AppLocalizations.of(context)!.loadingLogs, - style: TextStyle( - fontSize: 22, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ) - ], - ), + ], + body: Builder( + builder: (context) { + switch (logsProvider.loadStatus) { + case LoadStatus.loading: + return SafeArea( + top: false, + bottom: false, + child: Builder( + builder: (context) => CustomScrollView( + slivers: [ + SliverOverlapInjector( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + ), + SliverFillRemaining( + child: SizedBox( + width: double.maxFinite, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const CircularProgressIndicator(), + const SizedBox(height: 30), + Text( + AppLocalizations.of(context)!.loadingLogs, + style: TextStyle( + fontSize: 22, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ) + ], + ), + ) ) - ) - ], - ), - ) - ); - - case LoadStatus.loaded: - return SafeArea( - top: false, - bottom: false, - child: Builder( - builder: (context) => RefreshIndicator( - onRefresh: () async { - await logsProvider.fetchLogs(inOffset: 0); - }, - displacement: 95, - child: NotificationListener( - onNotification: scrollListener, - child: CustomScrollView( - slivers: [ - SliverOverlapInjector( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), - ), - if (logsProvider.logsData!.data.isNotEmpty) SliverList.builder( - itemCount: logsProvider.isLoadingMore - ? logsProvider.logsData!.data.length + 1 - : logsProvider.logsData!.data.length, - itemBuilder: (context, index) { - if (logsProvider.isLoadingMore == true && index == logsProvider.logsData!.data.length) { - return const Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: Center( - child: CircularProgressIndicator(), - ), - ); - } - else if (logsProvider.logsData!.data[index].question.name != null) { - return LogTile( - log: logsProvider.logsData!.data[index], - index: index, - length: logsProvider.logsData!.data.length, - isLogSelected: widget.selectedLog != null && widget.selectedLog == logsProvider.logsData!.data[index], - onLogTap: (log) { - if (!widget.twoColumns) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => LogDetailsScreen( - log: log, - dialog: false, + ], + ), + ) + ); + + case LoadStatus.loaded: + return SafeArea( + top: false, + bottom: false, + child: Builder( + builder: (context) => RefreshIndicator( + onRefresh: () async { + await logsProvider.fetchLogs(inOffset: 0); + }, + displacement: 95, + child: NotificationListener( + onNotification: scrollListener, + child: CustomScrollView( + slivers: [ + SliverOverlapInjector( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + ), + if (logsProvider.logsData!.data.isNotEmpty) SliverList.builder( + itemCount: logsProvider.isLoadingMore + ? logsProvider.logsData!.data.length + 1 + : logsProvider.logsData!.data.length, + itemBuilder: (context, index) { + if (logsProvider.isLoadingMore == true && index == logsProvider.logsData!.data.length) { + return const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Center( + child: CircularProgressIndicator(), + ), + ); + } + else if (logsProvider.logsData!.data[index].question.name != null) { + return LogTile( + log: logsProvider.logsData!.data[index], + index: index, + length: logsProvider.logsData!.data.length, + isLogSelected: widget.selectedLog != null && widget.selectedLog == logsProvider.logsData!.data[index], + onLogTap: (log) { + if (!widget.twoColumns) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => LogDetailsScreen( + log: log, + dialog: false, + ) ) - ) - ); - } - widget.onLogSelected(log); - }, - twoColumns: widget.twoColumns, - ); + ); + } + widget.onLogSelected(log); + }, + twoColumns: widget.twoColumns, + ); + } + else { + return null; + } } - else { - return null; - } - } - ), - if (logsProvider.logsData!.data.isEmpty) SliverFillRemaining( - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - AppLocalizations.of(context)!.noLogsDisplay, - style: TextStyle( - fontSize: 24, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - if (logsProvider.logsOlderThan != null) Padding( - padding: const EdgeInsets.only( - top: 30, - left: 20, - right: 20 - ), - child: Text( - AppLocalizations.of(context)!.noLogsThatOld, - textAlign: TextAlign.center, + ), + if (logsProvider.logsData!.data.isEmpty) SliverFillRemaining( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + AppLocalizations.of(context)!.noLogsDisplay, style: TextStyle( - fontSize: 16, + fontSize: 24, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), - ), - ] + if (logsProvider.logsOlderThan != null) Padding( + padding: const EdgeInsets.only( + top: 30, + left: 20, + right: 20 + ), + child: Text( + AppLocalizations.of(context)!.noLogsThatOld, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ), + ] + ), ), - ), - ) - ], + ) + ], + ), ), ), - ), - ) - ); - - case LoadStatus.error: - return SafeArea( - top: false, - bottom: false, - child: Builder( - builder: (context) => CustomScrollView( - slivers: [ - SliverOverlapInjector( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), - ), - SliverFillRemaining( - child: SizedBox( - width: double.maxFinite, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Icon( - Icons.error, - color: Colors.red, - size: 50, - ), - const SizedBox(height: 30), - Text( - AppLocalizations.of(context)!.logsNotLoaded, - style: TextStyle( - fontSize: 22, - color: Theme.of(context).colorScheme.onSurfaceVariant, + ) + ); + + case LoadStatus.error: + return SafeArea( + top: false, + bottom: false, + child: Builder( + builder: (context) => CustomScrollView( + slivers: [ + SliverOverlapInjector( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + ), + SliverFillRemaining( + child: SizedBox( + width: double.maxFinite, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Icon( + Icons.error, + color: Colors.red, + size: 50, ), - ) - ], - ), + const SizedBox(height: 30), + Text( + AppLocalizations.of(context)!.logsNotLoaded, + style: TextStyle( + fontSize: 22, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ) + ], + ), + ) ) - ) - ], - ), - ) - ); - - default: - return const SizedBox(); - } - }, - ) + ], + ), + ) + ); + + default: + return const SizedBox(); + } + }, + ) + ), ), ); } diff --git a/lib/screens/settings/settings.dart b/lib/screens/settings/settings.dart index 718593e..bce5e11 100644 --- a/lib/screens/settings/settings.dart +++ b/lib/screens/settings/settings.dart @@ -83,7 +83,7 @@ class _SettingsWidget extends StatefulWidget { } class _SettingsWidgetState extends State<_SettingsWidget> { - final scaffoldMessengerKey = GlobalKey(); + final _scaffoldMessengerKey = GlobalKey(); @override void initState() { @@ -104,7 +104,7 @@ class _SettingsWidgetState extends State<_SettingsWidget> { } return ScaffoldMessenger( - key: widget.twoColumns ? scaffoldMessengerKey : null, + key: widget.twoColumns ? _scaffoldMessengerKey : null, child: Scaffold( body: NestedScrollView( headerSliverBuilder: (context, innerBoxIsScrolled) => [ From 9de9b0afecd7664d19baedb982bedc7c6e8092a9 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 14:49:30 +0100 Subject: [PATCH 04/11] Fixed statistics config updated text --- lib/l10n/app_en.arb | 2 ++ lib/l10n/app_es.arb | 2 ++ .../settings/statistics_settings/statistics_settings.dart | 8 ++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 439dac5..dc938f5 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -754,6 +754,8 @@ "statisticsSettingsDescription": "Configure data collection for statistics", "loadingStatisticsSettings": "Loading statistics settings...", "statisticsSettingsLoadError": "An error occured when loading statistics settings.", + "statisticsConfigUpdated": "Statistics settings updated successfully", + "statisticsConfigNotUpdated": "Statistics settings couldn't be updated", "customTimeInHours": "Custom time (in hours)", "invalidTime": "Invalid time", "removeDomain": "Remove domain", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 79aaa7d..040beb1 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -754,6 +754,8 @@ "statisticsSettingsDescription": "Configura la recolección de datos para estadísticas", "loadingStatisticsSettings": "Cargando ajustes de estadísticas...", "statisticsSettingsLoadError": "Ocurrió un error al cargar los ajustes de estadísticas.", + "statisticsConfigNotUpdated": "La configuración de estadísticas no pudo ser actualizada.", + "statisticsConfigUpdated": "Configuración de estadísticas actualizada correctamente.", "customTimeInHours": "Tiempo personalizado (en horas)", "invalidTime": "Tiempo no válido", "removeDomain": "Eliminar dominio", diff --git a/lib/screens/settings/statistics_settings/statistics_settings.dart b/lib/screens/settings/statistics_settings/statistics_settings.dart index f514e78..27e4570 100644 --- a/lib/screens/settings/statistics_settings/statistics_settings.dart +++ b/lib/screens/settings/statistics_settings/statistics_settings.dart @@ -145,19 +145,19 @@ class _StatisticsSettingsState extends State { processModal.close(); - if (!mounted) return; + if (!context.mounted) return; if (result.successful == true) { showSnacbkar( appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.logsConfigUpdated, + label: AppLocalizations.of(context)!.statisticsConfigUpdated, color: Colors.green ); } else { showSnacbkar( appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.logsConfigNotUpdated, + label: AppLocalizations.of(context)!.statisticsConfigNotUpdated, color: Colors.red ); } @@ -209,7 +209,7 @@ class _StatisticsSettingsState extends State { if (value != null && value != "custom") { _customTimeError = null; _customTimeController.text = ""; - }; + } _retentionTime = value; }), decoration: InputDecoration( From ba2a27fef04e2f0daf819e869ea4430a39d3f867 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 14:55:40 +0100 Subject: [PATCH 05/11] Fixed fallback dns regex --- lib/l10n/app_en.arb | 3 ++- lib/l10n/app_es.arb | 3 ++- lib/screens/settings/dns/fallback_dns.dart | 5 +++-- lib/screens/settings/dns/upstream_dns.dart | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index dc938f5..89d1fb5 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -778,5 +778,6 @@ "enablePlainDns": "Enable plain DNS", "enablePlainDnsDescription": "Plain DNS is enabled by default. You can disable it to force all devices to use encrypted DNS. To do this, you must enable at least one encrypted DNS protocol.", "date": "Date", - "loadingChangelog": "Loading changelog..." + "loadingChangelog": "Loading changelog...", + "invalidIpOrUrl": "Invalid IP address or URL" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 040beb1..32fb2c6 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -778,5 +778,6 @@ "enablePlainDns": "Activar DNS simple (sin cifrado)", "enablePlainDnsDescription": "El DNS simple (sin cifrado) está activado de forma predeterminada. Puedes desactivarlo para obligar a todos los dispositivos a utilizar DNS cifrado. Para ello, debes habilitar al menos un protocolo DNS cifrado.", "date": "Fecha", - "loadingChangelog": "Cargando registro de cambios..." + "loadingChangelog": "Cargando registro de cambios...", + "invalidIpOrUrl": "Dirección IP o URL no válida" } \ No newline at end of file diff --git a/lib/screens/settings/dns/fallback_dns.dart b/lib/screens/settings/dns/fallback_dns.dart index dcae0a2..916aa90 100644 --- a/lib/screens/settings/dns/fallback_dns.dart +++ b/lib/screens/settings/dns/fallback_dns.dart @@ -24,11 +24,12 @@ class _FallbackDnsScreenState extends State { void validateIp(Map field, String value) { RegExp ipAddress = RegExp(r'(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$)'); - if (ipAddress.hasMatch(value) == true) { + RegExp url = RegExp(r'(https?|tls):\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)'); + if (ipAddress.hasMatch(value) == true || url.hasMatch(value) == true) { setState(() => field['error'] = null); } else { - setState(() => field['error'] = AppLocalizations.of(context)!.invalidIp); + setState(() => field['error'] = AppLocalizations.of(context)!.invalidIpOrUrl); } checkValidValues(); } diff --git a/lib/screens/settings/dns/upstream_dns.dart b/lib/screens/settings/dns/upstream_dns.dart index e540053..7f83fd8 100644 --- a/lib/screens/settings/dns/upstream_dns.dart +++ b/lib/screens/settings/dns/upstream_dns.dart @@ -263,7 +263,7 @@ class _UpstreamDnsScreenState extends State { const SizedBox(width: 4), ], ), - )).toList(), + )), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, From dac07edd893d95ef060ba9827c6b232e1c578e59 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 15:16:50 +0100 Subject: [PATCH 06/11] Changes vscode rules --- .vscode/settings.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9ad1ad1..791c93f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { "editor.formatOnSave": false, + "editor.formatOnPaste": false, + "editor.formatOnType": false, "editor.defaultFormatter": "Dart-Code.flutter", "dart.lineLength": 120, "[dart]": { @@ -8,5 +10,7 @@ ], "editor.defaultFormatter": "Dart-Code.dart-code", "editor.formatOnSave": false, + "editor.formatOnPaste": false, + "editor.formatOnType": false } } \ No newline at end of file From 133d29aa91ebe2d40d79b727cc842d9b3a53a75f Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 15:17:11 +0100 Subject: [PATCH 07/11] Bump compileSdkVersion and targetSdkVersion android --- android/app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 8ab520c..29785d0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -29,7 +29,7 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 33 + compileSdkVersion 34 ndkVersion flutter.ndkVersion compileOptions { @@ -51,7 +51,7 @@ android { // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion 26 - targetSdkVersion 33 + targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } From 7c0b592715f4a292140eb902442a7ea0225eb33b Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 15:17:27 +0100 Subject: [PATCH 08/11] Changed handling of comments fallback dns --- lib/screens/settings/dns/fallback_dns.dart | 95 +++++++++++++++++++--- lib/screens/settings/dns/upstream_dns.dart | 2 +- 2 files changed, 84 insertions(+), 13 deletions(-) diff --git a/lib/screens/settings/dns/fallback_dns.dart b/lib/screens/settings/dns/fallback_dns.dart index 916aa90..8c45af8 100644 --- a/lib/screens/settings/dns/fallback_dns.dart +++ b/lib/screens/settings/dns/fallback_dns.dart @@ -1,5 +1,6 @@ -// ignore_for_file: use_build_context_synchronously +import 'dart:io'; +import 'package:adguard_home_manager/screens/settings/dns/comment_modal.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -48,12 +49,20 @@ class _FallbackDnsScreenState extends State { final dnsProvider = Provider.of(context, listen: false); for (var item in dnsProvider.dnsInfo!.fallbackDns!) { - final controller = TextEditingController(); - controller.text = item; - fallbackControllers.add({ - 'controller': controller, - 'error': null - }); + if (item.contains("#")) { + fallbackControllers.add({ + 'comment': item + }); + } + else { + final controller = TextEditingController(); + controller.text = item; + fallbackControllers.add({ + 'controller': controller, + 'error': null, + 'isComment': item.contains("#") + }); + } } validValues = true; super.initState(); @@ -71,11 +80,16 @@ class _FallbackDnsScreenState extends State { processModal.open(AppLocalizations.of(context)!.savingConfig); final result = await dnsProvider.saveFallbackDnsConfig({ - "fallback_dns": fallbackControllers.map((e) => e['controller'].text).toList(), + "fallback_dns": fallbackControllers.map( + (e) => e['controller'] != null + ? e['controller'].text + : e['comment'] + ).toList(), }); processModal.close(); + if (!context.mounted) return; if (result.successful == true) { showSnacbkar( appConfigProvider: appConfigProvider, @@ -99,6 +113,37 @@ class _FallbackDnsScreenState extends State { } } + void openEditCommentModal(Map item, int position) { + if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) { + showDialog( + context: context, + builder: (context) => CommentModal( + comment: item['comment'], + onConfirm: (value) { + setState(() => fallbackControllers[position] = { 'comment': value }); + }, + dialog: true, + ), + ); + } + else { + showModalBottomSheet( + context: context, + useRootNavigator: true, + builder: (context) => CommentModal( + comment: item['comment'], + onConfirm: (value) { + setState(() => fallbackControllers[position] = { 'comment': value }); + }, + dialog: false, + ), + backgroundColor: Colors.transparent, + isScrollControlled: true, + isDismissible: true + ); + } + } + return Scaffold( appBar: AppBar( title: Text(AppLocalizations.of(context)!.fallbackDnsServers), @@ -168,29 +213,55 @@ class _FallbackDnsScreenState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded( + if (c['controller'] != null) Expanded( child: TextFormField( controller: c['controller'], onChanged: (value) => validateIp(c, value), decoration: InputDecoration( - prefixIcon: const Icon(Icons.dns_rounded), + prefixIcon: Icon( + c['isComment'] == true + ? Icons.comment_rounded + : Icons.dns_rounded + ), border: const OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(10) ) ), errorText: c['error'], - labelText: AppLocalizations.of(context)!.dnsServer, + labelText: c['isComment'] == true + ? AppLocalizations.of(context)!.comment + : AppLocalizations.of(context)!.dnsServer, ) ), ), const SizedBox(width: 8), + if (c['comment'] != null) Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + c['comment'], + style: TextStyle( + fontSize: 16, + color: Theme.of(context).listTileTheme.iconColor + ), + ), + IconButton( + onPressed: () => openEditCommentModal(c, fallbackControllers.indexOf(c)), + icon: const Icon(Icons.edit), + tooltip: AppLocalizations.of(context)!.edit, + ) + ], + ), + ), IconButton( onPressed: () { setState(() => fallbackControllers = fallbackControllers.where((con) => con != c).toList()); checkValidValues(); }, - icon: const Icon(Icons.remove_circle_outline) + icon: const Icon(Icons.remove_circle_outline), + tooltip: AppLocalizations.of(context)!.remove, ) ], ), diff --git a/lib/screens/settings/dns/upstream_dns.dart b/lib/screens/settings/dns/upstream_dns.dart index 7f83fd8..c99c9bc 100644 --- a/lib/screens/settings/dns/upstream_dns.dart +++ b/lib/screens/settings/dns/upstream_dns.dart @@ -47,7 +47,7 @@ class _UpstreamDnsScreenState extends State { final dnsProvider = Provider.of(context, listen: false); for (var item in dnsProvider.dnsInfo!.upstreamDns) { - if (item == '#') { + if (item.contains("#")) { dnsServers.add({ 'comment': item }); From 019367ca933513f8a643340456350341af6ed849 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 15:29:56 +0100 Subject: [PATCH 09/11] Fix hour mismatch home charts --- lib/screens/home/chart.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/home/chart.dart b/lib/screens/home/chart.dart index 0093ae8..ac1fce5 100644 --- a/lib/screens/home/chart.dart +++ b/lib/screens/home/chart.dart @@ -43,7 +43,7 @@ class _HomeChartState extends State { if (!(appConfigProvider.hideZeroValues == true && isEmpty == true)) { List dateTimes = []; - DateTime currentDate = DateTime.now().subtract(Duration(hours: widget.hoursInterval*widget.data.length+1)); + DateTime currentDate = DateTime.now().subtract(Duration(hours: widget.hoursInterval*widget.data.length)); for (var i = 0; i < widget.data.length; i++) { currentDate = currentDate.add(Duration(hours: widget.hoursInterval)); dateTimes.add(currentDate); From 654284b46ac4fc5acfaa1ef66637364f76b2ef96 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 15:33:26 +0100 Subject: [PATCH 10/11] Added add comment fallback dns --- lib/screens/settings/dns/fallback_dns.dart | 47 +++++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/screens/settings/dns/fallback_dns.dart b/lib/screens/settings/dns/fallback_dns.dart index 8c45af8..849eb4d 100644 --- a/lib/screens/settings/dns/fallback_dns.dart +++ b/lib/screens/settings/dns/fallback_dns.dart @@ -113,6 +113,44 @@ class _FallbackDnsScreenState extends State { } } + void openAddCommentModal() { + if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) { + showDialog( + context: context, + builder: (context) => CommentModal( + onConfirm: (value) { + setState(() { + fallbackControllers.add({ + 'comment': value + }); + }); + }, + dialog: true, + ), + ); + } + else { + showModalBottomSheet( + context: context, + useRootNavigator: true, + builder: (context) => CommentModal( + onConfirm: (value) { + setState(() { + fallbackControllers.add({ + 'comment': value + }); + }); + }, + dialog: false, + ), + backgroundColor: Colors.transparent, + isScrollControlled: true, + isDismissible: true + ); + } + } + + void openEditCommentModal(Map item, int position) { if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) { showDialog( @@ -267,9 +305,14 @@ class _FallbackDnsScreenState extends State { ), )), Row( - mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisSize: MainAxisSize.min, children: [ + ElevatedButton.icon( + onPressed: openAddCommentModal, + icon: const Icon(Icons.add), + label: Text(AppLocalizations.of(context)!.comment) + ), ElevatedButton.icon( onPressed: () { setState(() => fallbackControllers.add({ @@ -279,7 +322,7 @@ class _FallbackDnsScreenState extends State { checkValidValues(); }, icon: const Icon(Icons.add), - label: Text(AppLocalizations.of(context)!.addItem) + label: Text(AppLocalizations.of(context)!.address) ), ], ), From 59a7a31a4f5339bd39c27e39e4103cf8dd0eec0b Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Thu, 29 Feb 2024 15:34:11 +0100 Subject: [PATCH 11/11] Updated app version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 3ef7c66..70e1dff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 2.16.3+133 +version: 2.16.4+134 environment: sdk: '>=2.18.1 <3.0.0'