Update a bunch of libraries to typescript

This commit is contained in:
2024-08-30 15:16:01 +02:00
parent c152f36f49
commit c75cbb2e3f
18 changed files with 370 additions and 222 deletions

View File

@@ -10,7 +10,8 @@
"dependencies": {
"behave-js": "^1.5.0",
"chart.js": "^4.2.0",
"pure-color": "^1.3.0"
"pure-color": "^1.3.0",
"tslib": "^2.7.0"
},
"devDependencies": {
"@babel/core": "^7.22.20",
@@ -19,6 +20,7 @@
"@rollup/plugin-commonjs": "^25.0.0",
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-terser": "^0.4.3",
"@rollup/plugin-typescript": "^11.1.6",
"@types/jsmediatags": "^3.9.3",
"rollup": "^3.0.0",
"rollup-plugin-livereload": "^2.0.0",
@@ -1838,11 +1840,39 @@
}
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz",
"integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==",
"node_modules/@rollup/plugin-typescript": {
"version": "11.1.6",
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz",
"integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==",
"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": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
@@ -1852,7 +1882,7 @@
"node": ">=14.0.0"
},
"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": {
"rollup": {
@@ -3062,6 +3092,27 @@
"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": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",

View File

@@ -13,6 +13,7 @@
"@rollup/plugin-commonjs": "^25.0.0",
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-terser": "^0.4.3",
"@rollup/plugin-typescript": "^11.1.6",
"@types/jsmediatags": "^3.9.3",
"rollup": "^3.0.0",
"rollup-plugin-livereload": "^2.0.0",
@@ -22,6 +23,7 @@
"dependencies": {
"behave-js": "^1.5.0",
"chart.js": "^4.2.0",
"pure-color": "^1.3.0"
"pure-color": "^1.3.0",
"tslib": "^2.7.0"
}
}

View File

@@ -4,6 +4,7 @@ import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import terser from '@rollup/plugin-terser';
import babel from '@rollup/plugin-babel'
import typescript from '@rollup/plugin-typescript'
const production = !process.env.ROLLUP_WATCH;
@@ -57,6 +58,7 @@ export default [
}),
commonjs(),
nodeResolve(),
typescript({ compilerOptions: { lib: ["es2015", "dom"] } }),
// In dev mode, call `npm run start` once
// the bundle has been generated

View File

@@ -1,6 +1,6 @@
<script>
import { createEventDispatcher } from "svelte"
import { swipe_nav } from "./SwipeNavigate.svelte";
import { swipe_nav } from "./SwipeNavigate";
let dispatch = createEventDispatcher()
export const set_file = f => {
@@ -65,11 +65,7 @@ const mouseup = (e) => {
}
}
let swipe_style = ""
const on_load = () => {
dispatch("loading", false)
swipe_style = ""
}
const on_load = () => dispatch("loading", false)
</script>
<svelte:window on:mousemove={mousemove} on:mouseup={mouseup} />
@@ -78,8 +74,7 @@ const on_load = () => {
bind:this={container}
class="container"
class:zoom
use:swipe_nav={!zoom && is_list}
on:style={e => swipe_style = e.detail}
use:swipe_nav={{enabled: !zoom && is_list}}
on:prev
on:next
>
@@ -92,9 +87,9 @@ const on_load = () => {
on:mousedown={mousedown}
class="image"
class:zoom
style={swipe_style}
src={file.get_href}
alt={file.name} />
alt={file.name}
/>
</div>
<style>

View File

@@ -1,41 +1,42 @@
<script context="module">
// Dead zone before the swipe action gets detected
const swipe_inital_offset = 25
// Amount of pixels after which the navigation triggers
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_y = 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_y = e.touches[0].clientY
render_offset = 0
}
const touchmove = e => {
if (!enabled) {
const touchmove = (e: TouchEvent) => {
const offset_x = e.touches[0].clientX - start_x
if (!enabled || (offset_x < 0 && !next) || (offset_x > 0 && !previous)) {
return
}
const offset_x = e.touches[0].clientX - start_x
const abs_x = Math.abs(offset_x)
const abs_y = Math.abs(e.touches[0].clientY - start_y)
const neg = offset_x < 0 ? -1 : 1
// 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
if (abs_x > swipe_inital_offset && abs_y < abs_x/3) {
set_offset((abs_x-swipe_inital_offset)*neg, false)
if (abs_x > swipe_inital_offset && abs_y < abs_x / 3) {
set_offset((abs_x - swipe_inital_offset) * neg, false)
} else {
set_offset(0, true)
}
}
const touchend = e => {
const touchend = (e: TouchEvent) => {
if (!enabled) {
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
let detail = "transform: translateX("+off+"px);"
if (animate) {
detail += "transition: transform 400ms;"
}
// Clear the transformation if the offset is zero
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("touchmove", touchmove)
node.addEventListener("touchend", touchend)
// Get the child image so we can listen for the loaded event. When the
// loaded event fires we clear the transformations so that the image appears
// in the original position again
for (let i = 0; i < node.childNodes.length; i++) {
const child = node.childNodes.item(i)
if (child instanceof HTMLImageElement) {
child.addEventListener("load", () => set_offset(0, false))
}
}
return {
update(swipe_enabled) {
enabled = swipe_enabled
if (!enabled) {
render_offset = 0
}
update(enabled: boolean) {
// enabled = swipe_enabled
set_offset(0, false)
},
destroy() {
node.removeEventListener("touchstart", touchstart)
@@ -85,4 +93,3 @@ export const swipe_nav = (node, swipe_enabled) => {
}
}
}
</script>

View File

@@ -8,10 +8,10 @@ import DetailsWindow from './DetailsWindow.svelte';
import FilePreview from './viewers/FilePreview.svelte';
import SearchView from './SearchView.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 Menu from './Menu.svelte';
import { Navigator } from "./Navigator.js"
import { Navigator } from "./Navigator"
import { writable } from 'svelte/store';
let file_viewer

View File

@@ -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 })
)
}

View 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
}

View File

@@ -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("/")
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
let split = path.split("/")
for (let i = 0; i < split.length; i++) {
@@ -12,21 +14,26 @@ export const fs_encode_path = path => {
return split.join("/")
}
export const fs_path_url = path => {
export const fs_path_url = (path: string) => {
if (!path || path.length === 0) {
return ""
}
if (path[0] !== "/") {
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
}
export const fs_node_type = node => {
export const fs_node_type = (node: FSNode) => {
if (node.type === "dir") {
return "dir"
} 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") {
// Folders with an ID are publically shared, use the shared folder icon
if (node.id) {

View File

@@ -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 { Writable } from "svelte/store"
export class Navigator {
// Parts of the raw API response
path = []
base_index = 0
children = []
permissions = {}
path: Array<FSNode> = []
base_index: number = 0
children: Array<FSNode> = []
permissions: FSPermissions = <FSPermissions>{}
// 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 = false
@@ -36,9 +37,9 @@ export class Navigator {
// If you set the loading property to a boolean writable store the navigator
// will use it to publish its loading states
loading = null
set_loading(b) {
if (this.loading !== null && this.loading.set !== undefined) {
loading: Writable<boolean> | null = null
set_loading(b: boolean) {
if (this.loading !== null) {
this.loading.set(b)
}
}
@@ -46,20 +47,18 @@ export class Navigator {
// The Navigator acts as a svelte store. This allows for DOM reactivity.
// This works by implementing the store contract:
// https://svelte.dev/docs/svelte-components#script-4-prefix-stores-with-$-to-access-their-values
subscribers = []
subscribe(sub_func) {
subscribers: Array<(nav: Navigator) => void> = []
subscribe(sub_func: (nav: Navigator) => void) {
// Immediately return the current value
sub_func(this)
this.subscribers.push(sub_func)
// Return the unsubscribe function
return () => {
this.subscribers.splice(this.subscribers.indexOf(sub_func), 1)
}
return () => this.subscribers.splice(this.subscribers.indexOf(sub_func), 1)
}
async navigate(path, push_history) {
async navigate(path: string, push_history: boolean) {
if (path[0] !== "/") {
path = "/" + path
}
@@ -90,7 +89,7 @@ export class Navigator {
async navigate_up() {
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)
}
open_node(node, push_history) {
open_node(node: FSPath, push_history: boolean) {
// Update window title and navigation history. If push_history is false
// we still replace the URL with replaceState. This way the user is not
// 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
// used
cached_siblings_path = ""
cached_siblings = null
cached_siblings: Array<FSNode> | null = null
async get_siblings() {
// 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
// file which is currently open. Give a positive number to move forward and
// a negative number to move backward
async open_sibling(offset) {
async open_sibling(offset: number) {
if (this.path.length <= 1) {
return
}
let siblings
let siblings: Array<FSNode>
try {
this.set_loading(true)
siblings = await this.get_siblings()
@@ -191,7 +189,7 @@ export class Navigator {
this.set_loading(false)
}
let next_sibling = null
let next_sibling: FSNode | null = null
if (this.shuffle) {
// 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) => {
// Sort directories before files
if (a.type !== b.type) {

View File

@@ -22,7 +22,7 @@ const delete_file = async e => {
alert(err)
return
} finally {
nac.set_loading(false)
nav.set_loading(false)
}
if (open_after_edit) {
@@ -32,7 +32,6 @@ const delete_file = async e => {
}
visible = false
}
</script>
<h2>File settings</h2>

View File

@@ -1,5 +1,5 @@
<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 CreateDirectory from './CreateDirectory.svelte'
import ListView from './ListView.svelte'
@@ -103,7 +103,9 @@ const delete_selected = async () => {
// Save all promises with deletion requests in an array
let promises = []
nav.children.forEach(child => {
if (!child.fm_selected) { return }
if (!child.fm_selected) {
return
}
promises.push(fs_delete_all(child.path))
})

View File

@@ -96,7 +96,7 @@ export let hide_branding = false
border-bottom: 1px solid var(--separator);
}
.node:hover:not(.node_selected) {
background: var(--input_background);
background: var(--input_hover_background);
color: var(--input_text);
text-decoration: none;
}

View File

@@ -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 => {
dragging = false;
if (e.dataTransfer.files || e.dataTransfer.items) {
if (can_upload(e)) {
e.stopPropagation();
e.preventDefault();
} else {
return
}
// if directory support is available
@@ -26,7 +53,7 @@ const drop = async e => {
for (let i = 0; i < e.dataTransfer.items.length; i++) {
let entry = await e.dataTransfer.items[i].webkitGetAsEntry();
if (entry) {
await read_dir_recursive(entry);
read_dir_recursive(entry);
}
}
} else if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
@@ -50,9 +77,9 @@ const read_dir_recursive = item => {
</script>
<svelte:window
on:dragover|preventDefault|stopPropagation={() => { dragging = true }}
on:dragenter|preventDefault|stopPropagation={() => { dragging = true }}
on:dragleave|preventDefault|stopPropagation={() => { dragging = false }}
on:dragover={dragover}
on:dragenter={dragover}
on:dragleave={dragleave}
on:drop={drop}
on:paste={paste}
/>

View File

@@ -1,6 +1,6 @@
<script>
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";
let dispatch = createEventDispatcher()
@@ -15,11 +15,7 @@ export const update = () => {
dispatch("loading", true)
}
let swipe_style = ""
const on_load = () => {
dispatch("loading", false)
swipe_style = ""
}
const on_load = () => dispatch("loading", false)
const mousedown = (e) => {
if (!dragging && e.which === 1 && zoom) {
@@ -62,8 +58,7 @@ const mouseup = (e) => {
bind:this={container}
class="container"
class:zoom
use:swipe_nav={!zoom}
on:style={e => swipe_style = e.detail}
use:swipe_nav={{enabled: !zoom, previous: false, next: true}}
on:prev={() => nav.open_sibling(-1)}
on:next={() => nav.open_sibling(1)}
>
@@ -76,9 +71,9 @@ const mouseup = (e) => {
on:error={on_load}
class="image"
class:zoom
style={swipe_style}
src={fs_path_url($nav.base.path)}
alt="no description available" />
alt="no description available"
/>
</div>
<style>

View File

@@ -90,6 +90,7 @@ header > h1 {
.header_image_container {
text-align: initial;
margin: auto;
margin-bottom: 1.5em; /*Offset for menu button*/
height: 150px;
width: 500px;
max-width: 100%;

View File

@@ -408,7 +408,7 @@ const node_click = (index) => {
transition: background 0.2s;
}
.node:hover:not(.node_selected) {
background: var(--input_background);
background: var(--input_hover_background);
color: var(--input_text);
text-decoration: none;
}