feat(tracks): search + lazy load images
This commit is contained in:
@@ -1,18 +1,61 @@
|
||||
<script lang="ts">
|
||||
import TrackListing from '$lib/components/groove/TrackListing.svelte';
|
||||
import type { PageServerData } from './$types';
|
||||
import { getSearchState } from '$lib/search.svelte';
|
||||
import type { Action } from 'svelte/action';
|
||||
import { SvelteSet as Set } from 'svelte/reactivity';
|
||||
|
||||
interface Props {
|
||||
data: PageServerData;
|
||||
}
|
||||
|
||||
const search = getSearchState();
|
||||
|
||||
let { data }: Props = $props();
|
||||
|
||||
let container: HTMLDivElement;
|
||||
let visibleTracks = $state<Set<string>>(new Set());
|
||||
|
||||
const options: IntersectionObserverInit = {
|
||||
// @ts-ignore
|
||||
root: container,
|
||||
rootMargin: "400px 0px 400px 0px",
|
||||
threshold: 0.0,
|
||||
};
|
||||
|
||||
const callback: IntersectionObserverCallback = (entries, _observer) => {
|
||||
entries.forEach(entry => {
|
||||
const hash = entry.target.getAttribute('data-track-hash')!;
|
||||
if (entry.isIntersecting) {
|
||||
if (!visibleTracks.has(hash)) {
|
||||
visibleTracks.add(hash);
|
||||
}
|
||||
}
|
||||
else if (visibleTracks.has(hash)) {
|
||||
visibleTracks.delete(hash);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver(callback, options);
|
||||
|
||||
const observe: Action = (node) => {
|
||||
observer.observe(node);
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
const firstFewTracks = search.filterTracks(data.tracks).slice(0,40);
|
||||
firstFewTracks.forEach(e => {
|
||||
visibleTracks.add(e.item.hash);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="grid grid-cols-2 gap-4 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-7 2xl:grid-cols-8"
|
||||
bind:this={container}
|
||||
>
|
||||
{#each data.tracks as track}
|
||||
<TrackListing {track} />
|
||||
{#each search.input.length > 0 ? (search.filterTracks(data.tracks).map(r => r.item) ?? []) : data.tracks as track (track.hash)}
|
||||
<TrackListing {track} action={observe} hideCover={!visibleTracks.has(track.hash)}/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user