Design Prot Merge #1
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import LoaderCircle from '@lucide/svelte/icons/loader-circle';
|
import LoaderCircle from '@lucide/svelte/icons/loader-circle';
|
||||||
|
import { INFINITE_SCROLL_ROOT_MARGIN } from '$lib/config';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onLoadMore: () => void;
|
onLoadMore: () => void;
|
||||||
@@ -8,7 +9,7 @@
|
|||||||
rootMargin?: string;
|
rootMargin?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { onLoadMore, hasMore, loading, rootMargin = '600px' }: Props = $props();
|
let { onLoadMore, hasMore, loading, rootMargin = INFINITE_SCROLL_ROOT_MARGIN }: Props = $props();
|
||||||
|
|
||||||
let sentinel = $state<HTMLDivElement>();
|
let sentinel = $state<HTMLDivElement>();
|
||||||
let visible = $state(false);
|
let visible = $state(false);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
export const EXPLORE_PAGE_SIZE = 27;
|
export const EXPLORE_PAGE_SIZE = 27;
|
||||||
|
export const SEARCH_DEBOUNCE_MS = 450;
|
||||||
|
export const SEARCH_MIN_LENGTH = 2;
|
||||||
|
export const INFINITE_SCROLL_ROOT_MARGIN = '300px';
|
||||||
export const HOME_LATEST_PAGE_SIZE = 12;
|
export const HOME_LATEST_PAGE_SIZE = 12;
|
||||||
export const YOUTUBE_FILLER_LIMIT = 27;
|
export const YOUTUBE_FILLER_LIMIT = 27;
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import type { PageServerLoad, Actions } from './$types';
|
|||||||
import { createApiClient, requireUser, unwrapOrError } from '$lib/server/api';
|
import { createApiClient, requireUser, unwrapOrError } from '$lib/server/api';
|
||||||
import { fetchYoutubeFiller } from '$lib/server/youtube';
|
import { fetchYoutubeFiller } from '$lib/server/youtube';
|
||||||
import { addTrackAction, addYouTubeToPlaylistAction } from '$lib/server/playlistActions';
|
import { addTrackAction, addYouTubeToPlaylistAction } from '$lib/server/playlistActions';
|
||||||
import { EXPLORE_PAGE_SIZE as PAGE_SIZE, YOUTUBE_FILLER_LIMIT } from '$lib/config';
|
import {
|
||||||
|
EXPLORE_PAGE_SIZE as PAGE_SIZE,
|
||||||
|
SEARCH_MIN_LENGTH,
|
||||||
|
YOUTUBE_FILLER_LIMIT
|
||||||
|
} from '$lib/config';
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ url, locals, fetch }) => {
|
export const load: PageServerLoad = async ({ url, locals, fetch }) => {
|
||||||
const query = url.searchParams.get('q')?.trim() ?? '';
|
const query = url.searchParams.get('q')?.trim() ?? '';
|
||||||
@@ -15,9 +19,10 @@ export const load: PageServerLoad = async ({ url, locals, fetch }) => {
|
|||||||
params: { query: { name: query || undefined, pageNumber: page, pageSize: PAGE_SIZE } }
|
params: { query: { name: query || undefined, pageNumber: page, pageSize: PAGE_SIZE } }
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchPromise = query
|
const searchPromise =
|
||||||
? api.GET('/youtube/search', { params: { query: { query } } })
|
query.length >= SEARCH_MIN_LENGTH
|
||||||
: Promise.resolve(null);
|
? api.GET('/youtube/search', { params: { query: { query } } })
|
||||||
|
: Promise.resolve(null);
|
||||||
|
|
||||||
const playlistsPromise = api.GET('/playlists/users/{userId}', {
|
const playlistsPromise = api.GET('/playlists/users/{userId}', {
|
||||||
params: { path: { userId: user.sub }, query: { pageNumber: 1, pageSize: 50 } }
|
params: { path: { userId: user.sub }, query: { pageNumber: 1, pageSize: 50 } }
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
import Input from '$lib/components/ui/Input.svelte';
|
import Input from '$lib/components/ui/Input.svelte';
|
||||||
import EmptyState from '$lib/components/ui/EmptyState.svelte';
|
import EmptyState from '$lib/components/ui/EmptyState.svelte';
|
||||||
import InfiniteScroll from '$lib/components/ui/InfiniteScroll.svelte';
|
import InfiniteScroll from '$lib/components/ui/InfiniteScroll.svelte';
|
||||||
import { EXPLORE_PAGE_SIZE } from '$lib/config';
|
import { EXPLORE_PAGE_SIZE, SEARCH_DEBOUNCE_MS } from '$lib/config';
|
||||||
import { hueFor } from '$lib/theme/color';
|
import { hueFor } from '$lib/theme/color';
|
||||||
import type { YouTubeSong } from '$lib/types';
|
import type { YouTubeSong } from '$lib/types';
|
||||||
import TrackTile from '$lib/components/TrackTile.svelte';
|
import TrackTile from '$lib/components/TrackTile.svelte';
|
||||||
@@ -94,12 +94,14 @@
|
|||||||
const value = (event.currentTarget as HTMLInputElement).value;
|
const value = (event.currentTarget as HTMLInputElement).value;
|
||||||
clearTimeout(searchTimeout);
|
clearTimeout(searchTimeout);
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
goto(buildHref(value.trim()), {
|
const term = value.trim();
|
||||||
|
if (term === data.query) return;
|
||||||
|
goto(buildHref(term), {
|
||||||
keepFocus: true,
|
keepFocus: true,
|
||||||
replaceState: true,
|
replaceState: true,
|
||||||
noScroll: true
|
noScroll: true
|
||||||
});
|
});
|
||||||
}, 350);
|
}, SEARCH_DEBOUNCE_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function togglePlay(index: number) {
|
function togglePlay(index: number) {
|
||||||
|
|||||||
Reference in New Issue
Block a user