Sfoglia il codice sorgente

feat(web): new shortcuts (#3111)

* feat: shortcuts

Signed-off-by: martabal <74269598+martabal@users.noreply.github.com>

* fix: remove listener on component destroy

Signed-off-by: martabal <74269598+martabal@users.noreply.github.com>

* revert delete shortcut

Signed-off-by: martabal <74269598+martabal@users.noreply.github.com>

* feat: new notifications

Signed-off-by: martabal <74269598+martabal@users.noreply.github.com>

* fix: use handleError

Signed-off-by: martabal <74269598+martabal@users.noreply.github.com>

---------

Signed-off-by: martabal <74269598+martabal@users.noreply.github.com>
martin 2 anni fa
parent
commit
f9032866e7

+ 40 - 23
web/src/lib/components/asset-viewer/asset-viewer.svelte

@@ -20,6 +20,7 @@
   import { addAssetsToAlbum, downloadFile } from '$lib/utils/asset-utils';
   import { addAssetsToAlbum, downloadFile } from '$lib/utils/asset-utils';
   import NavigationArea from './navigation-area.svelte';
   import NavigationArea from './navigation-area.svelte';
   import { browser } from '$app/environment';
   import { browser } from '$app/environment';
+  import { handleError } from '$lib/utils/handle-error';
 
 
   export let asset: AssetResponseDto;
   export let asset: AssetResponseDto;
   export let publicSharedKey = '';
   export let publicSharedKey = '';
@@ -35,7 +36,7 @@
   let isShowProfileImageCrop = false;
   let isShowProfileImageCrop = false;
   let shouldShowDownloadButton = sharedLink ? sharedLink.allowDownload : true;
   let shouldShowDownloadButton = sharedLink ? sharedLink.allowDownload : true;
   let canCopyImagesToClipboard: boolean;
   let canCopyImagesToClipboard: boolean;
-  const onKeyboardPress = (keyInfo: KeyboardEvent) => handleKeyboardPress(keyInfo.key);
+  const onKeyboardPress = (keyInfo: KeyboardEvent) => handleKeyboardPress(keyInfo.key, keyInfo.shiftKey);
 
 
   onMount(async () => {
   onMount(async () => {
     document.addEventListener('keydown', onKeyboardPress);
     document.addEventListener('keydown', onKeyboardPress);
@@ -65,16 +66,11 @@
     }
     }
   };
   };
 
 
-  const handleKeyboardPress = (key: string) => {
+  const handleKeyboardPress = (key: string, shiftKey: boolean) => {
     switch (key) {
     switch (key) {
-      case 'Escape':
-        closeViewer();
-        return;
-      case 'Delete':
-        isShowDeleteConfirmation = true;
-        return;
-      case 'i':
-        $isShowDetail = !$isShowDetail;
+      case 'a':
+      case 'A':
+        if (shiftKey) toggleArchive();
         return;
         return;
       case 'ArrowLeft':
       case 'ArrowLeft':
         navigateAssetBackward();
         navigateAssetBackward();
@@ -82,6 +78,22 @@
       case 'ArrowRight':
       case 'ArrowRight':
         navigateAssetForward();
         navigateAssetForward();
         return;
         return;
+      case 'd':
+      case 'D':
+        if (shiftKey) downloadFile(asset, publicSharedKey);
+        return;
+      case 'Delete':
+        isShowDeleteConfirmation = true;
+        return;
+      case 'Escape':
+        closeViewer();
+        return;
+      case 'f':
+        toggleFavorite();
+        return;
+      case 'i':
+        $isShowDetail = !$isShowDetail;
+        return;
     }
     }
   };
   };
 
 
@@ -135,15 +147,24 @@
   };
   };
 
 
   const toggleFavorite = async () => {
   const toggleFavorite = async () => {
-    const { data } = await api.assetApi.updateAsset({
-      id: asset.id,
-      updateAssetDto: {
-        isFavorite: !asset.isFavorite,
-      },
-    });
+    try {
+      const { data } = await api.assetApi.updateAsset({
+        id: asset.id,
+        updateAssetDto: {
+          isFavorite: !asset.isFavorite,
+        },
+      });
+
+      asset.isFavorite = data.isFavorite;
+      assetStore.updateAsset(asset.id, data.isFavorite);
 
 
-    asset.isFavorite = data.isFavorite;
-    assetStore.updateAsset(asset.id, data.isFavorite);
+      notificationController.show({
+        type: NotificationType.Info,
+        message: asset.isFavorite ? `Added to favorites` : `Removed from favorites`,
+      });
+    } catch (error) {
+      handleError(error, `Unable to ${asset.isArchived ? `add asset to` : `remove asset from`} favorites`);
+    }
   };
   };
 
 
   const openAlbumPicker = (shared: boolean) => {
   const openAlbumPicker = (shared: boolean) => {
@@ -206,11 +227,7 @@
         message: asset.isArchived ? `Added to archive` : `Removed from archive`,
         message: asset.isArchived ? `Added to archive` : `Removed from archive`,
       });
       });
     } catch (error) {
     } catch (error) {
-      console.error(error);
-      notificationController.show({
-        type: NotificationType.Error,
-        message: `Error ${asset.isArchived ? 'archiving' : 'unarchiving'} asset, check console for more details`,
-      });
+      handleError(error, `Unable to ${asset.isArchived ? `add asset to` : `remove asset from`} archive`);
     }
     }
   };
   };
 
 

+ 21 - 2
web/src/lib/components/photos-page/asset-grid.svelte

@@ -26,6 +26,10 @@
   import AssetDateGroup from './asset-date-group.svelte';
   import AssetDateGroup from './asset-date-group.svelte';
   import MemoryLane from './memory-lane.svelte';
   import MemoryLane from './memory-lane.svelte';
 
 
+  import { AppRoute } from '$lib/constants';
+  import { goto } from '$app/navigation';
+  import { browser } from '$app/environment';
+
   export let user: UserResponseDto | undefined = undefined;
   export let user: UserResponseDto | undefined = undefined;
   export let isAlbumSelectionMode = false;
   export let isAlbumSelectionMode = false;
   export let showMemoryLane = false;
   export let showMemoryLane = false;
@@ -35,7 +39,10 @@
   let assetGridElement: HTMLElement;
   let assetGridElement: HTMLElement;
   let bucketInfo: AssetCountByTimeBucketResponseDto;
   let bucketInfo: AssetCountByTimeBucketResponseDto;
 
 
+  const onKeyboardPress = (event: KeyboardEvent) => handleKeyboardPress(event);
+
   onMount(async () => {
   onMount(async () => {
+    document.addEventListener('keydown', onKeyboardPress);
     const { data: assetCountByTimebucket } = await api.assetApi.getAssetCountByTimeBucket({
     const { data: assetCountByTimebucket } = await api.assetApi.getAssetCountByTimeBucket({
       getAssetCountByTimeBucketDto: {
       getAssetCountByTimeBucketDto: {
         timeGroup: TimeGroupEnum.Month,
         timeGroup: TimeGroupEnum.Month,
@@ -67,9 +74,21 @@
   });
   });
 
 
   onDestroy(() => {
   onDestroy(() => {
+    if (browser) document.removeEventListener('keydown', handleKeyboardPress);
     assetStore.setInitialState(0, 0, { totalCount: 0, buckets: [] }, undefined);
     assetStore.setInitialState(0, 0, { totalCount: 0, buckets: [] }, undefined);
   });
   });
 
 
+  const handleKeyboardPress = (event: KeyboardEvent) => {
+    if (event.key === '/') event.preventDefault();
+    if (!$isViewingAssetStoreState) {
+      switch (event.key) {
+        case '/':
+          goto(AppRoute.EXPLORE);
+          return;
+      }
+    }
+  };
+
   function intersectedHandler(event: CustomEvent) {
   function intersectedHandler(event: CustomEvent) {
     const el = event.detail.container as HTMLElement;
     const el = event.detail.container as HTMLElement;
     const target = el.firstChild as HTMLElement;
     const target = el.firstChild as HTMLElement;
@@ -128,14 +147,14 @@
   let shiftKeyIsDown = false;
   let shiftKeyIsDown = false;
 
 
   const onKeyDown = (e: KeyboardEvent) => {
   const onKeyDown = (e: KeyboardEvent) => {
-    if (e.key === 'Shift') {
+    if (e.shiftKey && e.key !== '/') {
       e.preventDefault();
       e.preventDefault();
       shiftKeyIsDown = true;
       shiftKeyIsDown = true;
     }
     }
   };
   };
 
 
   const onKeyUp = (e: KeyboardEvent) => {
   const onKeyUp = (e: KeyboardEvent) => {
-    if (e.key === 'Shift') {
+    if (e.shiftKey && e.key !== '/') {
       e.preventDefault();
       e.preventDefault();
       shiftKeyIsDown = false;
       shiftKeyIsDown = false;
     }
     }

+ 5 - 0
web/src/lib/utils/asset-utils.ts

@@ -122,6 +122,11 @@ export const downloadFile = async (asset: AssetResponseDto, key?: string) => {
         },
         },
       );
       );
 
 
+      notificationController.show({
+        type: NotificationType.Info,
+        message: `Downloading asset ${asset.originalFileName}`,
+      });
+
       downloadBlob(data, filename);
       downloadBlob(data, filename);
     } catch (e) {
     } catch (e) {
       handleError(e, `Error downloading ${filename}`);
       handleError(e, `Error downloading ${filename}`);