update: 单曲页面ssg

main
fadeaway 8 months ago
parent 9c3592d430
commit 09b497e865

@ -6,19 +6,12 @@ import EnterQueyueBtn from '@/components/EnterQueyueBtn';
import MusicBanner from '@/components/MusicBanner'; import MusicBanner from '@/components/MusicBanner';
import MusicPanel from '@/components/MusicPanel'; import MusicPanel from '@/components/MusicPanel';
async function getMusic(songId: string) { export default async function Music() {
const res = await fetch(`http://api.indie.cn:9012/luoo-music/song/${songId}`);
return res.json();
}
export default async function Music({ searchParams: { id } }: any) {
const res = await getMusic(id);
const musicInfo = res?.data;
return ( return (
<main className="max-w-screen-sm min-h-screen mx-auto flex flex-col items-center text-white font-normal bg-gradient-to-b from-[#030303] to-[#1f1f20] px-[18px]"> <main className="max-w-screen-sm min-h-screen mx-auto flex flex-col items-center text-white font-normal bg-gradient-to-b from-[#030303] to-[#1f1f20] px-[18px]">
<MusicBanner /> <MusicBanner />
<MusicPanel musicInfo={musicInfo} /> <MusicPanel />
<div className="mb-[30px]"> <div className="mb-[30px]">
<EnterQueyueBtn /> <EnterQueyueBtn />

@ -106,7 +106,7 @@ export default forwardRef(function AudioPlayer(
onTouchEnd={handleSlideEnd} onTouchEnd={handleSlideEnd}
onChange={handleSlideChange} onChange={handleSlideChange}
/> />
<div className="flex justify-between"> <div className="flex justify-between mt-[2px]">
<div className="text-[12px] leading-[16.8px] text-[#ffffff66]">{curTime}</div> <div className="text-[12px] leading-[16.8px] text-[#ffffff66]">{curTime}</div>
<div className="text-[12px] leading-[16.8px] text-[#ffffff66]">{totalTime}</div> <div className="text-[12px] leading-[16.8px] text-[#ffffff66]">{totalTime}</div>
</div> </div>

@ -7,8 +7,14 @@ import Image from 'next/image';
import AudioPlayer from '@/components/AudioPlayer'; import AudioPlayer from '@/components/AudioPlayer';
import type { IAudioPlayerRef } from '@/components/AudioPlayer'; import type { IAudioPlayerRef } from '@/components/AudioPlayer';
export default function MusicPanel(props: { musicInfo: ISong }) { async function getMusic(songId: string) {
const { musicInfo } = props || {}; const res = await fetch(`http://api.indie.cn:9012/luoo-music/song/${songId}`);
return res.json();
}
export default function MusicPanel() {
const [musicInfo, setMusicInfo] = useState<ISong>();
const [loading, setLoading] = useState(true);
const audioPlayerRef = useRef<IAudioPlayerRef>(null); const audioPlayerRef = useRef<IAudioPlayerRef>(null);
const [playing, setPlaying] = useState(false); const [playing, setPlaying] = useState(false);
@ -22,46 +28,70 @@ export default function MusicPanel(props: { musicInfo: ISong }) {
}; };
useEffect(() => { useEffect(() => {
setPlaying(!!!audioPlayerRef.current?.audio?.paused); const { searchParams } = new URL(window.location.href);
setLoading(true);
getMusic((searchParams as any)?.get('id'))
.then((res) => {
setMusicInfo(res?.data);
})
.finally(() => {
setLoading(false);
});
}, []); }, []);
useEffect(() => {
if (!loading && musicInfo?.src) {
audioPlayerRef.current?.audio?.play();
setPlaying(!!!audioPlayerRef.current?.audio?.paused);
}
}, [loading, musicInfo]);
return ( return (
<> <div className="w-full relative">
<div className="relative w-[100%] aspect-square mt-[12px]"> {loading && (
<Image className="rounded-[6px] object-cover" unoptimized fill src={musicInfo?.pic} alt="cover" /> <div className="text-[#ffffff66] absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%]">
<Image ...
className={`absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] w-[60px] h-[60px] ${!playing && 'hidden'}`} </div>
width={60} )}
height={60} <div className={`w-full ${loading && 'invisible'}`}>
unoptimized <div className="relative w-[100%] aspect-square mt-[12px]">
src="/img/icon_pause_w.png" {musicInfo?.pic && (
alt="pause" <Image className="rounded-[6px] object-cover" unoptimized fill src={musicInfo?.pic} alt="cover" />
onClick={togglePlay} )}
/> <Image
<Image className={`absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] w-[60px] h-[60px] ${!playing && 'hidden'}`}
className={`absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] w-[60px] h-[60px] ${playing && 'hidden'}`} width={60}
width={60} height={60}
height={60} unoptimized
unoptimized src="/img/icon_pause_w.png"
src="/img/icon_play_w.png" alt="pause"
alt="play" onClick={togglePlay}
onClick={togglePlay} />
/> <Image
</div> className={`absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] w-[60px] h-[60px] ${playing && 'hidden'}`}
width={60}
height={60}
unoptimized
src="/img/icon_play_w.png"
alt="play"
onClick={togglePlay}
/>
</div>
<div className="w-full mt-[20px]"> <div className="w-full mt-[20px]">
<div className="text-[12px] h-[22px] w-[fit-content] flex items-center text-white rounded-full px-[8px] py-[0] bg-[#2b2b2c]"> <div className="text-[12px] h-[22px] w-[fit-content] flex items-center text-white rounded-full px-[8px] py-[0] bg-[#2b2b2c]">
VOL&nbsp;{musicInfo?.journalNo} VOL&nbsp;{musicInfo?.journalNo}
</div>
</div> </div>
</div> <h5 className="mt-[9px] font-medium text-[20px] leading-[28px] w-full min-h-[28px]">{musicInfo?.title}</h5>
<h5 className="mt-[9px] font-medium text-[20px] leading-[28px] w-full">{musicInfo?.title}</h5> <p className="mt-[3px] text-[12px] text-[#ffffffb2] w-full min-h-[17px]">
<p className="mt-[3px] text-[12px] text-[#ffffffb2] w-full"> {[musicInfo?.artist, musicInfo?.album].filter((str) => !!str).join(' / ')}
{[musicInfo?.artist, musicInfo?.album].filter((str) => !!str).join(' / ')} </p>
</p>
<div className="w-full mt-[18px] mb-[46px]"> <div className="w-full mt-[12px] mb-[44px]">
<AudioPlayer ref={audioPlayerRef} src={musicInfo?.src} /> <AudioPlayer ref={audioPlayerRef} src={musicInfo?.src} />
</div>
</div> </div>
</> </div>
); );
} }

Loading…
Cancel
Save