|
|
|
@ -7,8 +7,14 @@ import Image from 'next/image';
|
|
|
|
|
import AudioPlayer from '@/components/AudioPlayer';
|
|
|
|
|
import type { IAudioPlayerRef } from '@/components/AudioPlayer';
|
|
|
|
|
|
|
|
|
|
export default function MusicPanel(props: { musicInfo: ISong }) {
|
|
|
|
|
const { musicInfo } = props || {};
|
|
|
|
|
async function getMusic(songId: string) {
|
|
|
|
|
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 [playing, setPlaying] = useState(false);
|
|
|
|
|
|
|
|
|
@ -22,13 +28,36 @@ export default function MusicPanel(props: { musicInfo: ISong }) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 (
|
|
|
|
|
<>
|
|
|
|
|
<div className="w-full relative">
|
|
|
|
|
{loading && (
|
|
|
|
|
<div className="text-[#ffffff66] absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%]">
|
|
|
|
|
加载中 ...
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<div className={`w-full ${loading && 'invisible'}`}>
|
|
|
|
|
<div className="relative w-[100%] aspect-square mt-[12px]">
|
|
|
|
|
{musicInfo?.pic && (
|
|
|
|
|
<Image className="rounded-[6px] object-cover" unoptimized fill src={musicInfo?.pic} alt="cover" />
|
|
|
|
|
)}
|
|
|
|
|
<Image
|
|
|
|
|
className={`absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] w-[60px] h-[60px] ${!playing && 'hidden'}`}
|
|
|
|
|
width={60}
|
|
|
|
@ -54,14 +83,15 @@ export default function MusicPanel(props: { musicInfo: ISong }) {
|
|
|
|
|
VOL {musicInfo?.journalNo}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<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">
|
|
|
|
|
<h5 className="mt-[9px] font-medium text-[20px] leading-[28px] w-full min-h-[28px]">{musicInfo?.title}</h5>
|
|
|
|
|
<p className="mt-[3px] text-[12px] text-[#ffffffb2] w-full min-h-[17px]">
|
|
|
|
|
{[musicInfo?.artist, musicInfo?.album].filter((str) => !!str).join(' / ')}
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<div className="w-full mt-[18px] mb-[46px]">
|
|
|
|
|
<div className="w-full mt-[12px] mb-[44px]">
|
|
|
|
|
<AudioPlayer ref={audioPlayerRef} src={musicInfo?.src} />
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|