snap_wish/lib/presentation/widgets/share_test_widget.dart
2025-09-17 13:32:25 +08:00

422 lines
13 KiB
Dart

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('刷新'),
),
],
);
}
/// 构建错误信息显示
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<Color>(
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();
}
}