feat(library): add album and artist scanning with cover art

This commit is contained in:
2025-10-01 11:32:40 -04:00
parent de04dbc323
commit 515a744734
11 changed files with 534 additions and 39 deletions

View File

@@ -0,0 +1,80 @@
<script lang="ts">
import type { Track } from '$lib/types/track';
interface Props {
tracks: Track[];
onTrackSelect?: (track: Track) => void;
}
let { tracks, onTrackSelect }: Props = $props();
let selectedIndex = $state<number | null>(null);
function handleRowClick(index: number) {
selectedIndex = index;
if (onTrackSelect) {
onTrackSelect(tracks[index]);
}
}
function formatDuration(seconds?: number): string {
if (!seconds) return '--:--';
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs.toString().padStart(2, '0')}`;
}
</script>
<div class="sunken-panel track-list-container">
<table class="interactive">
<thead>
<tr>
<th>#</th>
<th>Title</th>
<th>Artist</th>
<th>Album</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
{#each tracks as track, i}
<tr
class:highlighted={selectedIndex === i}
onclick={() => handleRowClick(i)}
>
<td>{track.metadata.trackNumber ?? i + 1}</td>
<td>{track.metadata.title ?? track.filename}</td>
<td>{track.metadata.artist ?? 'Unknown Artist'}</td>
<td>{track.metadata.album ?? 'Unknown Album'}</td>
<td>{formatDuration(track.metadata.duration)}</td>
</tr>
{/each}
</tbody>
</table>
</div>
<style>
.track-list-container {
height: 400px;
overflow: auto;
}
table {
width: 100%;
}
th {
text-align: left;
}
td:first-child {
width: 40px;
text-align: right;
}
td:last-child {
width: 60px;
text-align: right;
font-family: monospace;
}
</style>