import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; import '../providers/ble_provider.dart'; import '../providers/device_provider.dart'; import '../providers/wifi_provider.dart'; import '../theme/app_colors.dart'; import '../widgets/control_button.dart'; import '../widgets/status_card.dart'; import '../widgets/wifi_list_tile.dart'; class NetworkScreen extends StatefulWidget { const NetworkScreen({super.key}); @override State createState() => _NetworkScreenState(); } class _NetworkScreenState extends State { final TextEditingController _ssidController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); final TextEditingController _apSsidController = TextEditingController(text: 'showen'); final TextEditingController _apPasswordController = TextEditingController(text: '12345678'); @override void dispose() { _ssidController.dispose(); _passwordController.dispose(); _apSsidController.dispose(); _apPasswordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final bleProvider = context.watch(); final wifiProvider = context.watch(); final deviceProvider = context.watch(); final wifiStatus = wifiProvider.status; final bleStatus = deviceProvider.status.bleStatus; return Scaffold( appBar: AppBar(title: const Text('网络设置')), body: RefreshIndicator( onRefresh: _handleRefresh, child: ListView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.all(AppSpacing.md), children: [ StatusCard( title: 'WiFi 状态', value: wifiStatus.connected ? (wifiStatus.ssid ?? '已连接') : '未连接', subtitle: wifiStatus.ip ?? '尚未获取 IP 地址', icon: Icons.router_rounded, accentColor: wifiStatus.connected ? AppColors.success : AppColors.warning, ), const SizedBox(height: AppSpacing.md), Card( child: Padding( padding: const EdgeInsets.all(AppSpacing.md), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('连接 WiFi', style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: AppSpacing.md), TextField( controller: _ssidController, decoration: const InputDecoration(labelText: 'WiFi 名称'), ), const SizedBox(height: AppSpacing.md), TextField( controller: _passwordController, obscureText: true, decoration: const InputDecoration(labelText: 'WiFi 密码'), ), const SizedBox(height: AppSpacing.md), SizedBox( width: double.infinity, child: FilledButton.icon( onPressed: wifiProvider.isLoading ? null : _handleConnectWifi, icon: const Icon(Icons.wifi_password_rounded), label: const Text('连接当前 WiFi'), ), ), ], ), ), ), const SizedBox(height: AppSpacing.lg), Row( children: [ Expanded( child: ControlButton( label: '扫描 WiFi', icon: Icons.wifi_find_rounded, onPressed: wifiProvider.isLoading ? null : () => context.read().scanNetworks(), ), ), const SizedBox(width: AppSpacing.md), Expanded( child: ControlButton( label: bleStatus?.running == true ? 'BLE 已就绪' : '启动 BLE', icon: Icons.bluetooth_rounded, isFilled: false, onPressed: deviceProvider.isLoading ? null : () => context.read().startBle(deviceName: 'showen'), ), ), ], ), if (bleProvider.isConnected) ...[ const SizedBox(height: AppSpacing.lg), Card( child: Padding( padding: const EdgeInsets.all(AppSpacing.md), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('BLE 控制', style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: AppSpacing.sm), Text( bleProvider.selectedDevice?.name ?? '已连接 BLE 设备', style: Theme.of(context).textTheme.bodyMedium, ), const SizedBox(height: AppSpacing.md), Row( children: [ Expanded( child: ControlButton( label: '播放', icon: Icons.play_arrow_rounded, onPressed: bleProvider.isSendingCommand ? null : () => _sendBleCommand('play'), ), ), const SizedBox(width: AppSpacing.md), Expanded( child: ControlButton( label: '暂停', icon: Icons.pause_rounded, onPressed: bleProvider.isSendingCommand ? null : () => _sendBleCommand('pause'), ), ), ], ), const SizedBox(height: AppSpacing.md), Row( children: [ Expanded( child: ControlButton( label: '上一个', icon: Icons.skip_previous_rounded, isFilled: false, onPressed: bleProvider.isSendingCommand ? null : () => _sendBleCommand('prev'), ), ), const SizedBox(width: AppSpacing.md), Expanded( child: ControlButton( label: '下一个', icon: Icons.skip_next_rounded, isFilled: false, onPressed: bleProvider.isSendingCommand ? null : () => _sendBleCommand('next'), ), ), ], ), ], ), ), ), ], const SizedBox(height: AppSpacing.lg), Text('扫描结果', style: Theme.of(context).textTheme.headlineSmall), const SizedBox(height: AppSpacing.md), if (wifiProvider.networks.isEmpty) const Card( child: Padding( padding: EdgeInsets.all(AppSpacing.md), child: Text('暂无扫描结果'), ), ), ...wifiProvider.networks.map( (network) => Padding( padding: const EdgeInsets.only(bottom: AppSpacing.sm), child: WifiListTile( network: network, onTap: () { _ssidController.text = network.ssid; setState(() {}); }, ), ), ), const SizedBox(height: AppSpacing.lg), Card( child: Padding( padding: const EdgeInsets.all(AppSpacing.md), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text('热点开关', style: Theme.of(context).textTheme.titleMedium), ), Switch( value: wifiProvider.hotspotEnabled, onChanged: (enabled) { if (enabled) { context.read().startHotspot( ssid: _apSsidController.text.trim(), password: _apPasswordController.text, ); return; } context.read().stopHotspot(); }, ), ], ), const SizedBox(height: AppSpacing.sm), TextField( controller: _apSsidController, decoration: const InputDecoration(labelText: '热点 SSID'), ), const SizedBox(height: AppSpacing.md), TextField( controller: _apPasswordController, obscureText: true, decoration: const InputDecoration(labelText: '热点密码'), ), ], ), ), ), const SizedBox(height: AppSpacing.md), SizedBox( width: double.infinity, child: FilledButton.tonal( onPressed: () => context.push('/network/ble-provision'), child: const Text('进入 BLE 配网页面'), ), ), ], ), ), ); } Future _handleRefresh() async { await Future.wait([ context.read().bootstrap(), context.read().refresh(), ]); } void _handleConnectWifi() { final ssid = _ssidController.text.trim(); if (ssid.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请输入 WiFi 名称')), ); return; } context.read().connect( ssid: ssid, password: _passwordController.text, ); } Future _sendBleCommand(String command) async { try { await context.read().sendCommand(command); if (!mounted) { return; } ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('已发送 BLE 指令: $command')), ); } catch (error) { if (!mounted) { return; } ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('BLE 指令发送失败: $error')), ); } } }