perf: Optimize stack router performance

This commit is contained in:
Aleksi Lassila
2024-05-30 17:28:28 +03:00
parent 12edf92754
commit 9b08885afa
10 changed files with 63 additions and 66 deletions

View File

@@ -30,48 +30,47 @@
</script> </script>
<I18n /> <I18n />
<Container class="w-full h-full overflow-auto text-white scrollbar-hide"> <!--<Container class="w-full h-full overflow-auto text-white scrollbar-hide">-->
{#if $appState.user === undefined} {#if $appState.user === undefined}
<div class="h-full w-full flex flex-col items-center justify-center"> <div class="h-full w-full flex flex-col items-center justify-center">
<div class="flex items-center justify-center hover:text-inherit selectable rounded-sm mb-2"> <div class="flex items-center justify-center hover:text-inherit selectable rounded-sm mb-2">
<div class="rounded-full bg-amber-300 h-4 w-4 mr-2" /> <div class="rounded-full bg-amber-300 h-4 w-4 mr-2" />
<h1 class="font-display uppercase font-semibold tracking-wider text-xl">Reiverr</h1> <h1 class="font-display uppercase font-semibold tracking-wider text-xl">Reiverr</h1>
</div>
<div>Loading...</div>
</div> </div>
{:else if $appState.user === null} <div>Loading...</div>
<LoginPage /> </div>
{:else if $appState.user.onboardingDone === false} {:else if $appState.user === null}
<OnboardingPage /> <LoginPage />
{:else} {:else if $appState.user.onboardingDone === false}
<!-- <Router primary={false}>--> <OnboardingPage />
<Container class="flex flex-col relative" direction="horizontal" trapFocus> {:else}
<Sidebar /> <!-- <Router primary={false}>-->
<!-- <Route path="series/*">--> <!-- <Container class="flex flex-col relative" direction="horizontal" trapFocus>-->
<!-- <SeriesHomePage />--> <!-- <Route path="series/*">-->
<!-- </Route>--> <!-- <SeriesHomePage />-->
<!-- <Route path="movies/*">--> <!-- </Route>-->
<!-- <MoviesHomePage />--> <!-- <Route path="movies/*">-->
<!-- </Route>--> <!-- <MoviesHomePage />-->
<!-- <Route path="library/*">--> <!-- </Route>-->
<!-- <LibraryPage />--> <!-- <Route path="library/*">-->
<!-- </Route>--> <!-- <LibraryPage />-->
<!-- <Route path="manage">--> <!-- </Route>-->
<!-- <ManagePage />--> <!-- <Route path="manage">-->
<!-- </Route>--> <!-- <ManagePage />-->
<!-- <Route path="search">--> <!-- </Route>-->
<!-- <SearchPage />--> <!-- <Route path="search">-->
<!-- </Route>--> <!-- <SearchPage />-->
<!-- <Route path="*">--> <!-- </Route>-->
<!-- <PageNotFound />--> <!-- <Route path="*">-->
<!-- </Route>--> <!-- <PageNotFound />-->
<StackRouter stack={defaultStackRouter} /> <!-- </Route>-->
</Container> <StackRouter stack={defaultStackRouter} />
<!-- </Router>--> <!-- </Container>-->
<!-- </Router>-->
<ModalStack /> <ModalStack />
{/if} {/if}
</Container> <!--</Container>-->
<NavigationDebugger /> <NavigationDebugger />

View File

@@ -10,7 +10,7 @@
// Top element, that when focused and back is pressed, will exit the modal // Top element, that when focused and back is pressed, will exit the modal
const topSelectable = useRegistrar(); const topSelectable = useRegistrar();
function handleGoBack({ detail }: CustomEvent<KeyEvent> | CustomEvent<NavigateEvent>) { function handleGoBack() {
// if ('willLeaveContainer' in detail) { // if ('willLeaveContainer' in detail) {
// if (detail.direction !== 'left' || !detail.willLeaveContainer) return; // if (detail.direction !== 'left' || !detail.willLeaveContainer) return;
// detail.preventNavigation(); // detail.preventNavigation();
@@ -24,18 +24,11 @@
} }
} }
function handleGoToTop({ detail }: CustomEvent<KeyEvent> | CustomEvent<NavigateEvent>) { function handleGoToTop() {
if ('willLeaveContainer' in detail) { const selectable = get(topSelectable);
// Navigate event if (topSelectable) {
// if (detail.direction === 'left' && detail.willLeaveContainer) {
// detail.preventNavigation();
// get(topSelectable)?.focus();
// }
} else {
// Back event
const selectable = get(topSelectable);
selectable?.focusChild(0) || selectable?.focus(); selectable?.focusChild(0) || selectable?.focus();
} } else handleGoBack();
} }
</script> </script>
@@ -44,11 +37,12 @@
hidden: !topmost hidden: !topmost
})} })}
trapFocus trapFocus
focusOnMount
direction="horizontal" direction="horizontal"
on:mount on:mount
> >
<Sidebar /> <Sidebar />
<Container on:back={handleGoToTop} focusOnMount> <Container on:back={handleGoToTop} focusOnMount class={classNames($$restProps.class)}>
<slot {handleGoBack} registrar={topSelectable.registrar} /> <slot {handleGoBack} registrar={topSelectable.registrar} />
</Container> </Container>
</Container> </Container>

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import { modalStack, modalStackTop } from './modal.store'; import { modalStack, modalStackTop } from './modal.store';
import { onDestroy } from 'svelte'; import { onDestroy } from 'svelte';
import classNames from 'classnames';
// function handleShortcuts(event: KeyboardEvent) { // function handleShortcuts(event: KeyboardEvent) {
// const top = $modalStackTop; // const top = $modalStackTop;

View File

@@ -251,8 +251,7 @@ export const defaultStackRouter = useStackRouter({
searchRoute, searchRoute,
manageRoute manageRoute
], ],
notFound: notFoundRoute, notFound: notFoundRoute
maxDepth: 3
}); });
// export const defaultStackRouter = useStackRouter({ // export const defaultStackRouter = useStackRouter({
// '/': { // '/': {

View File

@@ -7,6 +7,7 @@
import CardGrid from '../components/CardGrid.svelte'; import CardGrid from '../components/CardGrid.svelte';
import JellyfinCard from '../components/Card/JellyfinCard.svelte'; import JellyfinCard from '../components/Card/JellyfinCard.svelte';
import { scrollIntoView } from '../selectable'; import { scrollIntoView } from '../selectable';
import DetachedPage from '../components/DetachedPage/DetachedPage.svelte';
const libraryItemsP = jellyfinApi.getLibraryItems(); const libraryItemsP = jellyfinApi.getLibraryItems();
@@ -22,7 +23,7 @@
})); }));
</script> </script>
<Container focusOnMount class="px-32 py-16"> <DetachedPage class="px-32 py-16">
<div class="mb-6"> <div class="mb-6">
<div class="header2">Library</div> <div class="header2">Library</div>
</div> </div>
@@ -40,4 +41,4 @@
{/each} {/each}
{/await} {/await}
</CardGrid> </CardGrid>
</Container> </DetachedPage>

View File

@@ -19,6 +19,7 @@
import { ArrowRight, Trash } from 'radix-icons-svelte'; import { ArrowRight, Trash } from 'radix-icons-svelte';
import TmdbIntegrationConnectDialog from '../components/Integrations/TmdbIntegrationConnectDialog.svelte'; import TmdbIntegrationConnectDialog from '../components/Integrations/TmdbIntegrationConnectDialog.svelte';
import { createModal } from '../components/Modal/modal.store'; import { createModal } from '../components/Modal/modal.store';
import DetachedPage from '../components/DetachedPage/DetachedPage.svelte';
enum Tabs { enum Tabs {
Interface, Interface,
@@ -127,7 +128,7 @@
}} }}
/> />
<Container class="px-32 py-16" focusOnMount> <DetachedPage class="px-32 py-16">
<Container <Container
direction="horizontal" direction="horizontal"
class="flex space-x-8 header2 pb-3 border-b-2 border-secondary-700 w-full mb-8" class="flex space-x-8 header2 pb-3 border-b-2 border-secondary-700 w-full mb-8"
@@ -313,4 +314,4 @@
</div> </div>
</Tab> </Tab>
</Container> </Container>
</Container> </DetachedPage>

View File

@@ -82,7 +82,6 @@
direction="horizontal" direction="horizontal"
class="flex mt-8" class="flex mt-8"
focusOnMount focusOnMount
on:navigate={handleGoBack}
on:back={handleGoBack} on:back={handleGoBack}
{registrar} {registrar}
> >

View File

@@ -10,6 +10,7 @@
import { formatDateToYearMonthDay } from '../utils'; import { formatDateToYearMonthDay } from '../utils';
import TmdbCard from '../components/Card/TmdbCard.svelte'; import TmdbCard from '../components/Card/TmdbCard.svelte';
import { navigate } from '../components/StackRouter/StackRouter'; import { navigate } from '../components/StackRouter/StackRouter';
import DetachedPage from '../components/DetachedPage/DetachedPage.svelte';
const continueWatching = jellyfinApi.getContinueWatching('movie'); const continueWatching = jellyfinApi.getContinueWatching('movie');
const recentlyAdded = jellyfinApi.getRecentlyAdded('movie'); const recentlyAdded = jellyfinApi.getRecentlyAdded('movie');
@@ -59,7 +60,7 @@
} }
</script> </script>
<Container focusOnMount class="flex flex-col"> <DetachedPage class="flex flex-col relative">
<div class="h-[calc(100vh-12rem)] flex px-32"> <div class="h-[calc(100vh-12rem)] flex px-32">
<HeroShowcase <HeroShowcase
items={recommendedMovies.then(({ top10 }) => getShowcasePropsFromTmdbMovie(top10))} items={recommendedMovies.then(({ top10 }) => getShowcasePropsFromTmdbMovie(top10))}
@@ -202,4 +203,4 @@
<!-- TRENDING PEOPLE --> <!-- TRENDING PEOPLE -->
<!-- Watchlist --> <!-- Watchlist -->
</div> </div>
</Container> </DetachedPage>

View File

@@ -9,6 +9,7 @@
import { scrollIntoView } from '../selectable'; import { scrollIntoView } from '../selectable';
import AnimateScale from '../components/AnimateScale.svelte'; import AnimateScale from '../components/AnimateScale.svelte';
import type { Readable } from 'svelte/store'; import type { Readable } from 'svelte/store';
import DetachedPage from '../components/DetachedPage/DetachedPage.svelte';
let searchQuery = ''; let searchQuery = '';
let typingTimeout: ReturnType<typeof setTimeout> | undefined = undefined; let typingTimeout: ReturnType<typeof setTimeout> | undefined = undefined;
@@ -36,7 +37,7 @@
}); });
</script> </script>
<Container class="px-32 py-16 h-screen flex flex-col" focusOnMount> <DetachedPage class="px-32 py-16 h-screen flex flex-col">
<Container <Container
direction="horizontal" direction="horizontal"
class={classNames('header2 pb-3 border-b-2 w-full mb-4', { class={classNames('header2 pb-3 border-b-2 w-full mb-4', {
@@ -80,4 +81,4 @@
{/await} {/await}
{/if} {/if}
</div> </div>
</Container> </DetachedPage>

View File

@@ -12,6 +12,7 @@
import TmdbCard from '../components/Card/TmdbCard.svelte'; import TmdbCard from '../components/Card/TmdbCard.svelte';
import { navigate } from '../components/StackRouter/StackRouter'; import { navigate } from '../components/StackRouter/StackRouter';
import { TMDB_SERIES_GENRES } from '../apis/tmdb/tmdb-api.js'; import { TMDB_SERIES_GENRES } from '../apis/tmdb/tmdb-api.js';
import DetachedPage from '../components/DetachedPage/DetachedPage.svelte';
const continueWatching = jellyfinApi.getContinueWatchingSeries(); const continueWatching = jellyfinApi.getContinueWatchingSeries();
const recentlyAdded = jellyfinApi.getRecentlyAdded('series'); const recentlyAdded = jellyfinApi.getRecentlyAdded('series');
@@ -53,7 +54,7 @@
} }
</script> </script>
<Container focusOnMount class="flex flex-col"> <DetachedPage class="flex flex-col relative">
<div class="h-[calc(100vh-12rem)] flex px-32"> <div class="h-[calc(100vh-12rem)] flex px-32">
<HeroShowcase <HeroShowcase
items={recommendations.then(({ top10 }) => getShowcasePropsFromTmdbSeries(top10))} items={recommendations.then(({ top10 }) => getShowcasePropsFromTmdbSeries(top10))}
@@ -196,4 +197,4 @@
<!-- TRENDING PEOPLE --> <!-- TRENDING PEOPLE -->
<!-- Watchlist --> <!-- Watchlist -->
</div> </div>
</Container> </DetachedPage>