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);
}}
/>
);
}