From 66b2ad7939d8e361a9eb02c354c3883569cf2a61 Mon Sep 17 00:00:00 2001 From: Russell Tan Date: Wed, 9 Aug 2023 18:11:26 -0700 Subject: [PATCH] fix(web): show warning on duplicate uploads #2557 (#3613) * fix(web): show warning on duplicate uploads #2557 * Prettier fix * color --------- Co-authored-by: Alex Tran --- .../notification/notification-card.svelte | 13 +++++++++++++ .../shared-components/notification/notification.ts | 3 ++- .../shared-components/upload-panel.svelte | 12 ++++++++++++ web/src/lib/stores/upload.ts | 2 ++ web/src/lib/utils/file-uploader.ts | 4 ++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/web/src/lib/components/shared-components/notification/notification-card.svelte b/web/src/lib/components/shared-components/notification/notification-card.svelte index 9443757ebf..f759ec0355 100644 --- a/web/src/lib/components/shared-components/notification/notification-card.svelte +++ b/web/src/lib/components/shared-components/notification/notification-card.svelte @@ -15,6 +15,7 @@ let infoPrimaryColor = '#4250AF'; let errorPrimaryColor = '#E64132'; + let warningPrimaryColor = '#D08613'; $: icon = notificationInfo.type === NotificationType.Error ? CloseCircleOutline : InformationOutline; @@ -26,6 +27,10 @@ if (notificationInfo.type === NotificationType.Error) { return '#FBE8E6'; } + + if (notificationInfo.type === NotificationType.Warning) { + return '#FFF6DC'; + } }; $: borderStyle = () => { @@ -36,6 +41,10 @@ if (notificationInfo.type === NotificationType.Error) { return '1px solid #F0E8E7'; } + + if (notificationInfo.type === NotificationType.Warning) { + return '1px solid #FFE6A5'; + } }; $: primaryColor = () => { @@ -46,6 +55,10 @@ if (notificationInfo.type === NotificationType.Error) { return errorPrimaryColor; } + + if (notificationInfo.type === NotificationType.Warning) { + return warningPrimaryColor; + } }; let removeNotificationTimeout: NodeJS.Timeout | undefined = undefined; diff --git a/web/src/lib/components/shared-components/notification/notification.ts b/web/src/lib/components/shared-components/notification/notification.ts index ff1e6d5951..815ac89e28 100644 --- a/web/src/lib/components/shared-components/notification/notification.ts +++ b/web/src/lib/components/shared-components/notification/notification.ts @@ -3,10 +3,11 @@ import { writable } from 'svelte/store'; export enum NotificationType { Info = 'Info', Error = 'Error', + Warning = 'Warning', } export class ImmichNotification { - id = new Date().getTime(); + id = new Date().getTime() + Math.random(); type!: NotificationType; message!: string; action!: NotificationAction; diff --git a/web/src/lib/components/shared-components/upload-panel.svelte b/web/src/lib/components/shared-components/upload-panel.svelte index 9d45a9e7a3..41cb4b3341 100644 --- a/web/src/lib/components/shared-components/upload-panel.svelte +++ b/web/src/lib/components/shared-components/upload-panel.svelte @@ -9,6 +9,7 @@ let showDetail = true; let uploadLength = 0; + let duplicateCount = 0; let isUploading = false; // Reactive action to update asset uploadLength whenever there is a new one added to the list @@ -21,6 +22,10 @@ uploadAssetsStore.isUploading.subscribe((value) => { isUploading = value; }); + + uploadAssetsStore.duplicateCounter.subscribe((value) => { + duplicateCount = value; + }); {#if isUploading} @@ -32,6 +37,13 @@ message: 'Upload success, refresh the page to see new upload assets', type: NotificationType.Info, }); + if (duplicateCount > 0) { + notificationController.show({ + message: `Skipped ${duplicateCount} duplicate picture${duplicateCount > 1 ? 's' : ''}`, + type: NotificationType.Warning, + }); + uploadAssetsStore.duplicateCounter.set(0); + } }} class="absolute bottom-6 right-6 z-[10000]" > diff --git a/web/src/lib/stores/upload.ts b/web/src/lib/stores/upload.ts index 0d8d31cfaf..c6da3bcffe 100644 --- a/web/src/lib/stores/upload.ts +++ b/web/src/lib/stores/upload.ts @@ -3,6 +3,7 @@ import type { UploadAsset } from '../models/upload-asset'; function createUploadStore() { const uploadAssets = writable>([]); + const duplicateCounter = writable(0); const { subscribe } = uploadAssets; @@ -35,6 +36,7 @@ function createUploadStore() { return { subscribe, + duplicateCounter, isUploading, addNewUploadAsset, updateProgress, diff --git a/web/src/lib/utils/file-uploader.ts b/web/src/lib/utils/file-uploader.ts index 774f3ac54f..7238310736 100644 --- a/web/src/lib/utils/file-uploader.ts +++ b/web/src/lib/utils/file-uploader.ts @@ -151,6 +151,10 @@ async function fileUploader( if (response.status == 200 || response.status == 201) { const res: AssetFileUploadResponseDto = response.data; + if (res.duplicate) { + uploadAssetsStore.duplicateCounter.update((count) => count + 1); + } + if (albumId && res.id) { await addAssetsToAlbum(albumId, [res.id], sharedKey); }