mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-05-25 11:22:23 +00:00
Added validation
This commit is contained in:
parent
ea1cb6165c
commit
bfe2572e04
7 changed files with 257 additions and 22 deletions
|
@ -468,5 +468,6 @@
|
|||
"blockingIpv4": "Blocking IPv4",
|
||||
"blockingIpv4Description": "IP address to be returned for a blocked A request",
|
||||
"blockingIpv6": "Blocking IPv6",
|
||||
"blockingIpv6Description": "IP address to be returned for a blocked AAAA request"
|
||||
"blockingIpv6Description": "IP address to be returned for a blocked AAAA request",
|
||||
"invalidIp": "Invalid IP address"
|
||||
}
|
|
@ -468,5 +468,6 @@
|
|||
"blockingIpv4": "Bloqueo de IPv4",
|
||||
"blockingIpv4Description": "Dirección IP devolverá una petición A bloqueada",
|
||||
"blockingIpv6": "Bloqueo de IPv6",
|
||||
"blockingIpv6Description": "Dirección IP devolverá una petición AAAA bloqueada"
|
||||
"blockingIpv6Description": "Dirección IP devolverá una petición AAAA bloqueada",
|
||||
"invalidIp": "Dirección IP no válida"
|
||||
}
|
|
@ -16,15 +16,45 @@ class BootstrapDnsScreen extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
||||
List<TextEditingController> bootstrapControllers = [];
|
||||
List<Map<String, dynamic>> bootstrapControllers = [];
|
||||
|
||||
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) {
|
||||
setState(() => field['error'] = null);
|
||||
}
|
||||
else {
|
||||
setState(() => field['error'] = AppLocalizations.of(context)!.invalidIp);
|
||||
}
|
||||
checkValidValues();
|
||||
}
|
||||
|
||||
void checkValidValues() {
|
||||
if (
|
||||
bootstrapControllers.isNotEmpty &&
|
||||
bootstrapControllers.every((element) => element['controller'].text != '') &&
|
||||
bootstrapControllers.every((element) => element['error'] == null)
|
||||
) {
|
||||
setState(() => validValues = true);
|
||||
}
|
||||
else {
|
||||
setState(() => validValues = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
for (var item in widget.serversProvider.dnsInfo.data!.bootstrapDns) {
|
||||
final controller = TextEditingController();
|
||||
controller.text = item;
|
||||
bootstrapControllers.add(controller);
|
||||
bootstrapControllers.add({
|
||||
'controller': controller,
|
||||
'error': null
|
||||
});
|
||||
}
|
||||
validValues = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -33,6 +63,16 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.bootstrapDns),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: validValues == true
|
||||
? () => {}
|
||||
: null,
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
tooltip: AppLocalizations.of(context)!.save,
|
||||
),
|
||||
const SizedBox(width: 10)
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
|
@ -83,8 +123,8 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width-90,
|
||||
child: TextFormField(
|
||||
controller: c,
|
||||
// onChanged: (_) => checkValidValues(),
|
||||
controller: c['controller'],
|
||||
onChanged: (value) => validateIp(c, value),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.dns_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
|
@ -92,12 +132,16 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: c['error'],
|
||||
labelText: AppLocalizations.of(context)!.dnsServer,
|
||||
)
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => setState(() => bootstrapControllers = bootstrapControllers.where((con) => con != c).toList()),
|
||||
onPressed: () {
|
||||
setState(() => bootstrapControllers = bootstrapControllers.where((con) => con != c).toList());
|
||||
checkValidValues();
|
||||
},
|
||||
icon: const Icon(Icons.remove_circle_outline)
|
||||
)
|
||||
],
|
||||
|
@ -108,7 +152,13 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => setState(() => bootstrapControllers.add(TextEditingController())),
|
||||
onPressed: () {
|
||||
setState(() => bootstrapControllers.add({
|
||||
'controller': TextEditingController(),
|
||||
'error': null
|
||||
}));
|
||||
checkValidValues();
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
label: Text(AppLocalizations.of(context)!.addItem)
|
||||
),
|
||||
|
|
|
@ -29,12 +29,31 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
|
||||
bool optimisticCache = false;
|
||||
|
||||
bool validData = false;
|
||||
|
||||
void checkValidData() {
|
||||
if (
|
||||
cacheSizeController.text != '' &&
|
||||
cacheSizeError == null &&
|
||||
overrideMinTtlController.text != '' &&
|
||||
overrideMinTtlError == null &&
|
||||
overrideMaxTtlController.text != '' &&
|
||||
overrideMaxTtlError == null
|
||||
) {
|
||||
setState(() => validData = true);
|
||||
}
|
||||
else {
|
||||
setState(() => validData = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
cacheSizeController.text = widget.serversProvider.dnsInfo.data!.cacheSize.toString();
|
||||
overrideMinTtlController.text = widget.serversProvider.dnsInfo.data!.cacheTtlMin.toString();
|
||||
overrideMaxTtlController.text = widget.serversProvider.dnsInfo.data!.cacheTtlMax.toString();
|
||||
optimisticCache = widget.serversProvider.dnsInfo.data!.cacheOptimistic;
|
||||
validData = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -73,6 +92,16 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.dnsCacheConfig),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: validData == true
|
||||
? () => {}
|
||||
: null,
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
tooltip: AppLocalizations.of(context)!.save,
|
||||
),
|
||||
const SizedBox(width: 10)
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
|
@ -89,6 +118,7 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
else {
|
||||
setState(() => cacheSizeError = AppLocalizations.of(context)!.valueNotNumber);
|
||||
}
|
||||
checkValidData();
|
||||
}
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
|
@ -104,6 +134,7 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
else {
|
||||
setState(() => overrideMinTtlError = AppLocalizations.of(context)!.valueNotNumber);
|
||||
}
|
||||
checkValidData();
|
||||
}
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
|
@ -119,6 +150,7 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
|
|||
else {
|
||||
setState(() => overrideMaxTtlError = AppLocalizations.of(context)!.valueNotNumber);
|
||||
}
|
||||
checkValidData();
|
||||
}
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
|
|
|
@ -33,6 +33,52 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
final TextEditingController ipv6controller = TextEditingController();
|
||||
String? ipv6error;
|
||||
|
||||
bool isDataValid = false;
|
||||
|
||||
void validateIpv4(String value) {
|
||||
RegExp ipAddress = RegExp(r'^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$');
|
||||
if (ipAddress.hasMatch(value) == true) {
|
||||
setState(() => ipv4error = null);
|
||||
}
|
||||
else {
|
||||
setState(() => ipv4error = AppLocalizations.of(context)!.invalidIp);
|
||||
}
|
||||
validateData();
|
||||
}
|
||||
|
||||
void validateIpv6(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) {
|
||||
setState(() => ipv6error = null);
|
||||
}
|
||||
else {
|
||||
setState(() => ipv6error = AppLocalizations.of(context)!.invalidIp);
|
||||
}
|
||||
validateData();
|
||||
}
|
||||
|
||||
void validateData() {
|
||||
if (
|
||||
limitRequestsController.text != '' &&
|
||||
limitRequestsError == null &&
|
||||
(
|
||||
blockingMode != 'custom_ip' ||
|
||||
(
|
||||
blockingMode == 'custom_ip' &&
|
||||
ipv4controller.text != '' &&
|
||||
ipv4error == null &&
|
||||
ipv6controller.text != '' &&
|
||||
ipv6error == null
|
||||
)
|
||||
) == true
|
||||
) {
|
||||
setState(() => isDataValid = true);
|
||||
}
|
||||
else {
|
||||
setState(() => isDataValid = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
limitRequestsController.text = widget.serversProvider.dnsInfo.data!.ratelimit.toString();
|
||||
|
@ -42,6 +88,7 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
blockingMode = widget.serversProvider.dnsInfo.data!.blockingMode;
|
||||
ipv4controller.text = widget.serversProvider.dnsInfo.data!.blockingIpv4;
|
||||
ipv6controller.text = widget.serversProvider.dnsInfo.data!.blockingIpv6;
|
||||
isDataValid = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -56,11 +103,22 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
ipv6error = null;
|
||||
}
|
||||
setState(() => blockingMode = mode);
|
||||
validateData();
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.dnsServerSettings),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: isDataValid == true
|
||||
? () => {}
|
||||
: null,
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
tooltip: AppLocalizations.of(context)!.save,
|
||||
),
|
||||
const SizedBox(width: 10)
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
|
@ -76,6 +134,7 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
else {
|
||||
setState(() => limitRequestsError = AppLocalizations.of(context)!.valueNotNumber);
|
||||
}
|
||||
validateData();
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.looks_one_rounded),
|
||||
|
@ -156,7 +215,7 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: TextFormField(
|
||||
controller: ipv4controller,
|
||||
// onChanged: onChanged,
|
||||
onChanged: validateIpv4,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.link_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
|
@ -177,7 +236,7 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: TextFormField(
|
||||
controller: ipv6controller,
|
||||
// onChanged: onChanged,
|
||||
onChanged: validateIpv6,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.link_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
|
|
|
@ -20,12 +20,46 @@ class PrivateReverseDnsServersScreen extends StatefulWidget {
|
|||
class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServersScreen> {
|
||||
List<String> defaultReverseResolvers = [];
|
||||
bool editReverseResolvers = false;
|
||||
List<TextEditingController> reverseResolversControllers = [
|
||||
TextEditingController()
|
||||
List<Map<String, dynamic>> reverseResolversControllers = [
|
||||
{
|
||||
'controller': TextEditingController(),
|
||||
'error': null
|
||||
}
|
||||
];
|
||||
bool usePrivateReverseDnsResolvers = false;
|
||||
bool enableReverseResolve = false;
|
||||
|
||||
bool validValues = false;
|
||||
|
||||
void validateAddress(Map<String, dynamic> item ,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 domain = RegExp(r'^((http|https|tls|udp|tcp|quic|sdns):\/\/)?([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+$');
|
||||
if (ipAddress.hasMatch(value) == true || domain.hasMatch(value) == true) {
|
||||
setState(() => item['error'] = null);
|
||||
}
|
||||
else {
|
||||
setState(() => item['error'] = AppLocalizations.of(context)!.invalidIpDomain);
|
||||
}
|
||||
|
||||
checkDataValid();
|
||||
}
|
||||
|
||||
void checkDataValid() {
|
||||
if (
|
||||
(
|
||||
editReverseResolvers == true &&
|
||||
reverseResolversControllers.isNotEmpty &&
|
||||
reverseResolversControllers.every((element) => element['controller'].text != '') &&
|
||||
reverseResolversControllers.every((element) => element['error'] == null)
|
||||
) == true
|
||||
) {
|
||||
setState(() => validValues = true);
|
||||
}
|
||||
else {
|
||||
setState(() => validValues = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
for (var item in widget.serversProvider.dnsInfo.data!.defaultLocalPtrUpstreams) {
|
||||
|
@ -34,13 +68,17 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
for (var item in widget.serversProvider.dnsInfo.data!.localPtrUpstreams) {
|
||||
final controller = TextEditingController();
|
||||
controller.text = item;
|
||||
reverseResolversControllers.add(controller);
|
||||
reverseResolversControllers.add({
|
||||
'controller': controller,
|
||||
'error': null
|
||||
});
|
||||
}
|
||||
if (widget.serversProvider.dnsInfo.data!.localPtrUpstreams.isNotEmpty) {
|
||||
editReverseResolvers = true;
|
||||
}
|
||||
usePrivateReverseDnsResolvers = widget.serversProvider.dnsInfo.data!.usePrivatePtrResolvers;
|
||||
enableReverseResolve = widget.serversProvider.dnsInfo.data!.resolveClients;
|
||||
validValues = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -49,6 +87,16 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.privateReverseDnsServers),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: validValues == true
|
||||
? () => {}
|
||||
: null,
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
tooltip: AppLocalizations.of(context)!.save,
|
||||
),
|
||||
const SizedBox(width: 10)
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
|
@ -90,7 +138,10 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => setState(() => editReverseResolvers = true),
|
||||
onPressed: () {
|
||||
setState(() => editReverseResolvers = true);
|
||||
checkDataValid();
|
||||
},
|
||||
icon: const Icon(Icons.edit),
|
||||
label: Text(AppLocalizations.of(context)!.edit)
|
||||
),
|
||||
|
@ -110,8 +161,8 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width-90,
|
||||
child: TextFormField(
|
||||
controller: c,
|
||||
// onChanged: (_) => checkValidValues(),
|
||||
controller: c['controller'],
|
||||
onChanged: (value) => validateAddress(c, value),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.dns_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
|
@ -119,12 +170,16 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: c['error'],
|
||||
labelText: AppLocalizations.of(context)!.serverAddress,
|
||||
)
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => setState(() => reverseResolversControllers = reverseResolversControllers.where((con) => con != c).toList()),
|
||||
onPressed: () {
|
||||
setState(() => reverseResolversControllers = reverseResolversControllers.where((con) => con != c).toList());
|
||||
checkDataValid();
|
||||
},
|
||||
icon: const Icon(Icons.remove_circle_outline)
|
||||
)
|
||||
],
|
||||
|
@ -152,7 +207,13 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => setState(() => reverseResolversControllers.add(TextEditingController())),
|
||||
onPressed: () {
|
||||
setState(() => reverseResolversControllers.add({
|
||||
'controller': TextEditingController(),
|
||||
'error': null
|
||||
}));
|
||||
checkDataValid();
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
label: Text(AppLocalizations.of(context)!.addItem)
|
||||
),
|
||||
|
|
|
@ -21,7 +21,21 @@ class UpstreamDnsScreen extends StatefulWidget {
|
|||
class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
||||
List<TextEditingController> upstreamControllers = [];
|
||||
|
||||
String upstreamMode = "load_balancing";
|
||||
String upstreamMode = "";
|
||||
|
||||
bool validValues = false;
|
||||
|
||||
checkValidValues() {
|
||||
if (
|
||||
upstreamControllers.isNotEmpty &&
|
||||
upstreamControllers.every((element) => element.text != '')
|
||||
) {
|
||||
setState(() => validValues = true);
|
||||
}
|
||||
else {
|
||||
setState(() => validValues = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -31,6 +45,7 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
upstreamControllers.add(controller);
|
||||
}
|
||||
upstreamMode = widget.serversProvider.dnsInfo.data!.upstreamMode;
|
||||
validValues = true;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -39,6 +54,16 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.upstreamDns),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: validValues == true
|
||||
? () => {}
|
||||
: null,
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
tooltip: AppLocalizations.of(context)!.save,
|
||||
),
|
||||
const SizedBox(width: 10)
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
|
@ -71,7 +96,7 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
width: MediaQuery.of(context).size.width-90,
|
||||
child: TextFormField(
|
||||
controller: c,
|
||||
// onChanged: (_) => checkValidValues(),
|
||||
onChanged: (_) => checkValidValues(),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.dns_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
|
@ -84,7 +109,10 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => setState(() => upstreamControllers = upstreamControllers.where((con) => con != c).toList()),
|
||||
onPressed: () {
|
||||
setState(() => upstreamControllers = upstreamControllers.where((con) => con != c).toList());
|
||||
checkValidValues();
|
||||
},
|
||||
icon: const Icon(Icons.remove_circle_outline)
|
||||
)
|
||||
],
|
||||
|
@ -95,7 +123,10 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => setState(() => upstreamControllers.add(TextEditingController())),
|
||||
onPressed: () {
|
||||
setState(() => upstreamControllers.add(TextEditingController()));
|
||||
checkValidValues();
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
label: Text(AppLocalizations.of(context)!.addItem)
|
||||
),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue