diff --git a/components/ImageViewer/index.jsx b/components/ImageViewer/index.jsx index 0cb8cfc..e413b9d 100644 --- a/components/ImageViewer/index.jsx +++ b/components/ImageViewer/index.jsx @@ -19,8 +19,10 @@ import MyModal from "../MyModal"; import { Image } from "expo-image"; import { Button } from "@rneui/themed"; import { LinearGradient } from "expo-linear-gradient"; +import { generateSignature } from "../../utils/crypto"; +import baseRequest from "../../utils/baseRequest"; -//imageUrls [{ url: string }] +//imageUrls [{ url: string , id: int }] 网络图片需要查看原图时才传id,其他情况不用 //index int //lockedStartIndex int //onPressUnlockBtn () => void @@ -33,6 +35,7 @@ export function ImageViewer({ index, lockedStartIndex, onPressUnlockBtn, + setImageViewerProps, }) { const tailwind = useTailwind(); const insets = useSafeAreaInsets(); @@ -57,76 +60,6 @@ export function ImageViewer({ return false; }, []); - const MenusComponent = useCallback( - ({ cancel, saveToLocal }) => ( - - - - - { - const isVip = await checkRole(); - if (isVip) { - saveToLocal(); - return; - } - closeImageViewer(); - navigation.navigate("WebWithoutHeader", { - uri: process.env.EXPO_PUBLIC_WEB_URL + "/vip", - }); - }} - style={tailwind("flex flex-col items-center px-4")} - > - - - 保存(会员特权) - - - - - - 取消 - - - - - - - ), - [] - ); - const [isVipModalVisible, setIsVipModalVisible] = useState(false); const [isSaving, setIsSaving] = useState(false); const hanldSaveImage = async (index) => { @@ -141,6 +74,62 @@ export function ImageViewer({ setIsSaving(false); }; + //查看原图 + const [isLoading, setIsLoading] = useState(false); + const handleCheckOriginalImage = async (index) => { + const isVip = await checkRole(); + if (!isVip) { + setIsVipModalVisible(true); + return; + } + setIsLoading(true); + const apiUrl = process.env.EXPO_PUBLIC_API_URL; + try { + const base = await baseRequest(); + const body = { + image_id: imageUrls[index].id, + ...base, + }; + const signature = await generateSignature(body); + const _response = await fetch( + `${apiUrl}/api/previews/original_image?signature=${signature}`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + } + ); + const _data = await _response.json(); + if (_data.ret === -1) { + Toast.show({ + type: "error", + text1: _data.msg, + topOffset: 60, + }); + return; + } + setImageViewerProps((prev) => { + let newImageViewerProps = prev; + newImageViewerProps.imageUrls[index] = { + id: imageUrls[index].id, + url: _data?.data?.urls[0], + }; + return { ...newImageViewerProps }; + }); + Toast.show({ + type: "success", + text1: "已切换至原图", + topOffset: 60, + }); + } catch (error) { + console.error(error); + } finally { + setIsLoading(false); + } + }; + return ( ; }} renderFooter={(index) => ( - hanldSaveImage(index)} - style={{ - marginLeft: 20, - marginBottom: insets.bottom, - ...tailwind( - "flex justify-center items-center w-12 h-12 bg-[#FFFFFF1A] rounded-full" - ), - }} - > - {isSaving && } - {!isSaving && ( - + + hanldSaveImage(index)} + style={{ + marginLeft: 20, + marginBottom: insets.bottom, + ...tailwind( + "flex justify-center items-center w-14 h-14 bg-[#FFFFFF1A] rounded-full" + ), + }} + > + {isSaving && } + {!isSaving && ( + + )} + + 保存 + + + {imageUrls[index]?.id && ( + handleCheckOriginalImage(index)} + style={{ + marginLeft: 20, + marginBottom: insets.bottom, + ...tailwind( + "flex justify-center items-center w-14 h-14 bg-[#FFFFFF1A] rounded-full" + ), + }} + > + {isLoading && } + {!isLoading && ( + + )} + + 原图 + + )} - + )} onSave={(url) => { saveImage(url); }} - saveToLocalByLongPress - menus={MenusComponent} + saveToLocalByLongPress={false} loadingRender={() => } /> @@ -222,7 +244,7 @@ export function ImageViewer({ visible={isVipModalVisible} setVisible={setIsVipModalVisible} title="是否开通会员?" - content="会员可无限制保存图片/视频,一次开通永久有效。" + content="会员可无限制保存图片、查看原图,一次开通永久有效。" cancel={() => { setIsVipModalVisible(false); }} diff --git a/components/Post/index.jsx b/components/Post/index.jsx index 332d3ca..a23c7f5 100644 --- a/components/Post/index.jsx +++ b/components/Post/index.jsx @@ -257,9 +257,8 @@ export default function Post({ data }) { //媒体为图片时展示内容的组件 function ImageDisplay({ media }) { - const navigation = useNavigation(); const tailwind = useTailwind(); - const images = media.map((item) => ({ url: item.urls[0] })); + const images = media.map((item) => ({ url: item.urls[0], id: item.id })); const { showImageViewer } = useImageViewer(); diff --git a/components/SpacePost/index.jsx b/components/SpacePost/index.jsx index 11b6657..10fe5a4 100644 --- a/components/SpacePost/index.jsx +++ b/components/SpacePost/index.jsx @@ -608,7 +608,7 @@ function ImageDisplay({ const { showImageViewer } = useImageViewer(); const images = displayMedia.map((item) => { - return { url: item?.urls[0] }; + return { url: item?.urls[0], id: item?.id }; }); const [isCollapsed, setIsCollapsed] = useState(true); diff --git a/context/ImageViewProvider.jsx b/context/ImageViewProvider.jsx index 0c87318..fcf5791 100644 --- a/context/ImageViewProvider.jsx +++ b/context/ImageViewProvider.jsx @@ -28,6 +28,7 @@ export const ImageViewerProvider = ({ children }) => { {...imageViewerProps} onClose={closeImageViewer} onChange={changeImageViewerIndex} + setImageViewerProps={setImageViewerProps} /> )} diff --git a/screeens/SpaceIntroduce/index.jsx b/screeens/SpaceIntroduce/index.jsx index 0c24635..1e9ecb4 100644 --- a/screeens/SpaceIntroduce/index.jsx +++ b/screeens/SpaceIntroduce/index.jsx @@ -87,9 +87,8 @@ export default function SpaceIntroduce({ navigation, route }) { const images = data?.streamer_ext?.album?.images ?.slice(0, 5) ?.map((image) => { - return image?.urls[0]; + return { url: image?.urls[0], id: image?.id }; }); - const imagesForImageViewer = images?.map((url) => ({ url })); //当空间价格为0时,直接加入空间 const handleJoinFreeSpace = async () => { @@ -288,7 +287,7 @@ export default function SpaceIntroduce({ navigation, route }) { activeOpacity={1} onPress={() => { showImageViewer({ - imageUrls: imagesForImageViewer, + imageUrls: images, index: index, }); }} diff --git a/screeens/StreamerProfile/index.jsx b/screeens/StreamerProfile/index.jsx index 01879d5..2749e5c 100644 --- a/screeens/StreamerProfile/index.jsx +++ b/screeens/StreamerProfile/index.jsx @@ -245,8 +245,10 @@ export default function StreamerProfile({ navigation, route }) { const { showImageViewer } = useImageViewer(); - const images = data?.album?.images?.map((image) => image?.urls[0]); - const imagesForImageViewer = images?.map((url) => ({ url })); + const images = data?.album?.images?.map((image) => ({ + url: image?.urls[0], + id: image?.id, + })); return ( <> { showImageViewer({ - imageUrls: imagesForImageViewer, + imageUrls: images, index: index - 1, }); }} diff --git a/screeens/StreamerSpace/index.jsx b/screeens/StreamerSpace/index.jsx index 707f8ba..ed7729c 100644 --- a/screeens/StreamerSpace/index.jsx +++ b/screeens/StreamerSpace/index.jsx @@ -215,6 +215,42 @@ export default function StreamerSpace({ navigation, route }) { //bottom sheet组件相关 const snapPoints = useMemo(() => ["73%", "100%"], []); + //刷新铁粉身份(解决主播降价导致的进度满100但未成为铁粉) + const handleFansIdentityRefresh = async () => { + const apiUrl = process.env.EXPO_PUBLIC_API_URL; + try { + const base = await baseRequest(); + const body = { + zid: data?.id, + ...base, + }; + const signature = await generateSignature(body); + const _response = await fetch( + `${apiUrl}/api/zone_moment/fans_identity_refresh?signature=${signature}`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + } + ); + const _data = await _response.json(); + if (_data.ret === -1) { + Toast.show({ + type: "error", + text1: _data.msg, + topOffset: 60, + }); + return; + } + await getData(); + setIsIronFanModalVisible(false); + } catch (error) { + console.error(error); + } + }; + //成为铁粉Modal组件 const [isIronFanModalVisible, setIsIronFanModalVisible] = useState(false); const ironFanProgress = useMemo( @@ -283,6 +319,15 @@ export default function StreamerSpace({ navigation, route }) { > 查看铁粉专享内容 + + 进度已满但还未成为铁粉? +