Swipable menu, draggable bookmarks

This commit is contained in:
2026-02-19 18:15:06 +01:00
parent 38566389db
commit d756d545db
10 changed files with 277 additions and 98 deletions

View File

@@ -1,15 +1,16 @@
<script lang="ts">
import { fs_encode_path } from "lib/FilesystemAPI.svelte";
import type { FSNavigator } from "./FSNavigator";
import { path_link, type FSNavigator } from "./FSNavigator";
import { menu_is_open } from "wrap/MainMenu.svelte";
let { nav }: {
nav: FSNavigator;
} = $props();
</script>
<div class="breadcrumbs">
<div class="breadcrumbs" class:menu_closed={!$menu_is_open}>
{#each $nav.path as node, i (node.path)}
<a href={"/d"+fs_encode_path(node.path)} class="breadcrumb button flat">
<a href={"/d"+fs_encode_path(node.path)} class="breadcrumb button flat" use:path_link={{nav: nav, node: node}}>
{#if node.abuse_type !== undefined}
<i class="icon small">block</i>
{:else if node.is_shared()}
@@ -57,4 +58,7 @@ let { nav }: {
/* The base name uses all available space */
max-width: unset;
}
.menu_closed {
padding-left: 2em;
}
</style>

View File

@@ -56,7 +56,7 @@ export class FSNavigator {
last_requested_path: string = ""
navigate = async (path: string, push_history: boolean) => {
if (path === this.last_requested_path) {
console.debug("FSNavigator: Requested path is equal to current path. Debouncing")
console.debug("FSNavigator: Requested path ", path, " is equal to current path. Debouncing")
return
}
this.last_requested_path = path
@@ -96,6 +96,7 @@ export class FSNavigator {
}
reload = async () => {
this.last_requested_path = ""
await this.navigate(this.base.path, false)
}
@@ -282,3 +283,23 @@ const sort_children = (children: FSNode[], field: string, asc: boolean) => {
}
export let global_navigator = new FSNavigator(true)
export const path_link = (node: HTMLAnchorElement, data: { nav: FSNavigator, node: FSNode }) => {
// Set url
node.href = "/d" + fs_encode_path(data.node.path)
// Override click handler
const click = (e: MouseEvent) => {
e.preventDefault()
data.nav.navigate(data.node.path, true)
}
node.addEventListener("click", click)
return {
destroy() {
node.removeEventListener("click", click)
}
}
}

View File

@@ -6,7 +6,6 @@ import Breadcrumbs from "./Breadcrumbs.svelte";
import DetailsWindow from "./DetailsWindow.svelte";
import FilePreview from "./viewers/FilePreview.svelte";
import FSUploadWidget from "./upload_widget/FSUploadWidget.svelte";
import { type FSPath } from "lib/FilesystemAPI.svelte";
import { global_navigator } from "./FSNavigator"
import { css_from_path } from "filesystem/edit_window/Branding";
import AffiliatePrompt from "user_home/AffiliatePrompt.svelte";
@@ -23,15 +22,7 @@ let details_window: DetailsWindow = $state()
const nav = global_navigator
onMount(() => {
if ((window as any).intial_node !== undefined) {
console.debug("Loading initial node")
nav.open_node((window as any).initial_node as FSPath, false)
} else {
console.debug("No initial node, fetching path", window.location.pathname)
nav.navigate(decodeURIComponent(window.location.pathname).replace(/^\/d/, ""), false)
}
// There is a global natigation handler which captures link clicks and loads
// There is a global navigation handler which captures link clicks and loads
// the right svelte components. When a filesystem link is clicked this store
// is updated. Catch it and use the filesystem navigator to navigate to the
// right file

View File

@@ -1,5 +1,4 @@
<script lang="ts">
import { preventDefault } from 'svelte/legacy';
import { onMount } from "svelte";
import { fs_mkdir } from "lib/FilesystemAPI.svelte";
import Button from "layout/Button.svelte";
@@ -11,7 +10,9 @@ let { nav }: { nav: FSNavigator } = $props();
let name_input: HTMLInputElement = $state();
let new_dir_name = $state("")
let error_msg = $state("")
let create_dir = async () => {
let create_dir = async (e: SubmitEvent) => {
e.preventDefault()
let form = new FormData()
form.append("type", "dir")
@@ -43,7 +44,7 @@ onMount(() => {
</div>
{/if}
<form id="create_dir_form" class="create_dir" onsubmit={preventDefault(create_dir)}>
<form id="create_dir_form" class="create_dir" onsubmit={create_dir}>
<img src="/res/img/mime/folder.png" class="icon" alt="icon"/>
<input class="dirname" type="text" bind:this={name_input} bind:value={new_dir_name} />
<Button form="create_dir_form" type="submit" icon="create_new_folder" label="Create"/>