diff --git a/lib/components/my_toast.dart b/lib/components/my_toast.dart index 806f604..40f394d 100644 --- a/lib/components/my_toast.dart +++ b/lib/components/my_toast.dart @@ -7,6 +7,7 @@ class MyToast { required String title, String? type, // 默认失败 String? position, // 默认底部显示 + Duration? duration }) { final baseStyle = position == 'top' ? MyDialog.theme.toastStyle?.top() @@ -16,7 +17,7 @@ class MyToast { MyDialog.toast( title, icon: type == 'success' ? const Icon(Icons.check_circle) : Icon(Icons.warning), - duration: Duration(milliseconds: 5000), + duration: duration ?? const Duration(milliseconds: 5000), style: baseStyle?.copyWith( backgroundColor: type == 'success' ? Colors.green.withAlpha(200) : Colors.red.withAlpha(200), ), diff --git a/lib/pages/video/module/recommend.dart b/lib/pages/video/module/recommend.dart index 096968a..59c85a9 100644 --- a/lib/pages/video/module/recommend.dart +++ b/lib/pages/video/module/recommend.dart @@ -1,9 +1,9 @@ /// 精选推荐模块 library; - import 'dart:async'; import 'dart:convert'; +import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; @@ -17,6 +17,8 @@ import 'package:loopin/components/network_or_asset_image.dart'; import 'package:loopin/models/summary_type.dart'; import 'package:loopin/service/http.dart'; import 'package:loopin/utils/wxsdk.dart'; +import 'package:loopin/utils/permissions.dart'; +import 'package:loopin/utils/download_video.dart'; import 'package:media_kit/media_kit.dart'; import 'package:media_kit_video/media_kit_video.dart'; import 'package:media_kit_video/media_kit_video_controls/src/controls/extensions/duration.dart'; @@ -903,14 +905,81 @@ void handleComment(index) { void handleShareClick(int index) { print("分享项 $index 被点击"); - final description = videoList[videoModuleController.videoPlayIndex.value]['title'] ?? '获取title失败'; - - if (index == 1) { - // 好友 - Wxsdk.shareToFriend(title: '快来看看这个视频', description: description, webpageUrl: 'https://baidu.com'); + final videoId = videoList[videoModuleController.videoPlayIndex.value]['id']; + final videoUrl = videoList[videoModuleController.videoPlayIndex.value]['url']; + final description = videoList[videoModuleController.videoPlayIndex.value]['title'] ?? '快来看看这个视频'; + var httpPrefix = 'http://43.143.227.203/adv'; + logger.i('分享链接地址----------------: ${httpPrefix}/goods-detail?id=${videoId}'); + if (index == 0) { + // 分享好友 + Wxsdk.shareToFriend(title: '快来看看这个视频', description: description, webpageUrl: '${httpPrefix}/video-detail?id=${videoId}'); + } else if (index == 1) { + // 分享到朋友圈 + Wxsdk.shareToTimeline(title: '快来看看这个视频', webpageUrl: '${httpPrefix}/goods-detail?id=${videoId}'); } else if (index == 2) { - // 朋友圈 - Wxsdk.shareToTimeline(title: '快来看看这个视频', webpageUrl: 'https://baidu.com'); + // 复制链接到剪切板 + copyToClipboard(videoUrl); + } else if (index == 3) { + // 下载视频到本地 + _downloadVideoWithDio(videoUrl,description); + } + } + // 复制链接到剪贴板 + void copyToClipboard(String text) async { + try { + await Clipboard.setData(ClipboardData(text: text)); + MyToast().tip( + title: '链接已复制到剪贴板', + position: 'center', + type: 'success', + ); + } catch (e) { + MyToast().tip( + title: '复制失败', + position: 'center', + type: 'success', + ); + } + } + + // 下载视频 + Future _downloadVideoWithDio(String videoUrl, String fileName) async { + try { + // 请求存储权限 + String? toastId; // 用于存储toast的ID,以便后续关闭 + var status = await Permissions.requestStoragePermission(); + if (!status) { + MyToast().tip( + title: '需要存储权限才能下载视频', + position: 'center', + type: 'success', + ); + return; + } + await DownloadManager.downloadFile( + url: videoUrl, + fileName: '$fileName.mp4', + onProgress: (progress) { + print("下载进度: $progress%"); + // 显示进度组件 + }, + onComplete: (filePath) { + MyToast().tip( + title: '下载完成', + position: 'center', + type: 'success', + ); + }, + onError: (error) { + MyToast().tip( + title: '下载失败: $error', + position: 'center', + type: 'error', + ); + }, + ); + } catch (e) { + print("下载视频失败: $e"); } } diff --git a/lib/utils/download_video.dart b/lib/utils/download_video.dart new file mode 100644 index 0000000..565a1ae --- /dev/null +++ b/lib/utils/download_video.dart @@ -0,0 +1,56 @@ +/// 精选推荐模块 +library; +import 'dart:io'; +import 'dart:async'; +import 'package:path_provider/path_provider.dart'; +import 'package:dio/dio.dart'; + +// 下载管理器类 +class DownloadManager { + static final Dio _dio = Dio(); + + static Future downloadFile({ + required String url, + required String fileName, + required Function(int) onProgress, + required Function(String) onComplete, + required Function(String) onError, + }) async { + try { + // 获取存储目录 + Directory directory; + if (Platform.isAndroid) { + directory = await getExternalStorageDirectory() ?? await getApplicationDocumentsDirectory(); + } else { + directory = await getApplicationDocumentsDirectory(); + } + + String downloadDir = '${directory.path}/Downloads'; + await Directory(downloadDir).create(recursive: true); + + String safeFileName = _getSafeFileName(fileName); + String filePath = '$downloadDir/$safeFileName'; + + await _dio.download( + url, + filePath, + onReceiveProgress: (received, total) { + if (total != -1) { + int progress = (received / total * 100).toInt(); + onProgress(progress); + } + }, + ); + + onComplete(filePath); + return filePath; + } catch (e) { + onError(e.toString()); + rethrow; + } + } + + static String _getSafeFileName(String fileName) { + return fileName.replaceAll(RegExp(r'[<>:"/\\|?*]'), '_'); + } +} \ No newline at end of file diff --git a/lib/utils/permissions.dart b/lib/utils/permissions.dart index a8c5110..6bfd261 100644 --- a/lib/utils/permissions.dart +++ b/lib/utils/permissions.dart @@ -41,6 +41,11 @@ class Permissions { return await _checkAndRequest(Permission.microphone); } + // 请求本地存储权限 + static Future requestStoragePermission() async { + return await _checkAndRequest(Permission.storage); + } + // 封装公共权限处理逻辑 static Future _checkAndRequest(Permission permission) async { final status = await permission.status;