import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/providers.dart'; import '../services/services.dart'; import '../widgets/widgets.dart'; /// 主页面 class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { final TrayService _trayService = TrayService(); final WindowService _windowService = WindowService(); @override void initState() { super.initState(); // 初始化数据 WidgetsBinding.instance.addPostFrameCallback((_) { final provider = context.read(); provider.initDefaultDevices(); provider.refreshAll(); provider.startAutoRefresh(intervalSeconds: 30); // 初始化系统托盘 _initSystemTray(provider); }); } /// 初始化系统托盘 Future _initSystemTray(MonitorProvider provider) async { if (!_trayService.isSupported) return; await _trayService.init( onShow: () => _windowService.showWindow(), onHide: () => _windowService.hideWindow(), onExit: () => _exitApp(), onRefresh: () => provider.refreshAll(), ); // 设置窗口关闭事件(最小化到托盘) _windowService.onCloseRequested = () => _handleCloseRequest(); } /// 处理窗口关闭请求 void _handleCloseRequest() { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('关闭窗口'), content: const Text('请选择操作:'), actions: [ TextButton( onPressed: () { Navigator.pop(context); _windowService.hideWindow(); }, child: const Text('最小化到托盘'), ), TextButton( onPressed: () { Navigator.pop(context); _exitApp(); }, child: const Text('退出程序'), ), TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), ], ), ); } /// 退出应用 Future _exitApp() async { await _trayService.destroy(); await _windowService.closeWindow(); } @override void dispose() { _trayService.destroy(); _windowService.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), body: _buildBody(), floatingActionButton: _buildFAB(), ); } PreferredSizeWidget _buildAppBar() { return AppBar( title: const Text('家庭网络监控'), centerTitle: true, actions: [ Consumer( builder: (context, provider, _) { return IconButton( icon: provider.isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.refresh), onPressed: provider.isLoading ? null : () => provider.refreshAll(), tooltip: '刷新', ); }, ), IconButton( icon: const Icon(Icons.settings), onPressed: () { _showSettingsDialog(); }, tooltip: '设置', ), // 最小化到托盘按钮(仅桌面端) if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) IconButton( icon: const Icon(Icons.minimize), onPressed: () => _windowService.hideWindow(), tooltip: '最小化到托盘', ), ], ); } Widget _buildBody() { return Consumer( builder: (context, provider, _) { return RefreshIndicator( onRefresh: () => provider.refreshAll(), child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 网速仪表盘 SpeedGauge( networkStatus: provider.networkStatus, isLoading: provider.isTestingSpeed, ), // 概览卡片 _buildOverviewCards(provider), // 设备列表标题 Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '监控设备', style: Theme.of(context).textTheme.titleMedium, ), TextButton.icon( onPressed: () => _showAddDeviceDialog(), icon: const Icon(Icons.add, size: 18), label: const Text('添加'), ), ], ), ), // 设备列表 _buildDeviceList(provider), const SizedBox(height: 80), ], ), ), ); }, ); } Widget _buildOverviewCards(MonitorProvider provider) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ Expanded( child: StatusCard( title: '在线设备', value: '${provider.onlineDevicesCount}', icon: Icons.check_circle, iconColor: Colors.green, subtitle: '共 ${provider.devices.length} 台设备', ), ), const SizedBox(width: 12), Expanded( child: StatusCard( title: '离线设备', value: '${provider.offlineDevicesCount}', icon: Icons.error, iconColor: provider.offlineDevicesCount > 0 ? Colors.red : Colors.grey, subtitle: provider.offlineDevicesCount > 0 ? '需要检查' : '全部正常', ), ), ], ), ); } Widget _buildDeviceList(MonitorProvider provider) { if (provider.devices.isEmpty) { return const Center( child: Padding( padding: EdgeInsets.all(32), child: Column( children: [ Icon(Icons.devices, size: 64, color: Colors.grey), SizedBox(height: 16), Text('暂无监控设备'), SizedBox(height: 8), Text('点击右上角添加设备', style: TextStyle(color: Colors.grey)), ], ), ), ); } return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: provider.devices.length, itemBuilder: (context, index) { final device = provider.devices[index]; return DeviceTile( device: device, onRefresh: () => provider.checkSingleDevice(device.id), onTap: () => _showDeviceDetail(device), ); }, ); } Widget _buildFAB() { return Consumer( builder: (context, provider, _) { return FloatingActionButton.extended( onPressed: provider.isTestingSpeed ? null : () => provider.runSpeedTest(), icon: provider.isTestingSpeed ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : const Icon(Icons.speed), label: Text(provider.isTestingSpeed ? '测速中...' : '测速'), ); }, ); } void _showSettingsDialog() { final provider = context.read(); int interval = provider.refreshInterval; showDialog( context: context, builder: (context) => AlertDialog( title: const Text('设置'), content: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( title: const Text('自动刷新间隔'), subtitle: Text('$interval 秒'), trailing: DropdownButton( value: interval, items: const [ DropdownMenuItem(value: 10, child: Text('10秒')), DropdownMenuItem(value: 30, child: Text('30秒')), DropdownMenuItem(value: 60, child: Text('1分钟')), DropdownMenuItem(value: 300, child: Text('5分钟')), ], onChanged: (value) { if (value != null) { provider.setRefreshInterval(value); Navigator.pop(context); } }, ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ); } void _showAddDeviceDialog() { // TODO: 实现添加设备对话框 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('添加设备功能开发中...')), ); } void _showDeviceDetail(device) { // TODO: 实现设备详情页 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('设备: ${device.name}')), ); } }