Add file tree to menu
This commit is contained in:
@@ -273,3 +273,5 @@ const sort_children = (children: FSNode[], field: string, asc: boolean) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export let global_navigator = new FSNavigator(true)
|
||||
|
||||
@@ -7,7 +7,7 @@ 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 { FSNavigator } from "./FSNavigator"
|
||||
import { global_navigator } from "./FSNavigator"
|
||||
import { css_from_path } from "filesystem/edit_window/Branding";
|
||||
import AffiliatePrompt from "user_home/AffiliatePrompt.svelte";
|
||||
import { current_page_store } from "wrap/RouterStore";
|
||||
@@ -20,7 +20,7 @@ let edit_window: EditWindow = $state()
|
||||
let edit_visible = $state(false)
|
||||
let details_window: DetailsWindow = $state()
|
||||
|
||||
const nav = $state(new FSNavigator(true))
|
||||
const nav = global_navigator
|
||||
|
||||
onMount(() => {
|
||||
if ((window as any).intial_node !== undefined) {
|
||||
|
||||
@@ -113,9 +113,9 @@ const add_styles = (style: Style, properties: FSNodeProperties) => {
|
||||
|
||||
const add_contrast = (color: string, amt: number) => {
|
||||
let hsl = rgb2hsl(parse(color)) // Convert hex to hsl
|
||||
// If the lightness is less than 40 it is considered a dark colour. This
|
||||
// threshold is 40 instead of 50 because overall dark text is more legible
|
||||
if (hsl[2] < 40) {
|
||||
// If the lightness is less than 30 it is considered a dark colour. This
|
||||
// threshold is 30 instead of 50 because overall dark text is more legible
|
||||
if (hsl[2] < 30) {
|
||||
hsl[2] = hsl[2] + amt // Dark color, add lightness
|
||||
} else {
|
||||
hsl[2] = hsl[2] - amt // Light color, remove lightness
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { fs_rename, fs_update, type FSNode, type NodeOptions } from "lib/FilesystemAPI.svelte";
|
||||
import { fs_rename, fs_update, type FSNode, type FSPermissions, type NodeOptions } from "lib/FilesystemAPI.svelte";
|
||||
import Modal from "util/Modal.svelte";
|
||||
import BrandingOptions from "./BrandingOptions.svelte";
|
||||
import { branding_from_props } from "./Branding";
|
||||
@@ -22,6 +22,10 @@ let {
|
||||
visible: boolean;
|
||||
} = $props();
|
||||
|
||||
const default_permissions: FSPermissions = {
|
||||
owner: false, read: false, write: false, delete: false
|
||||
}
|
||||
|
||||
// Open the edit window. Argument 1 is the file to edit, 2 is whether the file
|
||||
// should be opened after the user finishes editing and 3 is the default tab
|
||||
// that should be open when the window shows
|
||||
@@ -45,9 +49,9 @@ export const edit = (f: FSNode, oae = false, open_tab = "") => {
|
||||
}
|
||||
|
||||
options.custom_domain_name = file.custom_domain_name
|
||||
options.link_permissions = file.link_permissions
|
||||
options.user_permissions = file.user_permissions
|
||||
options.password_permissions = file.password_permissions
|
||||
options.link_permissions = file.link_permissions === undefined ? default_permissions : file.link_permissions
|
||||
options.user_permissions = file.user_permissions === undefined ? {} : file.user_permissions
|
||||
options.password_permissions = file.password_permissions === undefined ? {} : file.password_permissions
|
||||
|
||||
branding_enabled = options.branding_enabled === "true"
|
||||
if (branding_enabled) {
|
||||
|
||||
@@ -112,7 +112,6 @@ td {
|
||||
color: var(--highlight_text_color);
|
||||
}
|
||||
td {
|
||||
padding: 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.node_icon {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { onMount } from 'svelte'
|
||||
import { fs_path_url, fs_encode_path, fs_node_icon, FSNode } from "lib/FilesystemAPI.svelte"
|
||||
import TextBlock from "layout/TextBlock.svelte"
|
||||
import type { FSNavigator } from 'filesystem/FSNavigator';
|
||||
import { branding_from_props } from 'filesystem/edit_window/Branding';
|
||||
|
||||
let { nav, children }: {
|
||||
nav: FSNavigator;
|
||||
@@ -28,6 +27,7 @@ export const seek = (delta: number) => {
|
||||
}
|
||||
}
|
||||
|
||||
var background_div: HTMLDivElement
|
||||
export const update = async () => {
|
||||
if (media_session) {
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
@@ -41,12 +41,8 @@ export const update = async () => {
|
||||
|
||||
for(const sib of siblings) {
|
||||
if (sib.name === "cover.jpg") {
|
||||
console.log("found sibling", sib)
|
||||
if (sib.properties === undefined) {
|
||||
sib.properties = {}
|
||||
}
|
||||
sib.properties.brand_background_image = sib.path
|
||||
document.documentElement.style = branding_from_props(sib.properties)
|
||||
console.debug("Found album cover image", sib)
|
||||
background_div.style.backgroundImage = `url("/api/filesystem/${sib.path}")`
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -66,47 +62,55 @@ onMount(() => {
|
||||
|
||||
{@render children?.()}
|
||||
|
||||
<TextBlock width="1000px">
|
||||
<audio
|
||||
bind:this={player}
|
||||
class="player"
|
||||
src={fs_path_url($nav.base.path)}
|
||||
autoplay
|
||||
controls
|
||||
onpause={() => playing = false}
|
||||
onplay={() => playing = true}
|
||||
onended={() => nav.open_sibling(1)}>
|
||||
<track kind="captions"/>
|
||||
</audio>
|
||||
<div style="text-align: center;">
|
||||
<button onclick={() => nav.open_sibling(-1)}><i class="icon">skip_previous</i></button>
|
||||
<button onclick={() => seek(-10)}><i class="icon">replay_10</i></button>
|
||||
<button onclick={toggle_playback}>
|
||||
{#if playing}
|
||||
<i class="icon">pause</i>
|
||||
{:else}
|
||||
<i class="icon">play_arrow</i>
|
||||
{/if}
|
||||
</button>
|
||||
<button onclick={() => seek(10)}><i class="icon">forward_10</i></button>
|
||||
<button onclick={() => nav.open_sibling(1)}><i class="icon">skip_next</i></button>
|
||||
</div>
|
||||
<div bind:this={background_div} class="background_div">
|
||||
<TextBlock width="1000px">
|
||||
<audio
|
||||
bind:this={player}
|
||||
class="player"
|
||||
src={fs_path_url($nav.base.path)}
|
||||
autoplay
|
||||
controls
|
||||
onpause={() => playing = false}
|
||||
onplay={() => playing = true}
|
||||
onended={() => nav.open_sibling(1)}>
|
||||
<track kind="captions"/>
|
||||
</audio>
|
||||
<div style="text-align: center;">
|
||||
<button onclick={() => nav.open_sibling(-1)}><i class="icon">skip_previous</i></button>
|
||||
<button onclick={() => seek(-10)}><i class="icon">replay_10</i></button>
|
||||
<button onclick={toggle_playback}>
|
||||
{#if playing}
|
||||
<i class="icon">pause</i>
|
||||
{:else}
|
||||
<i class="icon">play_arrow</i>
|
||||
{/if}
|
||||
</button>
|
||||
<button onclick={() => seek(10)}><i class="icon">forward_10</i></button>
|
||||
<button onclick={() => nav.open_sibling(1)}><i class="icon">skip_next</i></button>
|
||||
</div>
|
||||
|
||||
<h2>Tracklist</h2>
|
||||
{#each siblings as sibling (sibling.path)}
|
||||
<a href={"/d"+fs_encode_path(sibling.path)} class="node">
|
||||
{#if sibling.path === $nav.base.path}
|
||||
<i class="play_arrow icon">play_arrow</i>
|
||||
{:else}
|
||||
<img src={fs_node_icon(sibling, 64, 64)} class="node_icon" alt="icon"/>
|
||||
{/if}
|
||||
<span>{sibling.name}</span>
|
||||
<br/>
|
||||
</a>
|
||||
{/each}
|
||||
</TextBlock>
|
||||
<h2>Tracklist</h2>
|
||||
{#each siblings as sibling (sibling.path)}
|
||||
<a href={"/d"+fs_encode_path(sibling.path)} class="node">
|
||||
{#if sibling.path === $nav.base.path}
|
||||
<i class="play_arrow icon">play_arrow</i>
|
||||
{:else}
|
||||
<img src={fs_node_icon(sibling, 64, 64)} class="node_icon" alt="icon"/>
|
||||
{/if}
|
||||
<span>{sibling.name}</span>
|
||||
<br/>
|
||||
</a>
|
||||
{/each}
|
||||
</TextBlock>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.background_div {
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
min-height: 100%;
|
||||
}
|
||||
.player {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user