Add scorebar to mapCard on compare histories tool

This commit is contained in:
pleb 2025-11-04 07:13:49 -08:00
parent 33b3e6f3c1
commit c7b3439fac
4 changed files with 36 additions and 14 deletions

View File

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

View File

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

View File

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

View File

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