Files
fnx_web/svelte/src/wrap/Router.svelte
2026-01-26 22:23:36 +01:00

154 lines
3.7 KiB
Svelte

<script lang="ts">
import { onMount, tick } from "svelte";
import HomePage from "home_page/HomePage.svelte";
import LoginRouter from "login/Router.svelte";
import HomeRouter from "user_home/Router.svelte";
import AdminRouter from "admin_panel/Router.svelte";
import Filesystem from "filesystem/Filesystem.svelte";
import NotFound from "./NotFound.svelte";
import SpeedtestPage from "speedtest/SpeedtestPage.svelte";
import Appearance from "pages/Appearance.svelte";
import Footer from "layout/Footer.svelte";
import { current_page_store, type Tab } from "./RouterStore";
import { get_user, type User } from "lib/PixeldrainAPI";
let pages: Tab[] = [
{
path: "/",
title: "Home",
component: HomePage,
}, {
path: "/login",
title: "Login",
component: LoginRouter,
}, {
path: "/register",
title: "Register",
component: LoginRouter,
}, {
path: "/user",
prefix: "/user/",
title: "Dashboard",
component: HomeRouter,
login: true,
}, {
path: "/d/me",
prefix: "/d/",
title: "Filesystem",
component: Filesystem,
footer: false,
login: true,
}, {
path: "/admin",
prefix: "/admin/",
title: "Admin Panel",
component: AdminRouter,
login: true,
}, {
path: "/speedtest",
title: "Speedtest",
component: SpeedtestPage,
}, {
path: "/appearance",
title: "Appearance",
component: Appearance,
},
]
let user: User = null
onMount(async () => {
user = await get_user()
load_page(window.location.pathname, false)
})
let current_page: Tab = $state(null)
const load_page = (pathname: string, history: boolean): boolean => {
console.debug("Navigating to page", pathname, "log history:", history)
const path_decoded = decodeURI(pathname)
let page_by_path: Tab = null
let page_by_prefix: Tab = null
for (const page of pages) {
if (path_decoded === page.path) {
page_by_path = page
}
if (page.prefix !== undefined && path_decoded.startsWith(page.prefix)) {
page_by_prefix = page
}
}
if (page_by_path !== null) {
current_page = page_by_path
} else if (page_by_prefix !== null) {
current_page = page_by_prefix
} else {
current_page = {
path: "",
title: "Not Found",
component: NotFound,
}
return false
}
// If this page requires login, and the user is not logged in, then we
// redirect the user to the login page
if (current_page.login === true && (user.username === "" || user.username === undefined)) {
console.debug("User is not logged in, redirecting to login page", user)
return load_page("/login", true)
}
window.document.title = current_page.title+" / Nova"
if(history) {
window.history.pushState({}, window.document.title, pathname)
}
// The current_page_store updates all the listening pages for navigation
// events. We first wait for a tick so that the current page gets unmounted
// before sending the event. That way a stale page will not get events which
// are not meant for them
tick().then(() => {
current_page_store.set(current_page)
})
return true
}
const click = (e: MouseEvent) => {
const origin = (e.target as Element).closest("a");
if (origin === null) {
return
}
const url = URL.parse(origin.href)
if (window.location.host !== url.host) {
return
}
console.log("Caught link click to", url.pathname);
// Try to load the page, if the page was found we cancel the browser
// navigation event so we can handle it ourselves
if (load_page(url.pathname, true)) {
e.preventDefault()
}
}
const popstate = (e: PopStateEvent) => {
load_page(window.location.pathname, false)
}
</script>
<svelte:document onclick={click}/>
<svelte:window onpopstate={popstate}/>
{#if current_page !== null}
<current_page.component />
{#if current_page.footer === undefined || current_page.footer === true}
<Footer/>
{/if}
{/if}