添加启动图和修复一些问题
|
@ -23,6 +23,9 @@ body{
|
|||
font-size: 16px !important;
|
||||
}
|
||||
}
|
||||
/* .adm-image-viewer-slides-inner > *{
|
||||
margin: 0;
|
||||
} */
|
||||
.custom-tabs .adm-tabs {
|
||||
border: none;
|
||||
--active-line-color: #ff8383;
|
||||
|
|
|
@ -77,15 +77,23 @@ export default function RootLayout({ children }) {
|
|||
{/* <!-- 这里要注意,这里图片的尺寸要和设备的静态图片显示尺寸完全对应,差一个像素都会导致启动动画无法显示 --> */}
|
||||
{/* <!-- 下面列举了iPhone的所有尺寸(ps:为了方便大家就全部贴出来了!!) --> */}
|
||||
{/* <!-- iPhone 678 startup image @2x--> */}
|
||||
<link href={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/images/splash.png"} media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/750_1334.png"} media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>
|
||||
{/* <!-- iPhone 678p startup image @3x--> */}
|
||||
<link href={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/images/splash.png"} media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1242_2208.png"} media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
{/* <!-- iPhone X Xs startup image @3x--> */}
|
||||
<link href={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/images/splash.png"} media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1125_2436.png"} media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
{/* <!-- iPhone XR startup image @2X --> */}
|
||||
<link href={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/images/splash.png"} media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/828_1792.png"} media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>
|
||||
{/* <!-- iPhone XR Max startup image @3x--> */}
|
||||
<link href={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/images/splash.png"} media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/640_960.png"} media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/640_1136.png"} media="(device-width: 320px) and (device-height: 568) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1080_1920.png"} media="(device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1080_2340.png"} media="(device-width: 360px) and (device-height: 780px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1170_2532.png"} media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1179_2556.png"} media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1242_2688.png"} media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1284_2778.png"} media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
<link href={"/images/launchPage/1290_2796.png"} media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>
|
||||
</head>
|
||||
<body className={`${inter.className} h-full`}>
|
||||
<main className={`w-full bg-deepBg h-full`}>
|
||||
|
|
|
@ -378,7 +378,7 @@ function Login({ handleLogin }) {
|
|||
</Swiper.Item>
|
||||
</Swiper>
|
||||
</div>
|
||||
{deviceType == "ios" && <BottomBox />}
|
||||
{deviceType != "ios" && <BottomBox />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import styles from "./index.module.scss";
|
|||
import { handleFollow } from "@/api/public";
|
||||
import requireAPI from "@/utils/requireAPI";
|
||||
import InfiniteScrollContent from "@/components/InfiniteScrollContent";
|
||||
import Empty from "@/components/Empty";
|
||||
export default function Relationship() {
|
||||
const [currentKey, setCurrentKey] = useState("");
|
||||
const [hasMore, setHasMore] = useState(1);
|
||||
|
@ -50,11 +49,16 @@ export default function Relationship() {
|
|||
}
|
||||
const getData = async (key, currentOffset) => {
|
||||
// api/account_relation/list_is_followed
|
||||
const followIds = await requireAPI("POST", `/api/account_relation/${
|
||||
key == "follow" ? "list_follow" : "list_is_followed"
|
||||
}`, {
|
||||
body: { offset: currentOffset, limit: 12 },
|
||||
}, true);
|
||||
const followIds = await requireAPI(
|
||||
"POST",
|
||||
`/api/account_relation/${
|
||||
key == "follow" ? "list_follow" : "list_is_followed"
|
||||
}`,
|
||||
{
|
||||
body: { offset: currentOffset, limit: 12 },
|
||||
},
|
||||
true
|
||||
);
|
||||
if (followIds.ret === -1) {
|
||||
Toast.show({
|
||||
icon: "fail",
|
||||
|
@ -64,14 +68,21 @@ export default function Relationship() {
|
|||
return;
|
||||
}
|
||||
setOffset(followIds.data.offset);
|
||||
setHasMore(followIds.data.more)
|
||||
setHasMore(followIds.data.more);
|
||||
if (!followIds.data.list.length) return [];
|
||||
const followsMids = followIds.data.list.map((item) => item.obj_mid);
|
||||
const streamers = await requireAPI("POST", `/api${
|
||||
key == "follow" ? "/streamer/list_ext_by_mids" : "/account/list_others_by_mids"
|
||||
}`, {
|
||||
body: { mids: followsMids, offset: 0, limit: 12 },
|
||||
}, true);
|
||||
const streamers = await requireAPI(
|
||||
"POST",
|
||||
`/api${
|
||||
key == "follow"
|
||||
? "/streamer/list_ext_by_mids"
|
||||
: "/account/list_others_by_mids"
|
||||
}`,
|
||||
{
|
||||
body: { mids: followsMids, offset: 0, limit: 12 },
|
||||
},
|
||||
true
|
||||
);
|
||||
if (streamers.ret === -1) {
|
||||
Toast.show({
|
||||
icon: "fail",
|
||||
|
@ -133,18 +144,26 @@ export default function Relationship() {
|
|||
<div
|
||||
className="grid gap-2 items-center"
|
||||
style={{
|
||||
gridTemplateColumns: "48px calc(100% - 128px) 64px",
|
||||
gridTemplateColumns: "calc(100% - 64px - 2rem) 64px",
|
||||
}}
|
||||
>
|
||||
<Avatar
|
||||
src={item?.avatar?.images[0].urls[0]}
|
||||
style={{ "--border-radius": "50px" }}
|
||||
onClick={()=>router.push("/profile/"+item.mid)}
|
||||
/>
|
||||
<div>
|
||||
<p>{item.name}</p>
|
||||
<p className="text-xs truncate">{item.bio}</p>
|
||||
<div
|
||||
className="grid"
|
||||
onClick={() => router.push("/profile/" + item.mid)}
|
||||
style={{
|
||||
gridTemplateColumns: "48px calc(100% - 48px - 2rem)",
|
||||
}}
|
||||
>
|
||||
<Avatar
|
||||
src={item?.avatar?.images[0].urls[0]}
|
||||
style={{ "--border-radius": "50px" }}
|
||||
/>
|
||||
<div className="ml-2">
|
||||
<p>{item.name}</p>
|
||||
<p className="text-xs truncate">{item.bio}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="text-sm leading-9 h-max bg-[#FFFFFF1A] px-2 rounded-full whitespace-nowrap flex items-center justify-center"
|
||||
onClick={() => cancleFollow(item, index)}
|
||||
|
@ -158,7 +177,11 @@ export default function Relationship() {
|
|||
loadMore={() => loadMore("follow")}
|
||||
hasMore={hasMore}
|
||||
>
|
||||
<InfiniteScrollContent hasMore={hasMore} isEmpty={data.length==0} showNoMore={data.length===0}/>
|
||||
<InfiniteScrollContent
|
||||
hasMore={hasMore}
|
||||
isEmpty={data.length == 0}
|
||||
showNoMore={data.length === 0}
|
||||
/>
|
||||
</InfiniteScroll>
|
||||
</List>
|
||||
{/* {!data.length && <div
|
||||
|
@ -211,7 +234,11 @@ export default function Relationship() {
|
|||
loadMore={() => loadMore("fans")}
|
||||
hasMore={hasMore}
|
||||
>
|
||||
<InfiniteScrollContent hasMore={hasMore} isEmpty={data.length==0} showNoMore={data.length===0}/>
|
||||
<InfiniteScrollContent
|
||||
hasMore={hasMore}
|
||||
isEmpty={data.length == 0}
|
||||
showNoMore={data.length === 0}
|
||||
/>
|
||||
</InfiniteScroll>
|
||||
</List>
|
||||
</JumboTabs.Tab>
|
||||
|
|
|
@ -420,7 +420,7 @@ export default function PersonSpace() {
|
|||
className="grid gap-1 justify-between border-[1.5px] border-[#ffffff43] rounded-xl p-2"
|
||||
style={{gridTemplateColumns:"calc(100% - 130px) 130px"}}
|
||||
>
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<Image
|
||||
height={32}
|
||||
width={32}
|
||||
|
|
|
@ -13,13 +13,16 @@ const newDebounce = debounce(function (fn) {
|
|||
}, 500);
|
||||
export default function Search() {
|
||||
const router = useRouter();
|
||||
const inputRef = useRef();
|
||||
// 获取屏幕高度
|
||||
// const scrollHeight = 600;
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [streamers, setStreamers] = useState([]);
|
||||
// const [zones, setZones] = useState([]);
|
||||
useEffect(() => {}, []);
|
||||
useEffect(() => {
|
||||
inputRef.current?.focus();
|
||||
}, []);
|
||||
|
||||
const isNumeric = (str) => {
|
||||
return /^\d+$/.test(str);
|
||||
|
@ -78,7 +81,9 @@ export default function Search() {
|
|||
<div className="relative bg-[#FFFFFF1A] rounded-lg px-4 py-1 w-full">
|
||||
<Input
|
||||
placeholder="搜索Ta的昵称或id"
|
||||
autoFocus={true}
|
||||
value={searchValue}
|
||||
ref={inputRef}
|
||||
onChange={(val) => {
|
||||
setSearchValue((old) => {
|
||||
let test = (e) => {
|
||||
|
|
|
@ -3,11 +3,18 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Image, ImageViewer, Dialog } from "antd-mobile";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faAngleUp, faClose} from "@fortawesome/free-solid-svg-icons";
|
||||
import { saveFile } from "@/utils/tools/handleFuns";
|
||||
import { faAngleUp, faClose } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useRouter } from "next/navigation";
|
||||
import baseRequest from "@/utils/baseRequest";
|
||||
export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, media, type, data }) {
|
||||
import Player from 'next-video/player';
|
||||
export default function Photos({
|
||||
isUnlocked,
|
||||
mediaVisibleRange,
|
||||
mediaAmount,
|
||||
media,
|
||||
type,
|
||||
data,
|
||||
}) {
|
||||
const [seeAllPhotos, setSeeAllPhotos] = useState(false);
|
||||
const [currentPhotos, setCurrentPhotos] = useState([]);
|
||||
const [photos, setPhotos] = useState([]);
|
||||
|
@ -27,15 +34,18 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
|
|||
let arr = [...imgArr, ...videoArr];
|
||||
let newPhotos = [...arr];
|
||||
if (mediaAmount && !isUnlocked) {
|
||||
console.log("newPhotos",newPhotos)
|
||||
console.log("newPhotos", newPhotos);
|
||||
newPhotos = Array(mediaAmount)
|
||||
.fill(null)
|
||||
.map((item, index) => {
|
||||
return newPhotos[index]
|
||||
&& mediaVisibleRange ? newPhotos[index]
|
||||
: { mp4:newPhotos[0]?.type==="video", url: newPhotos[0]?.url, type: "hid" };
|
||||
return newPhotos[index] && mediaVisibleRange
|
||||
? newPhotos[index]
|
||||
: {
|
||||
mp4: newPhotos[0]?.type === "video",
|
||||
url: newPhotos[0]?.url,
|
||||
type: "hid",
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
setPhotos(newPhotos);
|
||||
if (newPhotos.length > 9) {
|
||||
|
@ -84,17 +94,31 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
|
|||
</div>
|
||||
</div>
|
||||
<div className="my-4">
|
||||
<video
|
||||
{/* <video
|
||||
width="100%"
|
||||
height="100%"
|
||||
controls
|
||||
muted={true}
|
||||
className="w-screen h-[70vh] rounded-lg object-contain"
|
||||
poster={video?.url}
|
||||
// autoPlay={true}
|
||||
>
|
||||
<source src={video.mp4} type="video/mp4" />
|
||||
您的浏览器不支持 Video 标签。
|
||||
</video>
|
||||
</video> */}
|
||||
{/* <Video as={ReactPlayer} src={video.mp4} /> */}
|
||||
<Player
|
||||
src={video.mp4}
|
||||
poster={video?.url.src}
|
||||
blurDataURL={video?.url.blurDataURL}
|
||||
autoPlay={true}
|
||||
style={{height:"500px"}}
|
||||
/>
|
||||
{/* <Player
|
||||
src="https://www.mydomain.com/remote-video.mp4"
|
||||
poster="https://www.mydomain.com/remote-poster.webp"
|
||||
blurDataURL="data:image/webp;base64,UklGRlA..."
|
||||
/> */}
|
||||
</div>
|
||||
{/* <div
|
||||
className="flex w-12 h-12 justify-center items-center bg-[#33333348] rounded-full"
|
||||
|
@ -186,7 +210,11 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
|
|||
}}
|
||||
>
|
||||
{
|
||||
<div className={`overflow-hidden rounded h-full max-h-80 ${currentPhotos.length>1?"min-h-[24vw]":"min-h-[38vw]"}`}>
|
||||
<div
|
||||
className={`overflow-hidden rounded h-full max-h-80 ${
|
||||
currentPhotos.length > 1 ? "min-h-[24vw]" : "min-h-[38vw]"
|
||||
}`}
|
||||
>
|
||||
<Image
|
||||
// lazy={true}
|
||||
placeholder={
|
||||
|
@ -195,9 +223,7 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
|
|||
width={currentPhotos.length > 1 ? "24vw" : "100%"}
|
||||
height={currentPhotos.length > 1 ? "24vw" : "auto"}
|
||||
className={`rounded max-w-full ${
|
||||
(item?.type == "hid" && type == "space")
|
||||
? "imageBlur"
|
||||
: ""
|
||||
item?.type == "hid" && type == "space" ? "imageBlur" : ""
|
||||
}`}
|
||||
fit="cover"
|
||||
src={item?.url}
|
||||
|
@ -210,7 +236,9 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
|
|||
className=""
|
||||
width={98}
|
||||
height={98}
|
||||
src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/play.png"}
|
||||
src={
|
||||
process.env.NEXT_PUBLIC_WEB_ASSETS_URL + "/icons/play.png"
|
||||
}
|
||||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
|
@ -222,28 +250,29 @@ export default function Photos({ isUnlocked,mediaVisibleRange, mediaAmount, medi
|
|||
)} */}
|
||||
{index == currentPhotos.length - 1 &&
|
||||
photos.length > 9 &&
|
||||
(!seeAllPhotos ?(
|
||||
(!seeAllPhotos ? (
|
||||
<div
|
||||
className="absolute top-0 w-full h-full flex justify-center items-center bg-[#33333348]"
|
||||
onClick={handleSeeAllPhotos}
|
||||
>
|
||||
<span className="text-2xl">+{currentPhotos.length}</span>
|
||||
|
||||
</div>
|
||||
):(
|
||||
) : (
|
||||
<div
|
||||
className="absolute top-0 w-full h-full flex justify-center items-center bg-[#33333348]"
|
||||
key="closeBtn"
|
||||
onClick={handleSeeAllPhotos}
|
||||
>
|
||||
<FontAwesomeIcon icon={faAngleUp} size="xl" className="h-14" />
|
||||
<FontAwesomeIcon
|
||||
icon={faAngleUp}
|
||||
size="xl"
|
||||
className="h-14"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
'use client';
|
||||
|
||||
import ReactPlayer from 'react-player';
|
||||
|
||||
export default function Player(props) {
|
||||
let { asset, src, poster, blurDataURL, thumbnailTime, ...rest } = props;
|
||||
let config = { file: { attributes: { poster } } };
|
||||
|
||||
return <ReactPlayer
|
||||
url={src}
|
||||
config={config}
|
||||
width="100%"
|
||||
height="100%"
|
||||
{...rest}
|
||||
/>;
|
||||
}
|
|
@ -60,7 +60,7 @@ export default function PostItem({
|
|||
);
|
||||
});
|
||||
// console.log("matches", matches);
|
||||
// console.log("text", text);
|
||||
console.log("text", text);
|
||||
}
|
||||
|
||||
// 返回找到的链接数组
|
||||
|
@ -117,23 +117,23 @@ export default function PostItem({
|
|||
<div>
|
||||
{!data?.is_zone_moment_unlocked ? (
|
||||
<span>
|
||||
<pre
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: findLinksInText(data.text),
|
||||
}}
|
||||
className={`mb-2 mt-2 whitespace-normal ${
|
||||
className={`mb-2 mt-2 whitespace-pre-wrap ${
|
||||
!isOpenText ? "text-ellipsis-7" : ""
|
||||
} ${inter.className}`}
|
||||
// style={{
|
||||
// WebkitLineClamp: data?.text_visible_range < 999?data?.text_visible_range:7,
|
||||
// }}
|
||||
></pre>
|
||||
></div>
|
||||
</span>
|
||||
) : (
|
||||
<div>
|
||||
<span>
|
||||
<pre
|
||||
className={`mb-2 mt-2 whitespace-normal ${
|
||||
<div
|
||||
className={`mb-2 mt-2 whitespace-pre-wrap ${
|
||||
!isOpenText ? "text-ellipsis-7" : ""
|
||||
} ${inter.className}`}
|
||||
dangerouslySetInnerHTML={{
|
||||
|
@ -145,7 +145,7 @@ export default function PostItem({
|
|||
? data?.text_visible_range
|
||||
: 7,
|
||||
}}
|
||||
></pre>
|
||||
></div>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -4,7 +4,7 @@ const nextConfig = {
|
|||
return [
|
||||
{
|
||||
source: "/api/:path*",
|
||||
destination: "https://testapi.tiefen.fun/api/:path*",
|
||||
destination: "https://api.tiefen.fun/api/:path*",
|
||||
},
|
||||
];
|
||||
},
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
"html2canvas": "^1.0.0-alpha.12",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"next": "14.0.2",
|
||||
"next-video": "^1.1.3",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-player": "^2.16.0",
|
||||
"react-redux": "^9.1.2",
|
||||
"redux": "^5.0.1",
|
||||
"sass": "^1.77.6"
|
||||
|
|
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 32 KiB |