import { View, TouchableOpacity, Image } from "react-native"; import React, { useState, useEffect, useCallback } from "react"; import { useTailwind } from "tailwind-rn"; import { Icon } from "@rneui/themed"; import Toast from "react-native-toast-message"; import { DraggableGrid } from "react-native-draggable-grid"; import { useImageViewer } from "../../context/ImageViewProvider"; import VideoModal from "../VideoModal"; import * as ImagePicker from "expo-image-picker"; import * as VideoThumbnails from "expo-video-thumbnails"; /* props格式: setDragging 返回正在拖动的状态,用于该组件嵌套在ScrollView中的时候禁用ScrollView的滚动 type 选择的媒体类型 "image"|"video"|"mix" maxCount 最大选择数量 setAssets 向父组件返回媒体 */ export default function MediaPicker({ setDragging = () => null, maxCount, type = "image", setAssets, }) { const tailwind = useTailwind(); const [newAssets, setNewAssets] = useState([]); const [_assets, set_Assets] = useState([]); const { showImageViewer } = useImageViewer(); const [showVideo, setShowVideo] = useState(false); const [videoUrl, setVideoUrl] = useState(""); //为视频生成封面 const generateThumbnail = useCallback(async (uri) => { try { const videoCover = await VideoThumbnails.getThumbnailAsync(uri); return videoCover; } catch (e) { console.warn(e); } }, []); //选择媒体 const pickMedia = async () => { let mediaType; if (type === "image") { mediaType = ImagePicker.MediaTypeOptions.Images; } else if (type === "video") { mediaType = ImagePicker.MediaTypeOptions.Videos; } else { mediaType = ImagePicker.MediaTypeOptions.All; } let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: mediaType, allowsMultipleSelection: true, selectionLimit: maxCount - _assets.length, quality: 1, }); if (!result.canceled) { for (let i = 0; i < result.assets.length; i++) { if (result.assets[i].duration > 0) { const videoCover = await generateThumbnail(result.assets[i].uri); result.assets[i].cover = videoCover.uri; } } setNewAssets(result.assets); } }; //当newAssets改变的时候添加新数据到assets useEffect(() => { const temAssets = newAssets.map((item) => ({ ...item, key: Date.now().toString(36) + Math.random().toString(36), })); set_Assets([..._assets, ...temAssets]); setAssets([..._assets, ...temAssets]); }, [newAssets]); //加号选择器 const Picker = () => { return ( { //数量检查 maxCount - _assets.length !== 0 ? pickMedia() : Toast.show({ type: "error", text1: `已达到最大选择数量`, topOffset: 60, }); }} style={{ aspectRatio: 1, padding: 2, ...tailwind("w-1/4"), }} > ); }; const renderItem = (item) => { const handleDelete = () => { const updatedAssets = _assets.filter((_item) => _item.key !== item.key); set_Assets(updatedAssets); setAssets(updatedAssets); }; return ( {item.duration > 0 && ( )} ); }; return ( setDragging(true)} onDragRelease={(data) => { set_Assets(data); setAssets(data); setDragging(false); }} onItemPress={(item) => { if (!item.duration) { showImageViewer({ imageUrls: [{ url: item.uri }], index: 0, }); return; } setVideoUrl(item.uri); setShowVideo(true); }} /> ); }