Convert multiple pages into SPA

This commit is contained in:
2025-10-09 15:48:23 +02:00
parent c616b2da7f
commit 06d04a1abc
110 changed files with 1245 additions and 1319 deletions

View File

@@ -1,6 +1,6 @@
import { fs_get_node, fs_encode_path, fs_split_path } from "./FilesystemAPI";
import type { FSNode, FSPath, FSPermissions, FSContext } from "./FilesystemAPI";
import type { Writable } from "svelte/store"
import { loading_finish, loading_start } from "lib/Loading";
import { fs_get_node, fs_encode_path, fs_split_path } from "../lib/FilesystemAPI";
import type { FSNode, FSPath, FSPermissions, FSContext } from "../lib/FilesystemAPI";
export class FSNavigator {
// Parts of the raw API response
@@ -22,27 +22,16 @@ export class FSNavigator {
constructor(history_enabled = true) {
this.history_enabled = history_enabled
// If history logging is enabled we capture the popstate event, which
// fires when the user uses the back and forward buttons in the browser.
// Instead of reloading the page we use the navigator to navigate to the
// new page
if (history_enabled) {
window.addEventListener("popstate", () => {
// Get the part of the URL after the fs root and navigate to it
const path = document.location.pathname.replace("/d/", "")
this.navigate(decodeURIComponent(path), false)
})
}
}
// If you set the loading property to a boolean writable store the navigator
// will use it to publish its loading states
loading: Writable<boolean> | null = null
set_loading = (b: boolean) => {
if (this.loading !== null) {
this.loading.set(b)
}
// The popstate event can be used to listen for navigation events. Register
// this event listener on the <svelte:window> in the parent element. When
// the user presses the back or forward buttons in the browser we'll catch
// the event and navigate to the proper directory
popstate = (e: PopStateEvent) => {
// Get the part of the URL after the fs root and navigate to it
const path = window.location.pathname.replace(/^\/d/, "")
this.navigate(decodeURI(path), false)
}
// The FSNavigator acts as a svelte store. This allows for DOM reactivity.
@@ -72,7 +61,7 @@ export class FSNavigator {
console.debug("Navigating to path", path, push_history)
try {
this.set_loading(true)
loading_start()
const resp = await fs_get_node(path)
this.open_node(resp, push_history)
} catch (err: any) {
@@ -89,7 +78,7 @@ export class FSNavigator {
alert("Error: " + err)
}
} finally {
this.set_loading(false)
loading_finish()
}
}
@@ -108,7 +97,7 @@ export class FSNavigator {
// we still replace the URL with replaceState. This way the user is not
// greeted to a 404 page when refreshing after renaming a file
if (this.history_enabled) {
window.document.title = node.path[node.base_index].name + " ~ pixeldrain"
window.document.title = node.path[node.base_index].name + " / FNX"
const url = "/d" + fs_encode_path(node.path[node.base_index].path) + window.location.hash
if (push_history) {
window.history.pushState({}, window.document.title, url)
@@ -189,14 +178,14 @@ export class FSNavigator {
let siblings: Array<FSNode>
try {
this.set_loading(true)
loading_start()
siblings = await this.get_siblings()
} catch (err) {
console.error(err)
alert(err)
return
} finally {
this.set_loading(false)
loading_finish()
}
let next_sibling: FSNode | null = null