tiefen_space_app/components/ImageViewer/index.jsx

190 lines
5.7 KiB
JavaScript

import {
View,
Text,
Modal,
TouchableOpacity,
ActivityIndicator,
Platform,
} from "react-native";
import React, { useState, useCallback, useEffect } from "react";
import { ImageViewer as OriginImageViewer } from "react-native-image-zoom-viewer";
import { Icon } from "@rneui/themed";
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import saveImage from "../../utils/saveImage";
import Toast from "react-native-toast-message";
import { get } from "../../utils/storeInfo";
import { useNavigation } from "@react-navigation/native";
import MyModal from "../MyModal";
//isVisible boolean
//setIsVisible function
//imageUrls [{ url: string }]
//index int
export default function ImageViewer({
isVisible,
setIsVisible,
imageUrls,
index,
}) {
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
const navigation = useNavigation();
const checkRole = useCallback(async () => {
const account = await get("account");
const role = account.role;
const isVip = account.is_a_member;
if (role !== 0 || isVip === 1) return true;
return false;
}, []);
const MenusComponent = useCallback(
({ cancel, saveToLocal }) => (
<Modal
visible={true}
transparent={true}
statusBarTranslucent
animationType="fade"
>
<TouchableOpacity
onPress={cancel}
activeOpacity={1}
style={tailwind("flex flex-1 bg-[#00000080]")}
>
<TouchableOpacity
activeOpacity={1}
style={{
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind(
"absolute bottom-0 left-0 h-32 w-full bg-[#13121F] rounded-t-2xl"
),
}}
>
<View style={tailwind("flex flex-1 flex-row items-center px-4")}>
<TouchableOpacity
onPress={async () => {
const isVip = await checkRole();
if (isVip) {
saveToLocal();
return;
}
setIsVisible(false);
navigation.navigate("WebWithoutHeader", {
uri: process.env.EXPO_PUBLIC_WEB_URL + "/vip",
});
}}
style={tailwind("flex flex-col items-center px-4")}
>
<Icon type="ionicon" name="image" size={30} color="white" />
<Text
style={tailwind("text-sm text-[#FFFFFF80] font-medium mt-1")}
>
保存(会员特权)
</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={cancel}
style={tailwind("flex flex-col items-center px-4")}
>
<Icon
type="ionicon"
name="close-circle"
size={30}
color="white"
/>
<Text
style={tailwind("text-sm text-[#FFFFFF80] font-medium mt-1")}
>
取消
</Text>
</TouchableOpacity>
</View>
</TouchableOpacity>
</TouchableOpacity>
</Modal>
),
[]
);
const [isVipModalVisible, setIsVipModalVisible] = useState(false);
const [isSaving, setIsSaving] = useState(false);
const hanldSaveImage = async (index) => {
const isVip = await checkRole();
if (!isVip) {
setIsVipModalVisible(true);
return;
}
if (isSaving) return;
setIsSaving(true);
const isSuccess = await saveImage(imageUrls[index].url);
setIsSaving(false);
};
return (
<Modal visible={isVisible} statusBarTranslucent transparent={true}>
<OriginImageViewer
imageUrls={imageUrls}
index={index}
onClick={() => setIsVisible(false)}
onSwipeDown={() => setIsVisible(false)}
enableSwipeDown
backgroundColor="#07050A"
renderFooter={
Platform.OS === "android"
? (index) => (
<TouchableOpacity
onPress={() => hanldSaveImage(index)}
style={{
marginLeft: 20,
marginBottom: insets.bottom,
...tailwind(
"flex justify-center items-center w-12 h-12 bg-[#FFFFFF1A] rounded-full"
),
}}
>
{isSaving && <ActivityIndicator size="small" />}
{!isSaving && (
<Icon
type="ionicon"
name="save-outline"
size={20}
color="white"
/>
)}
</TouchableOpacity>
)
: () => <></>
}
onSave={async (url) => {
const isSuccess = await saveImage(url);
}}
saveToLocalByLongPress={Platform.OS === "android"}
menus={MenusComponent}
loadingRender={() => <ActivityIndicator size="large" />}
/>
<Toast />
<MyModal
visible={isVipModalVisible}
setVisible={setIsVipModalVisible}
title="是否开通会员?"
content="会员可无限制保存图片,一次开通永久有效。"
cancel={() => {
setIsVipModalVisible(false);
}}
confirm={() => {
setIsVipModalVisible(false);
setIsVisible(false);
navigation.navigate("WebWithoutHeader", {
uri: process.env.EXPO_PUBLIC_WEB_URL + "/vip",
});
}}
/>
</Modal>
);
}