tiefen_space_h5/app/profile/[mid]/page.js

588 lines
21 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, { useEffect, useRef, useState } from "react";
import { Image, Swiper, Divider, Popover, Toast } from "antd-mobile";
import { useRouter, useParams } from "next/navigation";
import Link from "next/link";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faAngleLeft,
faAngleRight,
faEllipsisVertical,
faWarning,
faCircleMinus,
} from "@fortawesome/free-solid-svg-icons";
import requireAPI from "@/utils/requireAPI";
import AddWeChat from "@/components/AddWeChat";
import { handleFollow, checkRelation, handleBlock } from "@/api/public";
import { getStreamerDetailInfo } from "@/api/space";
import { get } from "@/utils/storeInfo";
import { handleShowVideo } from "@/utils/tools/handleFuns";
import clipboard from "copy-to-clipboard";
import ImagesMask from "@/components/ImagesMask";
// import * as Clipboard from "expo-clipboard";
export default function PersonSpace() {
const { mid } = useParams();
const router = useRouter();
const [streamerInfo, setStreamerInfo] = useState(null);
const [spaceData, setSpaceData] = useState(null);
const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false);
const [isFollow, setIsFollow] = useState(false);
const [topPhotos, setTopPhotos] = useState([]);
const [account, setAccount] = useState([]);
const currentIndex = useRef();
const imagesMaskRef = useRef(null);
// 获取屏幕高度
// const scrollHeight = 600;
useEffect(() => {
handleGetStreamerInfo();
getSpaceData();
getRelationData();
const account = get("account");
setAccount(account);
}, []);
const showPhotos = (photos, index) => {
currentIndex.current = index;
imagesMaskRef.current.show(photos, index, streamerInfo);
};
const handleGetStreamerInfo = async () => {
try {
setLoading(true);
const data = await getStreamerDetailInfo(Number(mid));
setStreamerInfo({
...data,
});
const photosArr = [
...data?.streamer_ext?.cover?.images?.map((item) => ({
url: item.urls[0],
type: "video",
})),
...data?.streamer_ext?.album?.images.map((item) => ({
url: item.urls[0],
type: "img",
})),
];
// console.log("photosArr", photosArr);
setTopPhotos(photosArr);
setLoading(false);
} catch (error) {
// console.error(error);
}
};
const getSpaceData = async () => {
try {
const data = await requireAPI("POST", "/api/zone/list_by_mid", {
body: {
mid: Number(mid),
},
});
if (data.ret === -1) {
Toast.show({
icon: "fail",
content: data.msg,
position: "top",
});
return;
}
setSpaceData(data.data.list[0]);
} catch (error) {
// console.error(error);
}
};
const getRelationData = async () => {
const account = get("account");
const subMid = account.mid;
const objMid = Number(mid);
const temIsFollowed = await checkRelation(subMid, objMid, 0);
setIsFollow(temIsFollowed);
};
//保存内容到剪贴板
const copy = (_data) => {
// console.log("_data", _data);
clipboard(_data);
Toast.show({
icon: "success",
content: "已复制到剪贴板",
position: "top",
});
};
return (
<div className="h-screen overflow-x-hidden overflow-y-auto">
<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"
style={{ maxWidth: "12px" }}
onClick={() => {
router.back();
}}
/>
</div>
{get("account")?.mid != mid && (
<Popover
stopPropagation={["click", "touchstart"]}
destroyOnHide={true}
style={{ "--background": "#1E1C29" }}
content={
<ul>
<li
onClick={async () => {
const account = await get("account");
const subMid = account.mid;
const objMid = mid;
handleBlock(subMid, Number(mid));
}}
>
<FontAwesomeIcon
icon={faCircleMinus}
// size="xl"
color="#f87171"
className="mr-4"
/>
<span>拉黑</span>
</li>
<hr className="border-[#ffffff2b] my-1" />
<li
onClick={() => {
router.push("/messageDetail");
}}
>
<FontAwesomeIcon
icon={faWarning}
// size="xl"
color="#3B69B8"
className="mr-4"
/>
<span>举报</span>
</li>
</ul>
}
trigger="click"
placement="left"
>
<div className="w-[36px] flex justify-center">
<FontAwesomeIcon
icon={faEllipsisVertical}
size="xl"
style={{ maxWidth: "5px" }}
/>
</div>
</Popover>
)}
</div>
{/* 内容 */}
<div className="overflow-y-auto">
<div className="min-h-[60px]">
{!!topPhotos.length && (
<Swiper
autoplay
loop
indicatorProps={{
style: {
"--dot-color": "#FF669E30",
"--active-dot-color": "#FF669E",
},
}}
>
{topPhotos.map((photo, index) => (
<Swiper.Item key={index}>
<div
className="relative min-w-full max-w-[100vw]"
key={index}
onClick={() => {
if (photo.type == "video") {
handleShowVideo({
url: streamerInfo?.streamer_ext?.shorts?.videos[0]
?.cover_urls[0],
mp4: streamerInfo?.streamer_ext?.shorts?.videos[0]
?.urls[0],
});
} else {
showPhotos(
topPhotos.filter((it) => it.type == "img"),
topPhotos
.filter((it) => it.type == "img")
.indexOf(photo)
);
}
}}
>
<Image
className="h-12 w-full"
fit="cover"
height={320}
src={photo?.url}
// onClick={() => {
// Toast.show(`你点击了卡片 ${index + 1}`);
// }}
/>
{photo.type == "video" && (
<div className="absolute top-0 w-full h-full flex justify-center items-center bg-[#33333348]">
<Image
className=""
width={98}
height={98}
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/play.png"
}
/>
</div>
)}
</div>
</Swiper.Item>
))}
</Swiper>
)}
</div>
<div className="p-4 pb-24">
<div>
<div className="mb-2">
<div className="flex items-center mb-2">
<p className="text-2xl mr-2">
{streamerInfo?.streamer_ext?.name}
</p>
<div className="w-5 h-5">
<Image
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/verification.png"
}
/>
</div>
</div>
<ul className="flex">
{streamerInfo?.streamer_ext?.tag?.map((item, index) => (
<li
key={index}
className="rounded-md bg-primary mr-2 px-2 py-1 text-xs mb-1"
>
{item}
</li>
))}
</ul>
</div>
<div>
<ul className="flex mb-1 flex-wrap">
<li className="h-4 flex items-center text-xs bg-[#FFFFFF1A] rounded-full px-2 py-2.5 mb-1 mr-1">
<Image
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/ID.png"
}
width={14}
height={14}
className="w-4 h-full mr-1"
/>
<span>{streamerInfo?.streamer_ext?.user_id}</span>
</li>
<li className="h-4 flex items-center text-xs bg-[#FFFFFF1A] rounded-full px-2 py-2.5 mb-1 mr-1">
<Image
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/fan.png"
}
width={14}
height={14}
className="w-4 h-full mr-1"
/>
<span className="text-white text-xs font-medium ml-0.5">
{`全网粉丝 : ${streamerInfo?.streamer_ext?.fans || 0}`}
</span>
</li>
{streamerInfo?.streamer_ext?.age && (
<li className="h-4 flex items-center text-xs bg-[#FFFFFF1A] rounded-full px-2 py-2.5 mb-1 mr-1">
{streamerInfo?.streamer_ext?.gender === 1 ? (
<Image
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/female.png"
}
width={14}
height={14}
className="w-4 h-full mr-1"
/>
) : (
<Image
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/male.png"
}
width={14}
height={14}
className="w-4 h-full mr-1"
/>
)}
<span className="text-white text-xs font-medium ml-0.5">
{streamerInfo?.streamer_ext?.age}
</span>
</li>
)}
{streamerInfo?.streamer_ext?.height && (
<li className="h-4 flex items-center text-xs bg-[#FFFFFF1A] rounded-full px-2 py-2.5 mb-1 mr-1">
<Image
width={14}
height={14}
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/height.png"
}
className="w-4 h-full mr-1"
/>
<span className="text-white text-xs font-medium ml-0.5">
{`${streamerInfo?.streamer_ext?.height}cm`}
</span>
</li>
)}
{streamerInfo?.streamer_ext?.weight && (
<li className="h-4 flex items-center text-xs bg-[#FFFFFF1A] rounded-full px-2 py-2.5 mb-1 mr-1">
<Image
width={14}
height={14}
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/weight.png"
}
className="w-4 h-full mr-1"
/>
<span className="text-white text-xs font-medium ml-0.5">
{`${streamerInfo?.streamer_ext?.weight}kg`}
</span>
</li>
)}
{streamerInfo?.streamer_ext?.constellation && (
<li className="h-4 flex items-center text-xs bg-[#FFFFFF1A] rounded-full px-2 py-2.5 mb-1 mr-1">
<Image
width={14}
height={14}
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/constellation.png"
}
className="w-4 h-full mr-1"
/>
<span className="text-white text-xs font-medium ml-0.5">
{streamerInfo?.streamer_ext?.constellation}
</span>
</li>
)}
{streamerInfo?.streamer_ext?.city && (
<li className="h-4 flex items-center text-xs bg-[#FFFFFF1A] rounded-full px-2 py-2.5 mb-1 mr-1">
<Image
width={14}
height={14}
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/info/location.png"
}
className="w-4 h-full mr-1"
/>
<span className="text-white text-xs font-medium ml-0.5">
{streamerInfo?.streamer_ext?.city}
</span>
</li>
)}
</ul>
{streamerInfo?.streamer_ext?.bio && (
<div
className="whitespace-pre-wrap"
style={{ overflowWrap: "anywhere" }}
>
<span className="text-[#ffffff88]">个性签名</span>
{streamerInfo?.streamer_ext?.bio}
</div>
)}
</div>
</div>
{spaceData && !!spaceData?.previews?.images?.length && (
<>
<Divider />
<div>
<div
onClick={() =>
router.push(
spaceData?.visitor_role === 4
? `/space/person_space_introduce/${mid}`
: `/space/${mid}`
)
}
>
<div className="flex justify-between items-center mb-2">
<span className="font-bold text-base">空间动态</span>
<div className="h-4 text-xs text-[#ffffff88]">
<span className="mr-2">
查看{spaceData?.zone_moment_count}
</span>
<FontAwesomeIcon
icon={faAngleRight}
size="xl"
style={{ maxWidth: "12px" }}
className="h-4"
onClick={() => {
router.back();
}}
/>
</div>
</div>
<div className="flex ">
{spaceData?.previews?.images
?.slice(0, 4)
.map((item, index) => (
<div
key={item.id}
className="w-20 h-20 overflow-hidden rounded mr-1"
>
<Image
width="20vw"
height="20vw"
className={`rounded mr-2 ${
spaceData?.visitor_role === 4 && "imageBlur"
}`}
fit="cover"
src={item.urls[0]}
/>
</div>
))}
</div>
</div>
</div>
</>
)}
<>
<Divider />
<div>
<p className="font-bold mb-2 text-base">来这找我玩</p>
<ul>
<li className="flex justify-between border-[1.5px] border-[#ffffff43] rounded-xl p-2 mb-2">
<div className="flex justify-between items-center">
<Image
height={32}
width={32}
className="mr-2"
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/images/platform_wechat.png"
}
/>
<div className="text-base">
<span>微信</span>
<span
className="text-[#3B69B8]"
onClick={() => setVisible(true)}
>
点击查看
</span>
</div>
</div>
</li>
{streamerInfo?.streamer_ext?.platforms?.map((item) => (
<li
key={item.id}
className="grid gap-1 justify-between border-[1.5px] border-[#ffffff43] rounded-xl p-2"
style={{ gridTemplateColumns: "calc(100% - 130px) 130px" }}
>
<div className="flex items-center">
<Image
height={32}
width={32}
className="mr-2"
src={item?.icon.images[0].urls[0]}
/>
<div className="text-base max-w-28 truncate">
{item?.link_name}{item?.nickname}
</div>
</div>
<div className="flex justify-between text-sm">
<div
className="flex items-center"
onClick={() => {
copy(item.url);
}}
>
{/* <FontAwesomeIcon
icon={faCopy}
size="xl"
className="h-3 mr-1"
/> */}
<Image
height={24}
width={24}
className="mr-1"
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/copy.png"
}
/>
<span className="whitespace-nowrap">复制</span>
</div>
<div className="flex items-center">
{/* <FontAwesomeIcon
icon={faAngleRight}
size="xl"
className="h-3 mr-1"
/> */}
<Image
height={24}
width={24}
className="mr-1"
src={
process.env.NEXT_PUBLIC_WEB_ASSETS_URL +
"/icons/goto.png"
}
/>
<Link href={item?.url} className="whitespace-nowrap">
前往
</Link>
</div>
</div>
</li>
))}
</ul>
</div>
</>
</div>
<div className="flex justify-between items-center px-4 py-4 fixed bottom-0 bg-deepBg w-full border-t-2 border-[#FFFFFF1A]">
<div
className="text-base bg-[#FFFFFF1A] py-2 px-6 rounded-full whitespace-nowrap"
onClick={() => handleFollow(isFollow, Number(mid), setIsFollow)}
>
{isFollow ? "已关注" : "关注"}
</div>
<div
className="text-base bg-[#FFFFFF1A] py-2 px-6 rounded-full whitespace-nowrap"
onClick={() =>
router.push(
"/messageDetail?mid=" + streamerInfo?.streamer_ext?.mid
)
}
>
私聊
</div>
<div
className="bg-primary px-10 py-2 text-base rounded-full whitespace-nowrap"
onClick={() => setVisible(true)}
>
添加微信
</div>
</div>
</div>
<AddWeChat
visible={visible}
closeMask={setVisible}
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}
/>
<ImagesMask ref={imagesMaskRef} />
</div>
);
}