diff --git a/web/src/lib/components/elements/icon.svelte b/web/src/lib/components/elements/icon.svelte index bb22276286..5965928718 100644 --- a/web/src/lib/components/elements/icon.svelte +++ b/web/src/lib/components/elements/icon.svelte @@ -16,13 +16,14 @@ export let ariaLabelledby: string | undefined = undefined; export let strokeWidth: number = 0; export let strokeColor: string = 'currentColor'; + export let spin = false; + import Icon from '$lib/components/elements/icon.svelte'; + import { AppRoute } from '$lib/constants'; import type { UploadAsset } from '$lib/models/upload-asset'; import { UploadState } from '$lib/models/upload-asset'; import { locale } from '$lib/stores/preferences.store'; - import { getByteUnitString } from '$lib/utils/byte-units'; - import { fade } from 'svelte/transition'; - import ImmichLogo from './immich-logo.svelte'; - import { getFilenameExtension } from '$lib/utils/asset-utils'; import { uploadAssetsStore } from '$lib/stores/upload'; - import Icon from '$lib/components/elements/icon.svelte'; + import { getByteUnitString } from '$lib/utils/byte-units'; import { fileUploadHandler } from '$lib/utils/file-uploader'; - import { mdiRefresh, mdiCancel } from '@mdi/js'; + import { + mdiAlertCircle, + mdiCheckCircle, + mdiCircleOutline, + mdiClose, + mdiLoading, + mdiOpenInNew, + mdiRestart, + } from '@mdi/js'; import { t } from 'svelte-i18n'; + import { fade } from 'svelte/transition'; export let uploadAsset: UploadAsset; + const handleDismiss = (uploadAsset: UploadAsset) => { + uploadAssetsStore.removeItem(uploadAsset.id); + }; + const handleRetry = async (uploadAsset: UploadAsset) => { - uploadAssetsStore.removeUploadAsset(uploadAsset.id); + uploadAssetsStore.removeItem(uploadAsset.id); await fileUploadHandler([uploadAsset.file], uploadAsset.albumId); }; @@ -23,86 +34,69 @@
-
-
-
- -
-
-

- .{getFilenameExtension(uploadAsset.file.name)} -

-
+
+
+ {#if uploadAsset.state === UploadState.PENDING} + + {:else if uploadAsset.state === UploadState.STARTED} + + {:else if uploadAsset.state === UploadState.ERROR} + + {:else if uploadAsset.state === UploadState.DUPLICATED} + + {:else if uploadAsset.state === UploadState.DONE} + + {/if}
-
- + + {uploadAsset.file.name} -
- {#if uploadAsset.state === UploadState.STARTED} -
-

- {#if uploadAsset.message} - {uploadAsset.message} - {:else} - {uploadAsset.progress}% - {getByteUnitString(uploadAsset.speed || 0, $locale)}/s - {uploadAsset.eta}s - {/if} -

- {:else if uploadAsset.state === UploadState.PENDING} -
-

{$t('pending')}

- {:else if uploadAsset.state === UploadState.ERROR} -
-

{$t('error')}

- {:else if uploadAsset.state === UploadState.DUPLICATED} -
-

- {$t('asset_skipped')} - {#if uploadAsset.message} - ({uploadAsset.message}) - {/if} -

- {:else if uploadAsset.state === UploadState.DONE} -
-

- {$t('asset_uploaded')} - {#if uploadAsset.message} - ({uploadAsset.message}) - {/if} -

- {/if} -
-
- {#if uploadAsset.state === UploadState.ERROR} -
- - +
+ {:else if uploadAsset.state === UploadState.ERROR} +
+ +
{/if}
+ {#if uploadAsset.state === UploadState.STARTED} +
+
+

+ {#if uploadAsset.message} + {uploadAsset.message} + {:else} + {uploadAsset.progress}% - {getByteUnitString(uploadAsset.speed || 0, $locale)}/s - {uploadAsset.eta}s + {/if} +

+
+ {/if} + {#if uploadAsset.state === UploadState.ERROR}
-

+

{uploadAsset.error}

diff --git a/web/src/lib/components/shared-components/upload-panel.svelte b/web/src/lib/components/shared-components/upload-panel.svelte index ee213d7969..d536053286 100644 --- a/web/src/lib/components/shared-components/upload-panel.svelte +++ b/web/src/lib/components/shared-components/upload-panel.svelte @@ -15,8 +15,7 @@ let showOptions = false; let concurrency = uploadExecutionQueue.concurrency; - let { isUploading, hasError, remainingUploads, errorCounter, duplicateCounter, successCounter, totalUploadCounter } = - uploadAssetsStore; + let { stats, isDismissible, isUploading, remainingUploads } = uploadAssetsStore; const autoHide = () => { if (!$isUploading && showDetail) { @@ -33,29 +32,29 @@ } -{#if $hasError || $isUploading} +{#if $isUploading}
{ - if ($errorCounter > 0) { + if ($stats.errors > 0) { notificationController.show({ - message: $t('upload_errors', { values: { count: $errorCounter } }), + message: $t('upload_errors', { values: { count: $stats.errors } }), type: NotificationType.Warning, }); - } else if ($successCounter > 0) { + } else if ($stats.success > 0) { notificationController.show({ message: $t('upload_success'), type: NotificationType.Info, }); } - if ($duplicateCounter > 0) { + if ($stats.duplicates > 0) { notificationController.show({ - message: $t('upload_skipped_duplicates', { values: { count: $duplicateCounter } }), + message: $t('upload_skipped_duplicates', { values: { count: $stats.duplicates } }), type: NotificationType.Warning, }); } - uploadAssetsStore.resetStore(); + uploadAssetsStore.reset(); }} class="fixed bottom-6 right-6 z-[10000]" > @@ -70,20 +69,20 @@ {$t('upload_progress', { values: { remaining: $remainingUploads, - processed: $successCounter + $errorCounter, - total: $totalUploadCounter, + processed: $stats.total - $remainingUploads, + total: $stats.total, }, })}

{$t('upload_status_uploaded')} - {$successCounter.toLocaleString($locale)} + {$stats.success.toLocaleString($locale)} - {$t('upload_status_errors')} - {$errorCounter.toLocaleString($locale)} + {$stats.errors.toLocaleString($locale)} - {$t('upload_status_duplicates')} - {$duplicateCounter.toLocaleString($locale)} + {$stats.duplicates.toLocaleString($locale)}

@@ -103,7 +102,7 @@ on:click={() => (showDetail = false)} />
- {#if $hasError} + {#if $isDismissible}
{#if showOptions} -
+
@@ -133,7 +132,7 @@ />
{/if} -
+
{#each $uploadAssetsStore as uploadAsset (uploadAsset.id)} {/each} @@ -149,14 +148,14 @@ > {$remainingUploads.toLocaleString($locale)} - {#if $hasError} + {#if $stats.errors > 0} {/if}