mirror of
https://github.com/revanced/revanced-website.git
synced 2025-04-30 06:34:35 +02:00
refactor: add and use router event store
This commit is contained in:
parent
ea599f2397
commit
4feed9982b
42
src/data/RouterEvents.ts
Normal file
42
src/data/RouterEvents.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { navigating, page } from '$app/stores';
|
||||||
|
import { derived, type Readable } from 'svelte/store';
|
||||||
|
|
||||||
|
export interface RouterEvent {
|
||||||
|
// URL of the current page or the page we are navigating to.
|
||||||
|
target_url: URL;
|
||||||
|
// Are we navigating?
|
||||||
|
navigating: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeStore(): Readable<RouterEvent> {
|
||||||
|
// This stuff will run both client side and server side.
|
||||||
|
|
||||||
|
if (typeof location === 'undefined') {
|
||||||
|
// `location` does not exist on the server.
|
||||||
|
// Return a derived store based on `page` for SSR.
|
||||||
|
// Server will never navigate so this is fine.
|
||||||
|
return derived(page, $page => {
|
||||||
|
return { navigating: false, target_url: $page.url };
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// On client.
|
||||||
|
let current = new URL(location);
|
||||||
|
|
||||||
|
// Return store that responds to navigation events.
|
||||||
|
// The `navigating` store immediately "pushes" `null`.
|
||||||
|
// This in turn causes this derived store to immediately "push" the current URL.
|
||||||
|
return derived(navigating, $nav => {
|
||||||
|
let navigating = false;
|
||||||
|
// $nav is null when navigation finishes.
|
||||||
|
if ($nav != null && $nav.to != null) {
|
||||||
|
current = $nav.to.url;
|
||||||
|
navigating = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { navigating, target_url: current };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not subscribe to it outside of components!
|
||||||
|
export default makeStore();
|
@ -1,21 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { page, navigating } from '$app/stores';
|
import RouterEvents from '../../../data/RouterEvents';
|
||||||
export let href = '/';
|
export let href = '/';
|
||||||
let nav = null;
|
|
||||||
|
|
||||||
$: current_page = $page.url.pathname;
|
|
||||||
$: {
|
|
||||||
nav = $navigating;
|
|
||||||
if (nav != null && nav.to != null) {
|
|
||||||
current_page = nav.to.url.pathname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: current = href === current_page;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a data-sveltekit-prefetch {href}>
|
<a data-sveltekit-prefetch {href}>
|
||||||
<li class:selected={current === true}>
|
<li class:selected={href === $RouterEvents.target_url.pathname}>
|
||||||
<slot />
|
<slot />
|
||||||
</li>
|
</li>
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,31 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { derived } from "svelte/store";
|
||||||
|
|
||||||
import NavHost from "$lib/components/molecules/NavHost.svelte";
|
import NavHost from "$lib/components/molecules/NavHost.svelte";
|
||||||
|
import Spinner from '$lib/components/atoms/Spinner.svelte';
|
||||||
|
import RouterEvents from '../data/RouterEvents';
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
|
|
||||||
import { navigating } from '$app/stores'
|
// Just like the set/clearInterval example found here: https://svelte.dev/docs#run-time-svelte-store-derived
|
||||||
import { onMount } from "svelte";
|
const show_loading_animation = derived(RouterEvents, ($event, set) => {
|
||||||
import Spinner from '$lib/components/atoms/Spinner.svelte';
|
if ($event.navigating) {
|
||||||
|
// Wait 300 ms before showing the animation.
|
||||||
let timeout = 0;
|
const timeout = setTimeout(() => set(true), 300);
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
let is_navigating = false;
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
// Show spinner if we are still waiting for navigation after 150ms
|
|
||||||
navigating.subscribe(nav => {
|
|
||||||
// cancel current timer, if any
|
|
||||||
clearTimeout(timeout);
|
|
||||||
// null after navigation finishes
|
|
||||||
if (nav != null) {
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
is_navigating = true;
|
|
||||||
}, 150);
|
|
||||||
} else {
|
} else {
|
||||||
// navigation finished
|
set(false)
|
||||||
is_navigating = false;
|
|
||||||
}
|
}
|
||||||
});
|
}, false);
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@ -42,7 +32,7 @@
|
|||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<NavHost/>
|
<NavHost/>
|
||||||
{#if is_navigating}
|
{#if $show_loading_animation}
|
||||||
<Spinner />
|
<Spinner />
|
||||||
{:else}
|
{:else}
|
||||||
<slot />
|
<slot />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user