refactor song card component and match styling on both tools
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
<script lang="ts">
|
||||
import DifficultyLabel from './DifficultyLabel.svelte';
|
||||
import MapActionButtons from './MapActionButtons.svelte';
|
||||
import SongPlayer from './SongPlayer.svelte';
|
||||
|
||||
// Song metadata
|
||||
export let hash: string;
|
||||
export let coverURL: string | undefined = undefined;
|
||||
export let songName: string | undefined = undefined;
|
||||
export let mapper: string | undefined = undefined;
|
||||
export let stars: number | undefined = undefined;
|
||||
export let timeset: number | undefined = undefined;
|
||||
|
||||
// Difficulty info
|
||||
export let diffName: string;
|
||||
export let modeName: string = 'Standard';
|
||||
|
||||
// BeatLeader/BeatSaver links
|
||||
export let leaderboardId: string | undefined = undefined;
|
||||
export let beatsaverKey: string | undefined = undefined;
|
||||
|
||||
// Layout control
|
||||
export let playerWithDifficulty: boolean = true; // if false, player goes with buttons
|
||||
</script>
|
||||
|
||||
<div class="aspect-square bg-black/30">
|
||||
{#if coverURL}
|
||||
<img
|
||||
src={coverURL}
|
||||
alt={songName ?? hash}
|
||||
loading="lazy"
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
{:else}
|
||||
<div class="h-full w-full flex items-center justify-center text-xs text-muted">No cover</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<div class="font-semibold truncate" title={songName ?? hash}>
|
||||
{songName ?? hash}
|
||||
</div>
|
||||
{#if mapper}
|
||||
<div class="mt-0.5 text-xs text-muted truncate flex items-center justify-between">
|
||||
<span>
|
||||
{mapper}
|
||||
{#if stars !== undefined}
|
||||
<span class="ml-3" title="BeatLeader star rating">★ {stars.toFixed(2)}</span>
|
||||
{/if}
|
||||
</span>
|
||||
{#if timeset !== undefined}
|
||||
<span class="text-[11px] ml-2">{new Date(timeset * 1000).toLocaleDateString()}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if playerWithDifficulty}
|
||||
<div class="mt-2 flex items-center gap-2">
|
||||
<DifficultyLabel {diffName} {modeName} />
|
||||
<div class="flex-1">
|
||||
<SongPlayer {hash} preferBeatLeader={true} />
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="mt-2">
|
||||
<DifficultyLabel {diffName} {modeName} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<slot name="content" />
|
||||
|
||||
{#if playerWithDifficulty}
|
||||
<div class="mt-3">
|
||||
<MapActionButtons
|
||||
{hash}
|
||||
{leaderboardId}
|
||||
{diffName}
|
||||
{modeName}
|
||||
{beatsaverKey}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="mt-3 flex items-center gap-2">
|
||||
<div class="w-1/2">
|
||||
<MapActionButtons
|
||||
{hash}
|
||||
{leaderboardId}
|
||||
{diffName}
|
||||
{modeName}
|
||||
{beatsaverKey}
|
||||
/>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<SongPlayer {hash} preferBeatLeader={true} />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user