514 lines
17 KiB
JavaScript
514 lines
17 KiB
JavaScript
"use client";
|
|
|
|
import React, { useEffect, useState, useRef, useMemo } from "react";
|
|
import {
|
|
Image,
|
|
Mask,
|
|
FloatingPanel,
|
|
JumboTabs,
|
|
List,
|
|
InfiniteScroll,
|
|
ProgressBar,
|
|
Toast,
|
|
} from "antd-mobile";
|
|
import { useRouter, useParams } from "next/navigation";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import { faAngleLeft, faRefresh } from "@fortawesome/free-solid-svg-icons";
|
|
import PostItem from "@/components/PostItem";
|
|
import PostItemSkeleton from "@/components/skeletons/PostItemSkeleton";
|
|
import Empty from "@/components/Empty";
|
|
import require from "@/utils/require";
|
|
import AddWeChat from "@/components/AddWeChat";
|
|
import SeeTiefen from "@/components/SeeTiefen";
|
|
import DefaultMask from "@/components/DefaultMask";
|
|
import { getSpaceData, getStreamerInfo } from "@/api/space";
|
|
const anchors = [
|
|
window.innerHeight - 280,
|
|
window.innerHeight - 280,
|
|
window.innerHeight - 60,
|
|
];
|
|
const tabItems = [
|
|
{ label: "全部", key: "all" },
|
|
{ label: "铁粉专享", key: "ironFan" },
|
|
{ label: "超粉专享", key: "chaofen" },
|
|
];
|
|
export default function PersonSpace() {
|
|
const router = useRouter();
|
|
const { id } = useParams();
|
|
const contentBox = useRef();
|
|
const [hasMore, setHasMore] = useState(true);
|
|
const [scrollHeight, setScrollHeight] = useState(0);
|
|
const [postList, setPostList] = useState([]);
|
|
const [offset, setOffset] = useState(0);
|
|
const [maskVisible, setMaskVisible] = useState({ visible: false, type: "" });
|
|
const [currentKey, setCurrentKey] = useState("all");
|
|
const [loading, setLoading] = useState(false);
|
|
const [streamerInfo, setStreamerInfo] = useState(null);
|
|
const [currentTime, setCurrentTime] = useState();
|
|
const scrollRef = useRef(null);
|
|
//退款中Modal是否展示
|
|
const [isRefundingModalVisible, setIsRefundingModalVisible] = useState(false);
|
|
const ironFanProgress = useMemo(
|
|
() =>
|
|
Math.floor(
|
|
(streamerInfo?.expenditure / streamerInfo?.ironfanship_price) * 100
|
|
),
|
|
[streamerInfo]
|
|
);
|
|
useEffect(() => {
|
|
setScrollHeight(window.innerHeight - 126);
|
|
if (contentBox.current) {
|
|
contentBox.current.style.transform = "translateY(-12px)";
|
|
// debugger
|
|
}
|
|
getStreamerInfo(Number(id)).then((res) => {
|
|
setStreamerInfo(res);
|
|
});
|
|
getCurrentTime();
|
|
getSpaceData(Number(id)).then((res) => {
|
|
if (res) {
|
|
const { isRefunding, noRole } = res;
|
|
isRefunding && router.push("/");
|
|
noRole && router.push("/person_space_introduce/" + id);
|
|
}
|
|
});
|
|
}, []);
|
|
useEffect(() => {
|
|
if (currentKey) {
|
|
firstRequest(currentKey);
|
|
}
|
|
}, [currentKey, streamerInfo]);
|
|
const getCurrentTime = async () => {
|
|
setCurrentTime(Math.floor(new Date().getTime() / 1000));
|
|
};
|
|
async function loadMore() {
|
|
if (!offset) return;
|
|
const append = await getPostList(streamerInfo.id, currentKey, offset);
|
|
if (append) {
|
|
setPostList((val) => [...val, ...append]);
|
|
setHasMore(append.length > 0);
|
|
}
|
|
}
|
|
const getPostList = async (zid, activeKey, offset) => {
|
|
try {
|
|
setLoading(true);
|
|
let body = {
|
|
zid: zid,
|
|
ct_upper_bound: Math.floor(new Date().getTime() / 1000),
|
|
offset,
|
|
limit: 4,
|
|
};
|
|
switch (activeKey) {
|
|
case "all":
|
|
body = body;
|
|
break;
|
|
case "ironFan":
|
|
body = {
|
|
...body,
|
|
c_type: 1,
|
|
is_ironfan_visible: 1,
|
|
};
|
|
break;
|
|
case "chaofen":
|
|
body = {
|
|
...body,
|
|
c_type: 1,
|
|
};
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
const data = await require("POST", "/api/zone_moment/list_by_zid", {
|
|
body,
|
|
});
|
|
if (data.ret === -1) {
|
|
Toast.show({
|
|
icon: "fail",
|
|
content: data.msg,
|
|
position: "top",
|
|
});
|
|
return;
|
|
}
|
|
|
|
setLoading(false);
|
|
setOffset(offset + 1);
|
|
return data.data.list;
|
|
} catch (error) {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
const firstRequest = (currentKey) => {
|
|
let floatingPanel = document.getElementsByClassName(
|
|
"adm-floating-panel-content"
|
|
)[0];
|
|
floatingPanel?.scrollTo(0, 0);
|
|
setOffset(0);
|
|
setHasMore(true);
|
|
if (streamerInfo) {
|
|
getPostList(streamerInfo.id, currentKey, 0).then((res) => {
|
|
setPostList(res || []);
|
|
});
|
|
}
|
|
};
|
|
return (
|
|
<div className="">
|
|
<div className="flex justify-between items-center p-4 fixed top-0 z-10 w-full">
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full">
|
|
<FontAwesomeIcon
|
|
icon={faAngleLeft}
|
|
size="xl"
|
|
onClick={() => {
|
|
router.back();
|
|
}}
|
|
/>
|
|
</div>
|
|
<Image
|
|
width={42}
|
|
height={42}
|
|
src="/icons/setting.png"
|
|
placeholder=""
|
|
onClick={() => router.push("setting")}
|
|
/>
|
|
</div>
|
|
{/* 内容 */}
|
|
<div>
|
|
<div
|
|
className="bg-no-repeat bg-cover bg-fixed "
|
|
style={{
|
|
backgroundImage:
|
|
streamerInfo?.streamer_ext?.cover?.images[0]?.urls[0],
|
|
}}
|
|
>
|
|
<div className="px-4 pt-24 pb-8 bg-[#181818a9]">
|
|
<div className="flex justify-between items-center">
|
|
<div className="flex items-center">
|
|
<Image
|
|
width="64px"
|
|
height="64px"
|
|
className="rounded-full mr-2 border-2 border-white"
|
|
fit="cover"
|
|
src={streamerInfo?.streamer_ext?.avatar?.images[0]?.urls[0]}
|
|
/>
|
|
<div>
|
|
<p className="text-2xl mb-1 font-bold">
|
|
{streamerInfo?.streamer_ext?.name}
|
|
</p>
|
|
<div className="flex">
|
|
<div className="h-4 flex items-center text-xs bg-[#ffffff18] rounded-full px-2 py-2.5 mb-1 w-max mr-1">
|
|
<Image
|
|
src="/icons/info/ID.png"
|
|
width={14}
|
|
height={14}
|
|
className="w-4 h-full mr-1"
|
|
placeholder=""
|
|
/>
|
|
<span>{streamerInfo?.streamer_ext?.user_id}</span>
|
|
</div>
|
|
<div className="h-4 flex items-center text-xs bg-[#ffffff18] rounded-full px-2 py-2.5 mb-1 w-max">
|
|
<Image
|
|
src="/icons/edit.png"
|
|
width={14}
|
|
height={14}
|
|
className="w-4 h-full mr-1"
|
|
placeholder=""
|
|
/>
|
|
<span>{streamerInfo?.zone_moment_count}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
className="flex flex-col items-center"
|
|
// onClick={() => setMaskVisible(true)}
|
|
>
|
|
<p className="text-base px-3 py-1 rounded-full bg-primary">
|
|
分享
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<ul className="flex mt-8">
|
|
<li
|
|
className="flex flex-col items-center mr-6"
|
|
onClick={() =>
|
|
setMaskVisible({ visible: true, type: "weChat" })
|
|
}
|
|
>
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#1d1d1d71] rounded-full mb-1">
|
|
<Image
|
|
src="/images/wechat.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
<p className="text-xs">查看微信</p>
|
|
</li>
|
|
<li
|
|
className="flex flex-col items-center mr-6"
|
|
onClick={() =>
|
|
setMaskVisible({ visible: true, type: "ironFan" })
|
|
}
|
|
>
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#1d1d1d71] rounded-full mb-1">
|
|
<Image
|
|
src="/icons/tiefen.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
<p className="text-xs">
|
|
{streamerInfo?.is_ironfanship_unlocked === 1
|
|
? "已是铁粉"
|
|
: "成为铁粉"}
|
|
</p>
|
|
<p className="text-[#ffffff54] text-[10px]">{`${parseInt(
|
|
streamerInfo?.expenditure / 100,
|
|
10
|
|
)}/${parseInt(streamerInfo?.ironfanship_price / 100, 10)}`}</p>
|
|
</li>
|
|
<li
|
|
className="flex flex-col items-center mr-6"
|
|
onClick={() => {
|
|
streamerInfo?.is_superfanship_unlocked === 1
|
|
? setCurrentKey("chaofen")
|
|
: router.push("/pay");
|
|
}}
|
|
>
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#1d1d1d71] rounded-full mb-1">
|
|
<Image
|
|
src="/icons/chaofen.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
<p className="text-xs">
|
|
{streamerInfo?.is_superfanship_unlocked === 1
|
|
? "尊贵超粉"
|
|
: "成为超粉"}
|
|
</p>
|
|
</li>
|
|
<li
|
|
className="flex flex-col items-center"
|
|
// onClick={() => setMaskVisible(true)}
|
|
>
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#1d1d1d71] rounded-full mb-1">
|
|
<Image
|
|
src="/icons/report.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
<p className="text-xs">举报</p>
|
|
</li>
|
|
{streamerInfo?.visitor_role === 3 && (
|
|
<li
|
|
onClick={() => router.push("VisibleToOneselfSpacePosts")}
|
|
className="flex flex-col items-center"
|
|
>
|
|
<Image
|
|
src="/icons/review_fail_bg.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
<p className="text-xs">审核未通过</p>
|
|
</li>
|
|
)}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<FloatingPanel anchors={anchors} ref={scrollRef} className="bg-deepBg">
|
|
<JumboTabs
|
|
onChange={(key) => setCurrentKey(key)}
|
|
activeKey={currentKey}
|
|
className="bg-deepBg pb-12"
|
|
>
|
|
{tabItems.map((it) => (
|
|
<JumboTabs.Tab
|
|
title={it.label}
|
|
key={it.key}
|
|
description={
|
|
currentKey == it.key && (
|
|
<div className="titlePinkLine relative w-full"></div>
|
|
)
|
|
}
|
|
destroyOnClose={true}
|
|
>
|
|
<div className="overflow-y-auto scrollbarBox_hidden px-1">
|
|
<List>
|
|
{loading && (
|
|
<>
|
|
<PostItemSkeleton />
|
|
<PostItemSkeleton />
|
|
<PostItemSkeleton />
|
|
<PostItemSkeleton />
|
|
</>
|
|
)}
|
|
{!postList.length && (
|
|
<div
|
|
className={`flex flex-col items-center mt-20`}
|
|
style={{ height: `${scrollHeight}px` }}
|
|
>
|
|
<Empty type="nodata" />
|
|
</div>
|
|
)}
|
|
{postList.map((item, index) => (
|
|
<List.Item key={item.id + "_" + index} className="!p-0">
|
|
<PostItem type="space" data={item} />
|
|
</List.Item>
|
|
))}
|
|
<InfiniteScroll loadMore={loadMore} hasMore={hasMore} />
|
|
</List>
|
|
</div>
|
|
</JumboTabs.Tab>
|
|
))}
|
|
</JumboTabs>
|
|
</FloatingPanel>
|
|
<div
|
|
className={`fixed bottom-[96px] right-4 z-[999] w-10 h-10 flex items-center justify-center bg-[#1d1d1d71] rounded-full text-white ${
|
|
loading && !offset ? "animate-spin" : ""
|
|
}`}
|
|
>
|
|
<FontAwesomeIcon
|
|
icon={faRefresh}
|
|
size="xl"
|
|
// onClick={() => {
|
|
// router.refresh();
|
|
// }}
|
|
onClick={() => {
|
|
firstRequest();
|
|
}}
|
|
/>
|
|
</div>
|
|
<ul className="grid grid-cols-3 mt-8 px-4 py-2 fixed bottom-0 z-[999] bg-deepBg w-full border-t-2 border-[#FFFFFF1A]">
|
|
<li
|
|
className="flex flex-col items-center"
|
|
onClick={() => setMaskVisible({ visible: true, type: "weChat" })}
|
|
>
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#1d1d1d71] rounded-full mb-1">
|
|
<Image
|
|
src="/images/wechat.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
<p className="text-xs">查看微信</p>
|
|
</li>
|
|
<li
|
|
className="flex flex-col items-center"
|
|
onClick={() => setMaskVisible({ visible: true, type: "ironFan" })}
|
|
>
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#1d1d1d71] rounded-full mb-1">
|
|
<Image
|
|
src="/icons/tiefen.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
<p className="text-xs">
|
|
{" "}
|
|
{streamerInfo?.is_ironfanship_unlocked === 1
|
|
? "已是铁粉"
|
|
: "成为铁粉"}
|
|
</p>
|
|
{/* <p className="text-[#ffffff54] text-[10px]">0/299</p> */}
|
|
</li>
|
|
<li
|
|
className="flex flex-col items-center"
|
|
onClick={() => {
|
|
setCurrentKey("chaofen");
|
|
}}
|
|
>
|
|
<div className="w-9 h-9 flex items-center justify-center bg-[#1d1d1d71] rounded-full mb-1">
|
|
<Image
|
|
src="/icons/chaofen.png"
|
|
width={22}
|
|
height={22}
|
|
className="w-4 h-full"
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
<p className="text-xs">
|
|
{streamerInfo?.is_superfanship_unlocked === 1
|
|
? "尊贵超粉"
|
|
: "成为超粉"}
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
{maskVisible.type == "weChat" && (
|
|
<AddWeChat
|
|
visible={maskVisible.visible}
|
|
closeMask={(close) => setMaskVisible({ visible: false, type: "" })}
|
|
price={streamerInfo?.streamer_ext?.wechat_coin_price}
|
|
name={streamerInfo?.streamer_ext?.name}
|
|
streamerMid={streamerInfo?.streamer_ext?.mid}
|
|
avatar={streamerInfo?.streamer_ext?.avatar?.images[0]?.urls[0]}
|
|
streamerData={streamerInfo}
|
|
/>
|
|
)}
|
|
{maskVisible.type == "ironFan" && (
|
|
<SeeTiefen
|
|
visible={maskVisible.visible}
|
|
ironFanProgress={ironFanProgress}
|
|
expenditure={streamerInfo.expenditure}
|
|
ironfanship_price={streamerInfo.ironfanship_price}
|
|
closeMask={() => {
|
|
setMaskVisible({ visible: false, type: "" });
|
|
}}
|
|
handleClick={() => {
|
|
setCurrentKey("ironFan");
|
|
setMaskVisible({ visible: false, type: "" });
|
|
}}
|
|
/>
|
|
)}
|
|
<DefaultMask
|
|
title="当前空间正在退款中"
|
|
content="退款中空间不支持查看,请关注原支付渠道退款进度,退款后无法再次进入当前空间。"
|
|
visible={isRefundingModalVisible}
|
|
closeMask={() => {
|
|
setIsRefundingModalVisible(false);
|
|
// setTimeout(() => navigation.replace("HomeTab"), 500);
|
|
}}
|
|
/>
|
|
{/* <div className="flex justify-center items-center px-4 py-4 fixed bottom-0 bg-deepBg w-full border-t-2 border-[#FFFFFF1A]">
|
|
<div className="bg-primary px-10 py-1 text-base rounded-full">
|
|
<div
|
|
className="flex items-center py-2 text-base"
|
|
onClick={() => {
|
|
router.push("/pay");
|
|
}}
|
|
>
|
|
<Image
|
|
width={18}
|
|
height={18}
|
|
placeholder=""
|
|
className="mr-2"
|
|
src="/icons/money_pink.png"
|
|
/>
|
|
<span>39.9元立即加入</span>
|
|
<FontAwesomeIcon
|
|
icon={faAngleRight}
|
|
size="xl"
|
|
className="h-4 ml-2"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div> */}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|