mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-04-19 21:39:16 +00:00
Compare commits
25 commits
2.20.0_(14
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
a4bf4cd3c5 | ||
|
61b0f724ba | ||
|
52945b04ff | ||
|
8e5bbdbd4b | ||
|
e6a01ac546 | ||
|
e8440f7d1d | ||
|
6cc212751b | ||
|
ae9d23d4a8 | ||
|
566254e617 | ||
|
88339d1c40 | ||
|
254bbcef57 | ||
|
e7aacfbec1 | ||
|
7a75a67701 | ||
|
7632d9ef87 | ||
|
eded494024 | ||
|
e5979edf63 | ||
|
f27b17aad0 | ||
|
fd4daba2aa | ||
|
ce7a8e8cc5 | ||
|
4282792ebd | ||
|
4766d1907f | ||
|
7f6f686b2b | ||
|
02b659c1bc | ||
|
db6e63c4aa | ||
|
a666d109d9 |
40 changed files with 458 additions and 365 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -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
|
||||
|
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -16,5 +16,5 @@
|
|||
"cSpell.ignorePaths": [
|
||||
"/pubspec.yaml",
|
||||
"/.github/workflows"
|
||||
]
|
||||
],
|
||||
}
|
|
@ -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
2
debian/debian.yaml
vendored
|
@ -5,7 +5,7 @@ flutter_app:
|
|||
|
||||
control:
|
||||
Package: AdGuardHomeManager
|
||||
Version: 2.20.0
|
||||
Version: 2.20.1
|
||||
Architecture: amd64
|
||||
Essential: no
|
||||
Priority: optional
|
||||
|
|
|
@ -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()
|
||||
// }
|
||||
// )
|
||||
);
|
12
lib/constants/regexps.dart
Normal file
12
lib/constants/regexps.dart
Normal 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]+))?$');
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -154,6 +154,8 @@ class LogTile extends StatelessWidget {
|
|||
}
|
||||
|
||||
void blockUnblockRuleClient() async {
|
||||
if (!context.mounted) return;
|
||||
|
||||
ProcessModal processModal = ProcessModal();
|
||||
processModal.open(AppLocalizations.of(context)!.addingRule);
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ class LogsListAppBar extends StatelessWidget {
|
|||
}
|
||||
|
||||
void openLiveLogsScreen() {
|
||||
if (!context.mounted) return;
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MultiProvider(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
|||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
|
|
@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate {
|
|||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
206
pubspec.lock
206
pubspec.lock
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue