diff --git a/.vscode/settings.json b/.vscode/settings.json index 769a50d..553928e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,5 +16,6 @@ "cSpell.ignorePaths": [ "/pubspec.yaml", "/.github/workflows" - ] + ], + "dart.flutterRunAdditionalArgs": [ "--no-enable-impeller" ] } \ No newline at end of file diff --git a/debian/debian.yaml b/debian/debian.yaml index 046659c..43a90f9 100644 --- a/debian/debian.yaml +++ b/debian/debian.yaml @@ -5,7 +5,7 @@ flutter_app: control: Package: AdGuardHomeManager - Version: 2.20.0 + Version: 2.20.1 Architecture: amd64 Essential: no Priority: optional diff --git a/lib/functions/open_url.dart b/lib/functions/open_url.dart index 00cfc17..599eea0 100644 --- a/lib/functions/open_url.dart +++ b/lib/functions/open_url.dart @@ -5,6 +5,15 @@ import 'package:url_launcher/url_launcher.dart' as url_launcher; import 'package:sentry_flutter/sentry_flutter.dart'; void openUrl(String url) async { + if (!(url.startsWith("http") || url.startsWith("https"))) { + try { + url_launcher.launchUrl(Uri.parse(url)); + } catch (e, stackTrace) { + Sentry.captureException(e, stackTrace: stackTrace); + } + return; + } + if (Platform.isAndroid || Platform.isIOS) { try { await flutter_custom_tabs.launchUrl( @@ -20,6 +29,7 @@ void openUrl(String url) async { ), ); } catch (e, stackTrace) { + url_launcher.launchUrl(Uri.parse(url)); Sentry.captureException(e, stackTrace: stackTrace); } } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 4602c27..fa952aa 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -800,8 +800,8 @@ "hereWillAppearRealtimeLogs": "Here there will appear the logs on realtime.", "applicationDetails": "Application details", "applicationDetailsDescription": "App repository, stores where it's available, and more", - "myOtherApps": "Check my other apps", - "myOtherAppsDescription": "Created by JGeek00", + "myOtherApps": "My other apps", + "myOtherAppsDescription": "Check my other apps, make a donation, contact support, and more", "topToBottom": "From top to bottom", "bottomToTop": "From bottom to top" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 862e375..d18f8a9 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -800,8 +800,8 @@ "hereWillAppearRealtimeLogs": "Aquí aparecerán los registros en tiempo real.", "applicationDetails": "Detalles de la aplicación", "applicationDetailsDescription": "Repositorio de la app, tiendas donde está disponible, y más", - "myOtherApps": "Comprueba mis otras apps", - "myOtherAppsDescription": "Creadas por JGeek00", + "myOtherApps": "Mis otras apps", + "myOtherAppsDescription": "Comprueba mis otras apps, hacer una donación, contactar al soporte, y más", "topToBottom": "Desde arriba hacia abajo", "bottomToTop": "Desde abajo hacia arriba" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 10b1862..61126da 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -168,11 +168,22 @@ void main() async { return null; } + if (event.message?.formatted.contains("HttpException") == true) { + return null; + } + if ( event.message?.formatted.contains("Unexpected character") ?? false || (event.throwable != null && event.throwable!.toString().contains("Unexpected character")) ) { - return null; // Exclude this event + return null; + } + + if ( + event.message?.formatted.contains("Unexpected end of input") ?? false || + (event.throwable != null && event.throwable!.toString().contains("Unexpected end of input")) + ) { + return null; } return event; diff --git a/lib/models/dns_statistics.dart b/lib/models/dns_statistics.dart index ca6c247..ed787ce 100644 --- a/lib/models/dns_statistics.dart +++ b/lib/models/dns_statistics.dart @@ -43,9 +43,9 @@ class DnsStatistics { factory DnsStatistics.fromJson(Map json) => DnsStatistics( timeUnits: json["time_units"], - topQueriedDomains: List>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))), - topClients: List>.from(json["top_clients"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))), - topBlockedDomains: List>.from(json["top_blocked_domains"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))), + topQueriedDomains: json["top_queried_domains"] != null ? List>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))) : [], + topClients: json["top_clients"] != null ? List>.from(json["top_clients"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))) : [], + topBlockedDomains: json["top_blocked_domains"] != null ? List>.from(json["top_blocked_domains"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))): [], topUpstreamResponses: json["top_upstreams_responses"] != null ? List>.from(json["top_upstreams_responses"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))) : null, topUpstreamsAvgTime: json["top_upstreams_avg_time"] != null ? List>.from(json["top_upstreams_avg_time"].map((x) => Map.from(x).map((k, v) => MapEntry(k, v)))) : null, dnsQueries: List.from(json["dns_queries"].map((x) => x)), diff --git a/lib/screens/clients/fab.dart b/lib/screens/clients/fab.dart index 383a2f3..9571ae3 100644 --- a/lib/screens/clients/fab.dart +++ b/lib/screens/clients/fab.dart @@ -25,10 +25,14 @@ class ClientsFab extends StatelessWidget { final width = MediaQuery.of(context).size.width; void confirmAddClient(Client client) async { + if (!context.mounted) return; + ProcessModal processModal = ProcessModal(); processModal.open(AppLocalizations.of(context)!.addingClient); final result = await clientsProvider.addClient(client); + + if (!context.mounted) return; processModal.close(); diff --git a/lib/screens/filters/add_button.dart b/lib/screens/filters/add_button.dart index 1621b68..e2de2ff 100644 --- a/lib/screens/filters/add_button.dart +++ b/lib/screens/filters/add_button.dart @@ -33,6 +33,8 @@ class AddFiltersButton extends StatelessWidget { final width = MediaQuery.of(context).size.width; void confirmAddRule(String rule) async { + if (!context.mounted) return; + ProcessModal processModal = ProcessModal(); processModal.open(AppLocalizations.of(context)!.addingRule); @@ -58,6 +60,8 @@ class AddFiltersButton extends StatelessWidget { } void confirmEditCustomRules(List rules) async { + if (!context.mounted) return; + ProcessModal processModal = ProcessModal(); processModal.open(AppLocalizations.of(context)!.savingCustomRules); diff --git a/lib/screens/logs/log_tile.dart b/lib/screens/logs/log_tile.dart index 342817f..dc33048 100644 --- a/lib/screens/logs/log_tile.dart +++ b/lib/screens/logs/log_tile.dart @@ -154,6 +154,8 @@ class LogTile extends StatelessWidget { } void blockUnblockRuleClient() async { + if (!context.mounted) return; + ProcessModal processModal = ProcessModal(); processModal.open(AppLocalizations.of(context)!.addingRule); diff --git a/lib/screens/logs/logs_list_appbar.dart b/lib/screens/logs/logs_list_appbar.dart index 2a052f6..21e03b1 100644 --- a/lib/screens/logs/logs_list_appbar.dart +++ b/lib/screens/logs/logs_list_appbar.dart @@ -89,6 +89,7 @@ class LogsListAppBar extends StatelessWidget { } void openLiveLogsScreen() { + if (!context.mounted) return; Navigator.of(context).push( MaterialPageRoute( builder: (context) => MultiProvider( diff --git a/lib/widgets/add_server/add_server_modal.dart b/lib/widgets/add_server/add_server_modal.dart index 7164ba0..a7fc768 100644 --- a/lib/widgets/add_server/add_server_modal.dart +++ b/lib/widgets/add_server/add_server_modal.dart @@ -175,6 +175,8 @@ class _AddServerModalState extends State { final ApiClientV2 apiClient2 = ApiClientV2(server: serverObj); final serverStatus = await apiClient2.getServerStatus(); + if (!context.mounted) return; + // If something goes wrong when fetching server status if (serverStatus.successful == false) { statusProvider.setServerStatusLoad(LoadStatus.error); @@ -203,16 +205,16 @@ class _AddServerModalState extends State { final serverCreated = await serversProvider.createServer(serverObj); + if (!context.mounted) return; + // If something goes wrong when saving the connection on the db if (serverCreated != null) { - if (mounted) setState(() => isConnecting = false); - if (mounted) { - showSnackbar( - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.connectionNotCreated, - color: Colors.red - ); - } + setState(() => isConnecting = false); + showSnackbar( + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.connectionNotCreated, + color: Colors.red + ); return; } @@ -295,10 +297,12 @@ class _AddServerModalState extends State { } final serverSaved = await serversProvider.editServer(serverObj); + + if (!mounted) return; // If something goes wrong when saving the connection on the db if (serverSaved != null) { - if (mounted) setState(() => isConnecting = false); + setState(() => isConnecting = false); appConfigProvider.addLog( AppLog( type: 'save_connection_db', @@ -306,13 +310,11 @@ class _AddServerModalState extends State { message: serverSaved.toString() ) ); - if (mounted) { - showSnackbar( - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.connectionNotCreated, - color: Colors.red - ); - } + showSnackbar( + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.connectionNotCreated, + color: Colors.red + ); return; } diff --git a/pubspec.yaml b/pubspec.yaml index 489dfa0..4222db1 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.20.0+147 +version: 2.20.1+148 environment: sdk: '>=2.18.1 <3.0.0'