Remove unused buckets and directory_upload pages
This commit is contained in:
2
main.go
2
main.go
@@ -27,7 +27,7 @@ func main() {
|
|||||||
// systemd's socket, else we'll create our own to serve on
|
// systemd's socket, else we'll create our own to serve on
|
||||||
if *sock {
|
if *sock {
|
||||||
// Socket activation enabled. Get the provided sockets and serve on them
|
// Socket activation enabled. Get the provided sockets and serve on them
|
||||||
if listener, err = util.SystemdSocketByName("pd-web.socket"); err != nil {
|
if listener, err = util.SystemdListenerByName("pd-web.socket"); err != nil {
|
||||||
panic("Socket pd-web.socket not found")
|
panic("Socket pd-web.socket not found")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
{{define "directory_upload"}}<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
{{template "meta_tags" "Directory upload"}}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
window.api_endpoint = '{{.APIEndpoint}}';
|
|
||||||
window.user = {{.User}};
|
|
||||||
</script>
|
|
||||||
<link rel='stylesheet' href='/res/svelte/directory_upload.css?v{{cacheID}}'>
|
|
||||||
<script defer src='/res/svelte/directory_upload.js?v{{cacheID}}'></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
{{template "page_top" .}}
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<h1>Directory upload</h1>
|
|
||||||
</header>
|
|
||||||
<div id="page_content" class="page_content"></div>
|
|
||||||
|
|
||||||
{{template "page_bottom" .}}
|
|
||||||
{{template "analytics"}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
{{end}}
|
|
@@ -1,16 +0,0 @@
|
|||||||
{{define "user_buckets"}}<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
{{template "meta_tags" "Buckets"}}
|
|
||||||
|
|
||||||
<script>window.api_endpoint = '{{.APIEndpoint}}';</script>
|
|
||||||
<link rel='stylesheet' href='/res/svelte/user_buckets.css?v{{cacheID}}'>
|
|
||||||
<script defer src='/res/svelte/user_buckets.js?v{{cacheID}}'></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{{template "menu" .}}
|
|
||||||
<div id="page_body" class="page_body"></div>
|
|
||||||
{{template "analytics"}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
{{end}}
|
|
@@ -33,11 +33,9 @@ export default [
|
|||||||
"filesystem",
|
"filesystem",
|
||||||
"modal",
|
"modal",
|
||||||
"user_home",
|
"user_home",
|
||||||
"user_buckets",
|
|
||||||
"user_file_manager",
|
"user_file_manager",
|
||||||
"admin_panel",
|
"admin_panel",
|
||||||
"home_page",
|
"home_page",
|
||||||
"directory_upload",
|
|
||||||
"text_upload",
|
"text_upload",
|
||||||
].map((name, index) => ({
|
].map((name, index) => ({
|
||||||
input: `src/${name}.js`,
|
input: `src/${name}.js`,
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
import App from './directory_upload/Uploader.svelte';
|
|
||||||
|
|
||||||
const app = new App({
|
|
||||||
target: document.getElementById("page_content"),
|
|
||||||
props: {}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default app;
|
|
@@ -1,52 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { tick } from "svelte";
|
|
||||||
import FileManager from "../filesystem/filemanager/FileManager.svelte";
|
|
||||||
import { fs_create_bucket, fs_get_node } from "../filesystem/FilesystemAPI.svelte";
|
|
||||||
|
|
||||||
let fm
|
|
||||||
|
|
||||||
let bucket_id = ""
|
|
||||||
let bucket_state = null
|
|
||||||
let write_password = ""
|
|
||||||
|
|
||||||
export const add_files = async files => {
|
|
||||||
if (bucket_id === "") {
|
|
||||||
write_password = gen_password(10)
|
|
||||||
|
|
||||||
try {
|
|
||||||
let bucket = await fs_create_bucket("", "", write_password)
|
|
||||||
bucket_id = bucket.id
|
|
||||||
bucket_state = await fs_get_node(bucket_id, "")
|
|
||||||
bucket_state.write_password = write_password
|
|
||||||
} catch (err) {
|
|
||||||
alert("Failed to create bucket! "+err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await tick()
|
|
||||||
fm.upload(files)
|
|
||||||
}
|
|
||||||
|
|
||||||
const gen_password = len => {
|
|
||||||
var pw = "";
|
|
||||||
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
for ( var i = 0; i < len; i++ ) {
|
|
||||||
pw += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
||||||
}
|
|
||||||
return pw;
|
|
||||||
}
|
|
||||||
|
|
||||||
const navigate = async e => {
|
|
||||||
try {
|
|
||||||
let new_state = await fs_get_node(bucket_id, e.detail)
|
|
||||||
bucket_state = new_state
|
|
||||||
} catch (err) {
|
|
||||||
alert("Failed to create bucket! "+err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if bucket_state !== null }
|
|
||||||
<FileManager bind:this={fm} state={bucket_state} on:navigate={navigate}></FileManager>
|
|
||||||
{/if}
|
|
@@ -1,61 +0,0 @@
|
|||||||
<script>
|
|
||||||
import DirectoryUploader from "./DirectoryUploader.svelte";
|
|
||||||
|
|
||||||
let uploader
|
|
||||||
|
|
||||||
let file_input_field
|
|
||||||
const file_input_change = e => {
|
|
||||||
// Start uploading the files async
|
|
||||||
uploader.add_files(e.target.files)
|
|
||||||
|
|
||||||
// This resets the file input field
|
|
||||||
file_input_field.nodeValue = ""
|
|
||||||
}
|
|
||||||
let dragging = false
|
|
||||||
const drop = e => {
|
|
||||||
dragging = false;
|
|
||||||
if (e.dataTransfer && e.dataTransfer.items.length > 0) {
|
|
||||||
e.preventDefault()
|
|
||||||
e.stopPropagation()
|
|
||||||
uploader.add_files(e.dataTransfer.files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const paste = e => {
|
|
||||||
if (e.clipboardData.files[0]) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
uploader.add_files(e.clipboardData.files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:window
|
|
||||||
on:dragover|preventDefault|stopPropagation={() => { dragging = true }}
|
|
||||||
on:dragenter|preventDefault|stopPropagation={() => { dragging = true }}
|
|
||||||
on:dragleave|preventDefault|stopPropagation={() => { dragging = false }}
|
|
||||||
on:drop={drop}
|
|
||||||
on:paste={paste} />
|
|
||||||
|
|
||||||
<header style="padding-bottom: 50px;">
|
|
||||||
<h1>Directory uploader</h1>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<div class="highlight_red">
|
|
||||||
Pixeldrain's filesystem feature is still under development. Please
|
|
||||||
don't upload anything you can't afford to lose
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
|
|
||||||
<section>
|
|
||||||
|
|
||||||
<input bind:this={file_input_field} on:change={file_input_change} type="file" name="file" multiple="multiple"/>
|
|
||||||
<button on:click={() => { file_input_field.click() }} class="big_button button_highlight">
|
|
||||||
<i class="icon small">cloud_upload</i>
|
|
||||||
<u>U</u>pload Files
|
|
||||||
</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<DirectoryUploader bind:this={uploader}></DirectoryUploader>
|
|
@@ -55,7 +55,7 @@ let embed_iframe = () => {
|
|||||||
|
|
||||||
embed_html = `<iframe ` +
|
embed_html = `<iframe ` +
|
||||||
`src="${url}" ` +
|
`src="${url}" ` +
|
||||||
`style="border: none; width: 800px; max-width: 100%; height: 600px; max-height: 100%; border-radius: 16px;"` +
|
`style="border: none; width: 800px; max-width: 100%; height: 600px; max-height: 100%; border-radius: 8px;"` +
|
||||||
`></iframe>`
|
`></iframe>`
|
||||||
}
|
}
|
||||||
let embed_hotlink = () => {
|
let embed_hotlink = () => {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { formatDate, formatDataVolume, formatThousands } from '../util/Formatting.svelte'
|
import { formatDate, formatDataVolume, formatThousands } from '../util/Formatting.svelte'
|
||||||
import { fs_get_file_url, fs_get_node } from './FilesystemAPI.svelte'
|
import { fs_get_file_url, fs_get_node } from './FilesystemAPI.js'
|
||||||
import Sharebar from './Sharebar.svelte'
|
import Sharebar from './Sharebar.svelte'
|
||||||
import Modal from '../util/Modal.svelte'
|
import Modal from '../util/Modal.svelte'
|
||||||
import FileManager from './filemanager/FileManager.svelte';
|
import FileManager from './filemanager/FileManager.svelte';
|
||||||
|
84
svelte/src/filesystem/FilesystemAPI.js
Normal file
84
svelte/src/filesystem/FilesystemAPI.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
const path_url = (bucket, path) => {
|
||||||
|
return window.api_endpoint + "/filesystem/" + bucket + encodeURIComponent(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_get_file_url = (bucket, path) => {
|
||||||
|
return path_url(bucket, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_mkdir = async (bucket, path, opts = null) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "mkdir")
|
||||||
|
|
||||||
|
if (opts && opts.mode) {
|
||||||
|
form.append("mode", opts.mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await fetch(path_url(bucket, path), { method: "POST", body: form });
|
||||||
|
if (resp.status >= 400) {
|
||||||
|
throw new Error(await resp.text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_get_node = async (bucket, path) => {
|
||||||
|
const resp = await fetch(path_url(bucket, path) + "?stat");
|
||||||
|
if (resp.status >= 400) {
|
||||||
|
throw new Error(await resp.text())
|
||||||
|
}
|
||||||
|
return resp.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 (bucket, path, opts) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "update")
|
||||||
|
|
||||||
|
if (opts.created) {
|
||||||
|
form.append("created", opts.created.toISOString())
|
||||||
|
}
|
||||||
|
if (opts.modified) {
|
||||||
|
form.append("modified", opts.modified.toISOString())
|
||||||
|
}
|
||||||
|
if (opts.mode) {
|
||||||
|
form.append("mode", opts.mode)
|
||||||
|
}
|
||||||
|
if (opts.shared) {
|
||||||
|
form.append("shared", opts.shared)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await fetch(path_url(bucket, path), { method: "POST", body: form })
|
||||||
|
if (resp.status >= 400) {
|
||||||
|
throw new Error(await resp.text())
|
||||||
|
}
|
||||||
|
return resp.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_rename = async (bucket, old_path, new_path) => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append("action", "rename")
|
||||||
|
form.append("target", new_path)
|
||||||
|
|
||||||
|
const resp = await fetch(path_url(bucket, old_path), { method: "POST", body: form })
|
||||||
|
if (resp.status >= 400) {
|
||||||
|
throw new Error(await resp.text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fs_delete = async (bucket, path) => {
|
||||||
|
const resp = await fetch(path_url(bucket, path), { method: "DELETE" });
|
||||||
|
if (resp.status >= 400) {
|
||||||
|
throw new Error(await resp.text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const fs_delete_all = async (bucket, path) => {
|
||||||
|
const resp = await fetch(path_url(bucket, path) + "?recursive", { method: "DELETE" });
|
||||||
|
if (resp.status >= 400) {
|
||||||
|
throw new Error(await resp.text())
|
||||||
|
}
|
||||||
|
}
|
@@ -1,107 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
|
|
||||||
export const fs_create_bucket = async (name = "", read_pw = "", write_pw = "") => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("name", name)
|
|
||||||
form.append("read_password", read_pw)
|
|
||||||
form.append("write_password", write_pw)
|
|
||||||
|
|
||||||
const resp = await fetch(
|
|
||||||
window.api_endpoint+"/filesystem",
|
|
||||||
{ method: "POST", body: form }
|
|
||||||
);
|
|
||||||
if(resp.status >= 400) {
|
|
||||||
throw new Error(await resp.text());
|
|
||||||
}
|
|
||||||
return resp.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_get_buckets = async () => {
|
|
||||||
const resp = await fetch(window.api_endpoint+"/filesystem");
|
|
||||||
if(resp.status >= 400) {
|
|
||||||
throw new Error(await resp.text());
|
|
||||||
}
|
|
||||||
return resp.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_delete_bucket = async (id, recursive) => {
|
|
||||||
let uri = window.api_endpoint+"/filesystem/"+encodeURIComponent(id)
|
|
||||||
if (recursive) {
|
|
||||||
uri += "?recursive"
|
|
||||||
}
|
|
||||||
|
|
||||||
const resp = await fetch(uri, { method: "DELETE" });
|
|
||||||
if(resp.status >= 400) {
|
|
||||||
throw new Error(await resp.text());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_create_directory = async (bucket, path, dir_name) => {
|
|
||||||
if (!path.startsWith("/")) {
|
|
||||||
path = "/" + path
|
|
||||||
}
|
|
||||||
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("type", "dir")
|
|
||||||
|
|
||||||
const resp = await fetch(
|
|
||||||
window.api_endpoint+"/filesystem/"+bucket+encodeURIComponent(path+"/"+dir_name),
|
|
||||||
{ method: "POST", body: form }
|
|
||||||
);
|
|
||||||
if(resp.status >= 400) {
|
|
||||||
throw new Error(await resp.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_get_node = async (bucket, path) => {
|
|
||||||
if (!path.startsWith("/")) {
|
|
||||||
path = "/" + path
|
|
||||||
}
|
|
||||||
|
|
||||||
const resp = await fetch(
|
|
||||||
window.api_endpoint+"/filesystem/"+bucket+encodeURIComponent(path)+"?stat"
|
|
||||||
);
|
|
||||||
if(resp.status >= 400) {
|
|
||||||
throw new Error(await resp.text())
|
|
||||||
}
|
|
||||||
return resp.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_get_file_url = (bucket, path) => {
|
|
||||||
if (!path.startsWith("/")) {
|
|
||||||
path = "/" + path
|
|
||||||
}
|
|
||||||
return window.api_endpoint + "/filesystem/" + bucket + encodeURIComponent(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_rename_node = async (bucket, old_path, new_path) => {
|
|
||||||
if (!old_path.startsWith("/")) { old_path = "/" + old_path }
|
|
||||||
if (!new_path.startsWith("/")) { new_path = "/" + new_path }
|
|
||||||
|
|
||||||
const form = new FormData()
|
|
||||||
form.append("move_to", new_path)
|
|
||||||
|
|
||||||
const resp = await fetch(
|
|
||||||
window.api_endpoint+"/filesystem/"+bucket+encodeURIComponent(old_path),
|
|
||||||
{ method: "PUT", body: form }
|
|
||||||
)
|
|
||||||
if (resp.status >= 400) {
|
|
||||||
throw new Error(await resp.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fs_delete_node = async (bucket, path) => {
|
|
||||||
if (!path.startsWith("/")) {
|
|
||||||
path = "/" + path
|
|
||||||
}
|
|
||||||
|
|
||||||
const resp = await fetch(
|
|
||||||
window.api_endpoint+"/filesystem/"+bucket+encodeURIComponent(path)+"?recursive",
|
|
||||||
{ method: "DELETE" }
|
|
||||||
);
|
|
||||||
if (resp.status >= 400) {
|
|
||||||
throw new Error(await resp.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
@@ -1,21 +1,21 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount, createEventDispatcher } from "svelte";
|
import { onMount, createEventDispatcher } from "svelte";
|
||||||
import { fs_create_directory } from "../FilesystemAPI.svelte";
|
import { fs_mkdir } from "../FilesystemAPI.js";
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
|
|
||||||
export let state;
|
export let state;
|
||||||
let name_input;
|
let name_input;
|
||||||
let create_dir_name = ""
|
let new_dir_name = ""
|
||||||
let create_dir = () => {
|
let create_dir = () => {
|
||||||
dispatch("loading", true)
|
dispatch("loading", true)
|
||||||
|
|
||||||
let form = new FormData()
|
let form = new FormData()
|
||||||
form.append("type", "dir")
|
form.append("type", "dir")
|
||||||
|
|
||||||
fs_create_directory(
|
fs_mkdir(
|
||||||
state.root.id, state.base.path, create_dir_name,
|
state.root.id, state.base.path+"/"+new_dir_name,
|
||||||
).then(resp => {
|
).then(resp => {
|
||||||
create_dir_name = "" // Clear input field
|
new_dir_name = "" // Clear input field
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
alert("Error: "+err)
|
alert("Error: "+err)
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
@@ -28,7 +28,7 @@ onMount(() => { name_input.focus() })
|
|||||||
|
|
||||||
<form class="create_dir highlight_shaded" on:submit|preventDefault={create_dir}>
|
<form class="create_dir highlight_shaded" on:submit|preventDefault={create_dir}>
|
||||||
<img src="/res/img/mime/folder.png" class="icon" alt="icon"/>
|
<img src="/res/img/mime/folder.png" class="icon" alt="icon"/>
|
||||||
<input class="dirname" type="text" style="width: 100%;" bind:this={name_input} bind:value={create_dir_name} />
|
<input class="dirname" type="text" style="width: 100%;" bind:this={name_input} bind:value={new_dir_name} />
|
||||||
<input class="submit" type="submit" value="create"/>
|
<input class="submit" type="submit" value="create"/>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_delete_node } from './../FilesystemAPI.svelte'
|
import { fs_delete } from './../FilesystemAPI.js'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import CreateDirectory from './CreateDirectory.svelte'
|
import CreateDirectory from './CreateDirectory.svelte'
|
||||||
import FileUploader from './FileUploader.svelte'
|
import FileUploader from './FileUploader.svelte'
|
||||||
@@ -67,7 +67,7 @@ const delete_selected = () => {
|
|||||||
let promises = []
|
let promises = []
|
||||||
state.children.forEach(child => {
|
state.children.forEach(child => {
|
||||||
if (!child.fm_selected) { return }
|
if (!child.fm_selected) { return }
|
||||||
promises.push(fs_delete_node(state.root.id, child.path))
|
promises.push(fs_delete(state.root.id, child.path))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Wait for all the promises to finish
|
// Wait for all the promises to finish
|
||||||
|
@@ -67,17 +67,13 @@ const upload_file = () => {
|
|||||||
|
|
||||||
console.log(job);
|
console.log(job);
|
||||||
|
|
||||||
let form = new FormData();
|
|
||||||
form.append("type", "file");
|
|
||||||
form.append("file", job.file);
|
|
||||||
|
|
||||||
let url = window.api_endpoint+"/filesystem/"+bucket_id+encodeURIComponent(job.target_dir + "/" + job.file.name)
|
let url = window.api_endpoint+"/filesystem/"+bucket_id+encodeURIComponent(job.target_dir + "/" + job.file.name)
|
||||||
if (write_password) {
|
if (write_password) {
|
||||||
url += "?write_password="+write_password
|
url += "?write_password="+write_password
|
||||||
}
|
}
|
||||||
|
|
||||||
let xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST", url, true);
|
xhr.open("PUT", url, true);
|
||||||
xhr.timeout = 21600000; // 6 hours, to account for slow connections
|
xhr.timeout = 21600000; // 6 hours, to account for slow connections
|
||||||
|
|
||||||
// Report progress updates back to the caller
|
// Report progress updates back to the caller
|
||||||
@@ -147,7 +143,8 @@ const upload_file = () => {
|
|||||||
|
|
||||||
upload_jobs = upload_jobs;
|
upload_jobs = upload_jobs;
|
||||||
};
|
};
|
||||||
xhr.send(form);
|
|
||||||
|
xhr.send(job.file);
|
||||||
};
|
};
|
||||||
|
|
||||||
// File input dialog handling
|
// File input dialog handling
|
||||||
|
@@ -49,8 +49,9 @@ const node_icon = node => {
|
|||||||
<div class="directory">
|
<div class="directory">
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>name</td>
|
<td>Name</td>
|
||||||
<td>size</td>
|
<td>Size</td>
|
||||||
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
{#each state.children as child, index (child.path)}
|
{#each state.children as child, index (child.path)}
|
||||||
<a
|
<a
|
||||||
@@ -71,6 +72,13 @@ const node_icon = node => {
|
|||||||
{formatDataVolume(child.file_size, 3)}
|
{formatDataVolume(child.file_size, 3)}
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{#if child.id}
|
||||||
|
<a href="/d/{child.id}" on:click|stopPropagation>
|
||||||
|
<i class="icon" title="This file / directory is shared. Click to open public link">share</i>
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
</a>
|
</a>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_get_file_url } from "../FilesystemAPI.svelte";
|
import { fs_get_file_url } from "../FilesystemAPI.js";
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_get_file_url } from "../FilesystemAPI.svelte";
|
import { fs_get_file_url } from "../FilesystemAPI.js";
|
||||||
|
|
||||||
|
|
||||||
export let state
|
export let state
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_get_file_url } from "../FilesystemAPI.svelte";
|
import { fs_get_file_url } from "../FilesystemAPI.js";
|
||||||
export let state
|
export let state
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_get_file_url } from "../FilesystemAPI.svelte";
|
import { fs_get_file_url } from "../FilesystemAPI.js";
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
let dispatch = createEventDispatcher()
|
let dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
import App from './user_buckets/UserBuckets.svelte';
|
|
||||||
|
|
||||||
const app = new App({
|
|
||||||
target: document.getElementById("page_body"),
|
|
||||||
props: {}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default app;
|
|
@@ -1,74 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { fs_delete_bucket } from "../filesystem/FilesystemAPI.svelte";
|
|
||||||
import { createEventDispatcher } from "svelte";
|
|
||||||
import Expandable from "../util/Expandable.svelte";
|
|
||||||
let dispatch = createEventDispatcher()
|
|
||||||
|
|
||||||
export let bucket
|
|
||||||
|
|
||||||
const save_bucket = () => {
|
|
||||||
alert("save")
|
|
||||||
}
|
|
||||||
const delete_bucket = async () => {
|
|
||||||
if (!confirm(
|
|
||||||
"Are you sure you want to delete this bucket? All the files within "+
|
|
||||||
"the bucket will be irrevocably deleted. There is no way to recover "+
|
|
||||||
"from this! Press OK to proceed"
|
|
||||||
)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await fs_delete_bucket(bucket.id, true)
|
|
||||||
} catch (err) {
|
|
||||||
alert("Failed to delete bucket! "+err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch("refresh");
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Expandable highlight>
|
|
||||||
<div slot="header">
|
|
||||||
<a href={'/d/' + bucket.id} class="bucket_title">
|
|
||||||
<img class="bucket_icon" src="/res/img/mime/folder-remote.png" alt="Bucket icon"/>
|
|
||||||
{bucket.name}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<form on:submit|preventDefault={save_bucket}>
|
|
||||||
<table class="form">
|
|
||||||
<tr class="form">
|
|
||||||
<td>Name</td>
|
|
||||||
<td><input type="text" value={bucket.name} /></td>
|
|
||||||
</tr>
|
|
||||||
<tr class="form">
|
|
||||||
<td colspan="2">
|
|
||||||
<button class="button_red" on:click|preventDefault={delete_bucket}>
|
|
||||||
<i class="icon">delete</i> Delete
|
|
||||||
</button>
|
|
||||||
<button class="button_highlight" type="submit" style="float: right;">
|
|
||||||
<i class="icon">save</i> Save
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</Expandable>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.bucket_title {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
align-self: center;
|
|
||||||
display: block;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.bucket_icon {
|
|
||||||
height: 32px;
|
|
||||||
width: 32px;
|
|
||||||
margin: 4px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,89 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from "svelte";
|
|
||||||
import UserBucket from "./UserBucket.svelte";
|
|
||||||
import { fs_get_buckets, fs_create_bucket } from "../filesystem/FilesystemAPI.svelte";
|
|
||||||
import LoadingIndicator from "../util/LoadingIndicator.svelte";
|
|
||||||
import Footer from "../layout/Footer.svelte";
|
|
||||||
|
|
||||||
let loading = true
|
|
||||||
let buckets = []
|
|
||||||
|
|
||||||
let creating_bucket = false
|
|
||||||
let new_bucket_name
|
|
||||||
|
|
||||||
const get_buckets = async () => {
|
|
||||||
loading = true;
|
|
||||||
try {
|
|
||||||
buckets = await fs_get_buckets();
|
|
||||||
} catch (err) {
|
|
||||||
alert(err);
|
|
||||||
} finally {
|
|
||||||
loading = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const create_bucket = async () => {
|
|
||||||
if (!new_bucket_name.value) {
|
|
||||||
alert("Please enter a name!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
let bucket = await fs_create_bucket(new_bucket_name.value)
|
|
||||||
console.log(bucket)
|
|
||||||
} catch (err) {
|
|
||||||
alert("Failed to create bucket! "+err)
|
|
||||||
}
|
|
||||||
|
|
||||||
creating_bucket = false
|
|
||||||
get_buckets();
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(get_buckets);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<LoadingIndicator loading={loading}/>
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<h1>My Buckets</h1>
|
|
||||||
</header>
|
|
||||||
<div id="page_content" class="page_content">
|
|
||||||
<section>
|
|
||||||
<div class="toolbar" style="text-align: right;">
|
|
||||||
<button
|
|
||||||
class:button_highlight={creating_bucket}
|
|
||||||
on:click={() => {creating_bucket = !creating_bucket}}
|
|
||||||
>
|
|
||||||
<i class="icon">create_new_folder</i> New bucket
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{#if creating_bucket}
|
|
||||||
<div class="highlight_shaded">
|
|
||||||
<form on:submit|preventDefault={create_bucket}>
|
|
||||||
<table class="form">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Name
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input type="text" bind:this={new_bucket_name}/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<button class="button_highlight" type="submit" style="float: right;">
|
|
||||||
<i class="icon">save</i> Save
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#each buckets as bucket (bucket.id)}
|
|
||||||
<UserBucket bucket={bucket} on:refresh={get_buckets}></UserBucket>
|
|
||||||
{/each}
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<Footer/>
|
|
@@ -15,12 +15,20 @@ const header_click = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const keypress = e => {
|
||||||
|
if (e.code === "Space") {
|
||||||
|
if (click_expand) {
|
||||||
|
toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Highlight the title bar if the user moves their mouse over it
|
// Highlight the title bar if the user moves their mouse over it
|
||||||
export let highlight = false
|
export let highlight = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="expandable">
|
<div class="expandable">
|
||||||
<div class="header" class:click_expand class:highlight on:click={header_click}>
|
<div class="header" class:click_expand class:highlight on:click={header_click} on:keypress={keypress}>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -154,7 +154,6 @@ func New(r *httprouter.Router, prefix string, conf Config) (wc *WebController) {
|
|||||||
{GET, "limits" /* */, wc.serveMarkdown("limits.md", handlerOpts{})},
|
{GET, "limits" /* */, wc.serveMarkdown("limits.md", handlerOpts{})},
|
||||||
{GET, "abuse" /* */, wc.serveMarkdown("abuse.md", handlerOpts{})},
|
{GET, "abuse" /* */, wc.serveMarkdown("abuse.md", handlerOpts{})},
|
||||||
{GET, "apps" /* */, wc.serveTemplate("apps", handlerOpts{})},
|
{GET, "apps" /* */, wc.serveTemplate("apps", handlerOpts{})},
|
||||||
{GET, "directory_upload" /**/, wc.serveTemplate("directory_upload", handlerOpts{})},
|
|
||||||
|
|
||||||
// User account pages
|
// User account pages
|
||||||
{GET, "register" /* */, wc.serveForm(wc.registerForm, handlerOpts{NoEmbed: true})},
|
{GET, "register" /* */, wc.serveForm(wc.registerForm, handlerOpts{NoEmbed: true})},
|
||||||
@@ -165,7 +164,6 @@ func New(r *httprouter.Router, prefix string, conf Config) (wc *WebController) {
|
|||||||
{PST, "password_reset" /* */, wc.serveForm(wc.passwordResetForm, handlerOpts{NoEmbed: true})},
|
{PST, "password_reset" /* */, wc.serveForm(wc.passwordResetForm, handlerOpts{NoEmbed: true})},
|
||||||
{GET, "logout" /* */, wc.serveTemplate("logout", handlerOpts{Auth: true, NoEmbed: true})},
|
{GET, "logout" /* */, wc.serveTemplate("logout", handlerOpts{Auth: true, NoEmbed: true})},
|
||||||
{PST, "logout" /* */, wc.serveLogout},
|
{PST, "logout" /* */, wc.serveLogout},
|
||||||
{GET, "user/buckets" /* */, wc.serveTemplate("user_buckets", handlerOpts{Auth: true})},
|
|
||||||
{GET, "user/filemanager" /* */, wc.serveTemplate("file_manager", handlerOpts{Auth: true})},
|
{GET, "user/filemanager" /* */, wc.serveTemplate("file_manager", handlerOpts{Auth: true})},
|
||||||
{GET, "user/export/files" /**/, wc.serveUserExportFiles},
|
{GET, "user/export/files" /**/, wc.serveUserExportFiles},
|
||||||
{GET, "user/export/lists" /**/, wc.serveUserExportLists},
|
{GET, "user/export/lists" /**/, wc.serveUserExportLists},
|
||||||
|
Reference in New Issue
Block a user