From f32ad841780b9c6631fa995cdefabf237763b172 Mon Sep 17 00:00:00 2001 From: Juliet Date: Tue, 10 Mar 2026 23:58:04 +0100 Subject: [PATCH] clean up upload view --- web/src/pages/Upload.tsx | 263 ++++++++++++++++++++------------------- 1 file changed, 133 insertions(+), 130 deletions(-) diff --git a/web/src/pages/Upload.tsx b/web/src/pages/Upload.tsx index 1e77a06..5419426 100644 --- a/web/src/pages/Upload.tsx +++ b/web/src/pages/Upload.tsx @@ -3,10 +3,31 @@ import { createSignal, Show, onMount, onCleanup, createMemo } from "solid-js"; import { generateKey, encrypt } from "../lib/crypto"; import { formatBytes } from "../lib/utils"; +const btnClass = + "bg-accent hover:bg-accent-hover rounded-md border-none px-4 py-1.5 font-medium text-white transition-colors"; +const btnStyle = { "font-size": "clamp(1rem, 3vw, 1.5rem)" }; +const ghostClass = + "text-muted hover:text-text border-none bg-transparent p-0 text-xs"; + +const DURATION_UNITS: Record = { + s: 1, + m: 60, + h: 3600, + d: 86400, +}; +function parseDuration(s: string): number | undefined { + const n = parseInt(s); + const mult = DURATION_UNITS[s.trim().slice(-1)]; + if (isNaN(n) || mult === undefined) return undefined; + return n * mult; +} + +type Status = "idle" | "encrypting" | "uploading"; +type View = "result" | "uploading" | "file" | "empty"; + export default function Upload() { const [file, setFile] = createSignal(null); - const [uploading, setUploading] = createSignal(false); - const [encrypting, setEncrypting] = createSignal(false); + const [status, setStatus] = createSignal("idle"); const [progress, setProgress] = createSignal(0); const [error, setError] = createSignal(""); const [resultUrl, setResultUrl] = createSignal(""); @@ -65,14 +86,6 @@ export default function Upload() { return !!f && !!max && f.size > max; }); - const parseDuration = (s: string): number | undefined => { - const units: Record = { s: 1, m: 60, h: 3600, d: 86400 }; - const n = parseInt(s); - const mult = units[s.trim().slice(-1)]; - if (isNaN(n) || mult === undefined) return undefined; - return n * mult; - }; - const expiryTooLong = createMemo(() => { const val = expiryValue(); const max = maxTtl(); @@ -83,11 +96,12 @@ export default function Upload() { return valSec > maxSec; }); - const statusText = () => { - if (encrypting()) return "encrypting\u2026"; - if (uploading()) return "uploading\u2026"; - return ""; - }; + const view = createMemo(() => { + if (resultUrl()) return "result"; + if (status() !== "idle") return "uploading"; + if (file()) return "file"; + return "empty"; + }); const handleDragOver = (e: DragEvent) => { e.preventDefault(); @@ -133,29 +147,27 @@ export default function Upload() { document.removeEventListener("drop", handleDrop); }); + const removeFile = () => { + setFile(null); + setError(""); + fileInput.value = ""; + }; + const cancelUpload = () => { if (activeXhr) { activeXhr.abort(); activeXhr = null; } - setUploading(false); - setEncrypting(false); + setStatus("idle"); setProgress(0); removeFile(); }; - const removeFile = () => { - setFile(null); - setError(""); - fileInput.value = ""; - }; - const handleUpload = async () => { const f = file(); if (!f) return; - setEncrypting(true); - setUploading(true); + setStatus("encrypting"); setError(""); setResultUrl(""); setProgress(0); @@ -170,7 +182,7 @@ export default function Upload() { formData.append("expiresIn", expiryValue().trim()); formData.append("burnAfterRead", burn() ? "true" : "false"); - setEncrypting(false); + setStatus("uploading"); const res = await new Promise<{ id: string }>((resolve, reject) => { const xhr = new XMLHttpRequest(); @@ -207,8 +219,7 @@ export default function Upload() { setError(e.message); } finally { activeXhr = null; - setUploading(false); - setEncrypting(false); + setStatus("idle"); setProgress(0); } }; @@ -224,7 +235,7 @@ export default function Upload() { <>
!resultUrl() && fileInput.click()} + onClick={() => view() === "empty" && fileInput.click()} >
- + - {resultUrl()} + expires in {expiryValue()} - - - + + + + {progress()}% + + + {status() === "encrypting" + ? "encrypting\u2026" + : "uploading\u2026"} + + + + + + - {progress()}% + {file()!.name} - {statusText()} - - - - - - {file()!.name} - - - {formatBytes(file()!.size)} - {tooLarge() - ? ` / ${formatBytes(maxFileSize())} limit` - : ""} - - - - - } + -

- drop a file, or -

- - - - up to {formatBytes(maxFileSize())} - - -
+ {tooLarge() + ? `${formatBytes(file()!.size)} / ${formatBytes(maxFileSize())}` + : formatBytes(file()!.size)} + + + + +
+ + + + drop a file, or + + + + + up to {formatBytes(maxFileSize())} +
@@ -410,7 +413,7 @@ export default function Upload() { />
- +