tiefen_space_app/components/MediaGrid/index.jsx

116 lines
3.1 KiB
React
Raw Permalink Normal View History

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