tiefen_space_h5/app/space/page.js

280 lines
8.5 KiB
JavaScript

"use client";
import React, { useEffect, useRef, useState,useRef } from "react";
import { Tabs, Swiper, Toast, Image, List, InfiniteScroll } from "antd-mobile";
import PostItem from "@/components/PostItem";
import "./index.css";
import Link from "next/link";
import Empty from "@/components/Empty";
import { useRouter } from "next/navigation";
import PostItemSkeleton from "@/components/skeletons/PostItemSkeleton";
import require from "@/utils/require";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faRefresh } from "@fortawesome/free-solid-svg-icons";
const tabItems = [
{ key: "space", title: "空间" },
{ key: "post", title: "动态" },
];
// const scrollHeight = 700;
// const scrollHeight = window.innerHeight-126
export default function Space() {
const swiperRef = useRef(null);
const [activeIndex, setActiveIndex] = useState(0);
const [dataList, setDataList] = useState([]);
// const [spacePost, setSpacePost] = useState([]);
const [hasMore, setHasMore] = useState(true);
const [scrollHeight, setScrollHeight] = useState(0);
const [offset, setOffset] = useState(0);
const [loading, setLoading] = useState(false);
const scrollRef = useRef(null);
// 获取屏幕高度
// const scrollHeight = 600;
useEffect(() => {
setScrollHeight(window.innerHeight - 57);
// const handleResize = () => {
// setScrollHeight(window.innerHeight - 126);
// };
// window.addEventListener("resize", handleResize);
// return () => {
// // window.removeEventListener("resize", handleResize);
// };
}, []);
useEffect(() => {
firstRequest()
}, [activeIndex]);
const firstRequest = () => {
resetOffset();
if (activeIndex === 0) {
getSpaceList();
}
if (activeIndex === 1) {
getSpacePosts(0).then((res) => {
setDataList(res);
});
}
}
const resetOffset = () => {
setOffset(0);
// setDataList([]);
};
const getSpaceList = async () => {
setLoading(true);
try {
const data = await require("POST", "/api/zone/list_by_visitor_mid");
setLoading(false);
if (data.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
//在末尾添加元素以展示查看更多卡片
if (data.data.list.length !== 0) {
const finalData = [...data.data.list, { id: 999999, last: true }];
setDataList(finalData);
return;
}
} catch (error) {
console.error(error);
}
};
const getSpacePosts = async (offset) => {
setLoading(true);
try {
const data =
await require("POST", "/api/zone_moment/list_by_visitor_mid", {
body: { offset, limit: 4 },
});
setLoading(false);
if (data.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
//在末尾添加元素以展示查看更多卡片
if (data.data.list.length !== 0) {
const finalData = [...data.data.list];
setOffset(offset + 1);
return finalData;
}
} catch (error) {
console.error(error);
}
};
async function loadMore() {
if (!offset) return;
const append = await getSpacePosts(offset);
if(append){
setDataList((val) => [...val, ...append]);
setHasMore(append.length > 0);
}
}
return (
<div className="h-screen overflow-x-hidden" style={{ maxHeight: `${scrollHeight}px` }}>
<div className="flex justify-between items-center px-2 custom-tabs text-gray-400 sticky top-0 z-10 bg-deepBg">
<Tabs
activeKey={tabItems[activeIndex].key}
onChange={(key) => {
const index = tabItems.findIndex((item) => item.key === key);
setActiveIndex(index);
swiperRef.current?.swipeTo(index);
}}
>
{tabItems.map((item) => (
<Tabs.Tab
forceRender={false}
title={item.title}
key={item.key}
className="text-left"
/>
))}
</Tabs>
<Link
href="search"
className="w-9 h-9 flex items-center justify-center bg-[#FFFFFF1A] rounded-full"
>
<Image src="/icons/search.png" />
</Link>
</div>
<Swiper
direction="horizontal"
indicator={() => null}
ref={swiperRef}
defaultIndex={activeIndex}
onIndexChange={(index) => {
setActiveIndex(index);
}}
>
<Swiper.Item>
{!activeIndex && (
<div
className="px-4 pb-8"
>
<ul className="grid grid-cols-2 gap-2 overflow-y-auto">
{dataList.map((item) => (
<li key={item.id}>
<VisitingCard data={item} />
</li>
))}
</ul>
{!dataList.length && (
<div
className={`flex flex-col items-center justify-center`}
style={{ height: `${scrollHeight}px` }}
>
<Empty type="nospace" />
<div className="flex flex-col mt-6">
<Link
href="/search"
className="bg-[#FFFFFF40] px-12 py-2 rounded-full text-base text-white"
>
搜索空间
</Link>
<Link
href="/search"
className="bg-[#FFFFFF40] px-12 py-2 rounded-full text-base text-white mt-2"
>
查看推荐
</Link>
</div>
</div>
)}
</div>
)}
</Swiper.Item>
<Swiper.Item>
{activeIndex &&
<div
className="px-4 pb-8"
ref={scrollRef}
>
<List
className="scrollbarBox_hidden"
>
{loading && (
<>
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
<PostItemSkeleton />
</>
)}
{dataList.map((item, index) => (
<List.Item className="!p-0" key={item.id + "_" + index}>
<PostItem type="space" data={item} />
</List.Item>
))}
<InfiniteScroll loadMore={loadMore} hasMore={hasMore} />
</List>
{!dataList.length && (
<div
className={`flex flex-col items-center justify-center`}
style={{ height: `${scrollHeight}px` }}
>
<Empty type="nodata" />
</div>
)}
</div>
}
</Swiper.Item>
</Swiper>
<div
className={`fixed bottom-[78px] 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={firstRequest}
onClick={()=>{scrollRef.current?.scrollTo(0, 0); firstRequest();}}
/>
</div>
</div>
);
}
const VisitingCard = ({ data }) => {
const router = useRouter();
return (
<div
className="relative h-60"
onClick={() => router.push("/space/" + data?.streamer_ext?.mid)}
>
{data?.is_unread_zone_moment_exist === 1 && (
<Image
src="/images/space_new.png"
width={78}
fit="contain"
className="absolute top-2 right-2"
/>
)}
<Image
width={"100%"}
height={"100%"}
src={data?.streamer_ext?.cover.images[0].urls[0]}
fit="cover"
className="rounded-lg"
/>
<div className="absolute bottom-0 left-0 w-full px-2 py-3 bg-[#1b1b1b] flex items-center rounded-b-lg">
<span className="font-bold">{data?.streamer_ext?.name}</span>
<ul className="ml-2">
{data?.admission_price !== 0 && (
<li className="text-[10px] bg-primary rounded px-1 mr-1">付费</li>
)}
{data.visitor_role === 3 && (
<li className="text-[10px] bg-primary rounded px-1 mr-1">付费</li>
)}
</ul>
</div>
</div>
);
};