Browse Source

fix(web): ContextMenu unsatisfying UI behaviors (#3787)

Flyot 1 year ago
parent
commit
476b735e3c

+ 14 - 11
web/src/lib/components/photos-page/asset-select-context-menu.svelte

@@ -1,4 +1,5 @@
 <script lang="ts" context="module">
+  import { clickOutside } from '$lib/utils/click-outside';
   import { createContext } from '$lib/utils/context';
 
   const { get: getMenuContext, set: setContext } = createContext<() => void>();
@@ -16,20 +17,22 @@
   let showContextMenu = false;
   let contextMenuPosition = { x: 0, y: 0 };
 
-  const handleShowMenu = ({ x, y }: MouseEvent) => {
-    contextMenuPosition = { x, y };
+  const handleShowMenu = ({ x }: MouseEvent) => {
+    const navigationBarHeight = 75;
+    contextMenuPosition = { x: x, y: navigationBarHeight };
     showContextMenu = !showContextMenu;
   };
 
   setContext(() => (showContextMenu = false));
 </script>
 
-<CircleIconButton {title} logo={icon} on:click={handleShowMenu} />
-
-{#if showContextMenu}
-  <ContextMenu {...contextMenuPosition} on:outclick={() => (showContextMenu = false)}>
-    <div class="flex flex-col rounded-lg">
-      <slot />
-    </div>
-  </ContextMenu>
-{/if}
+<div use:clickOutside on:outclick={() => (showContextMenu = false)}>
+  <CircleIconButton {title} logo={icon} on:click={handleShowMenu} />
+  {#if showContextMenu}
+    <ContextMenu {...contextMenuPosition}>
+      <div class="flex flex-col rounded-lg">
+        <slot />
+      </div>
+    </ContextMenu>
+  {/if}
+</div>

+ 14 - 10
web/src/routes/(user)/albums/[albumId]/+page.svelte

@@ -44,6 +44,7 @@
   import Plus from 'svelte-material-icons/Plus.svelte';
   import ShareVariantOutline from 'svelte-material-icons/ShareVariantOutline.svelte';
   import type { PageData } from './$types';
+  import { clickOutside } from '$lib/utils/click-outside';
 
   export let data: PageData;
 
@@ -166,9 +167,10 @@
     timelineInteractionStore.clearMultiselect();
   };
 
-  const handleOpenAlbumOptions = ({ x, y }: MouseEvent) => {
-    contextMenuPosition = { x, y };
-    viewMode = ViewMode.ALBUM_OPTIONS;
+  const handleOpenAlbumOptions = ({ x }: MouseEvent) => {
+    const navigationBarHeight = 75;
+    contextMenuPosition = { x: x, y: navigationBarHeight };
+    viewMode = viewMode === ViewMode.VIEW ? ViewMode.ALBUM_OPTIONS : ViewMode.VIEW;
   };
 
   const handleSelectFromComputer = async () => {
@@ -330,13 +332,15 @@
             <CircleIconButton title="Download" on:click={handleDownloadAlbum} logo={FolderDownloadOutline} />
 
             {#if isOwned}
-              <CircleIconButton title="Album options" on:click={handleOpenAlbumOptions} logo={DotsVertical}>
-                {#if viewMode === ViewMode.ALBUM_OPTIONS}
-                  <ContextMenu {...contextMenuPosition} on:outclick={() => (viewMode = ViewMode.VIEW)}>
-                    <MenuOption on:click={() => (viewMode = ViewMode.SELECT_THUMBNAIL)} text="Set album cover" />
-                  </ContextMenu>
-                {/if}
-              </CircleIconButton>
+              <div use:clickOutside on:outclick={() => (viewMode = ViewMode.VIEW)}>
+                <CircleIconButton title="Album options" on:click={handleOpenAlbumOptions} logo={DotsVertical}>
+                  {#if viewMode === ViewMode.ALBUM_OPTIONS}
+                    <ContextMenu {...contextMenuPosition}>
+                      <MenuOption on:click={() => (viewMode = ViewMode.SELECT_THUMBNAIL)} text="Set album cover" />
+                    </ContextMenu>
+                  {/if}
+                </CircleIconButton>
+              </div>
             {/if}
           {/if}