mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-04-23 23:39:12 +00:00
Support AGH without DHCP server
This commit is contained in:
parent
2511ac2c24
commit
83ea589187
9 changed files with 291 additions and 274 deletions
|
@ -688,5 +688,7 @@
|
|||
"yourVersion": "Your version: {version}",
|
||||
"minimumRequiredVersion": "Minimum required version: {version}",
|
||||
"topUpstreams": "Top upstreams",
|
||||
"averageUpstreamResponseTime": "Average upstream response time"
|
||||
"averageUpstreamResponseTime": "Average upstream response time",
|
||||
"dhcpNotAvailable": "The DHCP server is not available.",
|
||||
"osServerInstalledIncompatible": "The OS where the server is installed is not compatible with this feature."
|
||||
}
|
|
@ -688,5 +688,7 @@
|
|||
"yourVersion": "Tu versión: {version}",
|
||||
"minimumRequiredVersion": "Versión mínima requerida: {version}",
|
||||
"topUpstreams": "DNS de subida más frecuentes",
|
||||
"averageUpstreamResponseTime": "Tiempo promedio de respuesta upstream"
|
||||
"averageUpstreamResponseTime": "Tiempo promedio de respuesta upstream",
|
||||
"dhcpNotAvailable": "El servidor DHCP no está disponible.",
|
||||
"osServerInstalledIncompatible": "El SO donde el servidor está instalado no es compatible con esta característica."
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
import 'dart:convert';
|
||||
class DhcpModel {
|
||||
bool dhcpAvailable;
|
||||
List<NetworkInterface> networkInterfaces;
|
||||
DhcpStatus dhcpStatus;
|
||||
DhcpStatus? dhcpStatus;
|
||||
|
||||
DhcpModel({
|
||||
required this.dhcpAvailable,
|
||||
required this.networkInterfaces,
|
||||
required this.dhcpStatus,
|
||||
});
|
||||
|
|
|
@ -69,7 +69,7 @@ class DhcpProvider with ChangeNotifier {
|
|||
|
||||
if (result.successful == true) {
|
||||
DhcpModel data = dhcp!;
|
||||
data.dhcpStatus.staticLeases = data.dhcpStatus.staticLeases.where((l) => l.mac != lease.mac).toList();
|
||||
data.dhcpStatus!.staticLeases = data.dhcpStatus!.staticLeases.where((l) => l.mac != lease.mac).toList();
|
||||
setDhcpData(data);
|
||||
return true;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class DhcpProvider with ChangeNotifier {
|
|||
|
||||
if (result.successful == true) {
|
||||
DhcpModel data = dhcp!;
|
||||
data.dhcpStatus.staticLeases.add(lease);
|
||||
data.dhcpStatus!.staticLeases.add(lease);
|
||||
setDhcpData(data);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@ import 'package:flutter_split_view/flutter_split_view.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||
import 'package:adguard_home_manager/screens/settings/dhcp/dhcp_not_available.dart';
|
||||
import 'package:adguard_home_manager/widgets/confirm_action_modal.dart';
|
||||
import 'package:adguard_home_manager/screens/settings/dhcp/dhcp_main_button.dart';
|
||||
import 'package:adguard_home_manager/widgets/section_label.dart';
|
||||
import 'package:adguard_home_manager/screens/settings/dhcp/dhcp_leases.dart';
|
||||
import 'package:adguard_home_manager/screens/settings/dhcp/select_interface_modal.dart';
|
||||
|
||||
|
@ -22,7 +24,7 @@ import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
|||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class DhcpScreen extends StatefulWidget {
|
||||
const DhcpScreen({Key? key}) : super(key: key);
|
||||
const DhcpScreen({super.key});
|
||||
|
||||
@override
|
||||
State<DhcpScreen> createState() => _DhcpScreenState();
|
||||
|
@ -55,24 +57,25 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
|
||||
void loadDhcpStatus() async {
|
||||
final result = await Provider.of<DhcpProvider>(context, listen: false).loadDhcpStatus();
|
||||
if (mounted && result == true) {
|
||||
final dhcpProvider = Provider.of<DhcpProvider>(context, listen: false);
|
||||
if (dhcpProvider.dhcp != null) {
|
||||
setState(() {
|
||||
if (dhcpProvider.dhcp!.dhcpStatus.interfaceName != null && dhcpProvider.dhcp!.dhcpStatus.interfaceName != '') {
|
||||
try {selectedInterface = dhcpProvider.dhcp!.networkInterfaces.firstWhere((iface) => iface.name == dhcpProvider.dhcp!.dhcpStatus.interfaceName);} catch (_) {}
|
||||
enabled = dhcpProvider.dhcp!.dhcpStatus.enabled;
|
||||
if (dhcpProvider.dhcp!.dhcpStatus.v4 != null) {
|
||||
ipv4StartRangeController.text = dhcpProvider.dhcp!.dhcpStatus.v4!.rangeStart;
|
||||
ipv4EndRangeController.text = dhcpProvider.dhcp!.dhcpStatus.v4!.rangeEnd ?? '';
|
||||
ipv4SubnetMaskController.text = dhcpProvider.dhcp!.dhcpStatus.v4!.subnetMask ?? '';
|
||||
ipv4GatewayController.text = dhcpProvider.dhcp!.dhcpStatus.v4!.gatewayIp ?? '';
|
||||
ipv4LeaseTimeController.text = dhcpProvider.dhcp!.dhcpStatus.v4!.leaseDuration.toString();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!mounted || result == false) return;
|
||||
|
||||
final dhcpProvider = Provider.of<DhcpProvider>(context, listen: false);
|
||||
if (dhcpProvider.dhcp == null) return;
|
||||
|
||||
setState(() {
|
||||
if (dhcpProvider.dhcp!.dhcpStatus!.interfaceName != null && dhcpProvider.dhcp!.dhcpStatus!.interfaceName != '') {
|
||||
try {selectedInterface = dhcpProvider.dhcp!.networkInterfaces.firstWhere((iface) => iface.name == dhcpProvider.dhcp!.dhcpStatus!.interfaceName);} catch (_) {}
|
||||
enabled = dhcpProvider.dhcp!.dhcpStatus!.enabled;
|
||||
if (dhcpProvider.dhcp!.dhcpStatus!.v4 != null) {
|
||||
ipv4StartRangeController.text = dhcpProvider.dhcp!.dhcpStatus!.v4!.rangeStart;
|
||||
ipv4EndRangeController.text = dhcpProvider.dhcp!.dhcpStatus!.v4!.rangeEnd ?? '';
|
||||
ipv4SubnetMaskController.text = dhcpProvider.dhcp!.dhcpStatus!.v4!.subnetMask ?? '';
|
||||
ipv4GatewayController.text = dhcpProvider.dhcp!.dhcpStatus!.v4!.gatewayIp ?? '';
|
||||
ipv4LeaseTimeController.text = dhcpProvider.dhcp!.dhcpStatus!.v4!.leaseDuration.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
checkDataValid();
|
||||
}
|
||||
|
||||
|
@ -266,8 +269,8 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
|
||||
if (result.successful == true) {
|
||||
DhcpModel data = dhcpProvider.dhcp!;
|
||||
data.dhcpStatus.staticLeases = [];
|
||||
data.dhcpStatus.leases = [];
|
||||
data.dhcpStatus!.staticLeases = [];
|
||||
data.dhcpStatus!.leases = [];
|
||||
dhcpProvider.setDhcpData(data);
|
||||
|
||||
showSnacbkar(
|
||||
|
@ -350,6 +353,14 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
});
|
||||
}
|
||||
|
||||
if (
|
||||
dhcpProvider.loadStatus == LoadStatus.loaded &&
|
||||
dhcpProvider.dhcp != null &&
|
||||
dhcpProvider.dhcp!.dhcpAvailable == false
|
||||
) {
|
||||
return const DhcpNotAvailable();
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.dhcpSettings),
|
||||
|
@ -429,60 +440,10 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
return SingleChildScrollView(
|
||||
child: Wrap(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 10,
|
||||
left: 16,
|
||||
right: 16
|
||||
),
|
||||
child: Material(
|
||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: InkWell(
|
||||
onTap: selectedInterface != null
|
||||
? () => setState(() => enabled = !enabled)
|
||||
: null,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context)!.enableDhcpServer,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
if (selectedInterface != null) ...[
|
||||
Text(
|
||||
selectedInterface!.name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).listTileTheme.textColor
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
Switch(
|
||||
value: enabled,
|
||||
onChanged: selectedInterface != null
|
||||
? (value) => setState(() => enabled = value)
|
||||
: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
DhcpMainButton(
|
||||
selectedInterface: selectedInterface,
|
||||
enabled: enabled,
|
||||
setEnabled: (v) => setState(() => enabled = v)
|
||||
),
|
||||
if (selectedInterface!.ipv4Addresses.isNotEmpty) ...[
|
||||
SectionLabel(
|
||||
|
@ -491,125 +452,47 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
top: 24, left: 16, right: 16, bottom: 8
|
||||
)
|
||||
),
|
||||
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),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.skip_previous_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv4StartRangeError,
|
||||
labelText: AppLocalizations.of(context)!.startOfRange,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.skip_previous_rounded,
|
||||
label: AppLocalizations.of(context)!.startOfRange,
|
||||
controller: ipv4StartRangeController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4StartRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
error: ipv4StartRangeError
|
||||
),
|
||||
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),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.skip_next_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv4EndRangeError,
|
||||
labelText: AppLocalizations.of(context)!.endOfRange,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.skip_next_rounded,
|
||||
label: AppLocalizations.of(context)!.endOfRange,
|
||||
controller: ipv4EndRangeController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4EndRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
error: ipv4EndRangeError
|
||||
),
|
||||
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),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.hub_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv4SubnetMaskError,
|
||||
labelText: AppLocalizations.of(context)!.subnetMask,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.hub_rounded,
|
||||
label: AppLocalizations.of(context)!.subnetMask,
|
||||
controller: ipv4SubnetMaskController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4SubnetMaskError', AppLocalizations.of(context)!.subnetMaskNotValid),
|
||||
error: ipv4SubnetMaskError
|
||||
),
|
||||
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),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.router_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv4GatewayError,
|
||||
labelText: AppLocalizations.of(context)!.gateway,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.router_rounded,
|
||||
label: AppLocalizations.of(context)!.gateway,
|
||||
controller: ipv4GatewayController,
|
||||
onChanged: (value) => validateIpV4(value, 'ipv4GatewayError', AppLocalizations.of(context)!.gatewayNotValid),
|
||||
error: ipv4GatewayError
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv4LeaseTimeController,
|
||||
onChanged: (value) {
|
||||
if (int.tryParse(value).runtimeType == int) {
|
||||
setState(() => ipv4LeaseTimeError = null);
|
||||
}
|
||||
else {
|
||||
setState(() => ipv4LeaseTimeError = AppLocalizations.of(context)!.leaseTimeNotValid);
|
||||
}
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.timer),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv4LeaseTimeError,
|
||||
labelText: AppLocalizations.of(context)!.leaseTime,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.timer,
|
||||
label: AppLocalizations.of(context)!.leaseTime,
|
||||
controller: ipv4LeaseTimeController,
|
||||
onChanged: (value) {
|
||||
if (int.tryParse(value).runtimeType == int) {
|
||||
setState(() => ipv4LeaseTimeError = null);
|
||||
}
|
||||
else {
|
||||
setState(() => ipv4LeaseTimeError = AppLocalizations.of(context)!.leaseTimeNotValid);
|
||||
}
|
||||
},
|
||||
error: ipv4LeaseTimeError
|
||||
),
|
||||
],
|
||||
if (selectedInterface!.ipv6Addresses.isNotEmpty) ...[
|
||||
|
@ -617,80 +500,34 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
label: AppLocalizations.of(context)!.ipv6settings,
|
||||
padding: const EdgeInsets.all(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),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.skip_next_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv6StartRangeError,
|
||||
labelText: AppLocalizations.of(context)!.startOfRange,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.skip_next_rounded,
|
||||
label: AppLocalizations.of(context)!.startOfRange,
|
||||
controller: ipv6StartRangeController,
|
||||
onChanged: (value) => validateIpV6(value, 'ipv6StartRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
error: ipv6StartRangeError
|
||||
),
|
||||
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),
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.skip_previous_rounded),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv6EndRangeError,
|
||||
labelText: AppLocalizations.of(context)!.endOfRange,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: TextFormField(
|
||||
controller: ipv6LeaseTimeController,
|
||||
onChanged: (value) {
|
||||
if (int.tryParse(value).runtimeType == int) {
|
||||
setState(() => ipv6LeaseTimeError = null);
|
||||
}
|
||||
else {
|
||||
setState(() => ipv6LeaseTimeError = AppLocalizations.of(context)!.leaseTimeNotValid);
|
||||
}
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.timer),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: ipv6LeaseTimeError,
|
||||
labelText: AppLocalizations.of(context)!.leaseTime,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.skip_previous_rounded,
|
||||
label: AppLocalizations.of(context)!.endOfRange,
|
||||
controller: ipv6EndRangeController,
|
||||
onChanged: (value) => validateIpV6(value, 'ipv6EndRangeError', AppLocalizations.of(context)!.ipNotValid),
|
||||
error: ipv6EndRangeError
|
||||
),
|
||||
_DhcpField(
|
||||
icon: Icons.timer,
|
||||
label: AppLocalizations.of(context)!.leaseTime,
|
||||
controller: ipv6LeaseTimeController,
|
||||
onChanged: (value) {
|
||||
if (int.tryParse(value).runtimeType == int) {
|
||||
setState(() => ipv6LeaseTimeError = null);
|
||||
}
|
||||
else {
|
||||
setState(() => ipv6LeaseTimeError = AppLocalizations.of(context)!.leaseTimeNotValid);
|
||||
}
|
||||
},
|
||||
error: ipv6LeaseTimeError
|
||||
)
|
||||
],
|
||||
const SizedBox(height: 20),
|
||||
SectionLabel(
|
||||
|
@ -704,7 +541,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.leases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus!.leases,
|
||||
staticLeases: false,
|
||||
)
|
||||
)
|
||||
|
@ -739,7 +576,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.staticLeases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus!.staticLeases,
|
||||
staticLeases: true,
|
||||
)
|
||||
)
|
||||
|
@ -775,7 +612,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
if (!(Platform.isAndroid || Platform.isIOS)) {
|
||||
SplitView.of(context).push(
|
||||
DhcpLeases(
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.leases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus!.leases,
|
||||
staticLeases: false,
|
||||
)
|
||||
);
|
||||
|
@ -784,7 +621,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.leases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus!.leases,
|
||||
staticLeases: false,
|
||||
)
|
||||
)
|
||||
|
@ -804,7 +641,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
if (!(Platform.isAndroid || Platform.isIOS)) {
|
||||
SplitView.of(context).push(
|
||||
DhcpLeases(
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.staticLeases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus!.staticLeases,
|
||||
staticLeases: true,
|
||||
)
|
||||
);
|
||||
|
@ -813,7 +650,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DhcpLeases(
|
||||
items: dhcpProvider.dhcp!.dhcpStatus.staticLeases,
|
||||
items: dhcpProvider.dhcp!.dhcpStatus!.staticLeases,
|
||||
staticLeases: true,
|
||||
)
|
||||
)
|
||||
|
@ -899,4 +736,49 @@ class _DhcpScreenState extends State<DhcpScreen> {
|
|||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DhcpField extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final TextEditingController controller;
|
||||
final void Function(String) onChanged;
|
||||
final String? error;
|
||||
|
||||
const _DhcpField({
|
||||
required this.icon,
|
||||
required this.label,
|
||||
required this.controller,
|
||||
required this.onChanged,
|
||||
required this.error,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
return 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: controller,
|
||||
onChanged: onChanged,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(icon),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10)
|
||||
)
|
||||
),
|
||||
errorText: error,
|
||||
labelText: label,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
76
lib/screens/settings/dhcp/dhcp_main_button.dart
Normal file
76
lib/screens/settings/dhcp/dhcp_main_button.dart
Normal file
|
@ -0,0 +1,76 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/models/dhcp.dart';
|
||||
|
||||
class DhcpMainButton extends StatelessWidget {
|
||||
final NetworkInterface? selectedInterface;
|
||||
final bool enabled;
|
||||
final void Function(bool) setEnabled;
|
||||
|
||||
const DhcpMainButton({
|
||||
super.key,
|
||||
required this.selectedInterface,
|
||||
required this.enabled,
|
||||
required this.setEnabled,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 10,
|
||||
left: 16,
|
||||
right: 16
|
||||
),
|
||||
child: Material(
|
||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: InkWell(
|
||||
onTap: selectedInterface != null
|
||||
? () => setEnabled(!enabled)
|
||||
: null,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context)!.enableDhcpServer,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
if (selectedInterface != null) ...[
|
||||
Text(
|
||||
selectedInterface!.name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).listTileTheme.textColor
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
Switch(
|
||||
value: enabled,
|
||||
onChanged: selectedInterface != null
|
||||
? (value) => setEnabled(value)
|
||||
: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
47
lib/screens/settings/dhcp/dhcp_not_available.dart
Normal file
47
lib/screens/settings/dhcp/dhcp_not_available.dart
Normal file
|
@ -0,0 +1,47 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/functions/desktop_mode.dart';
|
||||
|
||||
class DhcpNotAvailable extends StatelessWidget {
|
||||
const DhcpNotAvailable({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.dhcpSettings),
|
||||
centerTitle: false,
|
||||
surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context)!.dhcpNotAvailable,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 24
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.osServerInstalledIncompatible,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -482,8 +482,13 @@ class ApiClientV2 {
|
|||
return ApiResponse(
|
||||
successful: true,
|
||||
content: DhcpModel(
|
||||
dhcpAvailable: jsonDecode(results[1].body!)['message'] != null
|
||||
? false
|
||||
: true,
|
||||
networkInterfaces: interfaces,
|
||||
dhcpStatus: DhcpStatus.fromJson(jsonDecode(results[1].body!))
|
||||
dhcpStatus: jsonDecode(results[1].body!)['message'] != null
|
||||
? null
|
||||
: DhcpStatus.fromJson(jsonDecode(results[1].body!))
|
||||
)
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
|
|
|
@ -1352,6 +1352,7 @@ class ApiClient {
|
|||
return {
|
||||
'result': 'success',
|
||||
'data': DhcpModel(
|
||||
dhcpAvailable: true,
|
||||
networkInterfaces: interfaces,
|
||||
dhcpStatus: DhcpStatus.fromJson(jsonDecode(result[1]['body']))
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue