Compare commits

...

25 commits

Author SHA1 Message Date
Juan Gilsanz Polo
a4bf4cd3c5 Merge branch 'beta' 2025-03-23 19:52:20 +01:00
Juan Gilsanz Polo
61b0f724ba Updated app version 2025-03-23 19:51:58 +01:00
Juan Gilsanz Polo
52945b04ff Removed flutter displaymode 2025-03-23 19:46:52 +01:00
Juan Gilsanz Polo
8e5bbdbd4b Fixed update screen header color 2025-03-23 19:18:51 +01:00
Juan Gilsanz Polo
e6a01ac546 Disabled predictive back gesture 2025-03-23 19:18:43 +01:00
Juan Gilsanz Polo
e8440f7d1d Merge branch 'beta' 2025-03-17 19:13:25 +01:00
Juan Gilsanz Polo
6cc212751b Updated app version 2025-03-17 19:11:41 +01:00
Juan Gilsanz Polo
ae9d23d4a8 Support multiple subdomains 2025-03-17 19:10:06 +01:00
Juan
566254e617
Merge pull request #164 from mikropsoft/patch-1
Update app_tr.arb
2025-03-17 18:55:58 +01:00
𝗛𝗼𝗹𝗶
88339d1c40
Update app_tr.arb 2025-03-09 23:07:05 +03:00
𝗛𝗼𝗹𝗶
254bbcef57
Update app_tr.arb 2025-03-09 23:05:28 +03:00
𝗛𝗼𝗹𝗶
e7aacfbec1
Update app_tr.arb 2025-03-09 23:04:45 +03:00
Juan Gilsanz Polo
7a75a67701 Merge branch 'beta' 2025-03-09 20:37:16 +01:00
Juan Gilsanz Polo
7632d9ef87 Updated app version 2025-03-09 20:36:45 +01:00
Juan Gilsanz Polo
eded494024 Support TLD greater than 6 characters on domains 2025-03-09 20:28:00 +01:00
Juan Gilsanz Polo
e5979edf63 Added upstream dns timeout 2025-03-09 20:17:19 +01:00
Juan Gilsanz Polo
f27b17aad0 Fix filter logs by added client 2025-03-09 19:58:24 +01:00
Juan Gilsanz Polo
fd4daba2aa Merge branch 'master' into beta 2025-03-09 19:45:58 +01:00
Juan Gilsanz Polo
ce7a8e8cc5 Extracted some regexps to external file 2025-03-09 19:45:48 +01:00
Juan Gilsanz Polo
4282792ebd Updated stuff 2025-03-09 19:45:37 +01:00
Juan Gilsanz Polo
4766d1907f Merge branch 'beta' 2025-01-22 14:45:52 +01:00
Juan Gilsanz Polo
7f6f686b2b Updated app version 2025-01-22 14:45:38 +01:00
Juan Gilsanz Polo
02b659c1bc Changed my other apps text 2025-01-22 14:43:20 +01:00
Juan Gilsanz Polo
db6e63c4aa Fix bad performance debug mode 2025-01-22 14:41:04 +01:00
Juan Gilsanz Polo
a666d109d9 Bug fixes 2025-01-22 14:40:39 +01:00
40 changed files with 458 additions and 365 deletions

4
.gitignore vendored
View file

@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# Env
@ -49,3 +51,5 @@ app.*.map.json
/debian/packages
untranslated.json
android/app/.cxx

View file

@ -16,5 +16,5 @@
"cSpell.ignorePaths": [
"/pubspec.yaml",
"/.github/workflows"
]
],
}

View file

@ -113,7 +113,6 @@ 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)

2
debian/debian.yaml vendored
View file

@ -5,7 +5,7 @@ flutter_app:
control:
Package: AdGuardHomeManager
Version: 2.20.0
Version: 2.20.1
Architecture: amd64
Essential: no
Priority: optional

View file

@ -27,11 +27,12 @@ ThemeData lightTheme(ColorScheme? dynamicColorScheme) => ThemeData(
dialogTheme: DialogTheme(
surfaceTintColor: dynamicColorScheme?.surfaceTint
),
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
}
)
// DISABLE PREDICTIVE BACK GESTURE
// pageTransitionsTheme: const PageTransitionsTheme(
// builders: {
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
// }
// )
);
ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
@ -62,11 +63,12 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData(
dialogTheme: DialogTheme(
surfaceTintColor: dynamicColorScheme?.surfaceTint
),
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
}
)
// DISABLE PREDICTIVE BACK GESTURE
// pageTransitionsTheme: const PageTransitionsTheme(
// builders: {
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
// }
// )
);
ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
@ -85,11 +87,12 @@ ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData(
iconColor: Color.fromRGBO(117, 117, 117, 1),
),
brightness: Brightness.light,
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
}
)
// DISABLE PREDICTIVE BACK GESTURE
// pageTransitionsTheme: const PageTransitionsTheme(
// builders: {
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
// }
// )
);
ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
@ -111,9 +114,10 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData(
iconColor: Color.fromRGBO(187, 187, 187, 1),
),
brightness: Brightness.dark,
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
}
)
// DISABLE PREDICTIVE BACK GESTURE
// pageTransitionsTheme: const PageTransitionsTheme(
// builders: {
// TargetPlatform.android: PredictiveBackPageTransitionsBuilder()
// }
// )
);

View file

@ -0,0 +1,12 @@
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]+))?$');
}

View file

@ -1,7 +1,7 @@
import 'package:adguard_home_manager/constants/regexps.dart';
bool isIpAddress(String 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)) {
if (Regexps.ipv4Address.hasMatch(value) || Regexps.ipv6Address.hasMatch(value)) {
return true;
}
else {

View file

@ -5,6 +5,15 @@ import 'package:url_launcher/url_launcher.dart' as url_launcher;
import 'package:sentry_flutter/sentry_flutter.dart';
void openUrl(String url) async {
if (!(url.startsWith("http") || url.startsWith("https"))) {
try {
url_launcher.launchUrl(Uri.parse(url));
} catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
}
return;
}
if (Platform.isAndroid || Platform.isIOS) {
try {
await flutter_custom_tabs.launchUrl(
@ -20,6 +29,7 @@ void openUrl(String url) async {
),
);
} catch (e, stackTrace) {
url_launcher.launchUrl(Uri.parse(url));
Sentry.captureException(e, stackTrace: stackTrace);
}
}

View file

@ -800,8 +800,11 @@
"hereWillAppearRealtimeLogs": "Here there will appear the logs on realtime.",
"applicationDetails": "Application details",
"applicationDetailsDescription": "App repository, stores where it's available, and more",
"myOtherApps": "Check my other apps",
"myOtherAppsDescription": "Created by JGeek00",
"myOtherApps": "My other apps",
"myOtherAppsDescription": "Check my other apps, make a donation, contact support, and more",
"topToBottom": "From top to bottom",
"bottomToTop": "From bottom to top"
"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"
}

View file

@ -403,7 +403,7 @@
"dnsRewriteRuleDeleted": "Reescritura DNS eliminada correctamente",
"dnsRewriteRuleNotDeleted": "La reescritura DNS no pudo ser eliminada",
"addDnsRewrite": "Añadir reescritura DNS",
"addingRewrite": "Añadiend reescritura...",
"addingRewrite": "Añadiendo 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",
@ -800,8 +800,11 @@
"hereWillAppearRealtimeLogs": "Aquí aparecerán los registros en tiempo real.",
"applicationDetails": "Detalles de la aplicación",
"applicationDetailsDescription": "Repositorio de la app, tiendas donde está disponible, y más",
"myOtherApps": "Comprueba mis otras apps",
"myOtherAppsDescription": "Creadas por JGeek00",
"myOtherApps": "Mis otras apps",
"myOtherAppsDescription": "Comprueba mis otras apps, hacer una donación, contactar al soporte, y más",
"topToBottom": "Desde arriba hacia abajo",
"bottomToTop": "Desde abajo hacia arriba"
"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"
}

View file

@ -791,5 +791,20 @@
"clientDisallowedSuccessfully": "İstemci başarıyla reddedildi",
"changesNotSaved": "Değişiklikler kaydedilemedi",
"allowingClient": "İstemciye izin veriliyor...",
"disallowingClient": "İstemci reddediliyor..."
"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"
}

View file

@ -5,7 +5,6 @@ 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';
@ -168,11 +167,22 @@ void main() async {
return null;
}
if (event.message?.formatted.contains("HttpException") == true) {
return null;
}
if (
event.message?.formatted.contains("Unexpected character") ?? false ||
(event.throwable != null && event.throwable!.toString().contains("Unexpected character"))
) {
return null; // Exclude this event
return null;
}
if (
event.message?.formatted.contains("Unexpected end of input") ?? false ||
(event.throwable != null && event.throwable!.toString().contains("Unexpected end of input"))
) {
return null;
}
return event;
@ -186,37 +196,9 @@ void main() async {
}
}
class Main extends StatefulWidget {
class Main extends StatelessWidget {
const Main({super.key});
@override
State<Main> createState() => _MainState();
}
class _MainState extends State<Main> {
List<DisplayMode> modes = <DisplayMode>[];
DisplayMode? active;
DisplayMode? preferred;
Future<void> 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<AppConfigProvider>(context);

View file

@ -26,6 +26,7 @@ class DnsInfo {
int? ratelimitSubnetLenIpv4;
int? ratelimitSubnetLenIpv6;
List<String>? ratelimitWhitelist;
int? upstreamTimeout;
DnsInfo({
required this.upstreamDns,
@ -55,6 +56,7 @@ class DnsInfo {
required this.ratelimitSubnetLenIpv4,
required this.ratelimitSubnetLenIpv6,
required this.ratelimitWhitelist,
required this.upstreamTimeout,
});
factory DnsInfo.fromJson(Map<String, dynamic> json) => DnsInfo(
@ -85,6 +87,7 @@ class DnsInfo {
ratelimitSubnetLenIpv4: json["ratelimit_subnet_len_ipv4"],
ratelimitSubnetLenIpv6: json["ratelimit_subnet_len_ipv6"],
ratelimitWhitelist: json["ratelimit_whitelist"] != null ? List<String>.from(json["ratelimit_whitelist"].map((x) => x)) : [],
upstreamTimeout: json["upstream_timeout"],
);
Map<String, dynamic> toJson() => {
@ -115,5 +118,6 @@ class DnsInfo {
"ratelimit_subnet_len_ipv4": ratelimitSubnetLenIpv4,
"ratelimit_subnet_len_ipv6": ratelimitSubnetLenIpv6,
"ratelimit_whitelist": ratelimitWhitelist != null ? List<String>.from(ratelimitWhitelist!.map((x) => x)) : null,
"upstream_timeout": upstreamTimeout,
};
}

View file

@ -43,9 +43,9 @@ class DnsStatistics {
factory DnsStatistics.fromJson(Map<String, dynamic> json) => DnsStatistics(
timeUnits: json["time_units"],
topQueriedDomains: List<Map<String, int>>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
topClients: List<Map<String, int>>.from(json["top_clients"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
topBlockedDomains: List<Map<String, int>>.from(json["top_blocked_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
topQueriedDomains: json["top_queried_domains"] != null ? List<Map<String, int>>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))) : [],
topClients: json["top_clients"] != null ? List<Map<String, int>>.from(json["top_clients"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))) : [],
topBlockedDomains: json["top_blocked_domains"] != null ? List<Map<String, int>>.from(json["top_blocked_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))): [],
topUpstreamResponses: json["top_upstreams_responses"] != null ? List<Map<String, int>>.from(json["top_upstreams_responses"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))) : null,
topUpstreamsAvgTime: json["top_upstreams_avg_time"] != null ? List<Map<String, double>>.from(json["top_upstreams_avg_time"].map((x) => Map.from(x).map((k, v) => MapEntry<String, double>(k, v)))) : null,
dnsQueries: List<int>.from(json["dns_queries"].map((x) => x)),

View file

@ -25,11 +25,15 @@ class ClientsFab extends StatelessWidget {
final width = MediaQuery.of(context).size.width;
void confirmAddClient(Client client) async {
if (!context.mounted) return;
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.addingClient);
final result = await clientsProvider.addClient(client);
if (!context.mounted) return;
processModal.close();
if (result == true) {

View file

@ -33,6 +33,8 @@ class AddFiltersButton extends StatelessWidget {
final width = MediaQuery.of(context).size.width;
void confirmAddRule(String rule) async {
if (!context.mounted) return;
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.addingRule);
@ -58,6 +60,8 @@ class AddFiltersButton extends StatelessWidget {
}
void confirmEditCustomRules(List<String> rules) async {
if (!context.mounted) return;
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.savingCustomRules);

View file

@ -1,5 +1,6 @@
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';
@ -97,8 +98,7 @@ class _ContentState extends State<_Content> {
}
void validateUrl(String 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)) {
if (Regexps.url.hasMatch(value)) {
setState(() => urlError = null);
}
else {

View file

@ -1,5 +1,6 @@
// 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';
@ -63,8 +64,7 @@ class _ContentState extends State<_Content> {
Widget? resultWidget;
void validateDomain(String value) {
final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
if (domainRegex.hasMatch(value)) {
if (Regexps.domain.hasMatch(value)) {
setState(() => domainError = null);
}
else {

View file

@ -1,3 +1,4 @@
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';
@ -41,8 +42,7 @@ class _AddCustomRuleState extends State<AddCustomRule> {
}
void validateDomain(String 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)) {
if (Regexps.domain.hasMatch(value)) {
setState(() => _domainError = null);
}
else {

View file

@ -114,10 +114,12 @@ class _ClientsModalState extends State<ClientsModal> {
}
void searchAddedClient(_ClientLog client) {
final notIps = client.ids?.where((e) => isIpAddress(e) == false).toList();
if (notIps == null || notIps.isEmpty) return;
logsProvider.setSearchText('"${notIps[0]}"');
final ips = client.ids?.where((e) => isIpAddress(e) == true).toList();
if (ips == null || ips.isEmpty) return;
logsProvider.setSearchText(ips[0]);
logsProvider.filterLogs();
Navigator.of(context).pop();
Navigator.pop(context);
}
if (widget.dialog == true) {
@ -302,7 +304,7 @@ class _ClientsModalState extends State<ClientsModal> {
subtitle: _selectedList == 0 ? _filteredClients[index].name : _filteredClients[index].ids?.join(", "),
checkboxActive: logsProvider.selectedClients.contains(_filteredClients[index].ip),
isAddedClient: _selectedList == 1,
onSearchAddedClient: () => searchAddedClient(_filteredClients[index]),
onSearchAddedClient: _filteredClients[index].ids != null && _filteredClients[index].ids!.where((e) => isIpAddress(e) == true).isNotEmpty ? () => searchAddedClient(_filteredClients[index]) : null,
onChanged: (isSelected) {
if (isSelected == true) {
logsProvider.setSelectedClients([
@ -376,7 +378,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,

View file

@ -154,6 +154,8 @@ class LogTile extends StatelessWidget {
}
void blockUnblockRuleClient() async {
if (!context.mounted) return;
ProcessModal processModal = ProcessModal();
processModal.open(AppLocalizations.of(context)!.addingRule);

View file

@ -89,6 +89,7 @@ class LogsListAppBar extends StatelessWidget {
}
void openLiveLogsScreen() {
if (!context.mounted) return;
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => MultiProvider(

View file

@ -1,3 +1,4 @@
import 'package:adguard_home_manager/constants/regexps.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -67,8 +68,7 @@ class __ContentState extends State<_Content> {
bool validData = false;
void validateMac(String value) {
final RegExp macRegex = RegExp(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$');
if (macRegex.hasMatch(value)) {
if (Regexps.macAddress.hasMatch(value)) {
setState(() => macError = null);
}
else {
@ -78,8 +78,7 @@ class __ContentState extends State<_Content> {
}
void validateIp(String value) {
RegExp ipAddress = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$');
if (ipAddress.hasMatch(value) == true) {
if (Regexps.ipv4Address.hasMatch(value) == true) {
setState(() => ipError = null);
}
else {

View file

@ -2,6 +2,7 @@
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';
@ -100,8 +101,8 @@ class _DhcpScreenState extends State<DhcpScreen> {
break;
}
}
final regex = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$');
if (regex.hasMatch(value)) {
if (Regexps.ipv4Address.hasMatch(value)) {
setValue(null);
}
else {
@ -126,8 +127,8 @@ class _DhcpScreenState extends State<DhcpScreen> {
break;
}
}
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)) {
if (Regexps.ipv6Address.hasMatch(value)) {
setValue(null);
}
else {

View file

@ -1,5 +1,6 @@
// 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';
@ -23,8 +24,7 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
bool validValues = false;
void validateIp(Map<String, dynamic> field, String value) {
RegExp ipAddress = RegExp(r'(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$)');
if (ipAddress.hasMatch(value) == true) {
if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.ipv6Address.hasMatch(value) == true) {
setState(() => field['error'] = null);
}
else {

View file

@ -1,5 +1,6 @@
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';
@ -24,9 +25,7 @@ class _FallbackDnsScreenState extends State<FallbackDnsScreen> {
bool validValues = false;
void validateIp(Map<String, dynamic> field, String value) {
RegExp ipAddress = RegExp(r'(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$)');
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) {
if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.ipv6Address.hasMatch(value) || Regexps.url.hasMatch(value) == true) {
setState(() => field['error'] = null);
}
else {

View file

@ -1,3 +1,4 @@
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';
@ -33,8 +34,7 @@ class _RateLimitAllowlistModalState extends State<RateLimitAllowlistModal> {
List<_IpListItemController> _controllersList = [];
void _validateIp(String value, _IpListItemController item) {
final regexp = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$');
if (regexp.hasMatch(value)) {
if (Regexps.ipv4Address.hasMatch(value)) {
setState(() => _controllersList = _controllersList.map((e) {
if (e.id == item.id) {
return _IpListItemController(

View file

@ -1,5 +1,3 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:flutter/material.dart';
@ -30,6 +28,9 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
bool validValues = false;
final upstreamTimeoutController = TextEditingController();
String? upstreamTimeoutError = null;
checkValidValues() {
if (
dnsServers.isNotEmpty &&
@ -61,6 +62,7 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
}
}
upstreamMode = dnsProvider.dnsInfo!.upstreamMode ?? "";
upstreamTimeoutController.text = dnsProvider.dnsInfo!.upstreamTimeout != null ? dnsProvider.dnsInfo!.upstreamTimeout.toString() : "";
validValues = true;
super.initState();
}
@ -72,6 +74,23 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
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(
@ -146,11 +165,13 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
final result = await dnsProvider.saveUpstreamDnsConfig({
"upstream_dns": dnsServers.map((e) => e['controller'] != null ? e['controller'].text : e['comment']).toList(),
"upstream_mode": upstreamMode
"upstream_mode": upstreamMode,
"upstream_timeout": int.tryParse(upstreamTimeoutController.text)
});
processModal.close();
if (!context.mounted) return;
if (result.successful == true) {
showSnackbar(
appConfigProvider: appConfigProvider,
@ -312,6 +333,27 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
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
)
),
),
],
),
),

View file

@ -1,5 +1,6 @@
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';
@ -82,8 +83,7 @@ class _ContentState extends State<_Content> {
bool validData = false;
void validateDomain(String value) {
final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
if (domainRegex.hasMatch(value)) {
if (Regexps.wildcardDomain.hasMatch(value)) {
setState(() => domainError = null);
}
else {

View file

@ -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) {
RegExp regExp = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
if (regExp.hasMatch(domain)) {
if (Regexps.domain.hasMatch(domain)) {
return null;
}
else {
@ -23,8 +23,7 @@ String? validatePort(BuildContext context, String value) {
}
String? validateCertificate(BuildContext context, String cert) {
final regExp = RegExp(r'(-{3,}(\bBEGIN CERTIFICATE\b))|(-{3,}-{3,}(\END CERTIFICATE\b)-{3,})', multiLine: true);
if (regExp.hasMatch(cert.replaceAll('\n', ''))) {
if (Regexps.certificate.hasMatch(cert.replaceAll('\n', ''))) {
return null;
}
else {
@ -33,8 +32,7 @@ String? validateCertificate(BuildContext context, String cert) {
}
String? validatePrivateKey(BuildContext context, String cert) {
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', ''))) {
if (Regexps.privateKey.hasMatch(cert.replaceAll('\n', ''))) {
return null;
}
else {
@ -43,8 +41,7 @@ String? validatePrivateKey(BuildContext context, String cert) {
}
String? validatePath(BuildContext context, String cert) {
final regExp = RegExp(r'^(\/{0,1}(?!\/))[A-Za-z0-9\/\-_]+(\.([a-zA-Z]+))?$');
if (regExp.hasMatch(cert)) {
if (Regexps.path.hasMatch(cert)) {
return null;
}
else {

View file

@ -1,3 +1,4 @@
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';
@ -55,9 +56,8 @@ 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 (domainRegex.hasMatch(value)) {
if (Regexps.domain.hasMatch(value)) {
error = false;
}
else {

View file

@ -1,3 +1,4 @@
import 'package:adguard_home_manager/constants/regexps.dart';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import 'package:provider/provider.dart';
@ -91,9 +92,8 @@ class _StatisticsSettingsState extends State<StatisticsSettings> {
void validateDomain(String value, String id) {
final domainRegex = RegExp(r'^([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
bool error = false;
if (domainRegex.hasMatch(value)) {
if (Regexps.domain.hasMatch(value)) {
error = false;
}
else {

View file

@ -218,9 +218,16 @@ class _Header extends SliverPersistentHeaderDelegate {
final iconBottom = _iconMinBottomPositionExent + (iconMaxBottomPositionExent-iconMinBottomPositionExent)*(1-iconPercentage);
return LayoutBuilder(
builder: (context, constraints) => Container(
builder: (context, constraints) => Stack(
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
color: Theme.of(context).colorScheme.surface,
),
),
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceTint.withOpacity(0.075),
),
child: Align(
alignment: Alignment.topLeft,
@ -314,6 +321,8 @@ class _Header extends SliverPersistentHeaderDelegate {
),
),
),
],
),
);
}

View file

@ -1,3 +1,4 @@
import 'package:adguard_home_manager/constants/regexps.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -49,8 +50,7 @@ String? validateSubroute({
required String? value
}) {
if (value != null && value != '') {
RegExp subrouteRegexp = RegExp(r'^\/\b([A-Za-z0-9_\-~/]*)[^\/|\.|\:]$');
if (subrouteRegexp.hasMatch(value) == true) {
if (Regexps.subroute.hasMatch(value) == true) {
return null;
}
else {
@ -67,9 +67,7 @@ String? validateAddress({
required String? value
}) {
if (value != null && value != '') {
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) {
if (Regexps.ipv4Address.hasMatch(value) == true || Regexps.domain.hasMatch(value) == true) {
return null;
}
else {

View file

@ -175,6 +175,8 @@ class _AddServerModalState extends State<AddServerModal> {
final ApiClientV2 apiClient2 = ApiClientV2(server: serverObj);
final serverStatus = await apiClient2.getServerStatus();
if (!context.mounted) return;
// If something goes wrong when fetching server status
if (serverStatus.successful == false) {
statusProvider.setServerStatusLoad(LoadStatus.error);
@ -203,16 +205,16 @@ class _AddServerModalState extends State<AddServerModal> {
final serverCreated = await serversProvider.createServer(serverObj);
if (!context.mounted) return;
// If something goes wrong when saving the connection on the db
if (serverCreated != null) {
if (mounted) setState(() => isConnecting = false);
if (mounted) {
setState(() => isConnecting = false);
showSnackbar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.connectionNotCreated,
color: Colors.red
);
}
return;
}
@ -296,9 +298,11 @@ class _AddServerModalState extends State<AddServerModal> {
final serverSaved = await serversProvider.editServer(serverObj);
if (!mounted) return;
// If something goes wrong when saving the connection on the db
if (serverSaved != null) {
if (mounted) setState(() => isConnecting = false);
setState(() => isConnecting = false);
appConfigProvider.addLog(
AppLog(
type: 'save_connection_db',
@ -306,13 +310,11 @@ class _AddServerModalState extends State<AddServerModal> {
message: serverSaved.toString()
)
);
if (mounted) {
showSnackbar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.connectionNotCreated,
color: Colors.red
);
}
return;
}

View file

@ -6,33 +6,34 @@ PODS:
- FlutterMacOS (1.0.0)
- package_info_plus (0.0.1):
- FlutterMacOS
- screen_retriever (0.0.1):
- screen_retriever_macos (0.0.1):
- FlutterMacOS
- Sentry/HybridSDK (8.36.0)
- sentry_flutter (8.9.0):
- Sentry/HybridSDK (8.44.0)
- sentry_flutter (8.13.2):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 8.36.0)
- Sentry/HybridSDK (= 8.44.0)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sqflite (0.0.3):
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- "sqlite3 (3.46.1+1)":
- "sqlite3/common (= 3.46.1+1)"
- "sqlite3/common (3.46.1+1)"
- "sqlite3/dbstatvtab (3.46.1+1)":
- sqlite3 (3.49.1):
- sqlite3/common (= 3.49.1)
- sqlite3/common (3.49.1)
- sqlite3/dbstatvtab (3.49.1):
- sqlite3/common
- "sqlite3/fts5 (3.46.1+1)":
- sqlite3/fts5 (3.49.1):
- sqlite3/common
- "sqlite3/perf-threadsafe (3.46.1+1)":
- sqlite3/perf-threadsafe (3.49.1):
- sqlite3/common
- "sqlite3/rtree (3.46.1+1)":
- sqlite3/rtree (3.49.1):
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- FlutterMacOS
- "sqlite3 (~> 3.46.0+1)"
- sqlite3 (~> 3.49.1)
- sqlite3/dbstatvtab
- sqlite3/fts5
- sqlite3/perf-threadsafe
@ -47,11 +48,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 (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
- screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
- sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`)
- sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
@ -69,33 +70,33 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
screen_retriever:
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos
screen_retriever_macos:
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos
sentry_flutter:
:path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sqflite:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin
sqflite_darwin:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin
sqlite3_flutter_libs:
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin
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: ce1b7762849d3ec103d0e0517299f2db7ad60720
device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe
package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b
screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161
Sentry: 0f9bc9adfc0b960e7f3bb5ec67e9a3d8193f3bdb
sentry_flutter: 64a43fb39ab4c7f67d8a4cad52b49e22439e58b7
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
sqlite3_flutter_libs: 5ca46c1a04eddfbeeb5b16566164aa7ad1616e7b
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983
sqlite3_flutter_libs: cc304edcb8e1d8c595d1b08c7aeb46a47691d9db
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8

View file

@ -48,6 +48,7 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

View file

@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
}

View file

@ -29,42 +29,42 @@ packages:
dependency: transitive
description:
name: archive
sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a"
sha256: "7dcbd0f87fe5f61cb28da39a1a8b70dbc106e2fe0516f7836eb7bb2948481a12"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
version: "4.0.5"
args:
dependency: transitive
description:
name: args
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
url: "https://pub.dev"
source: hosted
version: "2.6.0"
version: "2.7.0"
async:
dependency: "direct main"
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
url: "https://pub.dev"
source: hosted
version: "2.11.0"
version: "2.12.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
checked_yaml:
dependency: transitive
description:
@ -85,18 +85,18 @@ packages:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.19.0"
version: "1.19.1"
contextmenu:
dependency: "direct main"
description:
@ -117,10 +117,10 @@ packages:
dependency: transitive
description:
name: csslib
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
url: "https://pub.dev"
source: hosted
version: "0.17.3"
version: "1.0.2"
cupertino_icons:
dependency: "direct main"
description:
@ -133,10 +133,10 @@ packages:
dependency: "direct main"
description:
name: device_info_plus
sha256: b37d37c2f912ad4e8ec694187de87d05de2a3cb82b465ff1f65f65a2d05de544
sha256: "306b78788d1bb569edb7c55d622953c2414ca12445b41c9117963e03afc5c513"
url: "https://pub.dev"
source: hosted
version: "11.2.1"
version: "11.3.3"
device_info_plus_platform_interface:
dependency: transitive
description:
@ -173,18 +173,18 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
ffi:
dependency: transitive
description:
name: ffi
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.4"
file:
dependency: transitive
description:
@ -254,14 +254,6 @@ 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:
@ -274,10 +266,10 @@ packages:
dependency: "direct main"
description:
name: flutter_html
sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee"
sha256: "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d"
url: "https://pub.dev"
source: hosted
version: "3.0.0-beta.2"
version: "3.0.0"
flutter_launcher_icons:
dependency: "direct dev"
description:
@ -303,18 +295,18 @@ packages:
dependency: "direct main"
description:
name: flutter_markdown
sha256: e37f4c69a07b07bb92622ef6b131a53c9aae48f64b176340af9e8e5238718487
sha256: e7bbc718adc9476aa14cfddc1ef048d2e21e4e8f18311aaac723266db9f9e7b5
url: "https://pub.dev"
source: hosted
version: "0.7.5"
version: "0.7.6+2"
flutter_native_splash:
dependency: "direct dev"
description:
name: flutter_native_splash
sha256: "7062602e0dbd29141fb8eb19220b5871ca650be5197ab9c1f193a28b17537bc7"
sha256: edb09c35ee9230c4b03f13dd45bb3a276d0801865f0a4650b7e2a3bba61a803a
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "2.4.5"
flutter_reorderable_list:
dependency: "direct main"
description:
@ -345,10 +337,10 @@ packages:
dependency: "direct main"
description:
name: html
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec"
url: "https://pub.dev"
source: hosted
version: "0.15.4"
version: "0.15.5"
http:
dependency: "direct main"
description:
@ -369,10 +361,10 @@ packages:
dependency: transitive
description:
name: image
sha256: "8346ad4b5173924b5ddddab782fc7d8a6300178c8b1dc427775405a01701c4a6"
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
url: "https://pub.dev"
source: hosted
version: "4.5.2"
version: "4.5.4"
intl:
dependency: "direct main"
description:
@ -393,18 +385,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
url: "https://pub.dev"
source: hosted
version: "10.0.7"
version: "10.0.8"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.dev"
source: hosted
version: "3.0.8"
version: "3.0.9"
leak_tracker_testing:
dependency: transitive
description:
@ -441,10 +433,10 @@ packages:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
@ -457,10 +449,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev"
source: hosted
version: "1.15.0"
version: "1.16.0"
nested:
dependency: transitive
description:
@ -473,26 +465,26 @@ packages:
dependency: "direct main"
description:
name: package_info_plus
sha256: "739e0a5c3c4055152520fa321d0645ee98e932718b4c8efeeb51451968fe0790"
sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
url: "https://pub.dev"
source: hosted
version: "8.1.3"
version: "8.3.0"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b
sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.2.0"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
path_parsing:
dependency: transitive
description:
@ -537,10 +529,10 @@ packages:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
url: "https://pub.dev"
source: hosted
version: "6.0.2"
version: "6.1.0"
pie_chart:
dependency: "direct main"
description:
@ -633,34 +625,34 @@ packages:
dependency: transitive
description:
name: sentry
sha256: "576ad83415102ba2060142a6701611abc6e67a55af1d7ab339cedd3ba1b0f84c"
sha256: "3a64dd001bff768ce5ab6fc3608deef4dde22acd4b5d947763557b20db9e2a32"
url: "https://pub.dev"
source: hosted
version: "8.12.0"
version: "8.14.0"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
sha256: dc3761e8659839cc67a18432d9f12e5531affb7ff68e196dbb56846909b5dfdc
sha256: "3d361f2d5f805783e2e4ed1bd475ef126b36cf525b359dc3627a765a3fb7424d"
url: "https://pub.dev"
source: hosted
version: "8.12.0"
version: "8.14.0"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: a752ce92ea7540fc35a0d19722816e04d0e72828a4200e83a98cf1a1eb524c9a
sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a"
url: "https://pub.dev"
source: hosted
version: "2.3.5"
version: "2.5.2"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "138b7bbbc7f59c56236e426c37afb8f78cbc57b094ac64c440e0bb90e380a4f5"
sha256: "3ec7210872c4ba945e3244982918e502fa2bfb5230dff6832459ca0e1879b7ad"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.4.8"
shared_preferences_foundation:
dependency: transitive
description:
@ -689,10 +681,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_web
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.4.3"
shared_preferences_windows:
dependency: transitive
description:
@ -710,10 +702,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.10.1"
sprintf:
dependency: transitive
description:
@ -726,42 +718,42 @@ packages:
dependency: "direct main"
description:
name: sqflite
sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb"
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3"
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.4.1"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709"
sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b"
url: "https://pub.dev"
source: hosted
version: "2.5.4+6"
version: "2.5.5"
sqflite_common_ffi:
dependency: "direct main"
description:
name: sqflite_common_ffi
sha256: "883dd810b2b49e6e8c3b980df1829ef550a94e3f87deab5d864917d27ca6bf36"
sha256: "1f3ef3888d3bfbb47785cc1dda0dc7dd7ebd8c1955d32a9e8e9dae1e38d1c4c1"
url: "https://pub.dev"
source: hosted
version: "2.3.4+4"
version: "2.3.5"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c"
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
url: "https://pub.dev"
source: hosted
version: "2.4.1+1"
version: "2.4.2"
sqflite_platform_interface:
dependency: transitive
description:
@ -774,66 +766,66 @@ packages:
dependency: transitive
description:
name: sqlite3
sha256: "35d3726fe18ab1463403a5cc8d97dbc81f2a0b08082e8173851363fcc97b6627"
sha256: "310af39c40dd0bb2058538333c9d9840a2725ae0b9f77e4fd09ad6696aa8f66e"
url: "https://pub.dev"
source: hosted
version: "2.7.2"
version: "2.7.5"
sqlite3_flutter_libs:
dependency: "direct main"
description:
name: sqlite3_flutter_libs
sha256: "50a7e3f294c741d3142eed0ff228e38498334e11e0ccb9d73e0496e005949e44"
sha256: "1a96b59227828d9eb1463191d684b37a27d66ee5ed7597fcf42eee6452c88a14"
url: "https://pub.dev"
source: hosted
version: "0.5.29"
version: "0.5.32"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.1"
synchronized:
dependency: transitive
description:
name: synchronized
sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225"
sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6"
url: "https://pub.dev"
source: hosted
version: "3.3.0+3"
version: "3.3.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.dev"
source: hosted
version: "0.7.3"
version: "0.7.4"
timezone:
dependency: "direct main"
description:
@ -870,10 +862,10 @@ packages:
dependency: transitive
description:
name: url_launcher_android
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
sha256: "1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4"
url: "https://pub.dev"
source: hosted
version: "6.3.14"
version: "6.3.15"
url_launcher_ios:
dependency: transitive
description:
@ -934,10 +926,10 @@ packages:
dependency: transitive
description:
name: vector_graphics
sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7"
sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de"
url: "https://pub.dev"
source: hosted
version: "1.1.15"
version: "1.1.18"
vector_graphics_codec:
dependency: transitive
description:
@ -966,34 +958,34 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
url: "https://pub.dev"
source: hosted
version: "14.3.0"
version: "14.3.1"
web:
dependency: transitive
description:
name: web
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.1"
win32:
dependency: transitive
description:
name: win32
sha256: "154360849a56b7b67331c21f09a386562d88903f90a1099c5987afc1912e1f29"
sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f
url: "https://pub.dev"
source: hosted
version: "5.10.0"
version: "5.12.0"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
url: "https://pub.dev"
source: hosted
version: "1.1.5"
version: "2.1.0"
window_manager:
dependency: "direct main"
description:
@ -1027,5 +1019,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.6.0 <4.0.0"
dart: ">=3.7.0 <4.0.0"
flutter: ">=3.27.0"

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
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 2.20.0+147
version: 2.20.4+151
environment:
sdk: '>=2.18.1 <3.0.0'
@ -42,7 +42,6 @@ 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