mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:39:37 -05:00 
			
		
		
		
	feat(web): show available shortcuts (#3342)
* feat(web): show available shortcuts * pr feeback * feat: new shortcut for deselect * fix: remove new shortcut * responsive
This commit is contained in:
		
							parent
							
								
									111372edc1
								
							
						
					
					
						commit
						b83e535010
					
				@ -30,6 +30,7 @@
 | 
				
			|||||||
  import { goto } from '$app/navigation';
 | 
					  import { goto } from '$app/navigation';
 | 
				
			||||||
  import { browser } from '$app/environment';
 | 
					  import { browser } from '$app/environment';
 | 
				
			||||||
  import { isSearchEnabled } from '$lib/stores/search.store';
 | 
					  import { isSearchEnabled } from '$lib/stores/search.store';
 | 
				
			||||||
 | 
					  import ShowShortcuts from '../shared-components/show-shortcuts.svelte';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let user: UserResponseDto | undefined = undefined;
 | 
					  export let user: UserResponseDto | undefined = undefined;
 | 
				
			||||||
  export let isAlbumSelectionMode = false;
 | 
					  export let isAlbumSelectionMode = false;
 | 
				
			||||||
@ -39,6 +40,7 @@
 | 
				
			|||||||
  let viewportWidth = 0;
 | 
					  let viewportWidth = 0;
 | 
				
			||||||
  let assetGridElement: HTMLElement;
 | 
					  let assetGridElement: HTMLElement;
 | 
				
			||||||
  let bucketInfo: AssetCountByTimeBucketResponseDto;
 | 
					  let bucketInfo: AssetCountByTimeBucketResponseDto;
 | 
				
			||||||
 | 
					  let showShortcuts = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onKeyboardPress = (event: KeyboardEvent) => handleKeyboardPress(event);
 | 
					  const onKeyboardPress = (event: KeyboardEvent) => handleKeyboardPress(event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,6 +95,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (!$isViewingAssetStoreState) {
 | 
					    if (!$isViewingAssetStoreState) {
 | 
				
			||||||
      switch (event.key) {
 | 
					      switch (event.key) {
 | 
				
			||||||
 | 
					        case '?':
 | 
				
			||||||
 | 
					          if (event.shiftKey) showShortcuts = !showShortcuts;
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
        case '/':
 | 
					        case '/':
 | 
				
			||||||
          goto(AppRoute.EXPLORE);
 | 
					          goto(AppRoute.EXPLORE);
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
@ -290,6 +295,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<svelte:window on:keydown={onKeyDown} on:keyup={onKeyUp} on:selectstart={onSelectStart} />
 | 
					<svelte:window on:keydown={onKeyDown} on:keyup={onKeyUp} on:selectstart={onSelectStart} />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if showShortcuts}
 | 
				
			||||||
 | 
					  <ShowShortcuts on:close={() => (showShortcuts = !showShortcuts)} />
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#if bucketInfo && viewportHeight && $assetGridState.timelineHeight > viewportHeight}
 | 
					{#if bucketInfo && viewportHeight && $assetGridState.timelineHeight > viewportHeight}
 | 
				
			||||||
  <Scrollbar
 | 
					  <Scrollbar
 | 
				
			||||||
    scrollbarHeight={viewportHeight}
 | 
					    scrollbarHeight={viewportHeight}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					  import Close from 'svelte-material-icons/Close.svelte';
 | 
				
			||||||
 | 
					  import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
 | 
				
			||||||
 | 
					  import { createEventDispatcher } from 'svelte';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const shortcuts = {
 | 
				
			||||||
 | 
					    general: [
 | 
				
			||||||
 | 
					      { key: ['←', '→'], action: 'Previous or next photo' },
 | 
				
			||||||
 | 
					      { key: ['Esc'], action: 'Back, close, or deselect' },
 | 
				
			||||||
 | 
					      { key: ['/'], action: 'Search your photos' },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    actions: [
 | 
				
			||||||
 | 
					      { key: ['f'], action: 'Favorite or unfavorite photo' },
 | 
				
			||||||
 | 
					      { key: ['i'], action: 'Show or hide info' },
 | 
				
			||||||
 | 
					      { key: ['⇧', 'a'], action: 'Archive or unarchive photo' },
 | 
				
			||||||
 | 
					      { key: ['⇧', 'd'], action: 'Download' },
 | 
				
			||||||
 | 
					      { key: ['Space'], action: 'Play or pause video' },
 | 
				
			||||||
 | 
					      { key: ['Del'], action: 'Delete Asset' },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  const dispatch = createEventDispatcher();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="absolute z-[99999] h-full w-full">
 | 
				
			||||||
 | 
					  <div class="flex h-full w-full place-content-center place-items-center overflow-hidden bg-black/50">
 | 
				
			||||||
 | 
					    <div
 | 
				
			||||||
 | 
					      class="w-[400px] max-w-[125vw] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg md:w-[650px]"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <div class="relative px-4 pt-4">
 | 
				
			||||||
 | 
					        <h1 class="px-4 py-4 font-medium text-immich-primary dark:text-immich-dark-primary">Keyboard Shortcuts</h1>
 | 
				
			||||||
 | 
					        <div class="absolute inset-y-0 right-0 px-4 py-4">
 | 
				
			||||||
 | 
					          <CircleIconButton logo={Close} on:click={() => dispatch('close')} />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div class="grid grid-cols-1 gap-4 px-4 pb-4 md:grid-cols-2">
 | 
				
			||||||
 | 
					        <div class="px-4 py-4">
 | 
				
			||||||
 | 
					          <h2>General</h2>
 | 
				
			||||||
 | 
					          <div class="text-sm">
 | 
				
			||||||
 | 
					            {#each shortcuts.general as shortcut}
 | 
				
			||||||
 | 
					              <div class="grid grid-cols-[20%_80%] items-center gap-4 pt-4 text-sm">
 | 
				
			||||||
 | 
					                <div class="flex justify-self-end">
 | 
				
			||||||
 | 
					                  {#each shortcut.key as key}
 | 
				
			||||||
 | 
					                    <p
 | 
				
			||||||
 | 
					                      class="mr-1 flex items-center justify-center justify-self-end rounded-lg bg-immich-primary/25 p-2"
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
 | 
					                      {key}
 | 
				
			||||||
 | 
					                    </p>
 | 
				
			||||||
 | 
					                  {/each}
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <p class="mb-1 mt-1 flex">{shortcut.action}</p>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            {/each}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="px-4 py-4">
 | 
				
			||||||
 | 
					          <h2>Actions</h2>
 | 
				
			||||||
 | 
					          <div class="text-sm">
 | 
				
			||||||
 | 
					            {#each shortcuts.actions as shortcut}
 | 
				
			||||||
 | 
					              <div class="grid grid-cols-[20%_80%] items-center gap-4 pt-4 text-sm">
 | 
				
			||||||
 | 
					                <div class="flex justify-self-end">
 | 
				
			||||||
 | 
					                  {#each shortcut.key as key}
 | 
				
			||||||
 | 
					                    <p
 | 
				
			||||||
 | 
					                      class="mr-1 flex items-center justify-center justify-self-end rounded-lg bg-immich-primary/25 p-2"
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
 | 
					                      {key}
 | 
				
			||||||
 | 
					                    </p>
 | 
				
			||||||
 | 
					                  {/each}
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <p class="mb-1 mt-1 flex">{shortcut.action}</p>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            {/each}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user