From feb9659dc14d12eead4c6817779da8bcfcdcf5be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ml=C3=A1dek?= Date: Fri, 28 Jun 2024 09:15:23 +0200 Subject: [PATCH] feat(webui): add ETA calculation to uploads --- webui/package.json | 1 + webui/pnpm-lock.yaml | 8 ++++++++ webui/src/lib/components/AddModal.svelte | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/webui/package.json b/webui/package.json index 8a34dba..2d347c8 100644 --- a/webui/package.json +++ b/webui/package.json @@ -73,6 +73,7 @@ "mitt": "^3.0.1", "normalize.css": "^8.0.1", "sass": "^1.66.1", + "simple-eta": "^3.0.2", "sirv-cli": "^2.0.2", "sswr": "^1.11.0", "svelte-i18next": "^1.2.2", diff --git a/webui/pnpm-lock.yaml b/webui/pnpm-lock.yaml index 047a352..8457338 100644 --- a/webui/pnpm-lock.yaml +++ b/webui/pnpm-lock.yaml @@ -95,6 +95,9 @@ importers: sass: specifier: ^1.66.1 version: 1.69.0 + simple-eta: + specifier: ^3.0.2 + version: 3.0.2 sirv-cli: specifier: ^2.0.2 version: 2.0.2 @@ -5100,6 +5103,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-eta@3.0.2: + resolution: {integrity: sha512-+OmPgi01yHK/bRNQDoehUcV8fqs9nNJkG2DoWCnnLvj0lmowab7BH3v9776BG0y7dGEOLh0F7mfd37k+ht26Yw==} + sirv-cli@2.0.2: resolution: {integrity: sha512-OtSJDwxsF1NWHc7ps3Sa0s+dPtP15iQNJzfKVz+MxkEo3z72mCD+yu30ct79rPr0CaV1HXSOBp+MIY5uIhHZ1A==} engines: {node: '>= 10'} @@ -11641,6 +11647,8 @@ snapshots: signal-exit@4.1.0: {} + simple-eta@3.0.2: {} + sirv-cli@2.0.2: dependencies: console-clear: 1.1.1 diff --git a/webui/src/lib/components/AddModal.svelte b/webui/src/lib/components/AddModal.svelte index b670654..de81847 100644 --- a/webui/src/lib/components/AddModal.svelte +++ b/webui/src/lib/components/AddModal.svelte @@ -22,6 +22,8 @@ import Modal from '$lib/components/layout/Modal.svelte'; import Selector, { type SelectorValue } from '$lib/components/utils/Selector.svelte'; import { ATTR_IN } from '@upnd/upend/constants'; + import makeEta from 'simple-eta'; + import { formatDuration, intervalToDuration } from 'date-fns'; let files: File[] = []; let URLs: string[] = []; @@ -32,6 +34,7 @@ let progress: Record = {}; let totalProgress: number | undefined; + let eta: ReturnType | undefined; let filesElement: HTMLDivElement; @@ -61,6 +64,8 @@ async function upload() { uploading = true; + eta = makeEta({ min: 0, max: 100 }); + try { abortController = new AbortController(); const addresses: string[] = []; @@ -74,6 +79,7 @@ onProgress: (p) => { progress[file.name] = (p.loaded / p.total) * 100; totalProgress = Object.values(progress).reduce((a, b) => a + b, 0) / files.length; + eta?.report(totalProgress); }, timeout: -1 }); @@ -200,7 +206,16 @@ {#if uploading}
- + + {#key totalProgress} + {totalProgress ? Math.round(totalProgress) : '?'}% (ETA: + {eta && eta.estimate() < Infinity + ? formatDuration( + intervalToDuration({ start: 0, end: Math.floor(eta.estimate() * 1000) }) + ) + : '?'}) + {/key} +
{/if}