import { View, Text, TouchableOpacity, Image, Modal, Platform, } from "react-native"; import React, { useState, useEffect } from "react"; import { useTailwind } from "tailwind-rn"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { ImagePicker } from "expo-image-multiple-picker"; import { Icon, Badge } from "@rneui/themed"; import * as MediaLibrary from "expo-media-library"; import * as Linking from "expo-linking"; import MyModal from "../MyModal"; /* props格式: visible 控制modal可见性 setVisible 控制modal可见性 type 选择的媒体类型 "image"|"video"|"mix" maxCount 最大选择数量 setAssets 向父组件返回媒体 */ export default function MediaPickerModal({ visible, setVisible, type, maxCount, setAssets, }) { const tailwind = useTailwind(); const insets = useSafeAreaInsets(); const [album, setAlbum] = useState({ title: "全部" }); //前往打开权限弹窗 const [requestModalVisible, setRequestModalVisible] = useState(false); //前往打开权限弹窗 const [overlayVisible, setOverlayVisible] = useState(false); //保存当前权限状态 const [permissionStatus, setPermissionStatus] = useState(); //检查并获取权限 useEffect(() => { if (visible) { async function checkMediaLibraryPermissions() { //权限检查、获取 // 第一步:检查是否已有权限 const { status } = await MediaLibrary.getPermissionsAsync(); if (status === "granted") { // 如果已有权限,直接执行操作 setPermissionStatus("granted"); return; } if (status === "undetermined") { setRequestModalVisible(true); return; } if (status === "denied") { requestMediaLibraryPermissions(); } } checkMediaLibraryPermissions(); } }, [visible]); async function requestMediaLibraryPermissions() { const permission = await MediaLibrary.requestPermissionsAsync(); if (permission.status === "denied") { // 用户拒绝了权限请求,打开应用设置页面 setPermissionStatus("denied"); setVisible(false); setOverlayVisible(true); return; } if (permission.status === "granted") { // 用户同意了权限请求,执行操作 setPermissionStatus("granted"); } } //将ios中assets的路径从ph://改为file:// const changeToLocalUri = async (assets) => { const editedAssets = await Promise.all( assets.map(async (item) => { const info = await MediaLibrary.getAssetInfoAsync(item.id); const uri = info.localUri; if (Platform.OS === "ios") { return { ...item, old_uri: item.uri, uri }; } return { ...item, old_uri: item.uri }; }) ); return editedAssets; }; //让视频秒数格式化 function formatDuration(duration) { let minutes = Math.floor(duration / 60); let seconds = Math.round(duration % 60); if (seconds < 10) { seconds = "0" + seconds; } return `${minutes}:${seconds}`; } //header组件 const ImagePickerHeader = (props) => { return ( {props.view == "album" && ( <> 选择相册 { setVisible(false); }} style={tailwind("flex-row items-center")} > 取消 )} {props.view == "gallery" && ( <> {props.album.title} {props.imagesPicked > 0 ? ( 完成 ) : ( { setVisible(false); }} style={tailwind("flex-row items-center")} > 取消 )} )} ); }; //check组件 const ImagePickerCheck = () => { return ( ); }; //album组件 const ImagePickerAlbum = (props) => { return ( props.goToGallery(props.album)} style={{ flex: 1, height: 200 }} > {props.album.title} ); }; //video组件 const ImagePickerVideo = (props) => { return ( {formatDuration(props.duration)} ); }; return ( <> { setVisible(false); const editedAssets = await changeToLocalUri(assets); setAssets(editedAssets); }} onCancel={() => { setVisible(false); }} galleryColumns={3} albumColumns={2} multiple onSelectAlbum={(album) => setAlbum(album)} selectedAlbum={album} limit={maxCount} video={type === "video" || type === "mix"} image={type === "image" || type === "mix"} /> { setRequestModalVisible(false); requestMediaLibraryPermissions(); }} customText="继续" /> { setOverlayVisible(false); }} confirm={() => { Linking.openSettings(); setOverlayVisible(false); }} /> ); }