mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Refactor frontend: extract widgets and eliminate duplicated scanner state
- Convert ArpScannerCard to a self-managing StatefulWidget (owns its own 5s refresh + 1s tick timers), removing the duplicated state management that existed in both HomeScreen and StatusScreen - Extract NotificationCard to home/notification_card.dart - Extract DeviceSummaryCard (with its 1-min refresh timer) to widgets/device_summary_card.dart - HomeScreen drops from 515 to 253 lines; StatusScreen from 82 to 19 lines Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
251d8a479e
commit
f113da9cd0
@@ -1,23 +1,70 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend/model/arp_scanner_status.dart';
|
||||
|
||||
class ArpScannerCard extends StatelessWidget {
|
||||
final ArpScannerStatus? status;
|
||||
final DateTime? statusReceivedAt;
|
||||
final String? error;
|
||||
final bool isLoading;
|
||||
import '../model/arp_scanner_status.dart';
|
||||
import '../utils/oott_api.dart';
|
||||
|
||||
const ArpScannerCard({
|
||||
super.key,
|
||||
this.status,
|
||||
this.statusReceivedAt,
|
||||
this.error,
|
||||
this.isLoading = false,
|
||||
});
|
||||
class ArpScannerCard extends StatefulWidget {
|
||||
const ArpScannerCard({super.key});
|
||||
|
||||
@override
|
||||
State<ArpScannerCard> createState() => _ArpScannerCardState();
|
||||
}
|
||||
|
||||
class _ArpScannerCardState extends State<ArpScannerCard> {
|
||||
ArpScannerStatus? _status;
|
||||
DateTime? _statusReceivedAt;
|
||||
bool _isLoading = true;
|
||||
String? _error;
|
||||
Timer? _refreshTimer;
|
||||
Timer? _tickTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_load();
|
||||
_refreshTimer = Timer.periodic(
|
||||
const Duration(seconds: 5),
|
||||
(_) => _load(),
|
||||
);
|
||||
_tickTimer = Timer.periodic(
|
||||
const Duration(seconds: 1),
|
||||
(_) {
|
||||
if (mounted) setState(() {});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_refreshTimer?.cancel();
|
||||
_tickTimer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
final status = await BackendAPI.instance.getArpScannerStatus();
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_status = status;
|
||||
_statusReceivedAt = DateTime.now();
|
||||
_error = null;
|
||||
_isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_error = e.toString();
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (isLoading) {
|
||||
if (_isLoading) {
|
||||
return const Card(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
@@ -64,7 +111,7 @@ class ArpScannerCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
(Color, String, String?) _resolveState(BuildContext context) {
|
||||
if (error != null || status == null) {
|
||||
if (_error != null || _status == null) {
|
||||
return (
|
||||
Colors.red,
|
||||
'Error',
|
||||
@@ -72,18 +119,18 @@ class ArpScannerCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
final elapsed = statusReceivedAt != null
|
||||
? DateTime.now().difference(statusReceivedAt!).inSeconds.toDouble()
|
||||
final elapsed = _statusReceivedAt != null
|
||||
? DateTime.now().difference(_statusReceivedAt!).inSeconds.toDouble()
|
||||
: 0.0;
|
||||
|
||||
if (status!.isRunning) {
|
||||
final sub = status!.runningForSeconds != null
|
||||
? 'Running for ${_formatSeconds(status!.runningForSeconds! + elapsed)}'
|
||||
if (_status!.isRunning) {
|
||||
final sub = _status!.runningForSeconds != null
|
||||
? 'Running for ${_formatSeconds(_status!.runningForSeconds! + elapsed)}'
|
||||
: null;
|
||||
return (Colors.green, 'Running', sub);
|
||||
}
|
||||
if (status!.nextRunInSeconds != null) {
|
||||
final remaining = (status!.nextRunInSeconds! - elapsed).clamp(
|
||||
if (_status!.nextRunInSeconds != null) {
|
||||
final remaining = (_status!.nextRunInSeconds! - elapsed).clamp(
|
||||
0.0,
|
||||
double.infinity,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user