106 lines
2.9 KiB
React
106 lines
2.9 KiB
React
|
import { View, TouchableOpacity, Image } from "react-native";
|
|||
|
import React, { useState, useEffect } from "react";
|
|||
|
import { useTailwind } from "tailwind-rn";
|
|||
|
import { Icon } from "@rneui/themed";
|
|||
|
import MediaPickerModal from "../MediaPickerModal";
|
|||
|
import Toast from "react-native-toast-message";
|
|||
|
|
|||
|
/*
|
|||
|
props格式:
|
|||
|
type 选择的媒体类型 "image"|"video"|"mix"
|
|||
|
maxCount 最大选择数量
|
|||
|
setAssets 向父组件返回媒体
|
|||
|
*/
|
|||
|
|
|||
|
export default function MediaPicker({ maxCount, type, setAssets }) {
|
|||
|
const tailwind = useTailwind();
|
|||
|
const [modalVisible, setModalVisible] = useState(false);
|
|||
|
const [newAssets, setNewAssets] = useState([]);
|
|||
|
const [_assets, set_Assets] = useState([]);
|
|||
|
|
|||
|
//当newAssets改变的时候添加新数据到assets
|
|||
|
useEffect(() => {
|
|||
|
set_Assets([..._assets, ...newAssets]);
|
|||
|
setAssets([..._assets, ...newAssets]);
|
|||
|
}, [newAssets]);
|
|||
|
|
|||
|
//加号选择器
|
|||
|
const Picker = () => {
|
|||
|
return (
|
|||
|
<TouchableOpacity
|
|||
|
onPress={() => {
|
|||
|
//数量检查
|
|||
|
maxCount - _assets.length !== 0
|
|||
|
? setModalVisible(true)
|
|||
|
: Toast.show({
|
|||
|
type: "error",
|
|||
|
text1: `已达到最大选择数量`,
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
}}
|
|||
|
style={{
|
|||
|
aspectRatio: 1,
|
|||
|
...tailwind("w-1/4 p-1"),
|
|||
|
}}
|
|||
|
>
|
|||
|
<View
|
|||
|
style={tailwind(
|
|||
|
"border border-dashed border-gray-400 rounded-lg flex-1 justify-center items-center"
|
|||
|
)}
|
|||
|
>
|
|||
|
<Icon type="ionicon" name="add" color="#9ca3af" size={40} />
|
|||
|
</View>
|
|||
|
</TouchableOpacity>
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
//展示已选择媒体
|
|||
|
const DisplayMedia = ({ asset, index }) => {
|
|||
|
const handleDelete = () => {
|
|||
|
const updatedAssets = [..._assets];
|
|||
|
updatedAssets.splice(index, 1);
|
|||
|
set_Assets(updatedAssets);
|
|||
|
setAssets(updatedAssets);
|
|||
|
};
|
|||
|
return (
|
|||
|
<View
|
|||
|
style={{
|
|||
|
aspectRatio: 1,
|
|||
|
...tailwind("w-1/4 p-1"),
|
|||
|
}}
|
|||
|
>
|
|||
|
<Image
|
|||
|
src={asset.old_uri}
|
|||
|
style={tailwind("w-full h-full rounded-lg")}
|
|||
|
/>
|
|||
|
<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>
|
|||
|
</View>
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
return (
|
|||
|
<View style={tailwind("flex flex-row flex-wrap")}>
|
|||
|
{_assets.map((asset, index) => (
|
|||
|
<DisplayMedia key={index} asset={asset} index={index} />
|
|||
|
))}
|
|||
|
<Picker />
|
|||
|
<MediaPickerModal
|
|||
|
visible={modalVisible}
|
|||
|
setVisible={setModalVisible}
|
|||
|
type={type}
|
|||
|
maxCount={maxCount - _assets.length}
|
|||
|
setAssets={setNewAssets}
|
|||
|
/>
|
|||
|
</View>
|
|||
|
);
|
|||
|
}
|