import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:liteauthconfig/models/appconfig.dart'; import 'package:liteauthconfig/l10n/app_localizations.dart'; import 'package:liteauthconfig/models/device_status.dart'; import 'package:liteauthconfig/pages/reconfigure_network.dart'; import 'package:liteauthconfig/utils/network.dart'; class DeviceInfoPage extends StatefulWidget { final int deviceIndex; const DeviceInfoPage({super.key, required this.deviceIndex}); @override State createState() => _DeviceInfoPageState(); } class _DeviceInfoPageState extends State { late Device device; DeviceStatus? deviceStatus; String statusMessage = ""; bool online = false; bool loading = false; Timer? refreshTimer; @override void initState() { super.initState(); refreshDevice(); checkStatus(); } void refreshDevice() { device = AppConfig().devices[widget.deviceIndex]; } Future checkStatus() async { statusMessage = ""; setState(() { loading = true; }); var client = await createEspHttpClient(); try { var resp = await client.get( Uri.parse("https://liteauth.local/api/status"), ); deviceStatus = DeviceStatus.fromJson(jsonDecode(resp.body)); online = resp.statusCode >= 200 && resp.statusCode < 300; } catch (e) { statusMessage = e.toString(); online = false; refreshTimer ??= Timer.periodic(const Duration(seconds: 5), ( timer, ) async { await checkStatus(); if (online) { timer.cancel(); refreshTimer = null; } }); } if (mounted) { setState(() { loading = false; }); } } void factoryReset() async { var appLocal = AppLocalizations.of(context)!; var reset = await showDialog(context: context, builder: (ctx) => AlertDialog.adaptive( title: Text(appLocal.factoryReset), content: Text(appLocal.resetConfirm), actions: [ TextButton(onPressed: () { Navigator.of(ctx).pop(false); }, child: Text(appLocal.cancel)), TextButton(onPressed: () { Navigator.of(ctx).pop(true); }, child: Text(appLocal.reset)), ], )) ?? false; if (!reset) return; var client = await createEspHttpClient(); client.get(Uri.parse("https://liteauth.local/api/factoryReset")); } @override void dispose() { refreshTimer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final appTheme = Theme.of(context); final appLocal = AppLocalizations.of(context)!; return Scaffold( appBar: AppBar( title: Text(device.name), bottom: loading ? PreferredSize( preferredSize: const Size.fromHeight(4), child: LinearProgressIndicator(), ) : null, actions: [ MenuAnchor( builder: (context, controller, child) { return IconButton( onPressed: () { if (controller.isOpen) { controller.close(); } else { controller.open(); } }, icon: Icon(Icons.adaptive.more), ); }, menuChildren: [ MenuItemButton( leadingIcon: const Icon(Icons.refresh), onPressed: checkStatus, child: Text(appLocal.refresh), ), MenuItemButton( leadingIcon: const Icon(Icons.network_wifi), child: Text(appLocal.reconfigureNetwork), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => ReconfigureNetworkPage(widget.deviceIndex), ), ).then((result) { if (result) { refreshDevice(); checkStatus(); } }); }, ), MenuItemButton( leadingIcon: const Icon(Icons.history), child: Text(appLocal.factoryReset), onPressed: factoryReset, ), MenuItemButton( leadingIcon: const Icon(Icons.delete), child: Text(appLocal.delete), onPressed: () { showDialog( context: context, builder: (context) => AlertDialog.adaptive( title: Text(appLocal.deletion), content: Text(appLocal.deviceDeleteConfirm), actions: [ TextButton( onPressed: () { Navigator.pop(context); }, child: Text(appLocal.cancel), ), TextButton( onPressed: () { AppConfig() ..devices.removeAt(widget.deviceIndex) ..save(); Navigator.pop(context); Navigator.pop(context); }, child: Text(appLocal.delete), ), ], ), ); }, ), ], ), ], ), body: SingleChildScrollView( child: Padding( padding: EdgeInsetsGeometry.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, spacing: 16, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(device.name, style: appTheme.textTheme.headlineLarge), Row( children: [ Text( appLocal.status, style: appTheme.textTheme.bodyLarge, ), Text( online ? appLocal.online : appLocal.offline, style: appTheme.textTheme.bodyLarge?.copyWith( color: online ? Colors.green : Colors.red, ), ), ], ), ], ), if (statusMessage.isNotEmpty) Text(statusMessage), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( spacing: 8, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.info), Text( appLocal.deviceInfo, style: appTheme.textTheme.headlineMedium, ), ], ), Text(appLocal.lastKnownIP(device.ip ?? "Unknown")), Text("BSSID: ${device.bssid ?? "Unknown"}"), Text(appLocal.routerSsid(device.routerSsid)), ], ), Column( children: [ Row( spacing: 8, children: [ Icon(Icons.list), Text( appLocal.activityLogs, style: appTheme.textTheme.headlineMedium, ), ], ), ], ), ], ), ), ), ); } }