116 lines
3.1 KiB
JavaScript
116 lines
3.1 KiB
JavaScript
import { View, Image } from "react-native";
|
||
import React, { useState, useEffect } from "react";
|
||
import { useTailwind } from "tailwind-rn";
|
||
import { Icon } from "@rneui/themed";
|
||
import { DraggableGrid } from "react-native-draggable-grid";
|
||
import { useImageViewer } from "../../context/ImageViewProvider";
|
||
import VideoModal from "../VideoModal";
|
||
|
||
/*
|
||
props格式:
|
||
setDragging 返回正在拖动的状态,用于该组件嵌套在ScrollView中的时候禁用ScrollView的滚动
|
||
type 选择的媒体类型 "image"|"video"|"mix"
|
||
maxCount 最大选择数量
|
||
setAssets 向父组件返回媒体
|
||
*/
|
||
|
||
export default function MediaGrid({
|
||
setDragging = () => null,
|
||
assets,
|
||
setAssets,
|
||
}) {
|
||
const tailwind = useTailwind();
|
||
|
||
const { showImageViewer } = useImageViewer();
|
||
|
||
const [showVideo, setShowVideo] = useState(false);
|
||
const [videoUrl, setVideoUrl] = useState("");
|
||
|
||
//当newAssets改变的时候添加新数据到assets
|
||
useEffect(() => {
|
||
const temAssets = assets.map((item) => ({
|
||
...item,
|
||
uri: item?.dur > 0 ? item.cover_urls[0] : item.urls[0],
|
||
key: Date.now().toString(36) + Math.random().toString(36),
|
||
}));
|
||
setAssets(temAssets);
|
||
}, []);
|
||
|
||
const renderItem = (item) => {
|
||
const handleDelete = () => {
|
||
const updatedAssets = assets.filter((_item) => _item.key !== item.key);
|
||
setAssets(updatedAssets);
|
||
};
|
||
|
||
return (
|
||
<View
|
||
activeOpacity={1}
|
||
style={{
|
||
aspectRatio: 1,
|
||
padding: 2,
|
||
...tailwind("w-full"),
|
||
}}
|
||
key={item.key}
|
||
>
|
||
<Image src={item.uri} style={tailwind("w-full h-full rounded")} />
|
||
<View style={tailwind("absolute top-2 right-2")}>
|
||
<Icon
|
||
type="ionicon"
|
||
name="close"
|
||
color="white"
|
||
size={18}
|
||
onPress={handleDelete}
|
||
style={tailwind("bg-black rounded-full opacity-70")}
|
||
/>
|
||
</View>
|
||
{item?.dur > 0 && (
|
||
<View
|
||
style={tailwind(
|
||
"absolute flex w-full h-full items-center justify-center"
|
||
)}
|
||
>
|
||
<Icon
|
||
type="ionicon"
|
||
name="play"
|
||
color="white"
|
||
size={14}
|
||
style={tailwind("bg-black p-2 rounded-full opacity-70")}
|
||
/>
|
||
</View>
|
||
)}
|
||
</View>
|
||
);
|
||
};
|
||
|
||
return (
|
||
<View style={tailwind("flex w-full")}>
|
||
<DraggableGrid
|
||
numColumns={4}
|
||
renderItem={renderItem}
|
||
data={assets}
|
||
onDragStart={() => setDragging(true)}
|
||
onDragRelease={(data) => {
|
||
setAssets(data);
|
||
setDragging(false);
|
||
}}
|
||
onItemPress={(item) => {
|
||
if (item?.dur > 0) {
|
||
setVideoUrl(item.urls[0]);
|
||
setShowVideo(true);
|
||
return;
|
||
}
|
||
showImageViewer({
|
||
imageUrls: [{ url: item.uri }],
|
||
index: 0,
|
||
});
|
||
}}
|
||
/>
|
||
<VideoModal
|
||
visible={showVideo}
|
||
setVisible={setShowVideo}
|
||
url={videoUrl}
|
||
/>
|
||
</View>
|
||
);
|
||
}
|