From f5b931f4a9221772ac0383ebf326f207f94dfbc9 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Sun, 1 Jun 2025 21:42:52 +1200 Subject: [PATCH] Inmprovements to search caching via state --- materialious/src/lib/store.ts | 5 +- .../routes/(app)/search/[slug]/+page.svelte | 54 ++++++++++++------- .../src/routes/(app)/search/[slug]/+page.ts | 19 ++++--- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/materialious/src/lib/store.ts b/materialious/src/lib/store.ts index 381ad075..9964d249 100644 --- a/materialious/src/lib/store.ts +++ b/materialious/src/lib/store.ts @@ -4,7 +4,7 @@ import type { DataConnection } from 'peerjs'; import { persisted } from 'svelte-persisted-store'; import { writable, type Writable } from 'svelte/store'; import type { TitleCase } from './letterCasing'; -import type { PlaylistPageVideo, Video, VideoBase } from './api/model'; +import type { Channel, HashTag, Playlist, PlaylistPageVideo, Video, VideoBase } from './api/model'; function platformDependentDefault(givenValue: any, defaultValue: any): any { if (typeof givenValue !== 'undefined' && typeof givenValue !== null) { @@ -115,4 +115,7 @@ export const searchHistoryStore: Writable = persisted('searchHistory', export const feedCacheStore: Writable<{ [key: string]: (VideoBase | Video | PlaylistPageVideo)[]; }> = writable({}); +export const searchCacheStore: Writable<{ + [searchType: string]: (Channel | Video | Playlist | HashTag)[]; +}> = writable({}); export const feedLastItemId: Writable = writable(undefined); diff --git a/materialious/src/routes/(app)/search/[slug]/+page.svelte b/materialious/src/routes/(app)/search/[slug]/+page.svelte index 65fbfc1d..34efccd2 100644 --- a/materialious/src/routes/(app)/search/[slug]/+page.svelte +++ b/materialious/src/routes/(app)/search/[slug]/+page.svelte @@ -6,33 +6,41 @@ import PageLoading from '$lib/components/PageLoading.svelte'; import PlaylistThumbnail from '$lib/components/PlaylistThumbnail.svelte'; import Thumbnail from '$lib/components/Thumbnail.svelte'; + import { feedLastItemId, searchCacheStore } from '$lib/store.js'; + import { onMount } from 'svelte'; import { _ } from 'svelte-i18n'; import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading'; let { data } = $props(); - let searchResults = $state(data); - + let currentType: 'playlist' | 'all' | 'video' | 'channel' = $state('all'); let currentPage = 1; + onMount(() => { + if ($feedLastItemId) { + document.getElementById($feedLastItemId)?.scrollIntoView({ behavior: 'instant' }); + } + }); + async function changeType(type: 'playlist' | 'all' | 'video' | 'channel') { - searchResults.searchType = type; + currentType = type; currentPage = 1; - searchResults.search = []; - searchResults.search = await getSearch(searchResults.slug, { type: type }); + searchCacheStore.set({ [type]: await getSearch(data.slug, { type: type }) }); } async function loadMore(event: InfiniteEvent) { currentPage++; - const newSearch = await getSearch(searchResults.slug, { + const newSearch = await getSearch(data.slug, { page: currentPage.toString(), - type: searchResults.searchType + type: currentType }); if (newSearch.length === 0) { event.detail.complete(); } else { - searchResults.search = [...searchResults.search, ...newSearch]; + searchCacheStore.set({ + [currentType]: [...($searchCacheStore[currentType] ?? []), ...newSearch] + }); event.detail.loaded(); } } @@ -40,16 +48,12 @@
-{#if searchResults.search.length > 0} +{#if $searchCacheStore[currentType].length > 0}
- {#each searchResults.search as item} + {#each $searchCacheStore[currentType] as item} {#key item} -
+
+ feedLastItemId.set( + 'videoId' in item ? item.videoId : 'authorId' in item ? item.authorId : item.title + )} + id={'videoId' in item + ? item.videoId + : 'authorId' in item + ? item.authorId + : item.title} + > {#if item.type === 'video'} {:else if item.type === 'channel'} diff --git a/materialious/src/routes/(app)/search/[slug]/+page.ts b/materialious/src/routes/(app)/search/[slug]/+page.ts index bb14dc2e..86a7d30a 100644 --- a/materialious/src/routes/(app)/search/[slug]/+page.ts +++ b/materialious/src/routes/(app)/search/[slug]/+page.ts @@ -1,5 +1,7 @@ import { getSearch } from '$lib/api/index'; +import { searchCacheStore } from '$lib/store.js'; import { error } from '@sveltejs/kit'; +import { get } from 'svelte/store'; export async function load({ params, url }) { let type: 'playlist' | 'all' | 'video' | 'channel'; @@ -11,16 +13,21 @@ export async function load({ params, url }) { type = 'all'; } - let search; + const search = get(searchCacheStore).all; - try { - search = await getSearch(params.slug, { type: type }); - } catch (errorMessage: any) { - error(500, errorMessage); + if (!search) { + try { + searchCacheStore.set({ [type]: await getSearch(params.slug, { type: type }) }); + } catch (errorMessage: any) { + error(500, errorMessage); + } + } else { + getSearch(params.slug, { type: type }).then((newSearch) => { + searchCacheStore.set({ [type]: Array.from(new Set({ ...newSearch, ...search })) }); + }); } return { - search: search, slug: params.slug, searchType: type };