Update a bunch of libraries to typescript
This commit is contained in:
63
svelte/package-lock.json
generated
63
svelte/package-lock.json
generated
@@ -10,7 +10,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"behave-js": "^1.5.0",
|
"behave-js": "^1.5.0",
|
||||||
"chart.js": "^4.2.0",
|
"chart.js": "^4.2.0",
|
||||||
"pure-color": "^1.3.0"
|
"pure-color": "^1.3.0",
|
||||||
|
"tslib": "^2.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.22.20",
|
"@babel/core": "^7.22.20",
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
"@rollup/plugin-commonjs": "^25.0.0",
|
"@rollup/plugin-commonjs": "^25.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.2.1",
|
"@rollup/plugin-node-resolve": "^15.2.1",
|
||||||
"@rollup/plugin-terser": "^0.4.3",
|
"@rollup/plugin-terser": "^0.4.3",
|
||||||
|
"@rollup/plugin-typescript": "^11.1.6",
|
||||||
"@types/jsmediatags": "^3.9.3",
|
"@types/jsmediatags": "^3.9.3",
|
||||||
"rollup": "^3.0.0",
|
"rollup": "^3.0.0",
|
||||||
"rollup-plugin-livereload": "^2.0.0",
|
"rollup-plugin-livereload": "^2.0.0",
|
||||||
@@ -1838,11 +1840,39 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/plugin-typescript": {
|
||||||
"version": "5.0.4",
|
"version": "11.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz",
|
||||||
"integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==",
|
"integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^5.1.0",
|
||||||
|
"resolve": "^1.22.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^2.14.0||^3.0.0||^4.0.0",
|
||||||
|
"tslib": "*",
|
||||||
|
"typescript": ">=3.7.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"rollup": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"tslib": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@rollup/pluginutils": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "^1.0.0",
|
"@types/estree": "^1.0.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
@@ -1852,7 +1882,7 @@
|
|||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"rollup": {
|
"rollup": {
|
||||||
@@ -3062,6 +3092,27 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||||
|
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/unicode-canonical-property-names-ecmascript": {
|
"node_modules/unicode-canonical-property-names-ecmascript": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
"@rollup/plugin-commonjs": "^25.0.0",
|
"@rollup/plugin-commonjs": "^25.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.2.1",
|
"@rollup/plugin-node-resolve": "^15.2.1",
|
||||||
"@rollup/plugin-terser": "^0.4.3",
|
"@rollup/plugin-terser": "^0.4.3",
|
||||||
|
"@rollup/plugin-typescript": "^11.1.6",
|
||||||
"@types/jsmediatags": "^3.9.3",
|
"@types/jsmediatags": "^3.9.3",
|
||||||
"rollup": "^3.0.0",
|
"rollup": "^3.0.0",
|
||||||
"rollup-plugin-livereload": "^2.0.0",
|
"rollup-plugin-livereload": "^2.0.0",
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"behave-js": "^1.5.0",
|
"behave-js": "^1.5.0",
|
||||||
"chart.js": "^4.2.0",
|
"chart.js": "^4.2.0",
|
||||||
"pure-color": "^1.3.0"
|
"pure-color": "^1.3.0",
|
||||||
|
"tslib": "^2.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ import commonjs from '@rollup/plugin-commonjs';
|
|||||||
import livereload from 'rollup-plugin-livereload';
|
import livereload from 'rollup-plugin-livereload';
|
||||||
import terser from '@rollup/plugin-terser';
|
import terser from '@rollup/plugin-terser';
|
||||||
import babel from '@rollup/plugin-babel'
|
import babel from '@rollup/plugin-babel'
|
||||||
|
import typescript from '@rollup/plugin-typescript'
|
||||||
|
|
||||||
const production = !process.env.ROLLUP_WATCH;
|
const production = !process.env.ROLLUP_WATCH;
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ export default [
|
|||||||
}),
|
}),
|
||||||
commonjs(),
|
commonjs(),
|
||||||
nodeResolve(),
|
nodeResolve(),
|
||||||
|
typescript({ compilerOptions: { lib: ["es2015", "dom"] } }),
|
||||||
|
|
||||||
// In dev mode, call `npm run start` once
|
// In dev mode, call `npm run start` once
|
||||||
// the bundle has been generated
|
// the bundle has been generated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { swipe_nav } from "./SwipeNavigate.svelte";
|
import { swipe_nav } from "./SwipeNavigate";
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
|
|
||||||
export const set_file = f => {
|
export const set_file = f => {
|
||||||
@@ -65,11 +65,7 @@ const mouseup = (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let swipe_style = ""
|
const on_load = () => dispatch("loading", false)
|
||||||
const on_load = () => {
|
|
||||||
dispatch("loading", false)
|
|
||||||
swipe_style = ""
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:mousemove={mousemove} on:mouseup={mouseup} />
|
<svelte:window on:mousemove={mousemove} on:mouseup={mouseup} />
|
||||||
@@ -78,8 +74,7 @@ const on_load = () => {
|
|||||||
bind:this={container}
|
bind:this={container}
|
||||||
class="container"
|
class="container"
|
||||||
class:zoom
|
class:zoom
|
||||||
use:swipe_nav={!zoom && is_list}
|
use:swipe_nav={{enabled: !zoom && is_list}}
|
||||||
on:style={e => swipe_style = e.detail}
|
|
||||||
on:prev
|
on:prev
|
||||||
on:next
|
on:next
|
||||||
>
|
>
|
||||||
@@ -92,9 +87,9 @@ const on_load = () => {
|
|||||||
on:mousedown={mousedown}
|
on:mousedown={mousedown}
|
||||||
class="image"
|
class="image"
|
||||||
class:zoom
|
class:zoom
|
||||||
style={swipe_style}
|
|
||||||
src={file.get_href}
|
src={file.get_href}
|
||||||
alt={file.name} />
|
alt={file.name}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@@ -1,41 +1,42 @@
|
|||||||
<script context="module">
|
|
||||||
// Dead zone before the swipe action gets detected
|
// Dead zone before the swipe action gets detected
|
||||||
const swipe_inital_offset = 25
|
const swipe_inital_offset = 25
|
||||||
// Amount of pixels after which the navigation triggers
|
// Amount of pixels after which the navigation triggers
|
||||||
const swipe_trigger_offset = 75
|
const swipe_trigger_offset = 75
|
||||||
|
|
||||||
export const swipe_nav = (node, swipe_enabled) => {
|
export const swipe_nav = (node: HTMLElement, props: { enabled: boolean, previous: boolean, next: boolean }) => {
|
||||||
let start_x = 0
|
let start_x = 0
|
||||||
let start_y = 0
|
let start_y = 0
|
||||||
let render_offset = 0
|
let render_offset = 0
|
||||||
let enabled = swipe_enabled
|
let enabled = props.enabled === undefined ? true : props.enabled
|
||||||
|
let previous = props.previous === undefined ? true : props.previous
|
||||||
|
let next = props.next === undefined ? true : props.next
|
||||||
|
|
||||||
const touchstart = e => {
|
const touchstart = (e: TouchEvent) => {
|
||||||
start_x = e.touches[0].clientX
|
start_x = e.touches[0].clientX
|
||||||
start_y = e.touches[0].clientY
|
start_y = e.touches[0].clientY
|
||||||
render_offset = 0
|
render_offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const touchmove = e => {
|
const touchmove = (e: TouchEvent) => {
|
||||||
if (!enabled) {
|
const offset_x = e.touches[0].clientX - start_x
|
||||||
|
if (!enabled || (offset_x < 0 && !next) || (offset_x > 0 && !previous)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const offset_x = e.touches[0].clientX - start_x
|
|
||||||
const abs_x = Math.abs(offset_x)
|
const abs_x = Math.abs(offset_x)
|
||||||
const abs_y = Math.abs(e.touches[0].clientY - start_y)
|
const abs_y = Math.abs(e.touches[0].clientY - start_y)
|
||||||
const neg = offset_x < 0 ? -1 : 1
|
const neg = offset_x < 0 ? -1 : 1
|
||||||
|
|
||||||
// The cursor must have moved at least 50 pixels and three times as much
|
// The cursor must have moved at least 50 pixels and three times as much
|
||||||
// on the x axis than the y axis for it to count as a swipe
|
// on the x axis than the y axis for it to count as a swipe
|
||||||
if (abs_x > swipe_inital_offset && abs_y < abs_x/3) {
|
if (abs_x > swipe_inital_offset && abs_y < abs_x / 3) {
|
||||||
set_offset((abs_x-swipe_inital_offset)*neg, false)
|
set_offset((abs_x - swipe_inital_offset) * neg, false)
|
||||||
} else {
|
} else {
|
||||||
set_offset(0, true)
|
set_offset(0, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const touchend = e => {
|
const touchend = (e: TouchEvent) => {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -51,32 +52,39 @@ export const swipe_nav = (node, swipe_enabled) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const set_offset = (off, animate) => {
|
const set_offset = (off: number, animate: boolean) => {
|
||||||
render_offset = off
|
render_offset = off
|
||||||
|
|
||||||
let detail = "transform: translateX("+off+"px);"
|
|
||||||
if (animate) {
|
|
||||||
detail += "transition: transform 400ms;"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the transformation if the offset is zero
|
|
||||||
if (off === 0) {
|
if (off === 0) {
|
||||||
detail = ""
|
// Clear the transformation if the offset is zero
|
||||||
|
node.style.transform = ""
|
||||||
|
node.style.transition = ""
|
||||||
|
} else {
|
||||||
|
node.style.transform = "translateX(" + off + "px)"
|
||||||
|
if (animate) {
|
||||||
|
node.style.transition = "transform 400ms"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node.dispatchEvent(new CustomEvent("style", {detail: detail}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node.addEventListener("touchstart", touchstart)
|
node.addEventListener("touchstart", touchstart)
|
||||||
node.addEventListener("touchmove", touchmove)
|
node.addEventListener("touchmove", touchmove)
|
||||||
node.addEventListener("touchend", touchend)
|
node.addEventListener("touchend", touchend)
|
||||||
|
|
||||||
return {
|
// Get the child image so we can listen for the loaded event. When the
|
||||||
update(swipe_enabled) {
|
// loaded event fires we clear the transformations so that the image appears
|
||||||
enabled = swipe_enabled
|
// in the original position again
|
||||||
if (!enabled) {
|
for (let i = 0; i < node.childNodes.length; i++) {
|
||||||
render_offset = 0
|
const child = node.childNodes.item(i)
|
||||||
|
if (child instanceof HTMLImageElement) {
|
||||||
|
child.addEventListener("load", () => set_offset(0, false))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
update(enabled: boolean) {
|
||||||
|
// enabled = swipe_enabled
|
||||||
|
set_offset(0, false)
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
node.removeEventListener("touchstart", touchstart)
|
node.removeEventListener("touchstart", touchstart)
|
||||||
@@ -85,4 +93,3 @@ export const swipe_nav = (node, swipe_enabled) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
|
@@ -8,10 +8,10 @@ import DetailsWindow from './DetailsWindow.svelte';
|
|||||||
import FilePreview from './viewers/FilePreview.svelte';
|
import FilePreview from './viewers/FilePreview.svelte';
|
||||||
import SearchView from './SearchView.svelte';
|
import SearchView from './SearchView.svelte';
|
||||||
import UploadWidget from './upload_widget/UploadWidget.svelte';
|
import UploadWidget from './upload_widget/UploadWidget.svelte';
|
||||||
import { fs_path_url } from './FilesystemUtil.js';
|
import { fs_path_url } from './FilesystemUtil';
|
||||||
import { branding_from_path } from './edit_window/Branding.js'
|
import { branding_from_path } from './edit_window/Branding.js'
|
||||||
import Menu from './Menu.svelte';
|
import Menu from './Menu.svelte';
|
||||||
import { Navigator } from "./Navigator.js"
|
import { Navigator } from "./Navigator"
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
let file_viewer
|
let file_viewer
|
||||||
|
@@ -1,124 +0,0 @@
|
|||||||
import { fs_path_url } from './FilesystemUtil.js'
|
|
||||||
|
|
||||||
export const fs_check_response = async resp => {
|
|
||||||
let text = await resp.text()
|
|
||||||
if (resp.status >= 400) {
|
|
||||||
let error
|
|
||||||
try {
|
|
||||||
error = JSON.parse(text)
|
|
||||||
} catch (err) {
|
|
||||||
error = text
|
|
||||||
}
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
return JSON.parse(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_mkdir = async (path, opts = null) => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("action", "mkdir")
|
|
||||||
|
|
||||||
if (opts && opts.mode) {
|
|
||||||
form.append("mode", opts.mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(path), { method: "POST", body: form })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_mkdirall = async (path, opts = null) => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("action", "mkdirall")
|
|
||||||
|
|
||||||
if (opts && opts.mode) {
|
|
||||||
form.append("mode", opts.mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(path), { method: "POST", body: form })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_get_node = async path => {
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(path) + "?stat")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates a node's parameters. Available options are:
|
|
||||||
// - created, Date object
|
|
||||||
// - modified, Date object
|
|
||||||
// - mode, file mode formatted as octal string
|
|
||||||
// - shared, boolean. If true the node will receive a public ID
|
|
||||||
//
|
|
||||||
// Returns the modified filesystem node object
|
|
||||||
export const fs_update = async (path, opts) => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("action", "update")
|
|
||||||
|
|
||||||
for (let key of Object.keys(opts)) {
|
|
||||||
if (key === "created" || key === "modified") {
|
|
||||||
form.append(key, opts[key].toISOString())
|
|
||||||
} else {
|
|
||||||
form.append(key, opts[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(path), { method: "POST", body: form })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_rename = async (old_path, new_path) => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("action", "rename")
|
|
||||||
form.append("target", new_path)
|
|
||||||
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(old_path), { method: "POST", body: form })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_delete = async path => {
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(path), { method: "DELETE" })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export const fs_delete_all = async path => {
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(path) + "?recursive", { method: "DELETE" })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_search = async (path, term, limit = 10) => {
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(
|
|
||||||
fs_path_url(path) +
|
|
||||||
"?search=" + encodeURIComponent(term) +
|
|
||||||
"&limit=" + limit
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_timeseries = async (path, start, end, interval = 60) => {
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(
|
|
||||||
fs_path_url(path) +
|
|
||||||
"?timeseries" +
|
|
||||||
"&start=" + start.toISOString() +
|
|
||||||
"&end=" + end.toISOString() +
|
|
||||||
"&interval=" + interval
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_import = async (parent_dir_path = "", filelist = []) => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("action", "import")
|
|
||||||
form.append("files", JSON.stringify(filelist))
|
|
||||||
|
|
||||||
return await fs_check_response(
|
|
||||||
await fetch(fs_path_url(parent_dir_path), { method: "POST", body: form })
|
|
||||||
)
|
|
||||||
}
|
|
184
svelte/src/filesystem/FilesystemAPI.ts
Normal file
184
svelte/src/filesystem/FilesystemAPI.ts
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
import { fs_path_url } from './FilesystemUtil'
|
||||||
|
|
||||||
|
export type GenericResponse = {
|
||||||
|
value: string,
|
||||||
|
message: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_check_response = async (resp: Response) => {
|
||||||
|
let text = await resp.text()
|
||||||
|
if (resp.status >= 400) {
|
||||||
|
let error: any
|
||||||
|
try {
|
||||||
|
error = JSON.parse(text) as GenericResponse
|
||||||
|
} catch (err) {
|
||||||
|
error = text
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
return JSON.parse(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NodeOptions = {
|
||||||
|
mode: number | undefined,
|
||||||
|
created: Date | undefined,
|
||||||
|
modified: Date | undefined,
|
||||||
|
shared: boolean | undefined,
|
||||||
|
|
||||||
|
branding_enabled: boolean | undefined,
|
||||||
|
brand_input_color: string | undefined,
|
||||||
|
brand_highlight_color: string | undefined,
|
||||||
|
brand_danger_color: string | undefined,
|
||||||
|
brand_background_color: string | undefined,
|
||||||
|
brand_body_color: string | undefined,
|
||||||
|
brand_card_color: string | undefined,
|
||||||
|
brand_header_image: string | undefined,
|
||||||
|
brand_header_link: string | undefined,
|
||||||
|
brand_background_image: string | undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
// mkdir only supports the "mode" option
|
||||||
|
export const fs_mkdir = async (path: string, opts: NodeOptions) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "mkdir")
|
||||||
|
|
||||||
|
if (opts && opts.mode) {
|
||||||
|
form.append("mode", opts.mode.toFixed(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(path), { method: "POST", body: form })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_mkdirall = async (path: string, opts: NodeOptions) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "mkdirall")
|
||||||
|
|
||||||
|
if (opts && opts.mode) {
|
||||||
|
form.append("mode", opts.mode.toFixed(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(path), { method: "POST", body: form })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FSPath = {
|
||||||
|
path: Array<FSNode>,
|
||||||
|
base_index: number,
|
||||||
|
children: Array<FSNode>,
|
||||||
|
permissions: FSPermissions,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FSNode = {
|
||||||
|
type: string,
|
||||||
|
path: string,
|
||||||
|
name: string,
|
||||||
|
created: Date,
|
||||||
|
modified: Date,
|
||||||
|
mode_string: string,
|
||||||
|
mode_octal: string,
|
||||||
|
|
||||||
|
abuse_type: string | undefined,
|
||||||
|
abuse_report_time: Date | undefined,
|
||||||
|
|
||||||
|
file_size: number,
|
||||||
|
file_type: string,
|
||||||
|
sha256_sum: string,
|
||||||
|
|
||||||
|
id: string | undefined,
|
||||||
|
read_password: string | undefined,
|
||||||
|
write_password: string | undefined,
|
||||||
|
properties: {} | undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FSPermissions = {
|
||||||
|
create: boolean,
|
||||||
|
read: boolean,
|
||||||
|
update: boolean,
|
||||||
|
delete: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_get_node = async (path: string) => {
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(path) + "?stat")
|
||||||
|
) as FSPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates a node's parameters. Available options are:
|
||||||
|
// - created, Date object
|
||||||
|
// - modified, Date object
|
||||||
|
// - mode, file mode formatted as octal string
|
||||||
|
// - shared, boolean. If true the node will receive a public ID
|
||||||
|
//
|
||||||
|
// Returns the modified filesystem node object
|
||||||
|
export const fs_update = async (path: string, opts: NodeOptions) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "update")
|
||||||
|
|
||||||
|
for (let key of Object.keys(opts)) {
|
||||||
|
if ((key === "created" || key === "modified") && opts[key] !== undefined) {
|
||||||
|
form.append(key, opts[key].toISOString())
|
||||||
|
} else {
|
||||||
|
form.append(key, opts[key])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(path), { method: "POST", body: form })
|
||||||
|
) as FSNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_rename = async (old_path: string, new_path: string) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "rename")
|
||||||
|
form.append("target", new_path)
|
||||||
|
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(old_path), { method: "POST", body: form })
|
||||||
|
) as FSNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_delete = async (path: string) => {
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(path), { method: "DELETE" })
|
||||||
|
) as GenericResponse
|
||||||
|
}
|
||||||
|
export const fs_delete_all = async (path: string) => {
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(path) + "?recursive", { method: "DELETE" })
|
||||||
|
) as GenericResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_search = async (path: string, term: string, limit = 10) => {
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(
|
||||||
|
fs_path_url(path) +
|
||||||
|
"?search=" + encodeURIComponent(term) +
|
||||||
|
"&limit=" + limit
|
||||||
|
)
|
||||||
|
) as Array<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_timeseries = async (path: string, start: Date, end: Date, interval = 60) => {
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(
|
||||||
|
fs_path_url(path) +
|
||||||
|
"?timeseries" +
|
||||||
|
"&start=" + start.toISOString() +
|
||||||
|
"&end=" + end.toISOString() +
|
||||||
|
"&interval=" + interval
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_import = async (parent_dir_path = "", filelist: Array<string>) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "import")
|
||||||
|
form.append("files", JSON.stringify(filelist))
|
||||||
|
|
||||||
|
return await fs_check_response(
|
||||||
|
await fetch(fs_path_url(parent_dir_path), { method: "POST", body: form })
|
||||||
|
) as GenericResponse
|
||||||
|
}
|
@@ -1,9 +1,11 @@
|
|||||||
export const fs_split_path = path => {
|
import { FSNode } from "./FilesystemAPI"
|
||||||
|
|
||||||
|
export const fs_split_path = (path: string) => {
|
||||||
let patharr = path.split("/")
|
let patharr = path.split("/")
|
||||||
return { base: patharr.pop(), parent: patharr.join("/") }
|
return { base: patharr.pop(), parent: patharr.join("/") }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fs_encode_path = path => {
|
export const fs_encode_path = (path: string) => {
|
||||||
// Encode all path elements separately to preserve forward slashes
|
// Encode all path elements separately to preserve forward slashes
|
||||||
let split = path.split("/")
|
let split = path.split("/")
|
||||||
for (let i = 0; i < split.length; i++) {
|
for (let i = 0; i < split.length; i++) {
|
||||||
@@ -12,21 +14,26 @@ export const fs_encode_path = path => {
|
|||||||
return split.join("/")
|
return split.join("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fs_path_url = path => {
|
export const fs_path_url = (path: string) => {
|
||||||
if (!path || path.length === 0) {
|
if (!path || path.length === 0) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if (path[0] !== "/") {
|
if (path[0] !== "/") {
|
||||||
path = "/" + path
|
path = "/" + path
|
||||||
}
|
}
|
||||||
return window.api_endpoint + "/filesystem" + fs_encode_path(path)
|
|
||||||
|
if (window["api_endpoint"] !== undefined) {
|
||||||
|
return window["api_endpoint"] + "/filesystem" + fs_encode_path(path)
|
||||||
|
} else {
|
||||||
|
throw Error("api_endpoint is undefined")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fs_thumbnail_url = (path, width = 64, height = 64) => {
|
export const fs_thumbnail_url = (path: string, width = 64, height = 64) => {
|
||||||
return fs_path_url(path) + "?thumbnail&width=" + width + "&height=" + height
|
return fs_path_url(path) + "?thumbnail&width=" + width + "&height=" + height
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fs_node_type = node => {
|
export const fs_node_type = (node: FSNode) => {
|
||||||
if (node.type === "dir") {
|
if (node.type === "dir") {
|
||||||
return "dir"
|
return "dir"
|
||||||
} else if (node.file_type === "application/bittorrent" || node.file_type === "application/x-bittorrent") {
|
} else if (node.file_type === "application/bittorrent" || node.file_type === "application/x-bittorrent") {
|
||||||
@@ -62,7 +69,7 @@ export const fs_node_type = node => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fs_node_icon = (node, width = 64, height = 64) => {
|
export const fs_node_icon = (node: FSNode, width = 64, height = 64) => {
|
||||||
if (node.type === "dir") {
|
if (node.type === "dir") {
|
||||||
// Folders with an ID are publically shared, use the shared folder icon
|
// Folders with an ID are publically shared, use the shared folder icon
|
||||||
if (node.id) {
|
if (node.id) {
|
@@ -1,15 +1,16 @@
|
|||||||
import { fs_get_node } from "./FilesystemAPI";
|
import { fs_get_node, FSNode, FSPath, FSPermissions } from "./FilesystemAPI";
|
||||||
import { fs_encode_path, fs_split_path } from "./FilesystemUtil";
|
import { fs_encode_path, fs_split_path } from "./FilesystemUtil";
|
||||||
|
import { Writable } from "svelte/store"
|
||||||
|
|
||||||
export class Navigator {
|
export class Navigator {
|
||||||
// Parts of the raw API response
|
// Parts of the raw API response
|
||||||
path = []
|
path: Array<FSNode> = []
|
||||||
base_index = 0
|
base_index: number = 0
|
||||||
children = []
|
children: Array<FSNode> = []
|
||||||
permissions = {}
|
permissions: FSPermissions = <FSPermissions>{}
|
||||||
|
|
||||||
// base equals path[base_index]. It's updated every time the path updates
|
// base equals path[base_index]. It's updated every time the path updates
|
||||||
base = {}
|
base: FSNode = <FSNode>{}
|
||||||
|
|
||||||
// Initialized will be set to true when the first file or directory is loaded
|
// Initialized will be set to true when the first file or directory is loaded
|
||||||
initialized = false
|
initialized = false
|
||||||
@@ -36,9 +37,9 @@ export class Navigator {
|
|||||||
|
|
||||||
// If you set the loading property to a boolean writable store the navigator
|
// If you set the loading property to a boolean writable store the navigator
|
||||||
// will use it to publish its loading states
|
// will use it to publish its loading states
|
||||||
loading = null
|
loading: Writable<boolean> | null = null
|
||||||
set_loading(b) {
|
set_loading(b: boolean) {
|
||||||
if (this.loading !== null && this.loading.set !== undefined) {
|
if (this.loading !== null) {
|
||||||
this.loading.set(b)
|
this.loading.set(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,20 +47,18 @@ export class Navigator {
|
|||||||
// The Navigator acts as a svelte store. This allows for DOM reactivity.
|
// The Navigator acts as a svelte store. This allows for DOM reactivity.
|
||||||
// This works by implementing the store contract:
|
// This works by implementing the store contract:
|
||||||
// https://svelte.dev/docs/svelte-components#script-4-prefix-stores-with-$-to-access-their-values
|
// https://svelte.dev/docs/svelte-components#script-4-prefix-stores-with-$-to-access-their-values
|
||||||
subscribers = []
|
subscribers: Array<(nav: Navigator) => void> = []
|
||||||
subscribe(sub_func) {
|
subscribe(sub_func: (nav: Navigator) => void) {
|
||||||
// Immediately return the current value
|
// Immediately return the current value
|
||||||
sub_func(this)
|
sub_func(this)
|
||||||
|
|
||||||
this.subscribers.push(sub_func)
|
this.subscribers.push(sub_func)
|
||||||
|
|
||||||
// Return the unsubscribe function
|
// Return the unsubscribe function
|
||||||
return () => {
|
return () => this.subscribers.splice(this.subscribers.indexOf(sub_func), 1)
|
||||||
this.subscribers.splice(this.subscribers.indexOf(sub_func), 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async navigate(path, push_history) {
|
async navigate(path: string, push_history: boolean) {
|
||||||
if (path[0] !== "/") {
|
if (path[0] !== "/") {
|
||||||
path = "/" + path
|
path = "/" + path
|
||||||
}
|
}
|
||||||
@@ -90,7 +89,7 @@ export class Navigator {
|
|||||||
|
|
||||||
async navigate_up() {
|
async navigate_up() {
|
||||||
if (this.path.length > 1) {
|
if (this.path.length > 1) {
|
||||||
await this.navigate(this.path[this.path.length - 2].path)
|
await this.navigate(this.path[this.path.length - 2].path, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ export class Navigator {
|
|||||||
await this.navigate(this.base.path, false)
|
await this.navigate(this.base.path, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
open_node(node, push_history) {
|
open_node(node: FSPath, push_history: boolean) {
|
||||||
// Update window title and navigation history. If push_history is false
|
// Update window title and navigation history. If push_history is false
|
||||||
// we still replace the URL with replaceState. This way the user is not
|
// we still replace the URL with replaceState. This way the user is not
|
||||||
// greeted to a 404 page when refreshing after renaming a file
|
// greeted to a 404 page when refreshing after renaming a file
|
||||||
@@ -148,7 +147,7 @@ export class Navigator {
|
|||||||
// directory is still the same. If it's different the siblings array is not
|
// directory is still the same. If it's different the siblings array is not
|
||||||
// used
|
// used
|
||||||
cached_siblings_path = ""
|
cached_siblings_path = ""
|
||||||
cached_siblings = null
|
cached_siblings: Array<FSNode> | null = null
|
||||||
|
|
||||||
async get_siblings() {
|
async get_siblings() {
|
||||||
// Check if we already have siblings cached
|
// Check if we already have siblings cached
|
||||||
@@ -173,13 +172,12 @@ export class Navigator {
|
|||||||
// Opens a sibling of the currently open file. The offset is relative to the
|
// Opens a sibling of the currently open file. The offset is relative to the
|
||||||
// file which is currently open. Give a positive number to move forward and
|
// file which is currently open. Give a positive number to move forward and
|
||||||
// a negative number to move backward
|
// a negative number to move backward
|
||||||
async open_sibling(offset) {
|
async open_sibling(offset: number) {
|
||||||
if (this.path.length <= 1) {
|
if (this.path.length <= 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let siblings: Array<FSNode>
|
||||||
let siblings
|
|
||||||
try {
|
try {
|
||||||
this.set_loading(true)
|
this.set_loading(true)
|
||||||
siblings = await this.get_siblings()
|
siblings = await this.get_siblings()
|
||||||
@@ -191,7 +189,7 @@ export class Navigator {
|
|||||||
this.set_loading(false)
|
this.set_loading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_sibling = null
|
let next_sibling: FSNode | null = null
|
||||||
|
|
||||||
if (this.shuffle) {
|
if (this.shuffle) {
|
||||||
// Shuffle is on, pick a random sibling
|
// Shuffle is on, pick a random sibling
|
||||||
@@ -230,7 +228,7 @@ export class Navigator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sort_children = (children) => {
|
const sort_children = (children: Array<FSNode>) => {
|
||||||
children.sort((a, b) => {
|
children.sort((a, b) => {
|
||||||
// Sort directories before files
|
// Sort directories before files
|
||||||
if (a.type !== b.type) {
|
if (a.type !== b.type) {
|
@@ -22,7 +22,7 @@ const delete_file = async e => {
|
|||||||
alert(err)
|
alert(err)
|
||||||
return
|
return
|
||||||
} finally {
|
} finally {
|
||||||
nac.set_loading(false)
|
nav.set_loading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_after_edit) {
|
if (open_after_edit) {
|
||||||
@@ -32,7 +32,6 @@ const delete_file = async e => {
|
|||||||
}
|
}
|
||||||
visible = false
|
visible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h2>File settings</h2>
|
<h2>File settings</h2>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_delete_all, fs_rename } from './../FilesystemAPI.js'
|
import { fs_delete_all, fs_rename } from './../FilesystemAPI.ts'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import CreateDirectory from './CreateDirectory.svelte'
|
import CreateDirectory from './CreateDirectory.svelte'
|
||||||
import ListView from './ListView.svelte'
|
import ListView from './ListView.svelte'
|
||||||
@@ -103,7 +103,9 @@ const delete_selected = async () => {
|
|||||||
// Save all promises with deletion requests in an array
|
// Save all promises with deletion requests in an array
|
||||||
let promises = []
|
let promises = []
|
||||||
nav.children.forEach(child => {
|
nav.children.forEach(child => {
|
||||||
if (!child.fm_selected) { return }
|
if (!child.fm_selected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
promises.push(fs_delete_all(child.path))
|
promises.push(fs_delete_all(child.path))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -96,7 +96,7 @@ export let hide_branding = false
|
|||||||
border-bottom: 1px solid var(--separator);
|
border-bottom: 1px solid var(--separator);
|
||||||
}
|
}
|
||||||
.node:hover:not(.node_selected) {
|
.node:hover:not(.node_selected) {
|
||||||
background: var(--input_background);
|
background: var(--input_hover_background);
|
||||||
color: var(--input_text);
|
color: var(--input_text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@@ -13,12 +13,39 @@ const paste = (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const can_upload = e => {
|
||||||
|
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < e.dataTransfer.items.length; i++) {
|
||||||
|
if (e.dataTransfer.items[i].kind === "file") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const dragover = e => {
|
||||||
|
if (can_upload(e)) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
dragging = true
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const dragleave = e => {
|
||||||
|
dragging = false
|
||||||
|
}
|
||||||
const drop = async e => {
|
const drop = async e => {
|
||||||
dragging = false;
|
dragging = false;
|
||||||
|
|
||||||
if (e.dataTransfer.files || e.dataTransfer.items) {
|
if (can_upload(e)) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
} else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// if directory support is available
|
// if directory support is available
|
||||||
@@ -26,7 +53,7 @@ const drop = async e => {
|
|||||||
for (let i = 0; i < e.dataTransfer.items.length; i++) {
|
for (let i = 0; i < e.dataTransfer.items.length; i++) {
|
||||||
let entry = await e.dataTransfer.items[i].webkitGetAsEntry();
|
let entry = await e.dataTransfer.items[i].webkitGetAsEntry();
|
||||||
if (entry) {
|
if (entry) {
|
||||||
await read_dir_recursive(entry);
|
read_dir_recursive(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
} else if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
||||||
@@ -50,9 +77,9 @@ const read_dir_recursive = item => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window
|
<svelte:window
|
||||||
on:dragover|preventDefault|stopPropagation={() => { dragging = true }}
|
on:dragover={dragover}
|
||||||
on:dragenter|preventDefault|stopPropagation={() => { dragging = true }}
|
on:dragenter={dragover}
|
||||||
on:dragleave|preventDefault|stopPropagation={() => { dragging = false }}
|
on:dragleave={dragleave}
|
||||||
on:drop={drop}
|
on:drop={drop}
|
||||||
on:paste={paste}
|
on:paste={paste}
|
||||||
/>
|
/>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
import { swipe_nav } from "../../file_viewer/viewers/SwipeNavigate.svelte";
|
import { swipe_nav } from "../../file_viewer/viewers/SwipeNavigate.ts";
|
||||||
import { fs_path_url } from "../FilesystemUtil";
|
import { fs_path_url } from "../FilesystemUtil";
|
||||||
|
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
@@ -15,11 +15,7 @@ export const update = () => {
|
|||||||
dispatch("loading", true)
|
dispatch("loading", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
let swipe_style = ""
|
const on_load = () => dispatch("loading", false)
|
||||||
const on_load = () => {
|
|
||||||
dispatch("loading", false)
|
|
||||||
swipe_style = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const mousedown = (e) => {
|
const mousedown = (e) => {
|
||||||
if (!dragging && e.which === 1 && zoom) {
|
if (!dragging && e.which === 1 && zoom) {
|
||||||
@@ -62,8 +58,7 @@ const mouseup = (e) => {
|
|||||||
bind:this={container}
|
bind:this={container}
|
||||||
class="container"
|
class="container"
|
||||||
class:zoom
|
class:zoom
|
||||||
use:swipe_nav={!zoom}
|
use:swipe_nav={{enabled: !zoom, previous: false, next: true}}
|
||||||
on:style={e => swipe_style = e.detail}
|
|
||||||
on:prev={() => nav.open_sibling(-1)}
|
on:prev={() => nav.open_sibling(-1)}
|
||||||
on:next={() => nav.open_sibling(1)}
|
on:next={() => nav.open_sibling(1)}
|
||||||
>
|
>
|
||||||
@@ -76,9 +71,9 @@ const mouseup = (e) => {
|
|||||||
on:error={on_load}
|
on:error={on_load}
|
||||||
class="image"
|
class="image"
|
||||||
class:zoom
|
class:zoom
|
||||||
style={swipe_style}
|
|
||||||
src={fs_path_url($nav.base.path)}
|
src={fs_path_url($nav.base.path)}
|
||||||
alt="no description available" />
|
alt="no description available"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@@ -90,6 +90,7 @@ header > h1 {
|
|||||||
.header_image_container {
|
.header_image_container {
|
||||||
text-align: initial;
|
text-align: initial;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
margin-bottom: 1.5em; /*Offset for menu button*/
|
||||||
height: 150px;
|
height: 150px;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@@ -408,7 +408,7 @@ const node_click = (index) => {
|
|||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
}
|
}
|
||||||
.node:hover:not(.node_selected) {
|
.node:hover:not(.node_selected) {
|
||||||
background: var(--input_background);
|
background: var(--input_hover_background);
|
||||||
color: var(--input_text);
|
color: var(--input_text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@@ -557,7 +557,8 @@ footer, .footer_content,
|
|||||||
.file, .file_button,
|
.file, .file_button,
|
||||||
.upload_task,
|
.upload_task,
|
||||||
.add_button,
|
.add_button,
|
||||||
.expandable {
|
.expandable,
|
||||||
|
.upload_widget {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
box-shadow: inset -1px -1px #0a0a0a,
|
box-shadow: inset -1px -1px #0a0a0a,
|
||||||
@@ -569,7 +570,8 @@ footer, .footer_content,
|
|||||||
padding: 3px !important;
|
padding: 3px !important;
|
||||||
}
|
}
|
||||||
.window > .header,
|
.window > .header,
|
||||||
.headerbar {
|
.headerbar,
|
||||||
|
.upload_widget > .header {
|
||||||
background: linear-gradient(90deg,navy,#1084d0) !important;
|
background: linear-gradient(90deg,navy,#1084d0) !important;
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user