Merge branch 'beta'

This commit is contained in:
Juan Gilsanz Polo 2024-09-12 14:47:31 +02:00
commit 9096367843
16 changed files with 184 additions and 170 deletions

View file

@ -24,10 +24,10 @@ jobs:
- name: Decode .env - name: Decode .env
run: echo "${{ secrets.ENV }}" | base64 --decode > .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env
- name: Read pubspec.yaml - name: Read pubspec.yaml
uses: adore-me/read-yaml@v1.0.0 uses: JGeek00/read-yaml-files@2.0.0
id: read_pubspec id: read_pubspec
with: with:
file: './pubspec.yaml' file: './pubspec.yaml' # File to read from
key-path: '["version"]' key-path: '["version"]'
- name: Save version on env variable - name: Save version on env variable
id: save_version id: save_version

View file

@ -22,7 +22,7 @@ jobs:
- name: Decode .env - name: Decode .env
run: echo "${{ secrets.ENV }}" | base64 --decode > .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env
- name: Read pubspec.yaml - name: Read pubspec.yaml
uses: jbutcher5/read-yaml@1.6 uses: JGeek00/read-yaml-files@2.0.0
id: read_pubspec id: read_pubspec
with: with:
file: './pubspec.yaml' # File to read from file: './pubspec.yaml' # File to read from
@ -79,7 +79,7 @@ jobs:
- name: Decode .env - name: Decode .env
run: echo "${{ secrets.ENV }}" | base64 --decode > .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env
- name: Read pubspec.yaml - name: Read pubspec.yaml
uses: jbutcher5/read-yaml@1.6 uses: JGeek00/read-yaml-files@2.0.0
id: read_pubspec id: read_pubspec
with: with:
file: './pubspec.yaml' file: './pubspec.yaml'
@ -139,7 +139,7 @@ jobs:
- name: Decode .env - name: Decode .env
run: echo "${{ secrets.ENV }}" | base64 --decode > .env run: echo "${{ secrets.ENV }}" | base64 --decode > .env
- name: Read pubspec.yaml - name: Read pubspec.yaml
uses: jbutcher5/read-yaml@1.6 uses: JGeek00/read-yaml-files@2.0.0
id: read_pubspec id: read_pubspec
with: with:
file: './pubspec.yaml' file: './pubspec.yaml'
@ -202,7 +202,7 @@ jobs:
run: | run: |
[IO.File]::WriteAllBytes('.env', [Convert]::FromBase64String('${{ secrets.ENV }}')) [IO.File]::WriteAllBytes('.env', [Convert]::FromBase64String('${{ secrets.ENV }}'))
- name: Read pubspec.yaml - name: Read pubspec.yaml
uses: jbutcher5/read-yaml@1.6 uses: JGeek00/read-yaml-files@2.0.0
id: read_pubspec id: read_pubspec
with: with:
file: './pubspec.yaml' file: './pubspec.yaml'

View file

@ -12,5 +12,9 @@
"editor.formatOnSave": false, "editor.formatOnSave": false,
"editor.formatOnPaste": false, "editor.formatOnPaste": false,
"editor.formatOnType": false "editor.formatOnType": false
} },
"cSpell.ignorePaths": [
"/pubspec.yaml",
"/.github/workflows"
]
} }

View file

@ -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/functions/compare_versions.dart';
import 'package:adguard_home_manager/services/external_requests.dart'; // import 'package:adguard_home_manager/services/external_requests.dart';
import 'package:adguard_home_manager/models/github_release.dart'; // import 'package:adguard_home_manager/models/github_release.dart';
Future<GitHubRelease?> checkAppUpdates({ // Future<GitHubRelease?> checkAppUpdates({
required String currentBuildNumber, // required String currentBuildNumber,
required void Function(GitHubRelease?) setUpdateAvailable, // required void Function(GitHubRelease?) setUpdateAvailable,
required InstallationAppReferrer? installationSource, // required InstallationAppReferrer? installationSource,
required bool isBeta // required bool isBeta
}) async { // }) async {
var result = isBeta // var result = isBeta
? await ExternalRequests.getReleasesGitHub() // ? await ExternalRequests.getReleasesGitHub()
: await ExternalRequests.getReleaseData(); // : await ExternalRequests.getReleaseData();
if (result.successful == true) { // if (result.successful == true) {
late GitHubRelease gitHubRelease; // late GitHubRelease gitHubRelease;
if (isBeta) { // if (isBeta) {
gitHubRelease = (result.content as List<GitHubRelease>).firstWhere((r) => r.prerelease == true); // gitHubRelease = (result.content as List<GitHubRelease>).firstWhere((r) => r.prerelease == true);
} // }
else { // else {
gitHubRelease = result.content as GitHubRelease; // gitHubRelease = result.content as GitHubRelease;
} // }
final update = gitHubUpdateExists( // final update = gitHubUpdateExists(
currentBuildNumber: currentBuildNumber, // currentBuildNumber: currentBuildNumber,
gitHubRelease: gitHubRelease, // gitHubRelease: gitHubRelease,
isBeta: isBeta // isBeta: isBeta
); // );
if (update == true) { // if (update == true) {
setUpdateAvailable(gitHubRelease); // setUpdateAvailable(gitHubRelease);
if (Platform.isAndroid) { // if (Platform.isAndroid) {
if (installationSource == InstallationAppReferrer.androidManually) { // if (installationSource == InstallationAppReferrer.androidManually) {
return gitHubRelease; // return gitHubRelease;
} // }
else { // else {
return null; // return null;
} // }
} // }
else if (Platform.isIOS) { // else if (Platform.isIOS) {
return null; // return null;
} // }
else { // else {
return gitHubRelease; // return gitHubRelease;
} // }
} // }
else { // else {
setUpdateAvailable(null); // setUpdateAvailable(null);
} // }
} // }
return null; // return null;
} // }

View file

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:install_referrer/install_referrer.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:dynamic_color/dynamic_color.dart'; import 'package:dynamic_color/dynamic_color.dart';
@ -79,11 +78,6 @@ void main() async {
HttpOverrides.global = MyHttpOverrides(); HttpOverrides.global = MyHttpOverrides();
} }
if (Platform.isAndroid || Platform.isIOS) {
InstallationAppReferrer installationSource = await InstallReferrer.referrer;
appConfigProvider.setInstallationSource(installationSource);
}
final dbData = await loadDb(); final dbData = await loadDb();
serversProvider.setDbInstance(dbData['dbInstance']); serversProvider.setDbInstance(dbData['dbInstance']);
serversProvider.saveFromDb(dbData['servers']); serversProvider.saveFromDb(dbData['servers']);
@ -169,6 +163,20 @@ void main() async {
(options) { (options) {
options.dsn = dotenv.env['SENTRY_DSN']; options.dsn = dotenv.env['SENTRY_DSN'];
options.sendDefaultPii = false; 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() appRunner: () => startApp()
); );

View file

@ -5,7 +5,7 @@ DnsStatistics dnsStatisticsFromJson(String str) => DnsStatistics.fromJson(json.d
String dnsStatisticsToJson(DnsStatistics data) => json.encode(data.toJson()); String dnsStatisticsToJson(DnsStatistics data) => json.encode(data.toJson());
class DnsStatistics { class DnsStatistics {
final String timeUnits; final String? timeUnits;
final List<Map<String, int>> topQueriedDomains; final List<Map<String, int>> topQueriedDomains;
final List<Map<String, int>> topClients; final List<Map<String, int>> topClients;
final List<Map<String, int>> topBlockedDomains; final List<Map<String, int>> topBlockedDomains;

View file

@ -152,19 +152,25 @@ class DnsProvider with ChangeNotifier {
data: value data: value
); );
void updateValue(dynamic parameter, dynamic value) {
if (value != null) {
parameter = value;
}
}
if (result.successful == true) { if (result.successful == true) {
DnsInfo data = dnsInfo!; DnsInfo data = dnsInfo!;
data.ratelimit = value['ratelimit']; updateValue(data.ratelimit, value['ratelimit']);
data.ednsCsEnabled = value['edns_cs_enabled']; updateValue(data.ednsCsEnabled, value['edns_cs_enabled']);
data.dnssecEnabled = value['dnssec_enabled']; updateValue(data.dnssecEnabled, value['dnssec_enabled']);
data.disableIpv6 = value['disable_ipv6']; updateValue(data.disableIpv6, value['disable_ipv6']);
data.blockingMode = value['blocking_mode']; updateValue(data.blockingMode, value['blocking_mode']);
data.blockingIpv4 = value['blocking_ipv4']; updateValue(data.blockingIpv4, value['blocking_ipv4']);
data.blockingIpv6 = value['blocking_ipv6']; updateValue(data.blockingIpv6, value['blocking_ipv6']);
data.blockedResponseTtl = value['blocked_response_ttl']; updateValue(data.blockedResponseTtl, value['blocked_response_ttl']);
data.ratelimitSubnetLenIpv4 = value['ratelimit_subnet_len_ipv4']; updateValue(data.ratelimitSubnetLenIpv4, value['ratelimit_subnet_len_ipv4']);
data.ratelimitSubnetLenIpv6 = value['ratelimit_subnet_len_ipv6']; updateValue(data.ratelimitSubnetLenIpv6, value['ratelimit_subnet_len_ipv6']);
data.ratelimitWhitelist = value['ratelimit_whitelist']; updateValue(data.ratelimitWhitelist, value['ratelimit_whitelist']);
setDnsInfoData(data); setDnsInfoData(data);
return result; return result;
} }

View file

@ -137,6 +137,8 @@ class AddFiltersButton extends StatelessWidget {
} }
void confirmAddList({required String name, required String url, required String type}) async { void confirmAddList({required String name, required String url, required String type}) async {
if (!context.mounted) return;
ProcessModal processModal = ProcessModal(); ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.addingList); processModal.open(AppLocalizations.of(context)!.addingList);

View file

@ -162,7 +162,7 @@ class _CustomRulesListState extends State<CustomRulesList> {
TextButton.icon( TextButton.icon(
onPressed: () async { onPressed: () async {
final result = await filteringProvider.fetchFilters(); final result = await filteringProvider.fetchFilters();
if (result == false) { if (result == false && context.mounted) {
showSnackbar( showSnackbar(
appConfigProvider: appConfigProvider, appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.errorLoadFilters, label: AppLocalizations.of(context)!.errorLoadFilters,

View file

@ -34,6 +34,7 @@ class HomeAppBar extends StatelessWidget {
void navigateServers() { void navigateServers() {
Future.delayed(const Duration(milliseconds: 0), (() { Future.delayed(const Duration(milliseconds: 0), (() {
if (!context.mounted) return;
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const Servers()) MaterialPageRoute(builder: (context) => const Servers())
); );

View file

@ -115,7 +115,7 @@ class _ClientsModalState extends State<ClientsModal> {
void searchAddedClient(_ClientLog client) { void searchAddedClient(_ClientLog client) {
final notIps = client.ids?.where((e) => isIpAddress(e) == false).toList(); final notIps = client.ids?.where((e) => isIpAddress(e) == false).toList();
if (notIps == null) return; if (notIps == null || notIps.isEmpty) return;
logsProvider.setSearchText('"${notIps[0]}"'); logsProvider.setSearchText('"${notIps[0]}"');
Navigator.of(context).pop(); Navigator.of(context).pop();
} }

View file

@ -96,6 +96,8 @@ class LogTile extends StatelessWidget {
} }
void blockUnblock({required String domain, required String newStatus}) async { void blockUnblock({required String domain, required String newStatus}) async {
if (!context.mounted) return;
final ProcessModal processModal = ProcessModal(); final ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.savingUserFilters); processModal.open(AppLocalizations.of(context)!.savingUserFilters);
@ -124,6 +126,8 @@ class LogTile extends StatelessWidget {
} }
void confirmAddClient(Client client) async { void confirmAddClient(Client client) async {
if (!context.mounted) return;
ProcessModal processModal = ProcessModal(); ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.addingClient); processModal.open(AppLocalizations.of(context)!.addingClient);

View file

@ -1,9 +1,4 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:install_referrer/install_referrer.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.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/custom_list_tile.dart';
import 'package:adguard_home_manager/widgets/section_label.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/desktop_mode.dart';
import 'package:adguard_home_manager/functions/snackbar.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'; import 'package:adguard_home_manager/providers/app_config_provider.dart';
class GeneralSettings extends StatefulWidget { class GeneralSettings extends StatefulWidget {
@ -48,6 +40,7 @@ class _GeneralSettingsState extends State<GeneralSettings> {
required Future Function(bool) function required Future Function(bool) function
}) async { }) async {
final result = await function(newStatus); final result = await function(newStatus);
if (!context.mounted) return;
if (result == true) { if (result == true) {
showSnackbar( showSnackbar(
appConfigProvider: appConfigProvider, appConfigProvider: appConfigProvider,
@ -64,60 +57,60 @@ class _GeneralSettingsState extends State<GeneralSettings> {
} }
} }
Future checkUpdatesAvailable() async { // Future checkUpdatesAvailable() async {
setState(() => appUpdatesStatus = AppUpdatesStatus.checking); // setState(() => appUpdatesStatus = AppUpdatesStatus.checking);
final res = await checkAppUpdates( // final res = await checkAppUpdates(
currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber, // currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable, // setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
installationSource: appConfigProvider.installationSource, // installationSource: appConfigProvider.installationSource,
isBeta: appConfigProvider.getAppInfo!.version.contains('beta'), // isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
); // );
if (!mounted) return; // if (!mounted) return;
if (res != null) { // if (res != null) {
setState(() => appUpdatesStatus = AppUpdatesStatus.available); // setState(() => appUpdatesStatus = AppUpdatesStatus.available);
} // }
else { // else {
setState(() => appUpdatesStatus = AppUpdatesStatus.recheck); // setState(() => appUpdatesStatus = AppUpdatesStatus.recheck);
} // }
} // }
Widget generateAppUpdateStatus() { // Widget generateAppUpdateStatus() {
if (appUpdatesStatus == AppUpdatesStatus.available) { // if (appUpdatesStatus == AppUpdatesStatus.available) {
return IconButton( // return IconButton(
onPressed: appConfigProvider.appUpdatesAvailable != null // onPressed: appConfigProvider.appUpdatesAvailable != null
? () async { // ? () async {
final link = getAppUpdateDownloadLink(appConfigProvider.appUpdatesAvailable!); // final link = getAppUpdateDownloadLink(appConfigProvider.appUpdatesAvailable!);
if (link != null) { // if (link != null) {
openUrl(link); // openUrl(link);
} // }
} // }
: null, // : null,
icon: const Icon(Icons.download_rounded), // icon: const Icon(Icons.download_rounded),
tooltip: AppLocalizations.of(context)!.downloadUpdate, // tooltip: AppLocalizations.of(context)!.downloadUpdate,
); // );
} // }
else if (appUpdatesStatus == AppUpdatesStatus.checking) { // else if (appUpdatesStatus == AppUpdatesStatus.checking) {
return const Padding( // return const Padding(
padding: EdgeInsets.only(right: 16), // padding: EdgeInsets.only(right: 16),
child: SizedBox( // child: SizedBox(
width: 24, // width: 24,
height: 24, // height: 24,
child: CircularProgressIndicator( // child: CircularProgressIndicator(
strokeWidth: 3, // strokeWidth: 3,
) // )
), // ),
); // );
} // }
else { // else {
return IconButton( // return IconButton(
onPressed: checkUpdatesAvailable, // onPressed: checkUpdatesAvailable,
icon: const Icon(Icons.refresh_rounded), // icon: const Icon(Icons.refresh_rounded),
tooltip: AppLocalizations.of(context)!.checkUpdates, // tooltip: AppLocalizations.of(context)!.checkUpdates,
); // );
} // }
} // }
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -253,17 +246,17 @@ class _GeneralSettingsState extends State<GeneralSettings> {
right: 10 right: 10
) )
), ),
if (!(Platform.isAndroid || Platform.isIOS) || (Platform.isAndroid && (appConfigProvider.installationSource == InstallationAppReferrer.androidManually ))) ...[ // if (!(Platform.isAndroid || Platform.isIOS) || (Platform.isAndroid && (appConfigProvider.installationSource == InstallationAppReferrer.androidManually ))) ...[
SectionLabel(label: AppLocalizations.of(context)!.application), // SectionLabel(label: AppLocalizations.of(context)!.application),
CustomListTile( // CustomListTile(
icon: Icons.system_update_rounded, // icon: Icons.system_update_rounded,
title: AppLocalizations.of(context)!.appUpdates, // title: AppLocalizations.of(context)!.appUpdates,
subtitle: appConfigProvider.appUpdatesAvailable != null // subtitle: appConfigProvider.appUpdatesAvailable != null
? AppLocalizations.of(context)!.updateAvailable // ? AppLocalizations.of(context)!.updateAvailable
: AppLocalizations.of(context)!.usingLatestVersion, // : AppLocalizations.of(context)!.usingLatestVersion,
trailing: generateAppUpdateStatus() // trailing: generateAppUpdateStatus()
) // )
] // ]
], ],
), ),
) )

View file

@ -138,7 +138,7 @@ class _StatisticsSettingsState extends State<StatisticsSettings> {
"enabled": _generalSwitch, "enabled": _generalSwitch,
"interval": _retentionTime == "custom" "interval": _retentionTime == "custom"
? Duration(hours: int.parse(_customTimeController.text)).inMilliseconds ? Duration(hours: int.parse(_customTimeController.text)).inMilliseconds
: int.parse(_retentionTime!), : int.parse(_retentionTime ?? _retentionItems[0]),
"ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList() "ignored": _ignoredDomainsControllers.map((e) => e.controller.text).toList()
} }
); );

View file

@ -1,14 +1,10 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:animations/animations.dart'; import 'package:animations/animations.dart';
import 'package:provider/provider.dart'; 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/widgets/update_modal.dart';
import 'package:adguard_home_manager/widgets/system_ui_overlay_style.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/providers/app_config_provider.dart';
import 'package:adguard_home_manager/config/app_screens.dart'; import 'package:adguard_home_manager/config/app_screens.dart';
import 'package:adguard_home_manager/config/sizes.dart'; import 'package:adguard_home_manager/config/sizes.dart';
@ -37,23 +33,23 @@ class _LayoutState extends State<Layout> with WidgetsBindingObserver {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async { WidgetsBinding.instance.addPostFrameCallback((_) async {
if (kDebugMode) return; // Don't check for app updates on debug mode // if (kDebugMode) return; // Don't check for app updates on debug mode
final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false); // final appConfigProvider = Provider.of<AppConfigProvider>(context, listen: false);
final result = await checkAppUpdates( // final result = await checkAppUpdates(
currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber, // currentBuildNumber: appConfigProvider.getAppInfo!.buildNumber,
installationSource: appConfigProvider.installationSource, // installationSource: appConfigProvider.installationSource,
setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable, // setUpdateAvailable: appConfigProvider.setAppUpdatesAvailable,
isBeta: appConfigProvider.getAppInfo!.version.contains('beta'), // isBeta: appConfigProvider.getAppInfo!.version.contains('beta'),
); // );
if (result != null && appConfigProvider.doNotRememberVersion != result.tagName && mounted) { // if (result != null && appConfigProvider.doNotRememberVersion != result.tagName && mounted) {
await showDialog( // await showDialog(
context: context, // context: context,
builder: (context) => UpdateModal( // builder: (context) => UpdateModal(
gitHubRelease: result, // gitHubRelease: result,
onDownload: (link, version) => openUrl(link), // onDownload: (link, version) => openUrl(link),
), // ),
); // );
} // }
}); });
} }

View file

@ -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 # 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 # 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. # 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: environment:
sdk: '>=2.18.1 <3.0.0' sdk: '>=2.18.1 <3.0.0'