Compare commits

..

2 Commits

5 changed files with 37 additions and 14 deletions

View File

@ -62,7 +62,7 @@
: `https://beatsaver.com/search/hash/${hash}`;
</script>
<div class="flex flex-wrap gap-2">
<div class="map-action-buttons flex flex-wrap gap-2">
<a
class="rounded-md border border-white/10 px-2 py-1 text-xs hover:border-white/20"
href={beatLeaderUrl}

View File

@ -2,6 +2,7 @@
import DifficultyLabel from './DifficultyLabel.svelte';
import MapActionButtons from './MapActionButtons.svelte';
import SongPlayer from './SongPlayer.svelte';
import ScoreBar from './ScoreBar.svelte';
// Song metadata
export let hash: string;
@ -19,10 +20,15 @@ export let modeName: string = 'Standard';
export let leaderboardId: string | undefined = undefined;
export let beatsaverKey: string | undefined = undefined;
// BeatSaver stats
export let score: number | undefined = undefined;
// Layout tweaks
export let compact = false;
export let showActions = true;
export let showPublished = true;
$: hasScore = typeof score === 'number' && Number.isFinite(score);
</script>
<div class:compact-wrapper={compact} class="card-wrapper">
@ -56,9 +62,9 @@ export let showPublished = true;
<slot name="meta-leading">
<DifficultyLabel {diffName} {modeName} />
</slot>
</div>
<div class="player">
<SongPlayer {hash} preferBeatLeader={true} />
{#if hasScore}
<ScoreBar value={score} showLabel={true} size="sm" decimals={1} className="score-meter--with-max" />
{/if}
</div>
</div>
@ -73,6 +79,9 @@ export let showPublished = true;
{modeName}
{beatsaverKey}
/>
<div class="player">
<SongPlayer {hash} preferBeatLeader={true} />
</div>
</div>
{/if}
</div>
@ -197,6 +206,8 @@ export let showPublished = true;
.meta-leading :global(.score-meter) {
width: 100%;
max-width: 45%;
margin-left: auto;
}
.meta.compact-row {
@ -204,18 +215,30 @@ export let showPublished = true;
gap: 0.35rem;
}
.player {
flex: 1;
}
.actions {
margin-top: auto;
margin-top: 0.6rem;
display: flex;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
}
.body.compact-body .actions {
margin-top: 0.3rem;
}
.player {
flex: 1;
max-width: 45%;
margin-left: auto;
}
.actions :global(.map-action-buttons) {
display: inline-flex;
flex-wrap: wrap;
gap: 0.5rem;
}
@media (max-width: 959px) {
.card-wrapper.compact-wrapper {
grid-template-columns: 1fr;
@ -240,10 +263,6 @@ export let showPublished = true;
.meta.compact-row .meta-leading {
width: 100%;
}
.meta.compact-row .player {
width: 100%;
}
}
:global(.difficulty-label) {

View File

@ -11,6 +11,7 @@ export type MapMeta = {
key?: string;
coverURL?: string;
mapper?: string;
score?: number;
};
export type StarInfo = {
@ -180,7 +181,8 @@ export async function fetchBeatSaverMeta(hash: string): Promise<MapMeta | null>
songName: data?.metadata?.songName ?? data?.name ?? undefined,
key: data?.id ?? undefined,
coverURL: cover,
mapper: data?.uploader?.name ?? undefined
mapper: data?.uploader?.name ?? undefined,
score: typeof data?.stats?.score === 'number' ? data.stats.score : undefined
};
} catch {
// Fallback to CDN cover only

View File

@ -241,6 +241,7 @@
modeName={item.difficulties[0]?.characteristic ?? 'Standard'}
leaderboardId={item.leaderboardId}
beatsaverKey={metaByHash[item.hash]?.key}
score={metaByHash[item.hash]?.score}
/>
</article>
{/each}

View File

@ -501,6 +501,7 @@
modeName={item.modeName}
leaderboardId={item.leaderboardId}
beatsaverKey={metaByHash[item.hash]?.key}
score={metaByHash[item.hash]?.score}
>
<div slot="content">
<div class="mt-3 grid grid-cols-2 gap-3 neon-surface">