import { View, Text, TouchableOpacity, Modal, TouchableWithoutFeedback, Platform, Image as NativeImage, } from "react-native"; import React, { useEffect, useState } from "react"; import { useTailwind } from "tailwind-rn"; import { Image } from "expo-image"; import VideoModal from "../VideoModal"; import { useNavigation } from "@react-navigation/native"; import formatTimestamp from "../../utils/formatTimestamp"; import { block } from "../../utils/relation"; import baseRequest from "../../utils/baseRequest"; import { generateSignature } from "../../utils/crypto"; import Toast from "react-native-toast-message"; import { get } from "../../utils/storeInfo"; import { Icon } from "@rneui/themed"; import ParsedText from "react-native-parsed-text"; import * as Linking from "expo-linking"; import { useImageViewer } from "../../context/ImageViewProvider"; //todo:完善视频逻辑;完善图片模糊逻辑 const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk"; export default function SpacePost({ data }) { const tailwind = useTailwind(); const navigation = useNavigation(); const [like, setLike] = useState( data?.is_zone_moment_thumbed_up === 1 ? true : false ); const [showVideo, setShowVideo] = useState(false); //判断是否是发帖人 const [isCreator, setIsCreator] = useState(false); useEffect(() => { const checkAuth = async () => { const account = await get("account"); if (account.mid === data.mid) setIsCreator(true); }; checkAuth(); }, []); //点赞和取消点赞功能 const thumbsUp = async (id, times = 1) => { const apiUrl = process.env.EXPO_PUBLIC_API_URL; try { const base = await baseRequest(); const signature = await generateSignature({ zone_moment_id: id, times: times, ...base, }); const _response = await fetch( `${apiUrl}/api/zone_moment/thumbs_up?signature=${signature}`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ zone_moment_id: id, times: times, ...base, }), } ); const _data = await _response.json(); if (_data.ret === -1) { Toast.show({ type: "error", text1: _data.msg, topOffset: 60, }); return; } } catch (error) { console.error(error); } }; const handleLike = () => { setLike(!like); if (like) { thumbsUp(data.id, -1); return; } thumbsUp(data.id, 1); }; //帖子操作功能 const [operationModalVisible, setOperationModalVisible] = useState(false); //点击文本中的网址 const handleURLPress = (url) => { Linking.openURL(url); }; //网址样式 const renderLink = (matchingString, matches) => { return ( handleURLPress(matchingString)} > #网页链接 ); }; return ( {data?.is_headed === 1 && ( )} navigation.navigate("StreamerProfile", { mid: data?.mid }) } > {data?.streamer_ext?.name} {(data?.status === 0 || data?.status === 1) && ( 审核中 )} {data?.status === 3 && ( navigation.navigate("EditSpacePost", { data: data }) } style={tailwind("flex flex-col items-start mt-2")} > 审核未通过,请 重新编辑 )} {data?.text} {/* 媒体展示 */} {data.media_component.video_ids?.length === 0 || data.media_component.video_ids === null ? ( ) : ( { setShowVideo(true); } : () => navigation.navigate("WebWithoutHeader", { uri: process.env.EXPO_PUBLIC_WEB_URL + "/zone/pay/" + data?.zid + "/h5_zone_moment/" + data?.id, }) } > )} {/* 用户未解锁时展示 */} {data.c_type === 1 && data.is_zone_moment_unlocked === 0 && ( navigation.navigate("WebWithoutHeader", { uri: process.env.EXPO_PUBLIC_WEB_URL + "/zone/pay/" + data?.zid + "/h5_zone_moment/" + data?.id, }) } style={{ backgroundColor: data.is_ironfan_visible === 1 ? "#301024" : "#331F0B", ...tailwind("flex flex-col py-2.5 px-3 mr-10 rounded-lg"), }} > {data.price / 100} {data.is_ironfan_visible === 1 ? "铁粉免费查看" : data.is_superfanship_enabled === 1 ? "超粉免费查看" : "付费解锁"} {data.is_ironfan_visible === 1 && ( 空间内任意消费满{data.ironfanship_price / 100}即可成为铁粉 )} )} {/* 用户已解锁时展示 */} {data.c_type === 1 && data.is_zone_moment_unlocked === 1 && !isCreator && ( {data.price / 100} {data.is_ironfanship_unlocked === 1 && data.is_ironfan_visible === 1 && "已使用铁粉特权解锁"} {data.is_superfanship_unlocked === 1 && data.is_ironfan_visible === 0 && "已使用超粉特权解锁"} {data.is_superfanship_unlocked === 0 && data.is_ironfanship_unlocked === 0 && "已付费解锁"} )} {/* 仅对发帖人展示 */} {data.c_type === 1 && isCreator && ( navigation.navigate("WebWithoutHeader", { uri: process.env.EXPO_PUBLIC_WEB_URL + "/zone/pay/" + data?.zid + "/h5_zone_moment/" + data?.id, }) } style={{ backgroundColor: data.is_ironfan_visible === 1 ? "#301024" : "#331F0B", ...tailwind("flex flex-col py-2.5 px-3 mr-10 rounded-lg"), }} > {data.price / 100} 共{data.buyer_cnt}人购买 {data.is_ironfan_visible === 1 && ( 空间内任意消费满{data.ironfanship_price / 100}即可成为铁粉 )} )} {formatTimestamp(data?.ct)} {like ? ( ) : ( )} {like ? "已赞" : "点赞"} setOperationModalVisible(!operationModalVisible) } > ); } //媒体为图片时展示内容的组件 function ImageDisplay({ data, isCreator, isUnlocked, visibleRange, mediaAmount, media, }) { const tailwind = useTailwind(); const navigation = useNavigation(); //如果图片数量与服务端图片数量不一致,则填充第一张图片url使数量与服务端数量一致 const displayMedia = media.concat( new Array(mediaAmount - media.length).fill(media[0]) ); const { showImageViewer } = useImageViewer(); const images = displayMedia.map((item) => { return { url: item.urls[0] }; }); const [isCollapsed, setIsCollapsed] = useState(true); if (images.length === 0) return null; return ( {displayMedia.map((item, index) => { if (index > 8 && isCollapsed) return null; return ( { showImageViewer({ imageUrls: images, index: index, lockedStartIndex: isUnlocked ? 999 : visibleRange, onPressUnlockBtn: () => navigation.navigate("WebWithoutHeader", { uri: process.env.EXPO_PUBLIC_WEB_URL + "/zone/pay/" + data?.zid + "/h5_zone_moment/" + data?.id, }), }); }} style={ displayMedia.length > 1 ? { aspectRatio: 1, ...tailwind("basis-1/3 p-0.5") } : { width: displayMedia[0].w < displayMedia[0].h ? (displayMedia[0].w / displayMedia[0].h) * 200 : 250, height: displayMedia[0].w < displayMedia[0].h ? 200 : (displayMedia[0].h / displayMedia[0].w) * 250, } } > {isCreator && visibleRange < index + 1 && ( 不可预览 )} {index === 8 && isCollapsed && ( setIsCollapsed(false)} style={{ marginLeft: 2, marginTop: 2, ...tailwind( "absolute flex w-full h-full items-center justify-center bg-[#00000099]" ), }} > +{media.length - 9} )} {index === media.length - 1 && !isCollapsed && ( setIsCollapsed(true)} style={{ marginLeft: 2, marginTop: 2, ...tailwind( "absolute flex w-full h-full items-center justify-center bg-[#00000099]" ), }} > )} ); })} ); } //媒体为视频时展示封面的组件 function PosterDisplay({ isUnlocked, blurCover, media }) { const tailwind = useTailwind(); return ( ); } //帖子操作组件 function OperationModal({ visible, setVisible, data }) { const tailwind = useTailwind(); const navigation = useNavigation(); //拉黑 const handleBlock = async () => { const account = await get("account"); const subMid = account.mid; const objMid = data.mid; await block(subMid, objMid); setVisible(false); }; //删除 const handleDelete = async () => { const apiUrl = process.env.EXPO_PUBLIC_API_URL; try { const base = await baseRequest(); const signature = await generateSignature({ id: data.id, ...base, }); const _response = await fetch( `${apiUrl}/api/zone_moment/delete?signature=${signature}`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ id: data.id, ...base, }), } ); const _data = await _response.json(); if (_data.ret === -1) { Toast.show({ type: "error", text1: _data.msg, topOffset: 60, }); return; } Toast.show({ type: "success", text1: "删除成功,请刷新页面", topOffset: 60, }); return; } catch (error) { console.error(error); } finally { setVisible(false); } }; //置顶 const handleTop = async () => { const apiUrl = process.env.EXPO_PUBLIC_API_URL; try { const base = await baseRequest(); const body = { zone_moment_ids: [data.id], op_type: data.is_headed ? 0 : 1, ...base, }; const signature = await generateSignature(body); const _response = await fetch( `${apiUrl}/api/zone_moment/head?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; } Toast.show({ type: "success", text1: "操作成功,请刷新页面查看", topOffset: 60, }); return; } catch (error) { console.error(error); } finally { setVisible(false); } }; //判断是否展示删除、拉黑、举报功能 const [display, setDisPlay] = useState({ delete: false, top: false, block: true, feedback: true, }); useEffect(() => { const checkAuth = async () => { const account = await get("account"); if (account.mid === data.mid || account.role === 1 || account.role === 2) setDisPlay((prev) => { return { ...prev, delete: true, top: true }; }); if (account.mid === data.mid) setDisPlay((prev) => { return { ...prev, block: false, feedback: false }; }); }; checkAuth(); }, []); return ( setVisible(false)} style={{ backgroundColor: "#00000080", ...tailwind("flex flex-1 items-center justify-center"), }} > {display.feedback && ( { navigation.navigate("MessageDetail", { mid: 1 }); setVisible(false); }} style={tailwind("flex flex-col w-full py-2 items-center")} > 举报 )} {display.block && ( 拉黑 )} {display.top && ( {data.is_headed ? "取消置顶" : "置顶"} )} {display.delete && ( 删除 )} setVisible(false)} style={tailwind("flex flex-col w-full py-2 items-center")} > 关闭 ); }