diff --git a/.gitignore b/.gitignore index e9d1504..6f4a17f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,11 +5,9 @@ *.swp .DS_Store .atom/ -.build/ .buildlog/ .history .svn/ -.swiftpm/ migrate_working_dir/ # Env @@ -50,6 +48,4 @@ app.*.map.json /debian/packages -untranslated.json - -android/app/.cxx +untranslated.json \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index fab9821..553928e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,4 +17,5 @@ "/pubspec.yaml", "/.github/workflows" ], + "dart.flutterRunAdditionalArgs": [ "--no-enable-impeller" ] } \ No newline at end of file diff --git a/README.md b/README.md index 1dcbc67..843bff8 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ If you like the project and you want to contribute with the development, you can - [expandable](https://pub.dev/packages/expandable) - [package info plus](https://pub.dev/packages/package_info_plus) - [flutter phoenix](https://pub.dev/packages/flutter_phoenix) +- [flutter displaymode](https://pub.dev/packages/flutter_displaymode) - [flutter launcher icons](https://pub.dev/packages/flutter_launcher_icons) - [flutter native splash](https://pub.dev/packages/flutter_native_splash) - [intl](https://pub.dev/packages/intl) diff --git a/lib/config/theme.dart b/lib/config/theme.dart index eba0b9c..93b5365 100644 --- a/lib/config/theme.dart +++ b/lib/config/theme.dart @@ -27,12 +27,11 @@ ThemeData lightTheme(ColorScheme? dynamicColorScheme) => ThemeData( dialogTheme: DialogTheme( surfaceTintColor: dynamicColorScheme?.surfaceTint ), - // DISABLE PREDICTIVE BACK GESTURE - // pageTransitionsTheme: const PageTransitionsTheme( - // builders: { - // TargetPlatform.android: PredictiveBackPageTransitionsBuilder() - // } - // ) + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: PredictiveBackPageTransitionsBuilder() + } + ) ); ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData( @@ -63,12 +62,11 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData( dialogTheme: DialogTheme( surfaceTintColor: dynamicColorScheme?.surfaceTint ), - // DISABLE PREDICTIVE BACK GESTURE - // pageTransitionsTheme: const PageTransitionsTheme( - // builders: { - // TargetPlatform.android: PredictiveBackPageTransitionsBuilder() - // } - // ) + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: PredictiveBackPageTransitionsBuilder() + } + ) ); ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData( @@ -87,12 +85,11 @@ ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData( iconColor: Color.fromRGBO(117, 117, 117, 1), ), brightness: Brightness.light, - // DISABLE PREDICTIVE BACK GESTURE - // pageTransitionsTheme: const PageTransitionsTheme( - // builders: { - // TargetPlatform.android: PredictiveBackPageTransitionsBuilder() - // } - // ) + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: PredictiveBackPageTransitionsBuilder() + } + ) ); ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData( @@ -114,10 +111,9 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData( iconColor: Color.fromRGBO(187, 187, 187, 1), ), brightness: Brightness.dark, - // DISABLE PREDICTIVE BACK GESTURE - // pageTransitionsTheme: const PageTransitionsTheme( - // builders: { - // TargetPlatform.android: PredictiveBackPageTransitionsBuilder() - // } - // ) + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: PredictiveBackPageTransitionsBuilder() + } + ) ); \ No newline at end of file diff --git a/lib/constants/regexps.dart b/lib/constants/regexps.dart deleted file mode 100644 index e882913..0000000 --- a/lib/constants/regexps.dart +++ /dev/null @@ -1,12 +0,0 @@ -class Regexps { - static final wildcardDomain = RegExp(r'^(\*\.)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,10}$'); - static final domain = RegExp(r'^((?:(?:[a-zA-Z]{1})|(?:[a-zA-Z]{1}[a-zA-Z]{1})|(?:[a-zA-Z]{1}[0-9]{1})|(?:[0-9]{1}[a-zA-Z]{1})|(?:[a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.)+([a-zA-Z]{2,10}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,10})$'); - static final ipv4Address = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$'); - static final ipv6Address = RegExp(r'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'); - static final subroute = RegExp(r'^\/\b([A-Za-z0-9_\-~/]*)[^\/|\.|\:]$'); - static final macAddress = RegExp(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'); - static final url = RegExp(r'^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$'); - static final certificate = RegExp(r'(-{3,}(\bBEGIN CERTIFICATE\b))|(-{3,}-{3,}(\END CERTIFICATE\b)-{3,})', multiLine: true); - static final privateKey = RegExp(r'(-{3,}(\bBEGIN\b).*(PRIVATE KEY\b))|(-{3,}-{3,}(\bEND\b).*(PRIVATE KEY\b)-{3,})', multiLine: true); - static final path = RegExp(r'^(\/{0,1}(?!\/))[A-Za-z0-9\/\-_]+(\.([a-zA-Z]+))?$'); -} \ No newline at end of file diff --git a/lib/functions/is_ip.dart b/lib/functions/is_ip.dart index 73ee1e9..667bf0b 100644 --- a/lib/functions/is_ip.dart +++ b/lib/functions/is_ip.dart @@ -1,7 +1,7 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; - bool isIpAddress(String value) { - if (Regexps.ipv4Address.hasMatch(value) || Regexps.ipv6Address.hasMatch(value)) { + final ipv4Regexp = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$'); + final ipv6Regexp = RegExp(r'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'); + if (ipv4Regexp.hasMatch(value) || ipv6Regexp.hasMatch(value)) { return true; } else { diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f923e8b..fa952aa 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -803,8 +803,5 @@ "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", - "upstreamTimeout": "Upstream timeout", - "upstreamTimeoutHelper": "Specifies the number of seconds to wait for a response from the upstream server", - "fieldCannotBeEmpty": "This field cannot be empty" + "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 c93c501..d18f8a9 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -403,7 +403,7 @@ "dnsRewriteRuleDeleted": "Reescritura DNS eliminada correctamente", "dnsRewriteRuleNotDeleted": "La reescritura DNS no pudo ser eliminada", "addDnsRewrite": "Añadir reescritura DNS", - "addingRewrite": "Añadiendo reescritura...", + "addingRewrite": "Añadiend reescritura...", "dnsRewriteRuleAdded": "Regla de reescritura DNS añadida correctamente", "dnsRewriteRuleNotAdded": "La regla de reescritura DNS no ha podido ser añadida", "logsSettings": "Ajustes de registros", @@ -803,8 +803,5 @@ "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", - "upstreamTimeout": "Tiempo de espera del upstream", - "upstreamTimeoutHelper": "Especifica el número de segundos que se debe esperar para recibir una respuesta del servidor upstream", - "fieldCannotBeEmpty": "El campo no puede estar vacío" + "bottomToTop": "Desde abajo hacia arriba" } \ No newline at end of file diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb index d0f26c5..423dfa3 100644 --- a/lib/l10n/app_tr.arb +++ b/lib/l10n/app_tr.arb @@ -791,20 +791,5 @@ "clientDisallowedSuccessfully": "İstemci başarıyla reddedildi", "changesNotSaved": "Değişiklikler kaydedilemedi", "allowingClient": "İstemciye izin veriliyor...", - "disallowingClient": "İstemci reddediliyor...", - "clientIpCopied": "İstemci IP'si panoya kopyalandı", - "clientNameCopied": "İstemci adı panoya kopyalandı", - "dnsServerAddressCopied": "DNS sunucu adresi panoya kopyalandı", - "select": "Seç", - "liveLogs": "Canlı günlükler", - "hereWillAppearRealtimeLogs": "Burada gerçek zamanlı günlükler görünecek.", - "applicationDetails": "Uygulama detayları", - "applicationDetailsDescription": "Uygulama deposu, mevcut olduğu mağazalar ve daha fazlası", - "myOtherApps": "Diğer uygulamalarım", - "myOtherAppsDescription": "Diğer uygulamalarımı kontrol et, bağış yap, destekle iletişime geç ve daha fazlası", - "topToBottom": "Yukarıdan aşağıya", - "bottomToTop": "Aşağıdan yukarıya", - "upstreamTimeout": "Üst sunucu zaman aşımı", - "upstreamTimeoutHelper": "Üst DNS sunucusundan yanıt bekleme süresini saniye cinsinden belirtir", - "fieldCannotBeEmpty": "Bu alan boş olamaz" -} + "disallowingClient": "İstemci reddediliyor..." +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 6402b70..61126da 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:provider/provider.dart'; +import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -196,9 +197,37 @@ void main() async { } } -class Main extends StatelessWidget { +class Main extends StatefulWidget { const Main({super.key}); + @override + State
createState() => _MainState(); +} + +class _MainState extends State
{ + List modes = []; + DisplayMode? active; + DisplayMode? preferred; + + Future displayMode() async { + try { + modes = await FlutterDisplayMode.supported; + preferred = await FlutterDisplayMode.preferred; + active = await FlutterDisplayMode.active; + await FlutterDisplayMode.setHighRefreshRate(); + setState(() {}); + } catch (_) { + // ---- // + } + } + + @override + void initState() { + displayMode(); + + super.initState(); + } + @override Widget build(BuildContext context) { final appConfigProvider = Provider.of(context); diff --git a/lib/models/dns_info.dart b/lib/models/dns_info.dart index 7007644..5a53023 100644 --- a/lib/models/dns_info.dart +++ b/lib/models/dns_info.dart @@ -26,7 +26,6 @@ class DnsInfo { int? ratelimitSubnetLenIpv4; int? ratelimitSubnetLenIpv6; List? ratelimitWhitelist; - int? upstreamTimeout; DnsInfo({ required this.upstreamDns, @@ -56,7 +55,6 @@ class DnsInfo { required this.ratelimitSubnetLenIpv4, required this.ratelimitSubnetLenIpv6, required this.ratelimitWhitelist, - required this.upstreamTimeout, }); factory DnsInfo.fromJson(Map json) => DnsInfo( @@ -87,7 +85,6 @@ class DnsInfo { ratelimitSubnetLenIpv4: json["ratelimit_subnet_len_ipv4"], ratelimitSubnetLenIpv6: json["ratelimit_subnet_len_ipv6"], ratelimitWhitelist: json["ratelimit_whitelist"] != null ? List.from(json["ratelimit_whitelist"].map((x) => x)) : [], - upstreamTimeout: json["upstream_timeout"], ); Map toJson() => { @@ -118,6 +115,5 @@ class DnsInfo { "ratelimit_subnet_len_ipv4": ratelimitSubnetLenIpv4, "ratelimit_subnet_len_ipv6": ratelimitSubnetLenIpv6, "ratelimit_whitelist": ratelimitWhitelist != null ? List.from(ratelimitWhitelist!.map((x) => x)) : null, - "upstream_timeout": upstreamTimeout, }; } diff --git a/lib/screens/filters/details/add_list_modal.dart b/lib/screens/filters/details/add_list_modal.dart index f153224..d5579a6 100644 --- a/lib/screens/filters/details/add_list_modal.dart +++ b/lib/screens/filters/details/add_list_modal.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -98,7 +97,8 @@ class _ContentState extends State<_Content> { } void validateUrl(String value) { - if (Regexps.url.hasMatch(value)) { + final urlRegex = RegExp(r'^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$'); + if (urlRegex.hasMatch(value)) { setState(() => urlError = null); } else { diff --git a/lib/screens/filters/details/check_host_modal.dart b/lib/screens/filters/details/check_host_modal.dart index be0efce..3065588 100644 --- a/lib/screens/filters/details/check_host_modal.dart +++ b/lib/screens/filters/details/check_host_modal.dart @@ -1,6 +1,5 @@ // ignore_for_file: use_build_context_synchronously -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -64,7 +63,8 @@ class _ContentState extends State<_Content> { Widget? resultWidget; void validateDomain(String value) { - if (Regexps.domain.hasMatch(value)) { + final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$'); + if (domainRegex.hasMatch(value)) { setState(() => domainError = null); } else { diff --git a/lib/screens/filters/modals/custom_rules/add_custom_rule.dart b/lib/screens/filters/modals/custom_rules/add_custom_rule.dart index 674c200..b528c02 100644 --- a/lib/screens/filters/modals/custom_rules/add_custom_rule.dart +++ b/lib/screens/filters/modals/custom_rules/add_custom_rule.dart @@ -1,4 +1,3 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:segmented_button_slide/segmented_button_slide.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -42,7 +41,8 @@ class _AddCustomRuleState extends State { } void validateDomain(String value) { - if (Regexps.domain.hasMatch(value)) { + final domainRegex = RegExp(r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$'); + if (domainRegex.hasMatch(value)) { setState(() => _domainError = null); } else { diff --git a/lib/screens/logs/filters/clients_modal.dart b/lib/screens/logs/filters/clients_modal.dart index 05b7213..ef0e989 100644 --- a/lib/screens/logs/filters/clients_modal.dart +++ b/lib/screens/logs/filters/clients_modal.dart @@ -114,12 +114,10 @@ class _ClientsModalState extends State { } void searchAddedClient(_ClientLog client) { - final ips = client.ids?.where((e) => isIpAddress(e) == true).toList(); - if (ips == null || ips.isEmpty) return; - logsProvider.setSearchText(ips[0]); - logsProvider.filterLogs(); + final notIps = client.ids?.where((e) => isIpAddress(e) == false).toList(); + if (notIps == null || notIps.isEmpty) return; + logsProvider.setSearchText('"${notIps[0]}"'); Navigator.of(context).pop(); - Navigator.pop(context); } if (widget.dialog == true) { @@ -304,7 +302,7 @@ class _ClientsModalState extends State { subtitle: _selectedList == 0 ? _filteredClients[index].name : _filteredClients[index].ids?.join(", "), checkboxActive: logsProvider.selectedClients.contains(_filteredClients[index].ip), isAddedClient: _selectedList == 1, - onSearchAddedClient: _filteredClients[index].ids != null && _filteredClients[index].ids!.where((e) => isIpAddress(e) == true).isNotEmpty ? () => searchAddedClient(_filteredClients[index]) : null, + onSearchAddedClient: () => searchAddedClient(_filteredClients[index]), onChanged: (isSelected) { if (isSelected == true) { logsProvider.setSelectedClients([ @@ -378,7 +376,7 @@ class _ListItem extends StatelessWidget { final bool checkboxActive; final void Function(bool) onChanged; final bool isAddedClient; - final void Function()? onSearchAddedClient; + final void Function() onSearchAddedClient; const _ListItem({ required this.title, diff --git a/lib/screens/settings/dhcp/add_static_lease_modal.dart b/lib/screens/settings/dhcp/add_static_lease_modal.dart index d40c506..c80e848 100644 --- a/lib/screens/settings/dhcp/add_static_lease_modal.dart +++ b/lib/screens/settings/dhcp/add_static_lease_modal.dart @@ -1,4 +1,3 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -68,7 +67,8 @@ class __ContentState extends State<_Content> { bool validData = false; void validateMac(String value) { - if (Regexps.macAddress.hasMatch(value)) { + final RegExp macRegex = RegExp(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'); + if (macRegex.hasMatch(value)) { setState(() => macError = null); } else { @@ -78,7 +78,8 @@ class __ContentState extends State<_Content> { } void validateIp(String value) { - if (Regexps.ipv4Address.hasMatch(value) == true) { + RegExp ipAddress = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$'); + if (ipAddress.hasMatch(value) == true) { setState(() => ipError = null); } else { diff --git a/lib/screens/settings/dhcp/dhcp.dart b/lib/screens/settings/dhcp/dhcp.dart index 76867ef..449b063 100644 --- a/lib/screens/settings/dhcp/dhcp.dart +++ b/lib/screens/settings/dhcp/dhcp.dart @@ -2,7 +2,6 @@ import 'dart:io'; -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -101,8 +100,8 @@ class _DhcpScreenState extends State { break; } } - - if (Regexps.ipv4Address.hasMatch(value)) { + final regex = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$'); + if (regex.hasMatch(value)) { setValue(null); } else { @@ -127,8 +126,8 @@ class _DhcpScreenState extends State { break; } } - - if (Regexps.ipv6Address.hasMatch(value)) { + final regex = RegExp(r'^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$'); + if (regex.hasMatch(value)) { setValue(null); } else { diff --git a/lib/screens/settings/dns/bootstrap_dns.dart b/lib/screens/settings/dns/bootstrap_dns.dart index dba929a..833396d 100644 --- a/lib/screens/settings/dns/bootstrap_dns.dart +++ b/lib/screens/settings/dns/bootstrap_dns.dart @@ -1,6 +1,5 @@ // ignore_for_file: use_build_context_synchronously -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:adguard_home_manager/functions/desktop_mode.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -24,7 +23,8 @@ class _BootstrapDnsScreenState extends State { bool validValues = false; void validateIp(Map field, String value) { - if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.ipv6Address.hasMatch(value) == true) { + 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) { setState(() => field['error'] = null); } else { diff --git a/lib/screens/settings/dns/fallback_dns.dart b/lib/screens/settings/dns/fallback_dns.dart index 6c8d8ce..19040ed 100644 --- a/lib/screens/settings/dns/fallback_dns.dart +++ b/lib/screens/settings/dns/fallback_dns.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:adguard_home_manager/screens/settings/dns/comment_modal.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -25,7 +24,9 @@ class _FallbackDnsScreenState extends State { bool validValues = false; void validateIp(Map field, String value) { - if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.ipv6Address.hasMatch(value) || Regexps.url.hasMatch(value) == true) { + 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,})?$)'); + 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 { diff --git a/lib/screens/settings/dns/rate_limit_allowlist_modal.dart b/lib/screens/settings/dns/rate_limit_allowlist_modal.dart index 2c2fed8..e5b678e 100644 --- a/lib/screens/settings/dns/rate_limit_allowlist_modal.dart +++ b/lib/screens/settings/dns/rate_limit_allowlist_modal.dart @@ -1,4 +1,3 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:uuid/uuid.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -34,7 +33,8 @@ class _RateLimitAllowlistModalState extends State { List<_IpListItemController> _controllersList = []; void _validateIp(String value, _IpListItemController item) { - if (Regexps.ipv4Address.hasMatch(value)) { + final regexp = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$'); + if (regexp.hasMatch(value)) { setState(() => _controllersList = _controllersList.map((e) { if (e.id == item.id) { return _IpListItemController( diff --git a/lib/screens/settings/dns/upstream_dns.dart b/lib/screens/settings/dns/upstream_dns.dart index 1ae8c5e..33818a1 100644 --- a/lib/screens/settings/dns/upstream_dns.dart +++ b/lib/screens/settings/dns/upstream_dns.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'dart:io'; import 'package:flutter/material.dart'; @@ -28,9 +30,6 @@ class _UpstreamDnsScreenState extends State { bool validValues = false; - final upstreamTimeoutController = TextEditingController(); - String? upstreamTimeoutError = null; - checkValidValues() { if ( dnsServers.isNotEmpty && @@ -62,7 +61,6 @@ class _UpstreamDnsScreenState extends State { } } upstreamMode = dnsProvider.dnsInfo!.upstreamMode ?? ""; - upstreamTimeoutController.text = dnsProvider.dnsInfo!.upstreamTimeout != null ? dnsProvider.dnsInfo!.upstreamTimeout.toString() : ""; validValues = true; super.initState(); } @@ -74,23 +72,6 @@ class _UpstreamDnsScreenState extends State { final width = MediaQuery.of(context).size.width; - void validateTimeout(String value) { - if (value != '' && int.tryParse(value) != null && int.parse(value) > 0) { - setState(() { - upstreamTimeoutError = null; - validValues = true; - }); - } - else { - setState(() { - upstreamTimeoutError = value == '' - ? AppLocalizations.of(context)!.fieldCannotBeEmpty - : AppLocalizations.of(context)!.invalidValue; - validValues = false; - }); - } - } - void openAddCommentModal() { if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) { showDialog( @@ -165,13 +146,11 @@ class _UpstreamDnsScreenState extends State { final result = await dnsProvider.saveUpstreamDnsConfig({ "upstream_dns": dnsServers.map((e) => e['controller'] != null ? e['controller'].text : e['comment']).toList(), - "upstream_mode": upstreamMode, - "upstream_timeout": int.tryParse(upstreamTimeoutController.text) + "upstream_mode": upstreamMode }); processModal.close(); - if (!context.mounted) return; if (result.successful == true) { showSnackbar( appConfigProvider: appConfigProvider, @@ -333,27 +312,6 @@ class _UpstreamDnsScreenState extends State { subtitle: AppLocalizations.of(context)!.fastestIpAddressDescription, onChanged: (value) => setState(() => upstreamMode = value), ), - const SizedBox(height: 16), - SectionLabel(label: AppLocalizations.of(context)!.others), - Padding( - padding: const EdgeInsets.all(16), - child: TextFormField( - controller: upstreamTimeoutController, - onChanged: validateTimeout, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.timer_rounded), - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(10) - ) - ), - labelText: AppLocalizations.of(context)!.upstreamTimeout, - helperText: AppLocalizations.of(context)!.upstreamTimeoutHelper, - helperMaxLines: 2, - errorText: upstreamTimeoutError - ) - ), - ), ], ), ), diff --git a/lib/screens/settings/dns_rewrites/dns_rewrite_modal.dart b/lib/screens/settings/dns_rewrites/dns_rewrite_modal.dart index 42524fa..439455c 100644 --- a/lib/screens/settings/dns_rewrites/dns_rewrite_modal.dart +++ b/lib/screens/settings/dns_rewrites/dns_rewrite_modal.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -83,7 +82,8 @@ class _ContentState extends State<_Content> { bool validData = false; void validateDomain(String value) { - if (Regexps.wildcardDomain.hasMatch(value)) { + final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$'); + if (domainRegex.hasMatch(value)) { setState(() => domainError = null); } else { diff --git a/lib/screens/settings/encryption/encryption_functions.dart b/lib/screens/settings/encryption/encryption_functions.dart index c7700e4..c9c0c4b 100644 --- a/lib/screens/settings/encryption/encryption_functions.dart +++ b/lib/screens/settings/encryption/encryption_functions.dart @@ -1,11 +1,11 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:adguard_home_manager/providers/app_config_provider.dart'; String? validateDomain(BuildContext context, String domain) { - if (Regexps.domain.hasMatch(domain)) { + RegExp regExp = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$'); + if (regExp.hasMatch(domain)) { return null; } else { @@ -23,7 +23,8 @@ String? validatePort(BuildContext context, String value) { } String? validateCertificate(BuildContext context, String cert) { - if (Regexps.certificate.hasMatch(cert.replaceAll('\n', ''))) { + final regExp = RegExp(r'(-{3,}(\bBEGIN CERTIFICATE\b))|(-{3,}-{3,}(\END CERTIFICATE\b)-{3,})', multiLine: true); + if (regExp.hasMatch(cert.replaceAll('\n', ''))) { return null; } else { @@ -32,7 +33,8 @@ String? validateCertificate(BuildContext context, String cert) { } String? validatePrivateKey(BuildContext context, String cert) { - if (Regexps.privateKey.hasMatch(cert.replaceAll('\n', ''))) { + final regExp = RegExp(r'(-{3,}(\bBEGIN\b).*(PRIVATE KEY\b))|(-{3,}-{3,}(\bEND\b).*(PRIVATE KEY\b)-{3,})', multiLine: true); + if (regExp.hasMatch(cert.replaceAll('\n', ''))) { return null; } else { @@ -41,7 +43,8 @@ String? validatePrivateKey(BuildContext context, String cert) { } String? validatePath(BuildContext context, String cert) { - if (Regexps.path.hasMatch(cert)) { + final regExp = RegExp(r'^(\/{0,1}(?!\/))[A-Za-z0-9\/\-_]+(\.([a-zA-Z]+))?$'); + if (regExp.hasMatch(cert)) { return null; } else { diff --git a/lib/screens/settings/logs_settings/config_widgets.dart b/lib/screens/settings/logs_settings/config_widgets.dart index 066f779..16700a9 100644 --- a/lib/screens/settings/logs_settings/config_widgets.dart +++ b/lib/screens/settings/logs_settings/config_widgets.dart @@ -1,4 +1,3 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:uuid/uuid.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -56,8 +55,9 @@ class LogsConfigOptions extends StatelessWidget { ]; void validateDomain(String value, String id) { + final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$'); bool error = false; - if (Regexps.domain.hasMatch(value)) { + if (domainRegex.hasMatch(value)) { error = false; } else { diff --git a/lib/screens/settings/statistics_settings/statistics_settings.dart b/lib/screens/settings/statistics_settings/statistics_settings.dart index 84439b1..7f58d67 100644 --- a/lib/screens/settings/statistics_settings/statistics_settings.dart +++ b/lib/screens/settings/statistics_settings/statistics_settings.dart @@ -1,4 +1,3 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:uuid/uuid.dart'; import 'package:provider/provider.dart'; @@ -92,8 +91,9 @@ class _StatisticsSettingsState extends State { void validateDomain(String value, String id) { + final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$'); bool error = false; - if (Regexps.domain.hasMatch(value)) { + if (domainRegex.hasMatch(value)) { error = false; } else { diff --git a/lib/screens/settings/update_server/update_screen.dart b/lib/screens/settings/update_server/update_screen.dart index ae894f8..4ddc959 100644 --- a/lib/screens/settings/update_server/update_screen.dart +++ b/lib/screens/settings/update_server/update_screen.dart @@ -218,110 +218,101 @@ class _Header extends SliverPersistentHeaderDelegate { final iconBottom = _iconMinBottomPositionExent + (iconMaxBottomPositionExent-iconMinBottomPositionExent)*(1-iconPercentage); return LayoutBuilder( - builder: (context, constraints) => Stack( - children: [ - Container( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface, - ), - ), - Container( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceTint.withOpacity(0.075), - ), - child: Align( - alignment: Alignment.topLeft, - child: SafeArea( - bottom: false, - child: Stack( - fit: StackFit.expand, - alignment: Alignment.center, - children: [ - if (Navigator.of(context).canPop()) Positioned( - top: 8, - left: 0, - child: BackButton( - onPressed: () => Navigator.pop(context), - ), - ), - Positioned( - top: 8, - right: 0, - child: IconButton( - onPressed: onRefresh, - icon: const Icon(Icons.refresh_rounded), - tooltip: AppLocalizations.of(context)!.refresh, - ) - ), - Positioned( - bottom: iconBottom, - left: (constraints.maxWidth/2)-(_iconSize/2), - child: Opacity( - opacity: 1-iconPercentage, - child: serversProvider.updateAvailable.loadStatus == LoadStatus.loading - ? const Column( - children: [ - CircularProgressIndicator(), - SizedBox(height: 4) - ], - ) - : Icon( - serversProvider.updateAvailable.data!.canAutoupdate == true - ? Icons.system_update_rounded - : Icons.system_security_update_good_rounded, - size: _iconSize, - color: Theme.of(context).colorScheme.primary, - ), - ), - ), - Positioned( - bottom: mainText, - child: ConstrainedBox( - constraints: BoxConstraints( - maxWidth: constraints.maxWidth-100 - ), - child: Text( - serversProvider.updateAvailable.loadStatus == LoadStatus.loading - ? AppLocalizations.of(context)!.checkingUpdates - : serversProvider.updateAvailable.data!.canAutoupdate == true - ? AppLocalizations.of(context)!.updateAvailable - : AppLocalizations.of(context)!.serverUpdated, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: textFontSize, - fontWeight: FontWeight.w400 - ), - ), - ) - ), - Positioned( - bottom: versionText, - child: ConstrainedBox( - constraints: BoxConstraints( - maxWidth: constraints.maxWidth-100 - ), - child: Opacity( - opacity: 1-iconPercentage, - child: Text( - serversProvider.updateAvailable.data!.canAutoupdate == true - ? "${AppLocalizations.of(context)!.newVersion}: ${serversProvider.updateAvailable.data!.newVersion ?? 'N/A'}" - : "${AppLocalizations.of(context)!.installedVersion}: ${serversProvider.updateAvailable.data!.currentVersion}", - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w700, - color: Theme.of(context).colorScheme.onSurfaceVariant - ), - ), - ), - ) - ) - ], + builder: (context, constraints) => Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainerHighest, + ), + child: Align( + alignment: Alignment.topLeft, + child: SafeArea( + bottom: false, + child: Stack( + fit: StackFit.expand, + alignment: Alignment.center, + children: [ + if (Navigator.of(context).canPop()) Positioned( + top: 8, + left: 0, + child: BackButton( + onPressed: () => Navigator.pop(context), + ), ), - ), + Positioned( + top: 8, + right: 0, + child: IconButton( + onPressed: onRefresh, + icon: const Icon(Icons.refresh_rounded), + tooltip: AppLocalizations.of(context)!.refresh, + ) + ), + Positioned( + bottom: iconBottom, + left: (constraints.maxWidth/2)-(_iconSize/2), + child: Opacity( + opacity: 1-iconPercentage, + child: serversProvider.updateAvailable.loadStatus == LoadStatus.loading + ? const Column( + children: [ + CircularProgressIndicator(), + SizedBox(height: 4) + ], + ) + : Icon( + serversProvider.updateAvailable.data!.canAutoupdate == true + ? Icons.system_update_rounded + : Icons.system_security_update_good_rounded, + size: _iconSize, + color: Theme.of(context).colorScheme.primary, + ), + ), + ), + Positioned( + bottom: mainText, + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: constraints.maxWidth-100 + ), + child: Text( + serversProvider.updateAvailable.loadStatus == LoadStatus.loading + ? AppLocalizations.of(context)!.checkingUpdates + : serversProvider.updateAvailable.data!.canAutoupdate == true + ? AppLocalizations.of(context)!.updateAvailable + : AppLocalizations.of(context)!.serverUpdated, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: textFontSize, + fontWeight: FontWeight.w400 + ), + ), + ) + ), + Positioned( + bottom: versionText, + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: constraints.maxWidth-100 + ), + child: Opacity( + opacity: 1-iconPercentage, + child: Text( + serversProvider.updateAvailable.data!.canAutoupdate == true + ? "${AppLocalizations.of(context)!.newVersion}: ${serversProvider.updateAvailable.data!.newVersion ?? 'N/A'}" + : "${AppLocalizations.of(context)!.installedVersion}: ${serversProvider.updateAvailable.data!.currentVersion}", + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w700, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + ), + ) + ) + ], ), ), - ], + ), ), ); } diff --git a/lib/widgets/add_server/add_server_functions.dart b/lib/widgets/add_server/add_server_functions.dart index bbb88fd..6dd9c38 100644 --- a/lib/widgets/add_server/add_server_functions.dart +++ b/lib/widgets/add_server/add_server_functions.dart @@ -1,4 +1,3 @@ -import 'package:adguard_home_manager/constants/regexps.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -50,7 +49,8 @@ String? validateSubroute({ required String? value }) { if (value != null && value != '') { - if (Regexps.subroute.hasMatch(value) == true) { + RegExp subrouteRegexp = RegExp(r'^\/\b([A-Za-z0-9_\-~/]*)[^\/|\.|\:]$'); + if (subrouteRegexp.hasMatch(value) == true) { return null; } else { @@ -67,7 +67,9 @@ String? validateAddress({ required String? value }) { if (value != null && value != '') { - if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.domain.hasMatch(value) == true) { + RegExp ipAddress = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$'); + RegExp domain = RegExp(r'^(([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+)$'); + if (ipAddress.hasMatch(value) == true || domain.hasMatch(value) == true) { return null; } else { diff --git a/macos/Podfile.lock b/macos/Podfile.lock index ae5c12f..e815ee7 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -6,34 +6,33 @@ PODS: - FlutterMacOS (1.0.0) - package_info_plus (0.0.1): - FlutterMacOS - - screen_retriever_macos (0.0.1): + - screen_retriever (0.0.1): - FlutterMacOS - - Sentry/HybridSDK (8.44.0) - - sentry_flutter (8.13.2): + - Sentry/HybridSDK (8.36.0) + - sentry_flutter (8.9.0): - Flutter - FlutterMacOS - - Sentry/HybridSDK (= 8.44.0) + - Sentry/HybridSDK (= 8.36.0) - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - - sqflite_darwin (0.0.4): + - sqflite (0.0.3): - Flutter - FlutterMacOS - - sqlite3 (3.49.1): - - sqlite3/common (= 3.49.1) - - sqlite3/common (3.49.1) - - sqlite3/dbstatvtab (3.49.1): + - "sqlite3 (3.46.1+1)": + - "sqlite3/common (= 3.46.1+1)" + - "sqlite3/common (3.46.1+1)" + - "sqlite3/dbstatvtab (3.46.1+1)": - sqlite3/common - - sqlite3/fts5 (3.49.1): + - "sqlite3/fts5 (3.46.1+1)": - sqlite3/common - - sqlite3/perf-threadsafe (3.49.1): + - "sqlite3/perf-threadsafe (3.46.1+1)": - sqlite3/common - - sqlite3/rtree (3.49.1): + - "sqlite3/rtree (3.46.1+1)": - sqlite3/common - sqlite3_flutter_libs (0.0.1): - - Flutter - FlutterMacOS - - sqlite3 (~> 3.49.1) + - "sqlite3 (~> 3.46.0+1)" - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/perf-threadsafe @@ -48,11 +47,11 @@ DEPENDENCIES: - dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`) + - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) - sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) - - sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`) + - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`) + - sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) @@ -70,33 +69,33 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral package_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos - screen_retriever_macos: - :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos + screen_retriever: + :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos sentry_flutter: :path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos shared_preferences_foundation: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin - sqflite_darwin: - :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin + sqflite: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin sqlite3_flutter_libs: - :path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin + :path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos window_manager: :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: - device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 + device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720 dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b - screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161 - Sentry: 0f9bc9adfc0b960e7f3bb5ec67e9a3d8193f3bdb - sentry_flutter: 64a43fb39ab4c7f67d8a4cad52b49e22439e58b7 + package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c + screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 + Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57 + sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d - sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983 - sqlite3_flutter_libs: cc304edcb8e1d8c595d1b08c7aeb46a47691d9db + sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec + sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb + sqlite3_flutter_libs: 5ca46c1a04eddfbeeb5b16566164aa7ad1616e7b url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index dcd4e29..6982a10 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -48,7 +48,6 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" - enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index b3c1761..8e02df2 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -6,8 +6,4 @@ class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } - - override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { - return true - } } diff --git a/pubspec.lock b/pubspec.lock index 207783c..da7317f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -29,42 +29,42 @@ packages: dependency: transitive description: name: archive - sha256: "7dcbd0f87fe5f61cb28da39a1a8b70dbc106e2fe0516f7836eb7bb2948481a12" + sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a" url: "https://pub.dev" source: hosted - version: "4.0.5" + version: "4.0.2" args: dependency: transitive description: name: args - sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.6.0" async: dependency: "direct main" description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.0" checked_yaml: dependency: transitive description: @@ -85,18 +85,18 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.19.1" + version: "1.19.0" contextmenu: dependency: "direct main" description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "0.17.3" cupertino_icons: dependency: "direct main" description: @@ -133,10 +133,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "306b78788d1bb569edb7c55d622953c2414ca12445b41c9117963e03afc5c513" + sha256: b37d37c2f912ad4e8ec694187de87d05de2a3cb82b465ff1f65f65a2d05de544 url: "https://pub.dev" source: hosted - version: "11.3.3" + version: "11.2.1" device_info_plus_platform_interface: dependency: transitive description: @@ -173,18 +173,18 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.1" ffi: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.3" file: dependency: transitive description: @@ -254,6 +254,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + flutter_displaymode: + dependency: "direct main" + description: + name: flutter_displaymode + sha256: "42c5e9abd13d28ed74f701b60529d7f8416947e58256e6659c5550db719c57ef" + url: "https://pub.dev" + source: hosted + version: "0.6.0" flutter_dotenv: dependency: "direct main" description: @@ -266,10 +274,10 @@ packages: dependency: "direct main" description: name: flutter_html - sha256: "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d" + sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.0-beta.2" flutter_launcher_icons: dependency: "direct dev" description: @@ -295,18 +303,18 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: e7bbc718adc9476aa14cfddc1ef048d2e21e4e8f18311aaac723266db9f9e7b5 + sha256: e37f4c69a07b07bb92622ef6b131a53c9aae48f64b176340af9e8e5238718487 url: "https://pub.dev" source: hosted - version: "0.7.6+2" + version: "0.7.5" flutter_native_splash: dependency: "direct dev" description: name: flutter_native_splash - sha256: edb09c35ee9230c4b03f13dd45bb3a276d0801865f0a4650b7e2a3bba61a803a + sha256: "7062602e0dbd29141fb8eb19220b5871ca650be5197ab9c1f193a28b17537bc7" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "2.4.4" flutter_reorderable_list: dependency: "direct main" description: @@ -337,10 +345,10 @@ packages: dependency: "direct main" description: name: html - sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" url: "https://pub.dev" source: hosted - version: "0.15.5" + version: "0.15.4" http: dependency: "direct main" description: @@ -361,10 +369,10 @@ packages: dependency: transitive description: name: image - sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + sha256: "8346ad4b5173924b5ddddab782fc7d8a6300178c8b1dc427775405a01701c4a6" url: "https://pub.dev" source: hosted - version: "4.5.4" + version: "4.5.2" intl: dependency: "direct main" description: @@ -385,18 +393,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -433,10 +441,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -449,10 +457,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.15.0" nested: dependency: transitive description: @@ -465,26 +473,26 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" + sha256: "739e0a5c3c4055152520fa321d0645ee98e932718b4c8efeeb51451968fe0790" url: "https://pub.dev" source: hosted - version: "8.3.0" + version: "8.1.3" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" + sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.0.2" path: dependency: transitive description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -529,10 +537,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.0.2" pie_chart: dependency: "direct main" description: @@ -625,34 +633,34 @@ packages: dependency: transitive description: name: sentry - sha256: "3a64dd001bff768ce5ab6fc3608deef4dde22acd4b5d947763557b20db9e2a32" + sha256: "576ad83415102ba2060142a6701611abc6e67a55af1d7ab339cedd3ba1b0f84c" url: "https://pub.dev" source: hosted - version: "8.14.0" + version: "8.12.0" sentry_flutter: dependency: "direct main" description: name: sentry_flutter - sha256: "3d361f2d5f805783e2e4ed1bd475ef126b36cf525b359dc3627a765a3fb7424d" + sha256: dc3761e8659839cc67a18432d9f12e5531affb7ff68e196dbb56846909b5dfdc url: "https://pub.dev" source: hosted - version: "8.14.0" + version: "8.12.0" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a" + sha256: a752ce92ea7540fc35a0d19722816e04d0e72828a4200e83a98cf1a1eb524c9a url: "https://pub.dev" source: hosted - version: "2.5.2" + version: "2.3.5" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "3ec7210872c4ba945e3244982918e502fa2bfb5230dff6832459ca0e1879b7ad" + sha256: "138b7bbbc7f59c56236e426c37afb8f78cbc57b094ac64c440e0bb90e380a4f5" url: "https://pub.dev" source: hosted - version: "2.4.8" + version: "2.4.2" shared_preferences_foundation: dependency: transitive description: @@ -681,10 +689,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.4.3" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: @@ -702,10 +710,10 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.0" sprintf: dependency: transitive description: @@ -718,42 +726,42 @@ packages: dependency: "direct main" description: name: sqflite - sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1" sqflite_android: dependency: transitive description: name: sqflite_android - sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" + sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.0" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b" + sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709" url: "https://pub.dev" source: hosted - version: "2.5.5" + version: "2.5.4+6" sqflite_common_ffi: dependency: "direct main" description: name: sqflite_common_ffi - sha256: "1f3ef3888d3bfbb47785cc1dda0dc7dd7ebd8c1955d32a9e8e9dae1e38d1c4c1" + sha256: "883dd810b2b49e6e8c3b980df1829ef550a94e3f87deab5d864917d27ca6bf36" url: "https://pub.dev" source: hosted - version: "2.3.5" + version: "2.3.4+4" sqflite_darwin: dependency: transitive description: name: sqflite_darwin - sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1+1" sqflite_platform_interface: dependency: transitive description: @@ -766,66 +774,66 @@ packages: dependency: transitive description: name: sqlite3 - sha256: "310af39c40dd0bb2058538333c9d9840a2725ae0b9f77e4fd09ad6696aa8f66e" + sha256: "35d3726fe18ab1463403a5cc8d97dbc81f2a0b08082e8173851363fcc97b6627" url: "https://pub.dev" source: hosted - version: "2.7.5" + version: "2.7.2" sqlite3_flutter_libs: dependency: "direct main" description: name: sqlite3_flutter_libs - sha256: "1a96b59227828d9eb1463191d684b37a27d66ee5ed7597fcf42eee6452c88a14" + sha256: "50a7e3f294c741d3142eed0ff228e38498334e11e0ccb9d73e0496e005949e44" url: "https://pub.dev" source: hosted - version: "0.5.32" + version: "0.5.29" stack_trace: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.3.0" synchronized: dependency: transitive description: name: synchronized - sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" + sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" url: "https://pub.dev" source: hosted - version: "3.3.1" + version: "3.3.0+3" term_glyph: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.3" timezone: dependency: "direct main" description: @@ -862,10 +870,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4" + sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" url: "https://pub.dev" source: hosted - version: "6.3.15" + version: "6.3.14" url_launcher_ios: dependency: transitive description: @@ -926,10 +934,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de" + sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7" url: "https://pub.dev" source: hosted - version: "1.1.18" + version: "1.1.15" vector_graphics_codec: dependency: transitive description: @@ -958,34 +966,34 @@ packages: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "14.3.0" web: dependency: transitive description: name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.0" win32: dependency: transitive description: name: win32 - sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f + sha256: "154360849a56b7b67331c21f09a386562d88903f90a1099c5987afc1912e1f29" url: "https://pub.dev" source: hosted - version: "5.12.0" + version: "5.10.0" win32_registry: dependency: transitive description: name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "1.1.5" window_manager: dependency: "direct main" description: @@ -1019,5 +1027,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.7.0 <4.0.0" + dart: ">=3.6.0 <4.0.0" flutter: ">=3.27.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2fffd97..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.4+151 +version: 2.20.1+148 environment: sdk: '>=2.18.1 <3.0.0' @@ -42,6 +42,7 @@ dependencies: provider: ^6.1.1 sqflite: ^2.3.0 package_info_plus: ^8.0.0 + flutter_displaymode: ^0.6.0 dynamic_color: ^1.7.0 animations: ^2.0.10 device_info_plus: ^11.2.1