tiefen_space_h5/components/PostItem/index.js

270 lines
9.4 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, useState, useMemo } from "react";
import Photos from "../Photos";
import { useRouter } from "next/navigation";
import PaySpacePost from "../PaySpacePost";
import { Image, Popover, Divider } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons";
import { handleFollow, thumbsUp } from "@/api/public";
import { get } from "@/utils/storeInfo";
export default function PostItem({
type,
follow,
date = new Date(),
data = {},
}) {
const router = useRouter();
const [isOpenText, setIsOpenText] = useState(false);
const [isFollow, setIsFollow] = useState(data.is_followed);
const [isThumbsUp, setIsThumbsUp] = useState(
data?.is_thumbed_up || data?.is_zone_moment_thumbed_up
);
//判断是否是发帖人
const [isCreator, setIsCreator] = useState(false);
useEffect(() => {
const account = get("account");
if (account.mid === data.mid) setIsCreator(true);
return () => {
router.prefetch("/profile/" + data.mid);
};
}, []);
const getDays = useMemo(() => {
const today = new Date();
const days = Math.floor((today - data.ct) / (1000 * 60 * 60 * 24));
return days;
}, []);
function findLinksInText(text) {
// 定义一个正则表达式来匹配URL
// 注意这个正则表达式可能无法匹配所有可能的URL但可以匹配大部分常见的格式
var urlPattern = /https?:\/\/[^\s\/$.?#].[^\s]*/g;
// 使用正则表达式的exec或match方法查找匹配项
// exec在全局搜索中需要循环调用而match在全局模式下直接返回所有匹配项
var matches = text?.match(urlPattern);
// // 如果没有找到匹配项,返回空数组
// if (!matches) {
// return text;
// }
if (matches) {
matches?.forEach((el) => {
// console.log("index", text.indexOf(el));
text = text.replace(
el,
`<a class="text-btn" href="${el}" target="_blank">#网页链接</a>`
);
});
// console.log("matches", matches);
// console.log("text", text);
}
// 返回找到的链接数组
return text;
}
return (
<div>
{type == "space" && data?.is_headed === 1 && (
<Image src="/images/top_post.png" width={76} className="mb-2" />
)}
<div className="flex">
<Image
className="flex-none w-8 h-8 rounded-full mr-2"
fit="cover"
src={data.streamer_ext?.avatar.images[0].urls[0]}
alt=""
onClick={() => router.push("/profile/" + data.mid)}
/>
<div className="flex-1">
<div
className="flex justify-between items-center"
onClick={() => handleFollow(isFollow, data?.mid, setIsFollow)}
>
<span className="font-bold text-md">{data.streamer_ext?.name}</span>
{type == "post" && (
<span className="rounded-full bg-[#FFFFFF1A] px-2 py-1 text-xs text-white font-medium">
{isFollow ? "已关注" : "关注"}
</span>
)}
</div>
<div>
{!data?.is_zone_moment_unlocked ? (
<>
<pre
dangerouslySetInnerHTML={{
__html: findLinksInText(data.text),
}}
className={`mb-2 mt-2 ${!isOpenText ? "text-ellipsis-7" : ""}`}
// style={{
// WebkitLineClamp: data?.text_visible_range < 999?data?.text_visible_range:7,
// }}
></pre>
</>
) : (
<div>
<pre
className={`mb-2 mt-2 ${!isOpenText ? "text-ellipsis-7" : ""}`}
dangerouslySetInnerHTML={{
__html: findLinksInText(data.text),
}}
style={{
WebkitLineClamp: data?.text_visible_range < 999?data?.text_visible_range:7,
}}
></pre>
</div>
)}
{!(
!data?.is_zone_moment_unlocked && data?.text_visible_range < 999
) &&
data.text?.length > 140 && (
<div
className="font-bold text-btn my-4 text-base"
onClick={() => setIsOpenText(!isOpenText)}
>
{isOpenText ? "收起" : "全文"}
</div>
)}
</div>
<div className="mr-8">
{data.media_component && (
<Photos
data={data}
media={data.media_component}
isUnlocked={data.is_zone_moment_unlocked}
mediaAmount={data.media_amount}
type={type}
/>
)}
{type == "space" && !!data.c_type && (
<PaySpacePost
type={data.is_ironfan_visible ? "ironFan" : "superFan"}
price={data.price / 100}
status={data.is_ironfanship_unlocked}
ironfanship_price={data.ironfanship_price / 100}
is_zone_moment_unlocked={data.is_zone_moment_unlocked}
data={data}
isCreator={isCreator}
/>
)}
</div>
<div className="flex justify-between items-center mt-2">
{type == "post" ? (
<div
className="flex items-center"
onClick={() =>
router.push("/space/person_space_introduce/" + data.mid)
}
>
{data.is_active_within_a_week ? (
<>
<Image
src="/icons/space_new_post.png"
width={18}
className="w-4 h-full mr-1"
placeholder=""
/>
<span className="mr-1 text-primary text-xs">
{data.days_elapsed_since_the_last_zones_update < 7 &&
`空间${
data.days_elapsed_since_the_last_zones_update === 0
? "今日"
: "new" === 1
? "昨日"
: "new" === 2
? "前天"
: data.days_elapsed_since_the_last_zones_update +
"天前"
}有更新`}
</span>
<FontAwesomeIcon
icon={faAngleRight}
color="#FF669E"
size="sm"
/>
</>
) : (
data?.streamer_ext?.zones?.length !== 0 && (
<div className="text-[#FFFFFFB2] font-medium text-xs flex items-center">
<span className="mr-1">查看TA的空间</span>
<FontAwesomeIcon icon={faAngleRight} size="sm" />
</div>
)
)}
</div>
) : (
<div className="text-[#ffffff88] text-xs">
<span className="mr-2">
{getDays < 3
? `${
getDays === 0 ? "今日" : "new" === 1 ? "昨日" : "前天"
}`
: date.getMonth() + 1 + "月" + date.getDate() + "日"}
</span>
<span>
{(date.getHours() > 9
? date.getHours()
: "0" + date.getHours()) +
":" +
(date.getMinutes() > 9
? date.getMinutes()
: "0" + date.getMinutes())}
</span>
</div>
)}
<div className="flex items-center">
<div
className="flex items-center mr-4 h-[32px]"
onClick={() =>
thumbsUp(data.id, isThumbsUp, setIsThumbsUp, type == "space")
}
>
<Image
src={
isThumbsUp == 1
? "/icons/thumbup.png"
: "/icons/notthumbup.png"
}
width={32}
className="w-4 h-full"
placeholder=""
/>
<span
className={`text-xs ${
isThumbsUp == 1 ? "text-[#FF669E]" : "text-[#FFFFFF80]"
}`}
>
{isThumbsUp == 1 ? "已赞" : "点赞"}
</span>
</div>
<Popover
style={{ "--background": "#1E1C29" }}
content={
<ul>
<li
className="py-1 px-4"
onClick={() => {
router.push("/messageDetail");
}}
>
举报
</li>
</ul>
}
trigger="click"
placement="left"
>
<span className="mr-2">···</span>
</Popover>
</div>
</div>
{/* <div className="rounded-full h-px bg-gray-200 mt-2"></div> */}
</div>
</div>
</div>
);
}