feat: add personal playlists and shareable track links
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
3a097c15c8
commit
fa79394869
46 files changed
+2307
-292
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import { unwrap } from '@pipu/core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useSession } from '../app/session';
|
||||
import { ArtistLinks, Cover, TrackList } from '../entities/catalog';
|
||||
import { formatDuration } from '../shared/lib/format';
|
||||
import { NotFound } from './NotFound';
|
||||
import s from './page.module.css';
|
||||
import c from './catalog.module.css';
|
||||
|
||||
export function TrackPage({ id }: { id: string }) {
|
||||
const { t } = useTranslation();
|
||||
const session = useSession();
|
||||
const track = useQuery({
|
||||
queryKey: ['track', id],
|
||||
queryFn: async () => unwrap(await session.client.GET('/api/v1/tracks/{id}', { params: { path: { id } } })),
|
||||
});
|
||||
if (track.isError) return <NotFound error={track.error} />;
|
||||
const tr = track.data;
|
||||
return (
|
||||
<div className={s.page}>
|
||||
<header className={c.hero}>
|
||||
{tr && <Cover album={tr.album} size={200} />}
|
||||
<div className={c.heroBody}>
|
||||
<span className={c.kind}>{t('player.track_page')}</span>
|
||||
<h1 className={c.heroTitle}>{tr?.title ?? '…'}</h1>
|
||||
{tr && <>
|
||||
<span className={c.heroMeta}><ArtistLinks artists={tr.artists} /> · {formatDuration(tr.duration_ms)}</span>
|
||||
<Link to="/album/$id" params={{ id: tr.album.id }}>{tr.album.title}</Link>
|
||||
</>}
|
||||
</div>
|
||||
</header>
|
||||
{tr && <TrackList tracks={[tr]} context={{ type: 'queue' }} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user