mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-22 05:46:26 -08:00
Merge pull request #34 from mollersuite/notifs
This commit is contained in:
commit
cbb9152529
4
.vscode/tasks.json
vendored
4
.vscode/tasks.json
vendored
|
@ -3,7 +3,7 @@
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command":"tsc\nsass src/style:out/style\nrollup -c",
|
"command":"npm run build",
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command":"tsc\nsass src/style:out/style\nrollup -c\nnode ./out/server/index.js\ndel ./out/* -Recurse",
|
"command":"npm run build\nnode ./out/server/index.js\ndel ./out/* -Recurse",
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
|
|
39
package-lock.json
generated
39
package-lock.json
generated
|
@ -1,17 +1,14 @@
|
||||||
{
|
{
|
||||||
"name": "monofile",
|
"name": "monofile",
|
||||||
"version": "1.3.0-beta",
|
"version": "1.4.0-dev",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "monofile",
|
"name": "monofile",
|
||||||
"version": "1.3.0-beta",
|
"version": "1.4.0-dev",
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/fira-code": "^5.0.8",
|
|
||||||
"@fontsource/inconsolata": "^5.0.8",
|
|
||||||
"@fontsource/source-sans-pro": "^5.0.8",
|
|
||||||
"@types/body-parser": "^1.19.2",
|
"@types/body-parser": "^1.19.2",
|
||||||
"@types/express": "^4.17.14",
|
"@types/express": "^4.17.14",
|
||||||
"@types/multer": "^1.4.7",
|
"@types/multer": "^1.4.7",
|
||||||
|
@ -37,7 +34,7 @@
|
||||||
"svelte": "^3.55.1"
|
"svelte": "^3.55.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=v18"
|
"node": ">=v16.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@discordjs/builders": {
|
"node_modules/@discordjs/builders": {
|
||||||
|
@ -90,21 +87,6 @@
|
||||||
"node": ">=16.9.0"
|
"node": ">=16.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fontsource/fira-code": {
|
|
||||||
"version": "5.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-5.0.8.tgz",
|
|
||||||
"integrity": "sha512-kp/tJUVnjaZeLHENMBFTTSgP2B7+/rIboeofuMfoGB40s2U0DKXNqQcOqIF5PtDhJ5QTG1LcviYXMnc1yG6oYQ=="
|
|
||||||
},
|
|
||||||
"node_modules/@fontsource/inconsolata": {
|
|
||||||
"version": "5.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/inconsolata/-/inconsolata-5.0.8.tgz",
|
|
||||||
"integrity": "sha512-KpBU6q1yCovfycaFprVEauh8U5RsWty3konFfUukyRRxZBK4Sf73XmGQc8iJ4CPrOP4dplGfdX2kjbRgdymajA=="
|
|
||||||
},
|
|
||||||
"node_modules/@fontsource/source-sans-pro": {
|
|
||||||
"version": "5.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/source-sans-pro/-/source-sans-pro-5.0.8.tgz",
|
|
||||||
"integrity": "sha512-5U2UvIYRkCMozZ388gCE73PEpa2MFgN/0t9O4a1FF7bGT/MIneQWSL1XpWZ8iMVYdh6ntxRf3iFA6slCIuFgkg=="
|
|
||||||
},
|
|
||||||
"node_modules/@rollup/plugin-node-resolve": {
|
"node_modules/@rollup/plugin-node-resolve": {
|
||||||
"version": "15.0.1",
|
"version": "15.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
|
||||||
|
@ -1750,21 +1732,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.1.0.tgz",
|
||||||
"integrity": "sha512-e7d+PaTLVQav6rOc2tojh2y6FE8S7REkqLldq1XF4soCx74XB/DIjbVbVLtBemf0nLW77ntz0v+o5DytKwFNLQ=="
|
"integrity": "sha512-e7d+PaTLVQav6rOc2tojh2y6FE8S7REkqLldq1XF4soCx74XB/DIjbVbVLtBemf0nLW77ntz0v+o5DytKwFNLQ=="
|
||||||
},
|
},
|
||||||
"@fontsource/fira-code": {
|
|
||||||
"version": "5.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-5.0.8.tgz",
|
|
||||||
"integrity": "sha512-kp/tJUVnjaZeLHENMBFTTSgP2B7+/rIboeofuMfoGB40s2U0DKXNqQcOqIF5PtDhJ5QTG1LcviYXMnc1yG6oYQ=="
|
|
||||||
},
|
|
||||||
"@fontsource/inconsolata": {
|
|
||||||
"version": "5.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/inconsolata/-/inconsolata-5.0.8.tgz",
|
|
||||||
"integrity": "sha512-KpBU6q1yCovfycaFprVEauh8U5RsWty3konFfUukyRRxZBK4Sf73XmGQc8iJ4CPrOP4dplGfdX2kjbRgdymajA=="
|
|
||||||
},
|
|
||||||
"@fontsource/source-sans-pro": {
|
|
||||||
"version": "5.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/source-sans-pro/-/source-sans-pro-5.0.8.tgz",
|
|
||||||
"integrity": "sha512-5U2UvIYRkCMozZ388gCE73PEpa2MFgN/0t9O4a1FF7bGT/MIneQWSL1XpWZ8iMVYdh6ntxRf3iFA6slCIuFgkg=="
|
|
||||||
},
|
|
||||||
"@rollup/plugin-node-resolve": {
|
"@rollup/plugin-node-resolve": {
|
||||||
"version": "15.0.1",
|
"version": "15.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./out/server/index.js",
|
"start": "node ./out/server/index.js",
|
||||||
|
"build": "tsc\nsass src/style:out/style\nrollup -c",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
|
|
@ -23,6 +23,20 @@
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1 > button {
|
||||||
|
background-color: #0000 !important;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
img { color: #DDD; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color:#999;
|
color:#999;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import { _void } from "./transition/_void.js";
|
import { _void } from "./transition/_void.js"
|
||||||
import { padding_scaleY } from "./transition/padding_scaleY.js"
|
import { padding_scaleY } from "./transition/padding_scaleY.js"
|
||||||
import { fade } from "svelte/transition";
|
import { fade } from "svelte/transition"
|
||||||
import { circIn, circOut } from "svelte/easing";
|
import { circIn, circOut } from "svelte/easing"
|
||||||
import { serverStats, refresh_stats, account } from "./stores.mjs";
|
import { serverStats, refresh_stats, account } from "./stores.mjs"
|
||||||
|
|
||||||
import AttachmentZone from "./uploader/AttachmentZone.svelte";
|
import AttachmentZone from "./uploader/AttachmentZone.svelte"
|
||||||
|
|
||||||
// stats
|
// stats
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
// uploads
|
// uploads
|
||||||
|
|
||||||
let attachmentZone;
|
let attachmentZone
|
||||||
let uploads = {};
|
let uploads = {}
|
||||||
let uploadInProgress = false;
|
let uploadInProgress = false
|
||||||
|
let notificationPermission = Notification.permission
|
||||||
let handle_file_upload = (ev) => {
|
let handle_file_upload = (ev) => {
|
||||||
if (ev.detail.type == "clone") {
|
if (ev.detail.type == "clone") {
|
||||||
uploads[Math.random().toString().slice(2)] = {
|
uploads[Math.random().toString().slice(2)] = {
|
||||||
|
@ -25,31 +25,31 @@
|
||||||
url: ev.detail.url,
|
url: ev.detail.url,
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
uploadId: ""
|
uploadId: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadStatus:{
|
uploadStatus: {
|
||||||
fileId: null,
|
fileId: null,
|
||||||
error: null,
|
error: null,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
uploads = uploads
|
uploads = uploads
|
||||||
} else if (ev.detail.type == "upload") {
|
} else if (ev.detail.type == "upload") {
|
||||||
ev.detail.files.forEach((v,x) => {
|
ev.detail.files.forEach((v, x) => {
|
||||||
uploads[Math.random().toString().slice(2)] = {
|
uploads[Math.random().toString().slice(2)] = {
|
||||||
type: "upload",
|
type: "upload",
|
||||||
name: v.name,
|
name: v.name,
|
||||||
file: v,
|
file: v,
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
uploadId: ""
|
uploadId: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadStatus:{
|
uploadStatus: {
|
||||||
fileId: null,
|
fileId: null,
|
||||||
error: null,
|
error: null,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -57,17 +57,47 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let handle_fetch_promise = (x,prom) => {
|
let handle_fetch_promise = (x, prom) => {
|
||||||
return prom.then(async (res) => {
|
return prom
|
||||||
|
.then(async (res) => {
|
||||||
let txt = await res.text()
|
let txt = await res.text()
|
||||||
if (txt.startsWith("[err]")) uploads[x].uploadStatus.error = txt;
|
if (txt.startsWith("[err]")) uploads[x].uploadStatus.error = txt
|
||||||
else {
|
else {
|
||||||
uploads[x].uploadStatus.fileId = txt;
|
uploads[x].uploadStatus.fileId = txt
|
||||||
|
try {
|
||||||
refresh_stats();
|
new Notification("Upload complete", {
|
||||||
|
body: `View at ${location.origin}/${uploads[x].uploadStatus.fileId}`,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
action: "open",
|
||||||
|
title: "Open",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "copy",
|
||||||
|
title: "Copy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).addEventListener(
|
||||||
|
"notificationclick",
|
||||||
|
({ action }) => {
|
||||||
|
if (action === "open") {
|
||||||
|
open(
|
||||||
|
"/download/" +
|
||||||
|
uploads[x].uploadStatus.fileId
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
navigator.clipboard.writeText(
|
||||||
|
`${location.origin}/${uploads[x].uploadStatus.fileId}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}
|
||||||
uploads[x].uploadStatus.error = err.toString();
|
)
|
||||||
|
} catch (_) {}
|
||||||
|
refresh_stats()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
uploads[x].uploadStatus.error = err.toString()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,37 +107,43 @@
|
||||||
let sequential = localStorage.getItem("sequentialMode") == "true"
|
let sequential = localStorage.getItem("sequentialMode") == "true"
|
||||||
|
|
||||||
// go through all files
|
// go through all files
|
||||||
for (let [x,v] of Object.entries(uploads)) {
|
for (let [x, v] of Object.entries(uploads)) {
|
||||||
// quick patch-in to allow for a switch to have everything upload sequentially
|
// quick patch-in to allow for a switch to have everything upload sequentially
|
||||||
// switch will have a proper menu option later, for now i'm lazy so it's just gonna be a Secret
|
// switch will have a proper menu option later, for now i'm lazy so it's just gonna be a Secret
|
||||||
let hdl = () => {
|
let hdl = () => {
|
||||||
switch(v.type) {
|
switch (v.type) {
|
||||||
case "upload":
|
case "upload":
|
||||||
let fd = new FormData()
|
let fd = new FormData()
|
||||||
fd.append("file",v.file)
|
fd.append("file", v.file)
|
||||||
|
|
||||||
return handle_fetch_promise(x,fetch("/upload",{
|
return handle_fetch_promise(
|
||||||
|
x,
|
||||||
|
fetch("/upload", {
|
||||||
headers: {
|
headers: {
|
||||||
"monofile-params": JSON.stringify(v.params)
|
"monofile-params": JSON.stringify(v.params),
|
||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: fd
|
body: fd,
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
break
|
break
|
||||||
case "clone":
|
case "clone":
|
||||||
return handle_fetch_promise(x,fetch("/clone",{
|
return handle_fetch_promise(
|
||||||
|
x,
|
||||||
|
fetch("/clone", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
url: v.url,
|
url: v.url,
|
||||||
...v.params
|
...v.params,
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
}))
|
)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sequential) await hdl();
|
if (sequential) await hdl()
|
||||||
else hdl();
|
else hdl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,23 +152,50 @@
|
||||||
function fileTransition(node) {
|
function fileTransition(node) {
|
||||||
return {
|
return {
|
||||||
duration: 300,
|
duration: 300,
|
||||||
css: t => {
|
css: (t) => {
|
||||||
let eased = circOut(t)
|
let eased = circOut(t)
|
||||||
|
|
||||||
return `
|
return `
|
||||||
height: ${eased*(node.offsetHeight-22)}px;
|
height: ${eased * (node.offsetHeight - 22)}px;
|
||||||
padding: ${eased*10}px 10px;
|
padding: ${eased * 10}px 10px;
|
||||||
`
|
`
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="uploadWindow">
|
<div id="uploadWindow">
|
||||||
<h1>monofile</h1>
|
<h1>
|
||||||
|
monofile
|
||||||
|
{#if notificationPermission === "default"}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
Notification.requestPermission().then(
|
||||||
|
(permission) => (notificationPermission = permission)
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
style="float:right"
|
||||||
|
title="Notify me when the upload finishes"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
aria-label="Notify me when the upload finishes"
|
||||||
|
><path
|
||||||
|
d="M9.042 19.003h5.916a3 3 0 0 1-5.916 0Zm2.958-17a7.5 7.5 0 0 1 7.5 7.5v4l1.418 3.16A.95.95 0 0 1 20.052 18h-16.1a.95.95 0 0 1-.867-1.338l1.415-3.16V9.49l.005-.25A7.5 7.5 0 0 1 12 2.004Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</h1>
|
||||||
<p style:color="#999999">
|
<p style:color="#999999">
|
||||||
<span class="number">{$serverStats.version ? `v${$serverStats.version}` : "•••"}</span> — Discord based file sharing
|
<span class="number"
|
||||||
|
>{$serverStats.version ? `v${$serverStats.version}` : "•••"}</span
|
||||||
|
> — Discord based file sharing
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div style:min-height="10px" />
|
<div style:min-height="10px" />
|
||||||
|
@ -143,46 +206,125 @@
|
||||||
{#each Object.entries(uploads) as upload (upload[0])}
|
{#each Object.entries(uploads) as upload (upload[0])}
|
||||||
<!-- container to allow for animate directive -->
|
<!-- container to allow for animate directive -->
|
||||||
<div>
|
<div>
|
||||||
<div class="file" transition:fileTransition style:border={upload[1].uploadStatus.error ? "1px solid #BB7070" : ""}>
|
<div
|
||||||
<h2>{upload[1].name} <span style:color="#999999" style:font-weight="400">{upload[1].type}{@html upload[1].type == "upload" ? ` (${Math.round(upload[1].file.size/1048576)}MiB)` : ""}</span></h2>
|
class="file"
|
||||||
|
transition:fileTransition
|
||||||
|
style:border={upload[1].uploadStatus.error
|
||||||
|
? "1px solid #BB7070"
|
||||||
|
: ""}
|
||||||
|
>
|
||||||
|
<h2>
|
||||||
|
{upload[1].name}
|
||||||
|
<span style:color="#999999" style:font-weight="400"
|
||||||
|
>{upload[1].type}{@html upload[1].type == "upload"
|
||||||
|
? ` (${Math.round(
|
||||||
|
upload[1].file.size / 1048576
|
||||||
|
)}MiB)`
|
||||||
|
: ""}</span
|
||||||
|
>
|
||||||
|
</h2>
|
||||||
|
|
||||||
{#if upload[1].maximized && !uploadInProgress}
|
{#if upload[1].maximized && !uploadInProgress}
|
||||||
<div transition:padding_scaleY|local>
|
<div transition:padding_scaleY|local>
|
||||||
<div style:height="10px" />
|
<div style:height="10px" />
|
||||||
<input placeholder="custom id" type="text" bind:value={ uploads[upload[0]].params.uploadId }>
|
<input
|
||||||
|
placeholder="custom id"
|
||||||
|
type="text"
|
||||||
|
bind:value={uploads[upload[0]].params.uploadId}
|
||||||
|
/>
|
||||||
<div style:height="10px" />
|
<div style:height="10px" />
|
||||||
<div class="buttonContainer">
|
<div class="buttonContainer">
|
||||||
<button on:click={() => {delete uploads[upload[0]];uploads=uploads;}}>
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
delete uploads[upload[0]]
|
||||||
|
uploads = uploads
|
||||||
|
}}
|
||||||
|
>
|
||||||
delete
|
delete
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => uploads[upload[0]].maximized = false}>
|
<button
|
||||||
|
on:click={() =>
|
||||||
|
(uploads[upload[0]].maximized = false)}
|
||||||
|
>
|
||||||
minimize
|
minimize
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if !uploadInProgress}
|
{:else if !uploadInProgress}
|
||||||
<button on:click={() => uploads[upload[0]].maximized = true} class="hitbox"></button>
|
<button
|
||||||
|
on:click={() =>
|
||||||
|
(uploads[upload[0]].maximized = true)}
|
||||||
|
class="hitbox"
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<div transition:padding_scaleY|local class="uploadingContainer">
|
<div
|
||||||
|
transition:padding_scaleY|local
|
||||||
|
class="uploadingContainer"
|
||||||
|
>
|
||||||
{#if !upload[1].uploadStatus.fileId}
|
{#if !upload[1].uploadStatus.fileId}
|
||||||
<p in:fade={{duration:300, delay:400, easingFunc:circOut}} out:padding_scaleY={{easingFunc:circIn,op:true}}>{upload[1].uploadStatus.error ?? "Uploading..."}</p>
|
<p
|
||||||
|
in:fade={{
|
||||||
|
duration: 300,
|
||||||
|
delay: 400,
|
||||||
|
easingFunc: circOut,
|
||||||
|
}}
|
||||||
|
out:padding_scaleY={{
|
||||||
|
easingFunc: circIn,
|
||||||
|
op: true,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{upload[1].uploadStatus.error ??
|
||||||
|
"Uploading..."}
|
||||||
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if upload[1].uploadStatus.fileId}
|
{#if upload[1].uploadStatus.fileId}
|
||||||
<div style:height="10px" transition:padding_scaleY />
|
<div
|
||||||
|
style:height="10px"
|
||||||
|
transition:padding_scaleY
|
||||||
|
/>
|
||||||
{#if !upload[1].viewingUrl}
|
{#if !upload[1].viewingUrl}
|
||||||
<div class="buttonContainer" out:_void in:_void={{easingFunc:circOut}}>
|
<div
|
||||||
<button on:click={() => uploads[upload[0]].viewingUrl = true}>
|
class="buttonContainer"
|
||||||
|
out:_void
|
||||||
|
in:_void={{ easingFunc: circOut }}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
on:click={() =>
|
||||||
|
(uploads[
|
||||||
|
upload[0]
|
||||||
|
].viewingUrl = true)}
|
||||||
|
>
|
||||||
view url
|
view url
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => navigator.clipboard.writeText(`https://${window.location.host}/download/${upload[1].uploadStatus.fileId}`)}>
|
<button
|
||||||
|
on:click={() =>
|
||||||
|
navigator.clipboard.writeText(
|
||||||
|
`https://${window.location.host}/download/${upload[1].uploadStatus.fileId}`
|
||||||
|
)}
|
||||||
|
>
|
||||||
copy url
|
copy url
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="buttonContainer" out:_void in:_void={{easingFunc:circOut}}>
|
<div
|
||||||
<input type="text" readonly value={`https://${window.location.host}/download/${upload[1].uploadStatus.fileId}`} style:flex-basis="80%">
|
class="buttonContainer"
|
||||||
<button on:click={() => uploads[upload[0]].viewingUrl = false} style:flex-basis="20%">
|
out:_void
|
||||||
|
in:_void={{ easingFunc: circOut }}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
readonly
|
||||||
|
value={`https://${window.location.host}/download/${upload[1].uploadStatus.fileId}`}
|
||||||
|
style:flex-basis="80%"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
on:click={() =>
|
||||||
|
(uploads[
|
||||||
|
upload[0]
|
||||||
|
].viewingUrl = false)}
|
||||||
|
style:flex-basis="20%"
|
||||||
|
>
|
||||||
ok
|
ok
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -197,46 +339,71 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if uploadInProgress == false}
|
{#if uploadInProgress == false}
|
||||||
|
|
||||||
<!-- if required for upload, check if logged in -->
|
<!-- if required for upload, check if logged in -->
|
||||||
{#if ($serverStats.accounts||{}).requiredForUpload ? !!$account.username : true}
|
{#if ($serverStats.accounts || {}).requiredForUpload ? !!$account.username : true}
|
||||||
|
<AttachmentZone
|
||||||
<AttachmentZone bind:this={attachmentZone} on:addFiles={handle_file_upload}/>
|
bind:this={attachmentZone}
|
||||||
<div style:min-height="10px" transition:_void={{rTarg:"height",prop:"min-height"}} />
|
on:addFiles={handle_file_upload}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style:min-height="10px"
|
||||||
|
transition:_void={{ rTarg: "height", prop: "min-height" }}
|
||||||
|
/>
|
||||||
{#if Object.keys(uploads).length > 0}
|
{#if Object.keys(uploads).length > 0}
|
||||||
<button in:padding_scaleY={{easingFunc:circOut}} out:_void on:click={upload_files}>upload</button>
|
<button
|
||||||
<div transition:_void={{rTarg:"height",prop:"min-height"}} style:min-height="10px" />
|
in:padding_scaleY={{ easingFunc: circOut }}
|
||||||
|
out:_void
|
||||||
|
on:click={upload_files}>upload</button
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
transition:_void={{ rTarg: "height", prop: "min-height" }}
|
||||||
|
style:min-height="10px"
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
|
<p transition:_void style:color="#999999" style:text-align="center">
|
||||||
<p transition:_void style:color="#999999" style:text-align="center">Please log in to upload files.</p>
|
Please log in to upload files.
|
||||||
<div transition:_void={{rTarg:"height",prop:"min-height"}} style:min-height="10px" />
|
</p>
|
||||||
|
<div
|
||||||
|
transition:_void={{ rTarg: "height", prop: "min-height" }}
|
||||||
|
style:min-height="10px"
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<p style:color="#999999" style:text-align="center">
|
<p style:color="#999999" style:text-align="center">
|
||||||
Hosting <span class="number" style:font-weight="600">{$serverStats.files || "•••"}</span> files
|
Hosting <span class="number" style:font-weight="600"
|
||||||
—
|
>{$serverStats.files || "•••"}</span
|
||||||
Maximum filesize is <span class="number" style:font-weight="600">{(($serverStats.maxDiscordFileSize || 0)*($serverStats.maxDiscordFiles || 0))/1048576 || "•••"}MiB</span>
|
>
|
||||||
|
files — Maximum filesize is
|
||||||
|
<span class="number" style:font-weight="600"
|
||||||
|
>{(($serverStats.maxDiscordFileSize || 0) *
|
||||||
|
($serverStats.maxDiscordFiles || 0)) /
|
||||||
|
1048576 || "•••"}MiB</span
|
||||||
|
>
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p style:color="#999999" style:text-align="center" style:font-size="12px">
|
<p style:color="#999999" style:text-align="center" style:font-size="12px">
|
||||||
Made with {Math.floor(Math.random()*10)==0 ? "🐟" : "❤"} by <a href="https://cetera.uk" style:font-size="12px"><svg
|
Made with {Math.floor(Math.random() * 10) == 0 ? "🐟" : "❤"} by
|
||||||
|
<a href="https://cetera.uk" style:font-size="12px"
|
||||||
|
><svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 173.8 275.72"
|
viewBox="0 0 173.8 275.72"
|
||||||
height="16"
|
height="16"
|
||||||
style="vertical-align:middle"
|
style="vertical-align:middle"
|
||||||
fill="currentColor">
|
fill="currentColor"
|
||||||
|
>
|
||||||
<circle cx="37.13" cy="26.43" r="21.6" />
|
<circle cx="37.13" cy="26.43" r="21.6" />
|
||||||
<circle cx="34.62" cy="117.87" r="34.62" class="middle" />
|
<circle cx="34.62" cy="117.87" r="34.62" class="middle" />
|
||||||
<circle cx="119.78" cy="130.68" r="21.6" class="middle" />
|
<circle cx="119.78" cy="130.68" r="21.6" class="middle" />
|
||||||
<circle cx="127.16" cy="46.64" r="46.65" />
|
<circle cx="127.16" cy="46.64" r="46.65" />
|
||||||
<circle cx="102.68" cy="219.58" r="56.14" class="bottom" />
|
<circle cx="102.68" cy="219.58" r="56.14" class="bottom" />
|
||||||
</svg> Etcetera</a> — <a href="https://github.com/mollersuite/monofile" style:font-size="12px">source</a>
|
</svg> Etcetera</a
|
||||||
|
>
|
||||||
|
—
|
||||||
|
<a href="https://github.com/mollersuite/monofile" style:font-size="12px"
|
||||||
|
>source</a
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
<div style:height="10px" />
|
<div style:height="10px" />
|
||||||
</div>
|
</div>
|
Loading…
Reference in a new issue