From f63faa20d4c6ab3463828c4a2ee301717879b6bb Mon Sep 17 00:00:00 2001 From: ildyria Date: Thu, 29 Jan 2026 12:27:40 +0100 Subject: [PATCH] fix event propagation --- .../gallery/albumModule/AlbumListItem.vue | 13 +++--- .../gallery/albumModule/AlbumListView.vue | 13 +++--- .../gallery/albumModule/AlbumThumbPanel.vue | 43 +++++++------------ .../albumModule/AlbumThumbPanelList.vue | 24 +++-------- .../js/composables/album/propagateEvents.ts | 16 +++++++ .../composables/contextMenus/contextMenu.ts | 2 +- .../js/composables/selections/selections.ts | 2 +- 7 files changed, 56 insertions(+), 57 deletions(-) create mode 100644 resources/js/composables/album/propagateEvents.ts diff --git a/resources/js/components/gallery/albumModule/AlbumListItem.vue b/resources/js/components/gallery/albumModule/AlbumListItem.vue index a12b21dca81..7ea05879c68 100644 --- a/resources/js/components/gallery/albumModule/AlbumListItem.vue +++ b/resources/js/components/gallery/albumModule/AlbumListItem.vue @@ -5,8 +5,8 @@ 'bg-primary-100 dark:bg-primary-900/50': isSelected, }" :data-album-id="album.id" - @click="$emit('clicked', $event, album)" - @contextmenu.prevent="$emit('contexted', $event, album)" + @click="propagateClicked($event, album.id)" + @contextmenu.prevent="propagateContexted($event, album.id)" > (); -defineEmits<{ - clicked: [event: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource]; - contexted: [event: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource]; +const emits = defineEmits<{ + clicked: [event: MouseEvent, id: string]; + contexted: [event: MouseEvent, id: string]; }>(); +const { propagateClicked, propagateContexted } = usePropagateAlbumEvents(emits); + const aspectRatio = computed( () => albumStore.config?.album_thumb_css_aspect_ratio ?? albumsStore.rootConfig?.album_thumb_css_aspect_ratio ?? "aspect-square", ); diff --git a/resources/js/components/gallery/albumModule/AlbumListView.vue b/resources/js/components/gallery/albumModule/AlbumListView.vue index bcf74fb5f40..1e91905d1df 100644 --- a/resources/js/components/gallery/albumModule/AlbumListView.vue +++ b/resources/js/components/gallery/albumModule/AlbumListView.vue @@ -5,8 +5,8 @@ v-if="!album.is_nsfw || are_nsfw_visible" :album="album" :is-selected="selectedIds.includes(album.id)" - @clicked="(event, album) => $emit('album-clicked', event, album)" - @contexted="(event, album) => $emit('album-contexted', event, album)" + @clicked="propagateClicked" + @contexted="propagateContexted" /> @@ -16,17 +16,20 @@ import { useLycheeStateStore } from "@/stores/LycheeState"; import AlbumListItem from "./AlbumListItem.vue"; import { storeToRefs } from "pinia"; +import { usePropagateAlbumEvents } from "@/composables/album/propagateEvents"; const props = defineProps<{ albums: App.Http.Resources.Models.ThumbAlbumResource[]; selectedIds: string[]; }>(); -defineEmits<{ - "album-clicked": [event: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource]; - "album-contexted": [event: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource]; +const emits = defineEmits<{ + clicked: [event: MouseEvent, id: string]; + contexted: [event: MouseEvent, id: string]; }>(); +const { propagateClicked, propagateContexted } = usePropagateAlbumEvents(emits); + const lycheeStore = useLycheeStateStore(); const { are_nsfw_visible } = storeToRefs(lycheeStore); diff --git a/resources/js/components/gallery/albumModule/AlbumThumbPanel.vue b/resources/js/components/gallery/albumModule/AlbumThumbPanel.vue index 27768a78665..77d32ce58f0 100644 --- a/resources/js/components/gallery/albumModule/AlbumThumbPanel.vue +++ b/resources/js/components/gallery/albumModule/AlbumThumbPanel.vue @@ -13,16 +13,15 @@ v-if="album_view_mode === 'list'" :albums="props.albums" :selected-ids="props.selectedAlbums" - @album-clicked="propagateClickedFromList" - @album-contexted="propagateMenuOpenFromList" + @clicked="propagateClicked" + @contexted="propagateContexted" /> @@ -43,17 +42,16 @@ v-if="album_view_mode === 'list'" :albums="slotProps.item.data" :selected-ids="props.selectedAlbums" - @album-clicked="propagateClickedFromList" - @album-contexted="propagateMenuOpenFromList" + @clicked="propagateClicked" + @contexted="propagateContexted" /> @@ -70,17 +68,16 @@ v-if="album_view_mode === 'list'" :albums="albumTimeline.data" :selected-ids="props.selectedAlbums" - @album-clicked="propagateClickedFromList" - @album-contexted="propagateMenuOpenFromList" + @clicked="propagateClicked" + @contexted="propagateContexted" /> @@ -98,6 +95,7 @@ import AlbumThumbPanelList from "./AlbumThumbPanelList.vue"; import AlbumListView from "./AlbumListView.vue"; import { useLtRorRtL } from "@/utils/Helpers"; import { isTouchDevice } from "@/utils/keybindings-utils"; +import { usePropagateAlbumEvents } from "@/composables/album/propagateEvents"; const { isLTR } = useLtRorRtL(); @@ -108,28 +106,19 @@ const props = defineProps<{ header: string; albums: App.Http.Resources.Models.ThumbAlbumResource[]; isAlone: boolean; - isInteractive?: boolean; selectedAlbums: string[]; isTimeline: boolean; }>(); // bubble up. const emits = defineEmits<{ - clicked: [id: string, event: MouseEvent]; - contexted: [id: string, event: MouseEvent]; + clicked: [event: MouseEvent, id: string]; + contexted: [event: MouseEvent, id: string]; }>(); +const { propagateClicked, propagateContexted } = usePropagateAlbumEvents(emits); const { spliter, verifyOrder } = useSplitter(); -// Handlers for list view - emit album ID directly -const propagateClickedFromList = (e: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource) => { - emits("clicked", album.id, e); -}; - -const propagateMenuOpenFromList = (e: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource) => { - emits("contexted", album.id, e); -}; - const albumsTimeLine = computed[]>(() => split(props.albums as App.Http.Resources.Models.ThumbAlbumResource[]), ); diff --git a/resources/js/components/gallery/albumModule/AlbumThumbPanelList.vue b/resources/js/components/gallery/albumModule/AlbumThumbPanelList.vue index a1da899a988..ea72cee28b0 100644 --- a/resources/js/components/gallery/albumModule/AlbumThumbPanelList.vue +++ b/resources/js/components/gallery/albumModule/AlbumThumbPanelList.vue @@ -5,13 +5,14 @@ :album="album" :cover_id="null" :is-selected="props.selectedAlbums.includes(album.id)" - @click="(e: MouseEvent) => maySelect(album.id, e)" - @contextmenu.prevent="(e: MouseEvent) => menuOpen(album.id, e)" + @click="propagateClicked($event, album.id)" + @contextmenu.prevent="propagateContexted($event, album.id)" /> diff --git a/resources/js/composables/album/propagateEvents.ts b/resources/js/composables/album/propagateEvents.ts new file mode 100644 index 00000000000..5b2d24500b5 --- /dev/null +++ b/resources/js/composables/album/propagateEvents.ts @@ -0,0 +1,16 @@ +export function usePropagateAlbumEvents( + emits: ((evt: "clicked", event: MouseEvent, id: string) => void) & ((evt: "contexted", event: MouseEvent, id: string) => void), +) { + function propagateClicked(event: MouseEvent, id: string) { + emits("clicked", event, id); + } + + function propagateContexted(event: MouseEvent, id: string) { + emits("contexted", event, id); + } + + return { + propagateClicked, + propagateContexted, + }; +} diff --git a/resources/js/composables/contextMenus/contextMenu.ts b/resources/js/composables/contextMenus/contextMenu.ts index 6e708642685..3df7dc14299 100644 --- a/resources/js/composables/contextMenus/contextMenu.ts +++ b/resources/js/composables/contextMenus/contextMenu.ts @@ -356,7 +356,7 @@ export function useContextMenu(selectors: Selectors, photoCallbacks: PhotoCallba menu.value.show(e); } - function albumMenuOpen(albumId: string, e: MouseEvent): void { + function albumMenuOpen(e: MouseEvent, albumId: string): void { // Clear up Photo selection (if any) if (selectors.selectedPhotosIds !== undefined) { selectors.selectedPhotosIds.value = []; diff --git a/resources/js/composables/selections/selections.ts b/resources/js/composables/selections/selections.ts index 2ae12a55784..e9714cbce10 100644 --- a/resources/js/composables/selections/selections.ts +++ b/resources/js/composables/selections/selections.ts @@ -149,7 +149,7 @@ export function useSelection(photosStore: PhotosStore, albumsStore: AlbumsStore, lastPhotoClicked.value = photoId; } - function albumSelect(albumId: string, e: MouseEvent): void { + function albumSelect(e: MouseEvent, albumId: string): void { // clear the Photo selection. selectedPhotosIds.value = [];