feat: add upload progress bar (#20)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { validateURL, CLIENT_API_HOST } from '$lib/utils.js';
|
import { validateURL, CLIENT_API_HOST } from '$lib/utils.js';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
|
import { uploadProgress } from '$lib/stores';
|
||||||
|
|
||||||
import toast from 'svelte-french-toast';
|
import toast from 'svelte-french-toast';
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
let language = 'auto';
|
let language = 'auto';
|
||||||
let sourceUrl = '';
|
let sourceUrl = '';
|
||||||
let fileInput;
|
let fileInput;
|
||||||
let device = (env.PUBLIC_WHISHPER_PROFILE == "gpu") ? 'cuda' : 'cpu';
|
let device = env.PUBLIC_WHISHPER_PROFILE == 'gpu' ? 'cuda' : 'cpu';
|
||||||
|
|
||||||
let languages = [
|
let languages = [
|
||||||
'auto',
|
'auto',
|
||||||
@@ -83,14 +84,44 @@
|
|||||||
formData.append('file', fileInput.files[0]);
|
formData.append('file', fileInput.files[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`${CLIENT_API_HOST}/api/transcriptions`, {
|
return new Promise((resolve, reject) => {
|
||||||
method: 'POST',
|
const xhr = new XMLHttpRequest();
|
||||||
body: formData
|
|
||||||
|
// Set up progress event listener
|
||||||
|
xhr.upload.addEventListener('progress', (event) => {
|
||||||
|
if (event.lengthComputable) {
|
||||||
|
const percentCompleted = Math.round((event.loaded * 100) / event.total);
|
||||||
|
uploadProgress.set(percentCompleted);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set up load event listener
|
||||||
|
xhr.addEventListener('load', () => {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
resolve(xhr.response);
|
||||||
|
toast.success('Success!');
|
||||||
|
} else {
|
||||||
|
reject(xhr.statusText);
|
||||||
|
toast.error('Upload failed');
|
||||||
|
}
|
||||||
|
uploadProgress.set(0); // Reset progress after completion
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set up error event listener
|
||||||
|
xhr.addEventListener('error', () => {
|
||||||
|
reject(xhr.statusText);
|
||||||
|
toast.error('An error occurred during upload');
|
||||||
|
uploadProgress.set(0); // Reset progress on error
|
||||||
|
});
|
||||||
|
|
||||||
|
xhr.open('POST', `${CLIENT_API_HOST}/api/transcriptions`);
|
||||||
|
xhr.send(formData);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set file and sourceUrl to empty
|
// Set file and sourceUrl to empty
|
||||||
sourceUrl = '';
|
sourceUrl = '';
|
||||||
fileInput.value = '';
|
fileInput.value = '';
|
||||||
|
uploadProgress.set(0);
|
||||||
|
|
||||||
toast.success('Success!');
|
toast.success('Success!');
|
||||||
}
|
}
|
||||||
@@ -182,7 +213,7 @@
|
|||||||
<span class="label-text">Device</span>
|
<span class="label-text">Device</span>
|
||||||
</label>
|
</label>
|
||||||
<select name="device" bind:value={device} class="select select-bordered">
|
<select name="device" bind:value={device} class="select select-bordered">
|
||||||
{#if env.PUBLIC_WHISHPER_PROFILE == "gpu" }
|
{#if env.PUBLIC_WHISHPER_PROFILE == 'gpu'}
|
||||||
<option selected value="cuda">GPU</option>
|
<option selected value="cuda">GPU</option>
|
||||||
<option value="cpu">CPU</option>
|
<option value="cpu">CPU</option>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -199,7 +230,7 @@
|
|||||||
>Start</button
|
>Start</button
|
||||||
>
|
>
|
||||||
</form>
|
</form>
|
||||||
<form method="dialog" class="modal-backdrop">
|
<form method="dialog" class="modal-backdrop">
|
||||||
<button>close</button>
|
<button>close</button>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
if (data) {
|
if (data) {
|
||||||
availableLanguages = data;
|
availableLanguages = data;
|
||||||
console.log(availableLanguages)
|
|
||||||
// Languages fetched successfully, stop trying
|
// Languages fetched successfully, stop trying
|
||||||
clearInterval(fetchLanguagesInterval);
|
clearInterval(fetchLanguagesInterval);
|
||||||
}
|
}
|
||||||
@@ -56,7 +55,7 @@
|
|||||||
<!-- Language picker -->
|
<!-- Language picker -->
|
||||||
<div class="w-full max-w-xs form-control">
|
<div class="w-full max-w-xs form-control">
|
||||||
<label for="target-lan" class="label">
|
<label for="target-lan" class="label">
|
||||||
<span class="label-text">Target language</span>
|
<span class="label-text">Target languages for {tr.result.language}</span>
|
||||||
</label>
|
</label>
|
||||||
<select bind:value={targetLanguage} name="target-lan" class="select select-bordered">
|
<select bind:value={targetLanguage} name="target-lan" class="select select-bordered">
|
||||||
<option disabled selected>Pick one</option>
|
<option disabled selected>Pick one</option>
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ export const downloadTranscription = writable(null);
|
|||||||
|
|
||||||
export const editorHistory = writable([]);
|
export const editorHistory = writable([]);
|
||||||
|
|
||||||
|
// Upload progress and status
|
||||||
|
export const uploadProgress = writable(0);
|
||||||
|
|
||||||
// editor settings
|
// editor settings
|
||||||
export let editorSettings = writable({
|
export let editorSettings = writable({
|
||||||
autosave: false,
|
autosave: false,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { Toaster } from 'svelte-french-toast';
|
import { Toaster } from 'svelte-french-toast';
|
||||||
import { transcriptions } from '$lib/stores';
|
import { transcriptions, uploadProgress } from '$lib/stores';
|
||||||
import { browser, dev } from '$app/environment';
|
import { browser, dev } from '$app/environment';
|
||||||
import { CLIENT_WS_HOST } from '$lib/utils';
|
import { CLIENT_WS_HOST } from '$lib/utils';
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
@@ -89,21 +89,28 @@
|
|||||||
<ModalTranscriptionForm />
|
<ModalTranscriptionForm />
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<h1 class="flex items-center justify-center space-x-4 font-bold text-4xl mt-8">
|
<h1 class="flex items-center justify-center mt-8 space-x-4 text-4xl font-bold">
|
||||||
<span>
|
<span>
|
||||||
<img class="w-20 h-20" src="/logo.svg" alt="Logo: a cloud whispering" />
|
<img class="w-20 h-20" src="/logo.svg" alt="Logo: a cloud whispering" />
|
||||||
</span>
|
</span>
|
||||||
<span> Whishper </span>
|
<span> Whishper </span>
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="text-md text-center opacity-70 font-mono">{data.randomSentence}</h2>
|
<h2 class="font-mono text-center text-md opacity-70">{data.randomSentence}</h2>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="card w-4/6 bg-neutral text-neutral-content mx-auto mt-4 mb-8">
|
<main class="w-4/6 mx-auto mt-4 mb-8 card bg-neutral text-neutral-content">
|
||||||
<button
|
{#if $uploadProgress > 0}
|
||||||
class="btn btn-primary mx-auto max-w-md mt-8 btn-md"
|
<div class="flex flex-col items-center justify-center px-4 pt-4 my-4">
|
||||||
onclick="modalNewTranscription.showModal()">✨ new transcription</button
|
<progress class="w-full mx-2 progress progress-success" value="{$uploadProgress}" max="100"></progress>
|
||||||
>
|
<span>Uploading...</span>
|
||||||
<div class="card-body items-center text-center mb-0">
|
</div>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
class="max-w-md mx-auto mt-8 btn btn-primary btn-md"
|
||||||
|
onclick="modalNewTranscription.showModal()">✨ new transcription</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
<div class="items-center mb-0 text-center card-body">
|
||||||
{#if $transcriptions.length > 0}
|
{#if $transcriptions.length > 0}
|
||||||
{#each $transcriptions as tr (tr.id)}
|
{#each $transcriptions as tr (tr.id)}
|
||||||
{#if tr.status == 2}
|
{#if tr.status == 2}
|
||||||
@@ -120,7 +127,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-center font-bold text-2xl">🔮 No transcriptions yet 🔮</p>
|
<p class="text-2xl font-bold text-center">🔮 No transcriptions yet 🔮</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
Reference in New Issue
Block a user