feat(wip): search

This commit is contained in:
2025-10-01 22:19:10 -04:00
parent ea1a017aa7
commit 81ef5bac90
9 changed files with 583 additions and 6 deletions

View File

@@ -0,0 +1,94 @@
<script lang="ts">
import { goto } from '$app/navigation';
import type { SearchResult, SearchType } from '$lib/types/search';
interface Props {
results: SearchResult[];
searchType: SearchType;
onDownload?: (result: SearchResult) => void;
}
let { results, searchType, onDownload }: Props = $props();
let selectedIndex = $state<number | null>(null);
function handleRowClick(index: number) {
selectedIndex = index;
}
function handleRowDoubleClick(result: SearchResult, index: number) {
if (searchType === 'local') {
// Navigate to album view
if (result.artistName && result.albumTitle) {
const artistEncoded = encodeURIComponent(result.artistName);
const albumEncoded = encodeURIComponent(result.albumTitle);
goto(`/albums/${artistEncoded}/${albumEncoded}`);
}
} else if (searchType === 'online') {
// Trigger download
if (onDownload) {
onDownload(result);
}
}
}
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="table-container">
<table class="interactive">
<thead>
<tr>
<th>Track</th>
<th>Artist</th>
<th>Duration</th>
<th>Album</th>
</tr>
</thead>
<tbody>
{#each results as result, i}
<tr
class:highlighted={selectedIndex === i}
onclick={() => handleRowClick(i)}
ondblclick={() => handleRowDoubleClick(result, i)}
>
<td>{result.title}</td>
<td>{result.artist}</td>
<td class="duration">{formatDuration(result.duration)}</td>
<td>{result.album}</td>
</tr>
{/each}
</tbody>
</table>
</div>
<style>
.table-container {
flex: 1;
overflow-y: auto;
min-height: 0;
}
table {
width: 100%;
}
th {
text-align: left;
}
.duration {
font-family: monospace;
text-align: center;
width: 80px;
}
td:last-child {
opacity: 0.7;
}
</style>