useMediaPreview.js 3.98 KB
import { ref } from 'vue';
import Taro from '@tarojs/taro';

/**
 * 媒体预览 composable
 * 提供图片和视频预览功能
 */
export function useMediaPreview() {
    // 图片预览相关状态
    const previewVisible = ref(false);
    const previewImages = ref([]);
    const previewIndex = ref(0);

    // 视频预览相关状态
    const videoVisible = ref(false);
    const currentVideo = ref(null);
    const videoId = ref(Date.now());

    /**
     * 处理媒体项目点击事件
     * @param {Object} item - 媒体项目
     * @param {Array} mediaList - 完整的媒体列表
     */
    const handleMediaClick = (item, mediaList = []) => {
        if (item.type === 'image') {
            // 图片预览
            const imageItems = mediaList.filter(media => media.type === 'image');
            previewImages.value = imageItems.map(img => ({ src: img.url }));

            // 计算当前图片在图片列表中的索引
            const imageIndex = imageItems.findIndex(img => img.url === item.url);
            previewIndex.value = imageIndex >= 0 ? imageIndex : 0;
            previewVisible.value = true;
        } else if (item.type === 'video') {
            // 视频播放
            currentVideo.value = item;
            videoId.value = Date.now(); // 生成新的视频ID
            videoVisible.value = true;
        }
    };

    /**
     * 预览单张图片
     * @param {string} imageUrl - 图片URL
     */
    const previewSingleImage = (imageUrl) => {
        previewImages.value = [{ src: imageUrl }];
        previewIndex.value = 0;
        previewVisible.value = true;
    };

    /**
     * 预览多张图片
     * @param {Array} images - 图片URL数组
     * @param {number} index - 初始显示的图片索引
     */
    const previewMultipleImages = (images, index = 0) => {
        previewImages.value = images.map(url => ({ src: url }));
        previewIndex.value = index;
        previewVisible.value = true;
    };

    /**
     * 播放视频
     * @param {Object} video - 视频对象 {url, thumbnail, duration}
     */
    const playVideo = (video) => {
        currentVideo.value = video;
        videoId.value = Date.now();
        videoVisible.value = true;
    };

    /**
     * 关闭图片预览
     */
    const closePreview = () => {
        previewVisible.value = false;
    };

    /**
     * 关闭视频播放
     */
    const closeVideo = () => {
        videoVisible.value = false;
        currentVideo.value = null;
    };

    /**
     * 处理视频播放
     */
    const handleVideoPlay = () => {
        // 视频开始播放
    };

    /**
     * 处理视频暂停
     */
    const handleVideoPause = () => {
        // 视频暂停播放
    };

    /**
     * 处理全屏状态变化
     */
    const handleFullscreenChange = () => {
        // 全屏状态变化
    };

    /**
     * 处理视频播放错误
     * @param {Event} error - 错误事件
     */
    const handleVideoError = (error) => {
        console.error('视频播放错误:', error);
        Taro.showToast({
            title: '视频播放失败',
            icon: 'error',
            duration: 2000
        });
        // 关闭视频弹框
        closeVideo();
    };

    /**
     * 格式化视频时长
     * @param {number} seconds - 秒数
     * @returns {string} 格式化后的时长
     */
    const formatDuration = (seconds) => {
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = seconds % 60;
        return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
    };

    return {
        // 状态
        previewVisible,
        previewImages,
        previewIndex,
        videoVisible,
        currentVideo,
        videoId,

        // 方法
        handleMediaClick,
        previewSingleImage,
        previewMultipleImages,
        playVideo,
        closePreview,
        closeVideo,
        handleVideoPlay,
        handleVideoPause,
        handleFullscreenChange,
        handleVideoError,
        formatDuration
    };
}