From a0c059e4ada9361ce04987976ece1d7e30df1e3d Mon Sep 17 00:00:00 2001 From: Key Date: Sun, 3 May 2026 21:35:00 +0100 Subject: [PATCH] FileUpload: UI stuff (#1043) * FileUpload: use XMLHttpRequest instead of fetch * FileUpload: improve the file host picker settings UI * FileUpload: track the upload progress instead of fallback count * fix lint * fix moreStickers * Update stickers.ts --------- Co-authored-by: thororen <78185467+thororen1234@users.noreply.github.com> --- src/equicordplugins/fileUpload/index.tsx | 21 ++ src/equicordplugins/fileUpload/settings.tsx | 349 +++++++++++------- src/equicordplugins/fileUpload/styles.css | 48 +++ src/equicordplugins/fileUpload/utils/s3.ts | 13 +- .../fileUpload/utils/upload.ts | 148 +++++++- src/equicordplugins/moreStickers/stickers.ts | 3 +- 6 files changed, 420 insertions(+), 162 deletions(-) diff --git a/src/equicordplugins/fileUpload/index.tsx b/src/equicordplugins/fileUpload/index.tsx index 0cd895db2..724b5e926 100644 --- a/src/equicordplugins/fileUpload/index.tsx +++ b/src/equicordplugins/fileUpload/index.tsx @@ -104,6 +104,21 @@ function handlePaste(event: ClipboardEvent) { void uploadProvidedFiles(files); } +function formatBytes(bytes: number): string { + if (!bytes) return ""; + + const units = ["B", "KB", "MB", "GB"]; + let value = bytes; + let unitIndex = 0; + + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024; + unitIndex++; + } + + return `${value.toFixed(value >= 10 || unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`; +} + const ProgressBarInner = () => { const [state, setState] = useState(getUploadState); @@ -112,6 +127,9 @@ const ProgressBarInner = () => { if (state.phase === "idle") return null; const percentage = Math.max(0, Math.min(100, state.percent)); + const progressLabel = state.totalBytes > 0 + ? `${Math.round(percentage)}% - ${formatBytes(state.transferredBytes)} of ${formatBytes(state.totalBytes)}` + : `${Math.round(percentage)}%`; return (
{ {state.status || "Uploading..."}
+ + {progressLabel} + {state.attempt > 0 && state.totalAttempts > 0 ? `${state.attempt}/${state.totalAttempts}` : ""} diff --git a/src/equicordplugins/fileUpload/settings.tsx b/src/equicordplugins/fileUpload/settings.tsx index 896a3e7df..d5451d3b3 100644 --- a/src/equicordplugins/fileUpload/settings.tsx +++ b/src/equicordplugins/fileUpload/settings.tsx @@ -285,7 +285,7 @@ function SettingTextInput(props: { const { description, name, onChange, placeholder, value } = props; return ( - + +
+ {children} +
+
+ ); +} + +function SettingSwitch(props: { + checked: boolean; + description: string; + name: string; + onChange: (value: boolean) => void; +}) { + const { checked, description, name, onChange } = props; + + return ( + + + + ); +} + +function ServicePicker(props: { + onChange: (service: ServiceType) => void; + value: ServiceType; +}) { + const { onChange, value } = props; + + return ( +
+ {serviceOptions.map(option => ( + + ))} +
+ ); +} + function FallbackOrderSettings() { const update = useForceUpdater(); const { store } = settings; @@ -413,21 +467,18 @@ export function SettingsComponent() { return ( <> - - v === store.embedProxyService} - select={v => { - store.embedProxyService = v; - update(); - }} - serialize={v => v} - placeholder="Select an embed proxy service" - /> - - )} + {store.embedProxyEnabled && ( + + v === (store.uploadTimeoutMs || 300000)} - select={v => { - store.uploadTimeoutMs = v; - update(); - }} - serialize={v => v} - placeholder="Select timeout" + + store.corsProxyUrl = v} + placeholder="https://your-cors-proxy.example.com" /> - + + + codeberg.org/key/corsproxy + + + +