import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import '../../core/utils/logger.dart'; import '../providers/share_provider.dart'; /// 分享测试组件 - 用于验证分享接收功能 /// 显示当前分享状态和待处理文件信息 class ShareTestWidget extends ConsumerWidget { const ShareTestWidget({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final shareState = ref.watch(shareProvider); return Card( margin: const EdgeInsets.all(16), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ // 标题 Text( '分享接收测试', style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), // 分享状态显示 _buildShareStatus(context, shareState), const SizedBox(height: 16), // 批量处理进度显示 if (shareState.isBatchProcessing) ...[ _buildBatchProgress(context, shareState), const SizedBox(height: 8), _buildBatchInfo(context, shareState), const SizedBox(height: 16), ], // 待处理文件列表 _buildPendingFilesList(context, shareState), const SizedBox(height: 16), // 操作按钮 _buildActionButtons(context, ref, shareState), // 错误信息显示 if (shareState.error != null) ...[ const SizedBox(height: 16), _buildErrorDisplay(context, shareState.error!, ref), ], ], ), ), ); } /// 构建分享状态显示 Widget _buildShareStatus(BuildContext context, ShareState shareState) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '当前状态:', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), Row( children: [ Icon( shareState.isProcessing ? Icons.sync : shareState.hasPendingShare ? Icons.notifications_active : Icons.check_circle, color: shareState.isProcessing ? Colors.orange : shareState.hasPendingShare ? Colors.blue : Colors.green, ), const SizedBox(width: 8), Text( shareState.isProcessing ? '处理中...' : shareState.hasPendingShare ? '有待处理分享' : '无待处理分享', style: Theme.of(context).textTheme.bodyMedium, ), ], ), const SizedBox(height: 4), Text( '文件数量: ${shareState.pendingFiles.length}', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), ), ), ], ); } /// 构建待处理文件列表 Widget _buildPendingFilesList(BuildContext context, ShareState shareState) { if (shareState.pendingFiles.isEmpty) { return Text( '暂无待处理文件', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), ), ); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '待处理文件:', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), ...shareState.pendingFiles.map((file) => _buildFileItem(context, file)), ], ); } /// 构建文件项 Widget _buildFileItem(BuildContext context, SharedMediaFile file) { return Container( margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5), borderRadius: BorderRadius.circular(8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( _getFileIcon(file.type), size: 24, color: Theme.of(context).colorScheme.primary, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _getFileName(file.path), style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 2), Text( file.path, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), ), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ), ], ), const SizedBox(height: 4), Text( '类型: ${_getFileType(file.type)}', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), ), ), ], ), ); } /// 构建操作按钮 Widget _buildActionButtons(BuildContext context, WidgetRef ref, ShareState shareState) { return Row( children: [ ElevatedButton.icon( onPressed: shareState.hasPendingShare && !shareState.isProcessing ? () => _handleSaveShare(ref) : null, icon: const Icon(Icons.save), label: const Text('保存分享'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), ), const SizedBox(width: 12), OutlinedButton.icon( onPressed: shareState.hasPendingShare && !shareState.isProcessing ? () => _handleClearShare(ref) : null, icon: const Icon(Icons.clear), label: const Text('清除'), ), const SizedBox(width: 12), OutlinedButton.icon( onPressed: !shareState.isProcessing ? () => _handleRefreshShare(ref) : null, icon: const Icon(Icons.refresh), label: const Text('刷新'), ), const SizedBox(width: 12), OutlinedButton.icon( onPressed: !shareState.isProcessing ? () => _simulateShareTest(ref) : null, icon: const Icon(Icons.photo), label: const Text('模拟分享'), ), ], ); } /// 构建错误信息显示 Widget _buildErrorDisplay(BuildContext context, String error, WidgetRef ref) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context).colorScheme.errorContainer, borderRadius: BorderRadius.circular(8), ), child: Row( children: [ Icon( Icons.error_outline, color: Theme.of(context).colorScheme.error, ), const SizedBox(width: 8), Expanded( child: Text( error, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Theme.of(context).colorScheme.error, ), ), ), IconButton( onPressed: () => _handleClearError(ref), icon: Icon( Icons.close, color: Theme.of(context).colorScheme.error, ), ), ], ), ); } /// 构建批量处理进度显示 Widget _buildBatchProgress(BuildContext context, ShareState shareState) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '批量处理进度:', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), Row( children: [ Expanded( child: LinearProgressIndicator( value: shareState.totalBatches > 0 ? shareState.currentBatchIndex / shareState.totalBatches : 0, backgroundColor: Theme.of(context).colorScheme.surfaceVariant, valueColor: AlwaysStoppedAnimation( Theme.of(context).colorScheme.primary, ), ), ), const SizedBox(width: 12), Text( '${shareState.currentBatchIndex}/${shareState.totalBatches}', style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, ), ), ], ), const SizedBox(height: 4), Text( '第 ${shareState.currentBatchIndex} 批,共 ${shareState.totalBatches} 批', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), ), ), ], ); } /// 构建批量处理信息 Widget _buildBatchInfo(BuildContext context, ShareState shareState) { final remainingBatches = shareState.totalBatches - shareState.currentBatchIndex; final progressPercent = shareState.totalBatches > 0 ? (shareState.currentBatchIndex / shareState.totalBatches * 100).toStringAsFixed(1) : '0.0'; return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primaryContainer.withOpacity(0.3), borderRadius: BorderRadius.circular(8), border: Border.all( color: Theme.of(context).colorScheme.primary.withOpacity(0.3), width: 1, ), ), child: Row( children: [ Icon( Icons.batch_prediction, color: Theme.of(context).colorScheme.primary, size: 20, ), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '批量保存模式', style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, color: Theme.of(context).colorScheme.primary, ), ), const SizedBox(height: 2), Text( '进度: $progressPercent% (${shareState.currentBatchIndex}/${shareState.totalBatches} 批次)', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), ), ), if (remainingBatches > 0) ...[ const SizedBox(height: 2), Text( '剩余 $remainingBatches 批次待处理', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), ), ), ], ], ), ), ], ), ); } /// 获取文件图标 IconData _getFileIcon(SharedMediaType type) { switch (type) { case SharedMediaType.image: return Icons.image; case SharedMediaType.video: return Icons.videocam; case SharedMediaType.file: return Icons.insert_drive_file; default: return Icons.description; } } /// 获取文件类型描述 String _getFileType(SharedMediaType type) { switch (type) { case SharedMediaType.image: return '图片'; case SharedMediaType.video: return '视频'; case SharedMediaType.file: return '文件'; default: return '未知'; } } /// 获取文件名 String _getFileName(String filePath) { return filePath.split('/').last; } /// 处理保存分享 void _handleSaveShare(WidgetRef ref) { Logger.info('用户点击保存分享'); final shareNotifier = ref.read(shareProvider.notifier); shareNotifier.startSavingSharedImages(); } /// 处理清除分享 void _handleClearShare(WidgetRef ref) { Logger.info('用户点击清除分享'); final shareNotifier = ref.read(shareProvider.notifier); shareNotifier.cancelShareSaving(); } /// 处理刷新分享 void _handleRefreshShare(WidgetRef ref) { Logger.info('用户点击刷新分享'); final shareNotifier = ref.read(shareProvider.notifier); shareNotifier.refreshShareStatus(); } /// 处理清除错误 void _handleClearError(WidgetRef ref) { final shareNotifier = ref.read(shareProvider.notifier); shareNotifier.clearError(); } /// 模拟分享测试 - 创建模拟的分享数据来测试保存对话框 void _simulateShareTest(WidgetRef ref) { Logger.info('用户点击模拟分享测试'); // 创建模拟的分享文件 final mockFiles = [ SharedMediaFile( path: 'test://image1.jpg', type: SharedMediaType.image, ), SharedMediaFile( path: 'test://image2.png', type: SharedMediaType.image, ), ]; // 模拟接收到分享文件 final shareNotifier = ref.read(shareProvider.notifier); shareNotifier.handleSharedFiles(mockFiles); Logger.info('模拟分享测试完成,创建了${mockFiles.length}个测试文件'); } }