diff --git a/materialious/src/lib/store.ts b/materialious/src/lib/store.ts index 9014d285..7c1ee505 100644 --- a/materialious/src/lib/store.ts +++ b/materialious/src/lib/store.ts @@ -13,6 +13,9 @@ import type { TitleCase } from './letterCasing'; import { serialize, deserialize } from '@macfja/serializer'; import type { Channel, + ChannelContentPlaylists, + ChannelContentVideos, + ChannelPage, HashTag, Playlist, PlaylistPage, @@ -334,3 +337,10 @@ export const playlistCacheStore: Writable<{ }> = writable({}); export const isAndroidTvStore: Writable = writable(false); + +export const channelCacheStore: Writable<{ + [key: string]: { + channel: ChannelPage; + displayContent: { [key: string]: ChannelContentVideos | ChannelContentPlaylists }; + }; +}> = writable({}); diff --git a/materialious/src/routes/(app)/channel/[slug]/+page.svelte b/materialious/src/routes/(app)/channel/[slug]/+page.svelte index 4f0d16a8..e6ea2a4c 100644 --- a/materialious/src/routes/(app)/channel/[slug]/+page.svelte +++ b/materialious/src/routes/(app)/channel/[slug]/+page.svelte @@ -9,16 +9,15 @@ import PageLoading from '$lib/components/PageLoading.svelte'; import { proxyGoogleImage } from '$lib/images'; import { cleanNumber } from '$lib/numbers'; - import { interfaceLowBandwidthMode, isAndroidTvStore } from '$lib/store'; + import { channelCacheStore, interfaceLowBandwidthMode, isAndroidTvStore } from '$lib/store'; import { Clipboard } from '@capacitor/clipboard'; import { Capacitor } from '@capacitor/core'; - import { onMount } from 'svelte'; import { _ } from '$lib/i18n'; import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading'; import ItemsList from '$lib/components/ItemsList.svelte'; import Author from '$lib/components/Author.svelte'; - - let { data } = $props(); + import { onMount } from 'svelte'; + import { page } from '$app/state'; let tab: channelContentTypes = $state('videos'); @@ -31,8 +30,12 @@ let displayContent: ChannelContentPlaylists | ChannelContentVideos | undefined = $state(undefined); + onMount(() => { + displayContent = $channelCacheStore[page.params.slug].displayContent.videos; + }); + async function searchChannel() { - displayContent = await searchChannelContent(data.channel.authorId, channelSearch); + displayContent = await searchChannelContent(page.params.slug, channelSearch); } async function loadMore(event: InfiniteEvent) { @@ -43,7 +46,7 @@ return; } - const newContent = await getChannelContent(data.channel.authorId, { + const newContent = await getChannelContent(page.params.slug, { type: tab, continuation: displayContent.continuation, sortBy: sortBy @@ -69,30 +72,28 @@ async function changeTab(newTab: 'videos' | 'playlists' | 'streams' | 'shorts') { tab = newTab; displayContent = undefined; - displayContent = await getChannelContent(data.channel.authorId, { type: tab }); + displayContent = await getChannelContent(page.params.slug, { type: tab }); } - - onMount(async () => { - displayContent = await getChannelContent(data.channel.authorId, { - type: 'videos', - sortBy: sortBy - }); - });
- {#if data.channel.authorBanners.length > 0 && !$interfaceLowBandwidthMode} + {#if $channelCacheStore[page.params.slug].channel.authorBanners.length > 0 && !$interfaceLowBandwidthMode} Channel banner {/if}
- -

{data.channel.description}

+ +

{$channelCacheStore[page.params.slug].channel.description}

{#if !$isAndroidTvStore}
- {#if data.channel.tabs.includes('videos')} + {#if $channelCacheStore[page.params.slug].channel.tabs.includes('videos')} changeTab('videos')} href="#video"> movie {$_('videoTabs.videos')} {/if} - {#if data.channel.tabs.includes('shorts')} + {#if $channelCacheStore[page.params.slug].channel.tabs.includes('shorts')} changeTab('shorts')} href="#short"> smartphone {$_('videoTabs.shorts')} {/if} - {#if data.channel.tabs.includes('streams')} + {#if $channelCacheStore[page.params.slug].channel.tabs.includes('streams')} changeTab('streams')} href="#stream"> stream {$_('videoTabs.streams')} {/if} - {#if data.channel.tabs.includes('playlists')} + {#if $channelCacheStore[page.params.slug].channel.tabs.includes('playlists')} changeTab('playlists')} href="#playlist"> playlist_add_check {$_('videoTabs.playlists')} @@ -165,7 +166,7 @@ onclick={async () => { sortBy = sortingOption; - displayContent = await getChannelContent(data.channel.authorId, { + displayContent = await getChannelContent(page.params.slug, { type: tab, sortBy: sortBy }); diff --git a/materialious/src/routes/(app)/channel/[slug]/+page.ts b/materialious/src/routes/(app)/channel/[slug]/+page.ts index 551e9c48..b582fb44 100644 --- a/materialious/src/routes/(app)/channel/[slug]/+page.ts +++ b/materialious/src/routes/(app)/channel/[slug]/+page.ts @@ -1,7 +1,28 @@ -import { getChannel } from '$lib/api/index'; +import { getChannel, getChannelContent } from '$lib/api/index'; +import type { ChannelContentVideos, Video } from '$lib/api/model'; +import { excludeDuplicateFeeds } from '$lib/misc.js'; +import { channelCacheStore } from '$lib/store.js'; import { error } from '@sveltejs/kit'; +import { get } from 'svelte/store'; export async function load({ params }) { + const currentChannelCache = get(channelCacheStore); + + if (params.slug in currentChannelCache) { + getChannelContent(params.slug, { + type: 'videos' + }).then((channelContent) => { + if (!('videos' in currentChannelCache[params.slug].displayContent)) return; + + (currentChannelCache[params.slug].displayContent.videos as ChannelContentVideos).videos = + excludeDuplicateFeeds( + (currentChannelCache[params.slug].displayContent.videos as ChannelContentVideos).videos, + (channelContent as ChannelContentVideos).videos + ) as Video[]; + }); + return; + } + let channel; try { @@ -10,7 +31,15 @@ export async function load({ params }) { error(500, errorMessage); } - return { - channel: channel - }; + const displayContent = await getChannelContent(params.slug, { + type: 'videos' + }); + + channelCacheStore.set({ + ...currentChannelCache, + [params.slug]: { + channel: channel, + displayContent: { videos: displayContent } + } + }); }