mirror of
https://github.com/markuryy/shark.git
synced 2025-12-13 12:01:01 +00:00
feat(library): add album and artist scanning with cover art
This commit is contained in:
80
src/lib/components/TrackList.svelte
Normal file
80
src/lib/components/TrackList.svelte
Normal 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>
|
||||
Reference in New Issue
Block a user