mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-05-04 20:30:35 +00:00
Dhcp and dns settings optimizations
This commit is contained in:
parent
4c86727b5d
commit
5d23f3c3e7
8 changed files with 676 additions and 515 deletions
|
@ -5,10 +5,12 @@ import 'package:adguard_home_manager/models/dhcp.dart';
|
|||
|
||||
class AddStaticLeaseModal extends StatefulWidget {
|
||||
final void Function(Lease) onConfirm;
|
||||
final bool dialog;
|
||||
|
||||
const AddStaticLeaseModal({
|
||||
Key? key,
|
||||
required this.onConfirm,
|
||||
required this.dialog
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -65,24 +67,19 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: MediaQuery.of(context).viewInsets,
|
||||
child: Container(
|
||||
height: 510,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).dialogBackgroundColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(28),
|
||||
topRight: Radius.circular(28)
|
||||
)
|
||||
),
|
||||
child: Column(
|
||||
Widget content() {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
physics: 550 < MediaQuery.of(context).size.height
|
||||
? const NeverScrollableScrollPhysics()
|
||||
: null,
|
||||
SingleChildScrollView(
|
||||
child: Wrap(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
|
@ -101,9 +98,15 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
|
|||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 28),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 24, right: 24, bottom: 12
|
||||
),
|
||||
child: TextFormField(
|
||||
controller: macController,
|
||||
onChanged: validateMac,
|
||||
|
@ -119,9 +122,8 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
|
|||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 28),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipController,
|
||||
onChanged: validateIp,
|
||||
|
@ -137,9 +139,10 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
|
|||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 28),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 24, right: 24, top: 12
|
||||
),
|
||||
child: TextFormField(
|
||||
controller: hostNameController,
|
||||
onChanged: (value) {
|
||||
|
@ -167,7 +170,7 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
|
|||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
|
@ -202,8 +205,33 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
|
|||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.dialog == true) {
|
||||
return Dialog(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 400
|
||||
),
|
||||
child: content(),
|
||||
),
|
||||
);
|
||||
}
|
||||
else {
|
||||
return Padding(
|
||||
padding: MediaQuery.of(context).viewInsets,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).dialogBackgroundColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(28),
|
||||
topRight: Radius.circular(28)
|
||||
)
|
||||
),
|
||||
child: content()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:bottom_sheet/bottom_sheet.dart';
|
||||
|
@ -213,6 +215,8 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
void saveSettings() async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.savingSettings);
|
||||
|
@ -354,24 +358,32 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
void selectInterface() {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
Future.delayed(const Duration(seconds: 0), () {
|
||||
showFlexibleBottomSheet(
|
||||
minHeight: 0.6,
|
||||
initHeight: 0.6,
|
||||
maxHeight: 0.95,
|
||||
isCollapsible: true,
|
||||
duration: const Duration(milliseconds: 250),
|
||||
anchors: [0.95],
|
||||
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx, controller, offset) => SelectInterfaceModal(
|
||||
builder: (context) => SelectInterfaceModal(
|
||||
interfaces: serversProvider.dhcp.data!.networkInterfaces,
|
||||
scrollController: controller,
|
||||
onSelect: (interface) => setState(() {
|
||||
clearAll();
|
||||
selectedInterface = interface;
|
||||
})
|
||||
),
|
||||
bottomSheetColor: Colors.transparent
|
||||
}),
|
||||
dialog: true,
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => SelectInterfaceModal(
|
||||
interfaces: serversProvider.dhcp.data!.networkInterfaces,
|
||||
onSelect: (i) => setState(() {
|
||||
clearAll();
|
||||
selectedInterface = i;
|
||||
}),
|
||||
dialog: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -399,7 +411,8 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
|
||||
case 1:
|
||||
if (selectedInterface != null) {
|
||||
return ListView(
|
||||
return SingleChildScrollView(
|
||||
child: Wrap(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
|
@ -459,10 +472,16 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
if (selectedInterface!.ipv4Addresses.isNotEmpty) ...[
|
||||
SectionLabel(
|
||||
label: AppLocalizations.of(context)!.ipv4settings,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
|
||||
padding: const EdgeInsets.only(
|
||||
top: 24, left: 16, right: 16, bottom: 8
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 900 ? 0.5 : 1,
|
||||
child: Padding(
|
||||
padding: width > 900
|
||||
? const EdgeInsets.only(top: 12, bottom: 12, left: 16, right: 8)
|
||||
: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv4StartRangeController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4StartRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
|
@ -479,9 +498,13 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 900 ? 0.5 : 1,
|
||||
child: Padding(
|
||||
padding: width > 900
|
||||
? const EdgeInsets.only(top: 12, bottom: 12, left: 8, right: 16)
|
||||
: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv4EndRangeController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4EndRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
|
@ -498,9 +521,13 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 900 ? 0.5 : 1,
|
||||
child: Padding(
|
||||
padding: width > 900
|
||||
? const EdgeInsets.only(top: 12, bottom: 12, left: 16, right: 8)
|
||||
: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv4SubnetMaskController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4SubnetMaskError', AppLocalizations.of(context)!.subnetMaskNotValid),
|
||||
|
@ -517,9 +544,13 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 900 ? 0.5 : 1,
|
||||
child: Padding(
|
||||
padding: width > 900
|
||||
? const EdgeInsets.only(top: 12, bottom: 12, left: 8, right: 16)
|
||||
: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv4GatewayController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4GatewayError', AppLocalizations.of(context)!.gatewayNotValid),
|
||||
|
@ -536,9 +567,11 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv4LeaseTimeController,
|
||||
onChanged: (value) {
|
||||
|
@ -562,13 +595,19 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (selectedInterface!.ipv6Addresses.isNotEmpty) ...[
|
||||
SectionLabel(
|
||||
label: AppLocalizations.of(context)!.ipv6settings,
|
||||
padding: const EdgeInsets.all(16)
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 900 ? 0.5 : 1,
|
||||
child: Padding(
|
||||
padding: width > 900
|
||||
? const EdgeInsets.only(top: 8, bottom: 12, left: 16, right: 8)
|
||||
: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv6StartRangeController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv6StartRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
|
@ -585,9 +624,13 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: width > 900 ? 0.5 : 1,
|
||||
child: Padding(
|
||||
padding: width > 900
|
||||
? const EdgeInsets.only(top: 8, bottom: 12, left: 8, right: 16)
|
||||
: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv6EndRangeController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv6EndRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
|
@ -604,9 +647,11 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv6LeaseTimeController,
|
||||
onChanged: (value) {
|
||||
|
@ -630,12 +675,14 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 20),
|
||||
SectionLabel(
|
||||
label: AppLocalizations.of(context)!.dhcpLeases,
|
||||
padding: const EdgeInsets.all(16),
|
||||
),
|
||||
Material(
|
||||
if (width <= 900) Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
|
@ -668,7 +715,7 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
),
|
||||
),
|
||||
),
|
||||
Material(
|
||||
if (width <= 900) Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
|
@ -701,12 +748,51 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (width > 900) Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.leases,
|
||||
staticLeases: false,
|
||||
)
|
||||
)),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(AppLocalizations.of(context)!.dhcpLeases),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.arrow_forward_rounded)
|
||||
],
|
||||
)
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: serversProvider.dhcp.data!.dhcpStatus.staticLeases,
|
||||
staticLeases: true,
|
||||
)
|
||||
)),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(AppLocalizations.of(context)!.dhcpStatic),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.arrow_forward_rounded)
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
else {
|
||||
return Column(
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
@ -728,6 +814,8 @@ class _DhcpWidgetState extends State<DhcpWidget> {
|
|||
child: Text(AppLocalizations.of(context)!.selectInterface)
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:animations/animations.dart';
|
||||
|
@ -30,6 +32,8 @@ class DhcpLeases extends StatelessWidget {
|
|||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
void deleteLease(Lease lease) async {
|
||||
ProcessModal processModal = ProcessModal(context: context);
|
||||
processModal.open(AppLocalizations.of(context)!.deleting);
|
||||
|
@ -119,15 +123,27 @@ class DhcpLeases extends StatelessWidget {
|
|||
}
|
||||
|
||||
void openAddStaticLease() {
|
||||
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AddStaticLeaseModal(
|
||||
onConfirm: createLease,
|
||||
dialog: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
else {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => AddStaticLeaseModal(
|
||||
onConfirm: createLease
|
||||
onConfirm: createLease,
|
||||
dialog: false,
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
isScrollControlled: true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
|
|
|
@ -7,31 +7,29 @@ import 'package:adguard_home_manager/models/dhcp.dart';
|
|||
|
||||
class SelectInterfaceModal extends StatelessWidget {
|
||||
final List<NetworkInterface> interfaces;
|
||||
final ScrollController scrollController;
|
||||
final void Function(NetworkInterface) onSelect;
|
||||
final bool dialog;
|
||||
|
||||
const SelectInterfaceModal({
|
||||
Key? key,
|
||||
required this.interfaces,
|
||||
required this.scrollController,
|
||||
required this.onSelect,
|
||||
required this.dialog
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).dialogBackgroundColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(28),
|
||||
topRight: Radius.circular(28)
|
||||
)
|
||||
),
|
||||
child: Column(
|
||||
Widget content() {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
controller: scrollController,
|
||||
SingleChildScrollView(
|
||||
child: Wrap(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
|
@ -50,6 +48,10 @@ class SelectInterfaceModal extends StatelessWidget {
|
|||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ListView.builder(
|
||||
primary: false,
|
||||
|
@ -190,7 +192,30 @@ class SelectInterfaceModal extends StatelessWidget {
|
|||
),
|
||||
if (Platform.isIOS) const SizedBox(height: 16)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if (dialog == true) {
|
||||
return Dialog(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 500
|
||||
),
|
||||
child: content()
|
||||
),
|
||||
);
|
||||
}
|
||||
else {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).dialogBackgroundColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(28),
|
||||
topRight: Radius.circular(28)
|
||||
)
|
||||
),
|
||||
child: content()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -182,8 +182,7 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width-74,
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: c['controller'],
|
||||
onChanged: (value) => validateIp(c, value),
|
||||
|
@ -199,6 +198,7 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
|
|||
)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() => bootstrapControllers = bootstrapControllers.where((con) => con != c).toList());
|
||||
|
|
|
@ -229,8 +229,7 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width-74,
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: c['controller'],
|
||||
onChanged: (value) => validateAddress(c, value),
|
||||
|
@ -246,6 +245,7 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
|
|||
)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() => reverseResolversControllers = reverseResolversControllers.where((con) => con != c).toList());
|
||||
|
|
|
@ -185,13 +185,12 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
),
|
||||
...dnsServers.map((item) => Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16, right: 6, bottom: 20
|
||||
left: 16, right: 6, bottom: 24
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if (item['controller'] != null) SizedBox(
|
||||
width: MediaQuery.of(context).size.width-74,
|
||||
if (item['controller'] != null) Expanded(
|
||||
child: TextFormField(
|
||||
controller: item['controller'],
|
||||
onChanged: (_) => checkValidValues(),
|
||||
|
@ -206,6 +205,7 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
)
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
if (item['comment'] != null) Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
@ -232,10 +232,12 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
|
|||
},
|
||||
icon: const Icon(Icons.remove_circle_outline),
|
||||
tooltip: AppLocalizations.of(context)!.remove,
|
||||
)
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
),
|
||||
)).toList(),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
|
|
@ -41,7 +41,8 @@ class CustomRadioListTile extends StatelessWidget {
|
|||
backgroundColor: radioBackgroundColor,
|
||||
),
|
||||
const SizedBox(width: 24),
|
||||
Column(
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
|
@ -69,6 +70,7 @@ class CustomRadioListTile extends StatelessWidget {
|
|||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue