diff --git a/.github/workflows/release-beta.yaml b/.github/workflows/release-beta.yaml index 3ded1c1..854ee28 100644 --- a/.github/workflows/release-beta.yaml +++ b/.github/workflows/release-beta.yaml @@ -24,10 +24,10 @@ jobs: - name: Decode .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env - name: Read pubspec.yaml - uses: adore-me/read-yaml@v1.0.0 + uses: JGeek00/read-yaml-files@2.0.0 id: read_pubspec with: - file: './pubspec.yaml' + file: './pubspec.yaml' # File to read from key-path: '["version"]' - name: Save version on env variable id: save_version diff --git a/.github/workflows/release-stable.yaml b/.github/workflows/release-stable.yaml index 01630ac..0b0ae0c 100644 --- a/.github/workflows/release-stable.yaml +++ b/.github/workflows/release-stable.yaml @@ -22,7 +22,7 @@ jobs: - name: Decode .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env - name: Read pubspec.yaml - uses: jbutcher5/read-yaml@1.6 + uses: JGeek00/read-yaml-files@2.0.0 id: read_pubspec with: file: './pubspec.yaml' # File to read from @@ -79,7 +79,7 @@ jobs: - name: Decode .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env - name: Read pubspec.yaml - uses: jbutcher5/read-yaml@1.6 + uses: JGeek00/read-yaml-files@2.0.0 id: read_pubspec with: file: './pubspec.yaml' @@ -139,7 +139,7 @@ jobs: - name: Decode .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env - name: Read pubspec.yaml - uses: jbutcher5/read-yaml@1.6 + uses: JGeek00/read-yaml-files@2.0.0 id: read_pubspec with: file: './pubspec.yaml' @@ -202,7 +202,7 @@ jobs: run: | [IO.File]::WriteAllBytes('.env', [Convert]::FromBase64String('${{ secrets.ENV }}')) - name: Read pubspec.yaml - uses: jbutcher5/read-yaml@1.6 + uses: JGeek00/read-yaml-files@2.0.0 id: read_pubspec with: file: './pubspec.yaml' diff --git a/.vscode/settings.json b/.vscode/settings.json index 791c93f..769a50d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,5 +12,9 @@ "editor.formatOnSave": false, "editor.formatOnPaste": false, "editor.formatOnType": false - } + }, + "cSpell.ignorePaths": [ + "/pubspec.yaml", + "/.github/workflows" + ] } \ No newline at end of file diff --git a/lib/functions/check_app_updates.dart b/lib/functions/check_app_updates.dart index e6137d7..504ba2c 100644 --- a/lib/functions/check_app_updates.dart +++ b/lib/functions/check_app_updates.dart @@ -1,57 +1,57 @@ -import 'dart:io'; +// import 'dart:io'; -import 'package:install_referrer/install_referrer.dart'; +// import 'package:install_referrer/install_referrer.dart'; -import 'package:adguard_home_manager/functions/compare_versions.dart'; -import 'package:adguard_home_manager/services/external_requests.dart'; -import 'package:adguard_home_manager/models/github_release.dart'; +// import 'package:adguard_home_manager/functions/compare_versions.dart'; +// import 'package:adguard_home_manager/services/external_requests.dart'; +// import 'package:adguard_home_manager/models/github_release.dart'; -Future checkAppUpdates({ - required String currentBuildNumber, - required void Function(GitHubRelease?) setUpdateAvailable, - required InstallationAppReferrer? installationSource, - required bool isBeta -}) async { - var result = isBeta - ? await ExternalRequests.getReleasesGitHub() - : await ExternalRequests.getReleaseData(); +// Future checkAppUpdates({ +// required String currentBuildNumber, +// required void Function(GitHubRelease?) setUpdateAvailable, +// required InstallationAppReferrer? installationSource, +// required bool isBeta +// }) async { +// var result = isBeta +// ? await ExternalRequests.getReleasesGitHub() +// : await ExternalRequests.getReleaseData(); - if (result.successful == true) { - late GitHubRelease gitHubRelease; - if (isBeta) { - gitHubRelease = (result.content as List).firstWhere((r) => r.prerelease == true); - } - else { - gitHubRelease = result.content as GitHubRelease; - } +// if (result.successful == true) { +// late GitHubRelease gitHubRelease; +// if (isBeta) { +// gitHubRelease = (result.content as List).firstWhere((r) => r.prerelease == true); +// } +// else { +// gitHubRelease = result.content as GitHubRelease; +// } - final update = gitHubUpdateExists( - currentBuildNumber: currentBuildNumber, - gitHubRelease: gitHubRelease, - isBeta: isBeta - ); +// final update = gitHubUpdateExists( +// currentBuildNumber: currentBuildNumber, +// gitHubRelease: gitHubRelease, +// isBeta: isBeta +// ); - if (update == true) { - setUpdateAvailable(gitHubRelease); +// if (update == true) { +// setUpdateAvailable(gitHubRelease); - if (Platform.isAndroid) { - if (installationSource == InstallationAppReferrer.androidManually) { - return gitHubRelease; - } - else { - return null; - } - } - else if (Platform.isIOS) { - return null; - } - else { - return gitHubRelease; - } - } - else { - setUpdateAvailable(null); - } - } - return null; -} \ No newline at end of file +// if (Platform.isAndroid) { +// if (installationSource == InstallationAppReferrer.androidManually) { +// return gitHubRelease; +// } +// else { +// return null; +// } +// } +// else if (Platform.isIOS) { +// return null; +// } +// else { +// return gitHubRelease; +// } +// } +// else { +// setUpdateAvailable(null); +// } +// } +// return null; +// } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index ecd9f7e..10b1862 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:install_referrer/install_referrer.dart'; import 'package:provider/provider.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:dynamic_color/dynamic_color.dart'; @@ -79,11 +78,6 @@ void main() async { HttpOverrides.global = MyHttpOverrides(); } - if (Platform.isAndroid || Platform.isIOS) { - InstallationAppReferrer installationSource = await InstallReferrer.referrer; - appConfigProvider.setInstallationSource(installationSource); - } - final dbData = await loadDb(); serversProvider.setDbInstance(dbData['dbInstance']); serversProvider.saveFromDb(dbData['servers']); @@ -169,6 +163,20 @@ void main() async { (options) { options.dsn = dotenv.env['SENTRY_DSN']; options.sendDefaultPii = false; + options.beforeSend = (event, hint) { + if (event.throwable is HttpException) { + 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 event; + }; }, appRunner: () => startApp() ); diff --git a/lib/models/dns_statistics.dart b/lib/models/dns_statistics.dart index f279886..ca6c247 100644 --- a/lib/models/dns_statistics.dart +++ b/lib/models/dns_statistics.dart @@ -5,7 +5,7 @@ DnsStatistics dnsStatisticsFromJson(String str) => DnsStatistics.fromJson(json.d String dnsStatisticsToJson(DnsStatistics data) => json.encode(data.toJson()); class DnsStatistics { - final String timeUnits; + final String? timeUnits; final List> topQueriedDomains; final List> topClients; final List> topBlockedDomains; diff --git a/lib/providers/dns_provider.dart b/lib/providers/dns_provider.dart index 198053b..a59c3c5 100644 --- a/lib/providers/dns_provider.dart +++ b/lib/providers/dns_provider.dart @@ -151,20 +151,26 @@ class DnsProvider with ChangeNotifier { final result = await _serversProvider!.apiClient2!.setDnsConfig( data: value ); + + void updateValue(dynamic parameter, dynamic value) { + if (value != null) { + parameter = value; + } + } if (result.successful == true) { DnsInfo data = dnsInfo!; - data.ratelimit = value['ratelimit']; - data.ednsCsEnabled = value['edns_cs_enabled']; - data.dnssecEnabled = value['dnssec_enabled']; - data.disableIpv6 = value['disable_ipv6']; - data.blockingMode = value['blocking_mode']; - data.blockingIpv4 = value['blocking_ipv4']; - data.blockingIpv6 = value['blocking_ipv6']; - data.blockedResponseTtl = value['blocked_response_ttl']; - data.ratelimitSubnetLenIpv4 = value['ratelimit_subnet_len_ipv4']; - data.ratelimitSubnetLenIpv6 = value['ratelimit_subnet_len_ipv6']; - data.ratelimitWhitelist = value['ratelimit_whitelist']; + updateValue(data.ratelimit, value['ratelimit']); + updateValue(data.ednsCsEnabled, value['edns_cs_enabled']); + updateValue(data.dnssecEnabled, value['dnssec_enabled']); + updateValue(data.disableIpv6, value['disable_ipv6']); + updateValue(data.blockingMode, value['blocking_mode']); + updateValue(data.blockingIpv4, value['blocking_ipv4']); + updateValue(data.blockingIpv6, value['blocking_ipv6']); + updateValue(data.blockedResponseTtl, value['blocked_response_ttl']); + updateValue(data.ratelimitSubnetLenIpv4, value['ratelimit_subnet_len_ipv4']); + updateValue(data.ratelimitSubnetLenIpv6, value['ratelimit_subnet_len_ipv6']); + updateValue(data.ratelimitWhitelist, value['ratelimit_whitelist']); setDnsInfoData(data); return result; } diff --git a/lib/screens/filters/add_button.dart b/lib/screens/filters/add_button.dart index 2eca7d4..1621b68 100644 --- a/lib/screens/filters/add_button.dart +++ b/lib/screens/filters/add_button.dart @@ -137,6 +137,8 @@ class AddFiltersButton extends StatelessWidget { } void confirmAddList({required String name, required String url, required String type}) async { + if (!context.mounted) return; + ProcessModal processModal = ProcessModal(); processModal.open(AppLocalizations.of(context)!.addingList); diff --git a/lib/screens/filters/custom_rules_list.dart b/lib/screens/filters/custom_rules_list.dart index 304972f..4cd5bde 100644 --- a/lib/screens/filters/custom_rules_list.dart +++ b/lib/screens/filters/custom_rules_list.dart @@ -162,7 +162,7 @@ class _CustomRulesListState extends State { TextButton.icon( onPressed: () async { final result = await filteringProvider.fetchFilters(); - if (result == false) { + if (result == false && context.mounted) { showSnackbar( appConfigProvider: appConfigProvider, label: AppLocalizations.of(context)!.errorLoadFilters, diff --git a/lib/screens/home/appbar.dart b/lib/screens/home/appbar.dart index 5cd481f..d4b447c 100644 --- a/lib/screens/home/appbar.dart +++ b/lib/screens/home/appbar.dart @@ -34,6 +34,7 @@ class HomeAppBar extends StatelessWidget { void navigateServers() { Future.delayed(const Duration(milliseconds: 0), (() { + if (!context.mounted) return; Navigator.of(context).push( MaterialPageRoute(builder: (context) => const Servers()) ); diff --git a/lib/screens/logs/filters/clients_modal.dart b/lib/screens/logs/filters/clients_modal.dart index 403f098..ef0e989 100644 --- a/lib/screens/logs/filters/clients_modal.dart +++ b/lib/screens/logs/filters/clients_modal.dart @@ -115,7 +115,7 @@ class _ClientsModalState extends State { void searchAddedClient(_ClientLog client) { final notIps = client.ids?.where((e) => isIpAddress(e) == false).toList(); - if (notIps == null) return; + if (notIps == null || notIps.isEmpty) return; logsProvider.setSearchText('"${notIps[0]}"'); Navigator.of(context).pop(); } diff --git a/lib/screens/logs/log_tile.dart b/lib/screens/logs/log_tile.dart index bed2e40..342817f 100644 --- a/lib/screens/logs/log_tile.dart +++ b/lib/screens/logs/log_tile.dart @@ -96,6 +96,8 @@ class LogTile extends StatelessWidget { } void blockUnblock({required String domain, required String newStatus}) async { + if (!context.mounted) return; + final ProcessModal processModal = ProcessModal(); processModal.open(AppLocalizations.of(context)!.savingUserFilters); @@ -124,6 +126,8 @@ class LogTile extends StatelessWidget { } void confirmAddClient(Client client) async { + if (!context.mounted) return; + ProcessModal processModal = ProcessModal(); processModal.open(AppLocalizations.of(context)!.addingClient); diff --git a/lib/screens/settings/general_settings/general_settings.dart b/lib/screens/settings/general_settings/general_settings.dart index 0029752..f32446d 100644 --- a/lib/screens/settings/general_settings/general_settings.dart +++ b/lib/screens/settings/general_settings/general_settings.dart @@ -1,9 +1,4 @@ -// ignore_for_file: use_build_context_synchronously - -import 'dart:io'; - import 'package:flutter/material.dart'; -import 'package:install_referrer/install_referrer.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -13,11 +8,8 @@ import 'package:adguard_home_manager/screens/settings/general_settings/top_items import 'package:adguard_home_manager/widgets/custom_list_tile.dart'; import 'package:adguard_home_manager/widgets/section_label.dart'; -import 'package:adguard_home_manager/functions/check_app_updates.dart'; import 'package:adguard_home_manager/functions/desktop_mode.dart'; import 'package:adguard_home_manager/functions/snackbar.dart'; -import 'package:adguard_home_manager/functions/open_url.dart'; -import 'package:adguard_home_manager/functions/app_update_download_link.dart'; import 'package:adguard_home_manager/providers/app_config_provider.dart'; class GeneralSettings extends StatefulWidget { @@ -48,6 +40,7 @@ class _GeneralSettingsState extends State { required Future Function(bool) function }) async { final result = await function(newStatus); + if (!context.mounted) return; if (result == true) { showSnackbar( appConfigProvider: appConfigProvider, @@ -64,60 +57,60 @@ class _GeneralSettingsState extends State { } } - Future checkUpdatesAvailable() async { - setState(() => appUpdatesStatus = AppUpdatesStatus.checking); + // Future checkUpdatesAvailable() async { + // setState(() => appUpdatesStatus = AppUpdatesStatus.checking); - final res = await checkAppUpdates( - currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber, - setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable, - installationSource: appConfigProvider.installationSource, - isBeta: appConfigProvider.getAppInfo!.version.contains('beta'), - ); + // final res = await checkAppUpdates( + // currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber, + // setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable, + // installationSource: appConfigProvider.installationSource, + // isBeta: appConfigProvider.getAppInfo!.version.contains('beta'), + // ); - if (!mounted) return; - if (res != null) { - setState(() => appUpdatesStatus = AppUpdatesStatus.available); - } - else { - setState(() => appUpdatesStatus = AppUpdatesStatus.recheck); - } - } + // if (!mounted) return; + // if (res != null) { + // setState(() => appUpdatesStatus = AppUpdatesStatus.available); + // } + // else { + // setState(() => appUpdatesStatus = AppUpdatesStatus.recheck); + // } + // } - Widget generateAppUpdateStatus() { - if (appUpdatesStatus == AppUpdatesStatus.available) { - return IconButton( - onPressed: appConfigProvider.appUpdatesAvailable != null - ? () async { - final link = getAppUpdateDownloadLink(appConfigProvider.appUpdatesAvailable!); - if (link != null) { - openUrl(link); - } - } - : null, - icon: const Icon(Icons.download_rounded), - tooltip: AppLocalizations.of(context)!.downloadUpdate, - ); - } - else if (appUpdatesStatus == AppUpdatesStatus.checking) { - return const Padding( - padding: EdgeInsets.only(right: 16), - child: SizedBox( - width: 24, - height: 24, - child: CircularProgressIndicator( - strokeWidth: 3, - ) - ), - ); - } - else { - return IconButton( - onPressed: checkUpdatesAvailable, - icon: const Icon(Icons.refresh_rounded), - tooltip: AppLocalizations.of(context)!.checkUpdates, - ); - } - } + // Widget generateAppUpdateStatus() { + // if (appUpdatesStatus == AppUpdatesStatus.available) { + // return IconButton( + // onPressed: appConfigProvider.appUpdatesAvailable != null + // ? () async { + // final link = getAppUpdateDownloadLink(appConfigProvider.appUpdatesAvailable!); + // if (link != null) { + // openUrl(link); + // } + // } + // : null, + // icon: const Icon(Icons.download_rounded), + // tooltip: AppLocalizations.of(context)!.downloadUpdate, + // ); + // } + // else if (appUpdatesStatus == AppUpdatesStatus.checking) { + // return const Padding( + // padding: EdgeInsets.only(right: 16), + // child: SizedBox( + // width: 24, + // height: 24, + // child: CircularProgressIndicator( + // strokeWidth: 3, + // ) + // ), + // ); + // } + // else { + // return IconButton( + // onPressed: checkUpdatesAvailable, + // icon: const Icon(Icons.refresh_rounded), + // tooltip: AppLocalizations.of(context)!.checkUpdates, + // ); + // } + // } return Scaffold( appBar: AppBar( @@ -253,17 +246,17 @@ class _GeneralSettingsState extends State { right: 10 ) ), - if (!(Platform.isAndroid || Platform.isIOS) || (Platform.isAndroid && (appConfigProvider.installationSource == InstallationAppReferrer.androidManually ))) ...[ - SectionLabel(label: AppLocalizations.of(context)!.application), - CustomListTile( - icon: Icons.system_update_rounded, - title: AppLocalizations.of(context)!.appUpdates, - subtitle: appConfigProvider.appUpdatesAvailable != null - ? AppLocalizations.of(context)!.updateAvailable - : AppLocalizations.of(context)!.usingLatestVersion, - trailing: generateAppUpdateStatus() - ) - ] + // if (!(Platform.isAndroid || Platform.isIOS) || (Platform.isAndroid && (appConfigProvider.installationSource == InstallationAppReferrer.androidManually ))) ...[ + // SectionLabel(label: AppLocalizations.of(context)!.application), + // CustomListTile( + // icon: Icons.system_update_rounded, + // title: AppLocalizations.of(context)!.appUpdates, + // subtitle: appConfigProvider.appUpdatesAvailable != null + // ? AppLocalizations.of(context)!.updateAvailable + // : AppLocalizations.of(context)!.usingLatestVersion, + // trailing: generateAppUpdateStatus() + // ) + // ] ], ), ) diff --git a/lib/screens/settings/statistics_settings/statistics_settings.dart b/lib/screens/settings/statistics_settings/statistics_settings.dart index 67a2989..7f58d67 100644 --- a/lib/screens/settings/statistics_settings/statistics_settings.dart +++ b/lib/screens/settings/statistics_settings/statistics_settings.dart @@ -138,7 +138,7 @@ class _StatisticsSettingsState extends State { "enabled": _generalSwitch, "interval": _retentionTime == "custom" ? Duration(hours: int.parse(_customTimeController.text)).inMilliseconds - : int.parse(_retentionTime!), + : int.parse(_retentionTime ?? _retentionItems[0]), "ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList() } ); diff --git a/lib/widgets/layout.dart b/lib/widgets/layout.dart index 9a42415..119bee1 100644 --- a/lib/widgets/layout.dart +++ b/lib/widgets/layout.dart @@ -1,14 +1,10 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:animations/animations.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:adguard_home_manager/widgets/update_modal.dart'; import 'package:adguard_home_manager/widgets/system_ui_overlay_style.dart'; -import 'package:adguard_home_manager/functions/check_app_updates.dart'; -import 'package:adguard_home_manager/functions/open_url.dart'; import 'package:adguard_home_manager/providers/app_config_provider.dart'; import 'package:adguard_home_manager/config/app_screens.dart'; import 'package:adguard_home_manager/config/sizes.dart'; @@ -37,23 +33,23 @@ class _LayoutState extends State with WidgetsBindingObserver { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) async { - if (kDebugMode) return; // Don't check for app updates on debug mode - final appConfigProvider = Provider.of(context, listen: false); - final result = await checkAppUpdates( - currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber, - installationSource: appConfigProvider.installationSource, - setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable, - isBeta: appConfigProvider.getAppInfo!.version.contains('beta'), - ); - if (result != null && appConfigProvider.doNotRememberVersion != result.tagName && mounted) { - await showDialog( - context: context, - builder: (context) => UpdateModal( - gitHubRelease: result, - onDownload: (link, version) => openUrl(link), - ), - ); - } + // if (kDebugMode) return; // Don't check for app updates on debug mode + // final appConfigProvider = Provider.of(context, listen: false); + // final result = await checkAppUpdates( + // currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber, + // installationSource: appConfigProvider.installationSource, + // setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable, + // isBeta: appConfigProvider.getAppInfo!.version.contains('beta'), + // ); + // if (result != null && appConfigProvider.doNotRememberVersion != result.tagName && mounted) { + // await showDialog( + // context: context, + // builder: (context) => UpdateModal( + // gitHubRelease: result, + // onDownload: (link, version) => openUrl(link), + // ), + // ); + // } }); } diff --git a/pubspec.yaml b/pubspec.yaml index f821dbf..2fd5ee4 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.19.0+143 +version: 2.19.1+144 environment: sdk: '>=2.18.1 <3.0.0'