mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:29:32 -05:00 
			
		
		
		
	album and face menu dots visible on hover only (#3859)
This commit is contained in:
		
							parent
							
								
									dad7cf47b4
								
							
						
					
					
						commit
						dc3f53a973
					
				@ -12,6 +12,7 @@
 | 
				
			|||||||
  export let user: UserResponseDto;
 | 
					  export let user: UserResponseDto;
 | 
				
			||||||
  export let showItemCount = true;
 | 
					  export let showItemCount = true;
 | 
				
			||||||
  export let showContextMenu = true;
 | 
					  export let showContextMenu = true;
 | 
				
			||||||
 | 
					  let showVerticalDots = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $: imageData = album.albumThumbnailAssetId
 | 
					  $: imageData = album.albumThumbnailAssetId
 | 
				
			||||||
    ? api.getAssetThumbnailUrl(album.albumThumbnailAssetId, ThumbnailFormat.Webp)
 | 
					    ? api.getAssetThumbnailUrl(album.albumThumbnailAssetId, ThumbnailFormat.Webp)
 | 
				
			||||||
@ -63,6 +64,8 @@
 | 
				
			|||||||
  class="group relative mt-4 rounded-3xl border-[3px] border-transparent p-5 hover:cursor-pointer hover:border-immich-primary/75 dark:hover:border-immich-dark-primary/75"
 | 
					  class="group relative mt-4 rounded-3xl border-[3px] border-transparent p-5 hover:cursor-pointer hover:border-immich-primary/75 dark:hover:border-immich-dark-primary/75"
 | 
				
			||||||
  on:click={() => dispatchClick('click', album)}
 | 
					  on:click={() => dispatchClick('click', album)}
 | 
				
			||||||
  on:keydown={() => dispatchClick('click', album)}
 | 
					  on:keydown={() => dispatchClick('click', album)}
 | 
				
			||||||
 | 
					  on:mouseenter={() => (showVerticalDots = true)}
 | 
				
			||||||
 | 
					  on:mouseleave={() => (showVerticalDots = false)}
 | 
				
			||||||
  data-testid="album-card"
 | 
					  data-testid="album-card"
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
  <!-- svelte-ignore a11y-click-events-have-key-events -->
 | 
					  <!-- svelte-ignore a11y-click-events-have-key-events -->
 | 
				
			||||||
@ -71,9 +74,10 @@
 | 
				
			|||||||
      id={`icon-${album.id}`}
 | 
					      id={`icon-${album.id}`}
 | 
				
			||||||
      class="absolute right-6 top-6 z-10"
 | 
					      class="absolute right-6 top-6 z-10"
 | 
				
			||||||
      on:click|stopPropagation|preventDefault={showAlbumContextMenu}
 | 
					      on:click|stopPropagation|preventDefault={showAlbumContextMenu}
 | 
				
			||||||
 | 
					      class:hidden={!showVerticalDots}
 | 
				
			||||||
      data-testid="context-button-parent"
 | 
					      data-testid="context-button-parent"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <IconButton color="overlay-primary">
 | 
					      <IconButton color="transparent-primary">
 | 
				
			||||||
        <DotsVertical size="20" class="icon-white-drop-shadow" color="white" />
 | 
					        <DotsVertical size="20" class="icon-white-drop-shadow" color="white" />
 | 
				
			||||||
      </IconButton>
 | 
					      </IconButton>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -10,16 +10,37 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  export let person: PersonResponseDto;
 | 
					  export let person: PersonResponseDto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let showContextMenu = false;
 | 
					  type MenuItemEvent = 'change-name' | 'set-birth-date' | 'merge-faces' | 'hide-face';
 | 
				
			||||||
  let dispatch = createEventDispatcher<{
 | 
					  let dispatch = createEventDispatcher<{
 | 
				
			||||||
    'change-name': void;
 | 
					    'change-name': void;
 | 
				
			||||||
    'set-birth-date': void;
 | 
					    'set-birth-date': void;
 | 
				
			||||||
    'merge-faces': void;
 | 
					    'merge-faces': void;
 | 
				
			||||||
    'hide-face': void;
 | 
					    'hide-face': void;
 | 
				
			||||||
  }>();
 | 
					  }>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let showVerticalDots = false;
 | 
				
			||||||
 | 
					  let showContextMenu = false;
 | 
				
			||||||
 | 
					  let contextMenuPosition = { x: 0, y: 0 };
 | 
				
			||||||
 | 
					  const showMenu = ({ x, y }: MouseEvent) => {
 | 
				
			||||||
 | 
					    contextMenuPosition = { x, y };
 | 
				
			||||||
 | 
					    showContextMenu = !showContextMenu;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  const onMenuExit = () => {
 | 
				
			||||||
 | 
					    showContextMenu = false;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  const onMenuClick = (event: MenuItemEvent) => {
 | 
				
			||||||
 | 
					    onMenuExit();
 | 
				
			||||||
 | 
					    dispatch(event);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div id="people-card" class="relative">
 | 
					<div
 | 
				
			||||||
 | 
					  id="people-card"
 | 
				
			||||||
 | 
					  class="relative"
 | 
				
			||||||
 | 
					  on:mouseenter={() => (showVerticalDots = true)}
 | 
				
			||||||
 | 
					  on:mouseleave={() => (showVerticalDots = false)}
 | 
				
			||||||
 | 
					  role="group"
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
  <a href="/people/{person.id}" draggable="false">
 | 
					  <a href="/people/{person.id}" draggable="false">
 | 
				
			||||||
    <div class="h-48 w-48 rounded-xl brightness-95 filter">
 | 
					    <div class="h-48 w-48 rounded-xl brightness-95 filter">
 | 
				
			||||||
      <ImageThumbnail shadow url={api.getPeopleThumbnailUrl(person.id)} altText={person.name} widthStyle="100%" />
 | 
					      <ImageThumbnail shadow url={api.getPeopleThumbnailUrl(person.id)} altText={person.name} widthStyle="100%" />
 | 
				
			||||||
@ -35,29 +56,24 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  <button
 | 
					  <button
 | 
				
			||||||
    class="absolute right-2 top-2 z-20"
 | 
					    class="absolute right-2 top-2 z-20"
 | 
				
			||||||
    on:click|stopPropagation|preventDefault={() => {
 | 
					    on:click|stopPropagation|preventDefault={showMenu}
 | 
				
			||||||
      showContextMenu = !showContextMenu;
 | 
					    class:hidden={!showVerticalDots}
 | 
				
			||||||
    }}
 | 
					 | 
				
			||||||
    data-testid="context-button-parent"
 | 
					    data-testid="context-button-parent"
 | 
				
			||||||
    id={`icon-${person.id}`}
 | 
					    id={`icon-${person.id}`}
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <IconButton color="transparent-primary">
 | 
					    <IconButton color="transparent-primary">
 | 
				
			||||||
      <DotsVertical size="20" class="icon-white-drop-shadow" color="white" />
 | 
					      <DotsVertical size="20" class="icon-white-drop-shadow" color="white" />
 | 
				
			||||||
    </IconButton>
 | 
					    </IconButton>
 | 
				
			||||||
 | 
					 | 
				
			||||||
    {#if showContextMenu}
 | 
					 | 
				
			||||||
      <ContextMenu on:outclick={() => (showContextMenu = false)}>
 | 
					 | 
				
			||||||
        <MenuOption on:click={() => dispatch('hide-face')} text="Hide face" />
 | 
					 | 
				
			||||||
        <MenuOption on:click={() => dispatch('change-name')} text="Change name" />
 | 
					 | 
				
			||||||
        <MenuOption on:click={() => dispatch('set-birth-date')} text="Set date of birth" />
 | 
					 | 
				
			||||||
        <MenuOption on:click={() => dispatch('merge-faces')} text="Merge faces" />
 | 
					 | 
				
			||||||
      </ContextMenu>
 | 
					 | 
				
			||||||
    {/if}
 | 
					 | 
				
			||||||
  </button>
 | 
					  </button>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#if showContextMenu}
 | 
					{#if showContextMenu}
 | 
				
			||||||
  <Portal target="body">
 | 
					  <Portal target="body">
 | 
				
			||||||
    <div class="heyo absolute left-0 top-0 z-10 h-screen w-screen bg-transparent" />
 | 
					    <ContextMenu {...contextMenuPosition} on:outclick={() => onMenuExit()}>
 | 
				
			||||||
 | 
					      <MenuOption on:click={() => onMenuClick('hide-face')} text="Hide face" />
 | 
				
			||||||
 | 
					      <MenuOption on:click={() => onMenuClick('change-name')} text="Change name" />
 | 
				
			||||||
 | 
					      <MenuOption on:click={() => onMenuClick('set-birth-date')} text="Set date of birth" />
 | 
				
			||||||
 | 
					      <MenuOption on:click={() => onMenuClick('merge-faces')} text="Merge faces" />
 | 
				
			||||||
 | 
					    </ContextMenu>
 | 
				
			||||||
  </Portal>
 | 
					  </Portal>
 | 
				
			||||||
{/if}
 | 
					{/if}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user