import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../providers/network_provider.dart'; /// 网络状态指示器 class NetworkIndicator extends ConsumerWidget { final Widget child; final bool showBanner; const NetworkIndicator({ super.key, required this.child, this.showBanner = true, }); @override Widget build(BuildContext context, WidgetRef ref) { final networkState = ref.watch(networkProvider); return Column( children: [ if (showBanner && networkState.status == NetworkStatus.disconnected) _buildOfflineBanner(context), Expanded(child: child), ], ); } Widget _buildOfflineBanner(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), color: Colors.red[600], child: Row( children: [ const Icon( Icons.wifi_off, color: Colors.white, size: 20, ), const SizedBox(width: 8), const Expanded( child: Text( '网络连接已断开', style: TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500, ), ), ), TextButton( onPressed: () { // 可以添加重试逻辑 }, child: const Text( '重试', style: TextStyle( color: Colors.white, fontSize: 14, ), ), ), ], ), ); } } /// 网络状态图标 class NetworkStatusIcon extends ConsumerWidget { final double size; final Color? color; const NetworkStatusIcon({ super.key, this.size = 24, this.color, }); @override Widget build(BuildContext context, WidgetRef ref) { final networkState = ref.watch(networkProvider); return Icon( _getNetworkIcon(networkState.status, networkState.type), size: size, color: color ?? _getNetworkColor(networkState.status), ); } IconData _getNetworkIcon(NetworkStatus status, NetworkType type) { if (status == NetworkStatus.disconnected) { return Icons.wifi_off; } switch (type) { case NetworkType.wifi: return Icons.wifi; case NetworkType.mobile: return Icons.signal_cellular_4_bar; case NetworkType.ethernet: return Icons.cable; case NetworkType.unknown: default: return Icons.device_unknown; } } Color _getNetworkColor(NetworkStatus status) { switch (status) { case NetworkStatus.connected: return Colors.green; case NetworkStatus.disconnected: return Colors.red; case NetworkStatus.unknown: return Colors.grey; } } } /// 网络状态卡片 class NetworkStatusCard extends ConsumerWidget { const NetworkStatusCard({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final networkState = ref.watch(networkProvider); return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ NetworkStatusIcon( size: 32, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _getStatusText(networkState.status), style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), Text( _getTypeText(networkState.type), style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Colors.grey[600], ), ), ], ), ), ], ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '最后更新: ${_formatTime(networkState.lastChecked)}', style: Theme.of(context).textTheme.bodySmall, ), TextButton( onPressed: () { ref.read(networkProvider.notifier).refreshNetworkStatus(); }, child: const Text('刷新'), ), ], ), ], ), ), ); } String _getStatusText(NetworkStatus status) { switch (status) { case NetworkStatus.connected: return '已连接'; case NetworkStatus.disconnected: return '未连接'; case NetworkStatus.unknown: return '未知状态'; } } String _getTypeText(NetworkType type) { switch (type) { case NetworkType.wifi: return 'Wi-Fi'; case NetworkType.mobile: return '移动网络'; case NetworkType.ethernet: return '以太网'; case NetworkType.unknown: default: return '未知'; } } String _formatTime(DateTime time) { final now = DateTime.now(); final difference = now.difference(time); if (difference.inMinutes < 1) { return '刚刚'; } else if (difference.inHours < 1) { return '${difference.inMinutes}分钟前'; } else if (difference.inDays < 1) { return '${difference.inHours}小时前'; } else { return '${difference.inDays}天前'; } } }