Skip to content

Commit c543baa

Browse files
committed
improve selection
1 parent ec4e0a6 commit c543baa

File tree

16 files changed

+309
-319
lines changed

16 files changed

+309
-319
lines changed

resources/js/components/gallery/albumModule/AlbumPanel.vue

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@
4646
:albums="albumsStore.albums"
4747
:config="albumPanelConfig"
4848
:is-alone="photosStore.photos.length === 0"
49-
:idx-shift="0"
5049
:selected-albums="selectedAlbumsIds"
5150
:is-timeline="albumStore.config.is_album_timeline_enabled"
52-
@clicked="albumClick"
53-
@contexted="albumMenuOpen"
51+
@clicked="albumSelect"
52+
@contexted="contextMenuAlbumOpen"
5453
/>
5554
<!-- Pagination for albums -->
5655
<Pagination
@@ -77,7 +76,7 @@
7776
:with-control="true"
7877
@clicked="photoClick"
7978
@selected="photoSelect"
80-
@contexted="photoMenuOpen"
79+
@contexted="contextMenuPhotoOpen"
8180
@toggle-buy-me="toggleBuyMe"
8281
/>
8382
<!-- Pagination for photos -->
@@ -200,24 +199,13 @@ const {
200199
201200
const { toggleBuyMe } = useBuyMeActions(albumStore, photosStore, orderManagement, catalogStore, toast);
202201
203-
const {
204-
selectedPhotosIdx,
205-
selectedAlbumsIdx,
206-
selectedPhoto,
207-
selectedAlbum,
208-
selectedPhotos,
209-
selectedAlbums,
210-
selectedPhotosIds,
211-
selectedAlbumsIds,
212-
photoSelect,
213-
albumClick,
214-
unselect,
215-
} = useSelection(photosStore, albumsStore, togglableStore);
202+
const { selectedPhoto, selectedAlbum, selectedPhotos, selectedAlbums, selectedPhotosIds, selectedAlbumsIds, photoSelect, albumSelect, unselect } =
203+
useSelection(photosStore, albumsStore, togglableStore);
216204
217205
const { photoRoute, getParentId } = usePhotoRoute(router);
218206
219-
function photoClick(idx: number, _e: MouseEvent) {
220-
router.push(photoRoute(photosStore.filteredPhotos[idx].id));
207+
function photoClick(photoId: string, _e: MouseEvent) {
208+
router.push(photoRoute(photoId));
221209
}
222210
223211
function goToPhotosPage(page: number) {
@@ -345,16 +333,21 @@ const albumCallbacks = {
345333
const computedAlbum = computed(() => albumStore.album);
346334
const computedConfig = computed(() => albumStore.config);
347335
348-
const { menu, Menu, photoMenuOpen, albumMenuOpen } = useContextMenu(
336+
const {
337+
menu,
338+
Menu,
339+
photoMenuOpen: contextMenuPhotoOpen,
340+
albumMenuOpen: contextMenuAlbumOpen,
341+
} = useContextMenu(
349342
{
350343
config: computedConfig,
351344
album: computedAlbum,
352345
selectedPhoto: selectedPhoto,
353346
selectedPhotos: selectedPhotos,
354-
selectedPhotosIdx: selectedPhotosIdx,
347+
selectedPhotosIds: selectedPhotosIds,
355348
selectedAlbum: selectedAlbum,
356349
selectedAlbums: selectedAlbums,
357-
selectedAlbumIdx: selectedAlbumsIdx,
350+
selectedAlbumsIds: selectedAlbumsIds,
358351
},
359352
photoCallbacks,
360353
albumCallbacks,

resources/js/components/gallery/albumModule/AlbumThumbPanel.vue

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
<AlbumThumbPanelList
2020
v-else
2121
:albums="props.albums"
22-
:idx-shift="props.idxShift"
23-
:iter="0"
22+
:is-interactive="props.isInteractive"
2423
:selected-albums="props.selectedAlbums"
25-
@clicked="propagateClicked"
26-
@contexted="propagateMenuOpen"
24+
@clicked="(id, e) => emits('clicked', id, e)"
25+
@contexted="(id, e) => emits('contexted', id, e)"
2726
/>
2827
</div>
2928
</Panel>
@@ -51,11 +50,10 @@
5150
<AlbumThumbPanelList
5251
v-else
5352
:albums="slotProps.item.data"
54-
:idx-shift="props.idxShift"
55-
:iter="slotProps.item.iter"
53+
:is-interactive="props.isInteractive"
5654
:selected-albums="props.selectedAlbums"
57-
@clicked="propagateClicked"
58-
@contexted="propagateMenuOpen"
55+
@clicked="(id, e) => emits('clicked', id, e)"
56+
@contexted="(id, e) => emits('contexted', id, e)"
5957
/>
6058
</div>
6159
</template>
@@ -79,11 +77,10 @@
7977
<AlbumThumbPanelList
8078
v-else
8179
:albums="albumTimeline.data"
82-
:idx-shift="props.idxShift"
83-
:iter="albumTimeline.iter"
80+
:is-interactive="props.isInteractive"
8481
:selected-albums="props.selectedAlbums"
85-
@clicked="propagateClicked"
86-
@contexted="propagateMenuOpen"
82+
@clicked="(id, e) => emits('clicked', id, e)"
83+
@contexted="(id, e) => emits('contexted', id, e)"
8784
/>
8885
</div>
8986
</template>
@@ -111,40 +108,26 @@ const props = defineProps<{
111108
header: string;
112109
albums: App.Http.Resources.Models.ThumbAlbumResource[];
113110
isAlone: boolean;
114-
idxShift: number;
111+
isInteractive?: boolean;
115112
selectedAlbums: string[];
116113
isTimeline: boolean;
117114
}>();
118115
119116
// bubble up.
120117
const emits = defineEmits<{
121-
clicked: [idx: number, event: MouseEvent];
122-
contexted: [idx: number, event: MouseEvent];
118+
clicked: [id: string, event: MouseEvent];
119+
contexted: [id: string, event: MouseEvent];
123120
}>();
124121
125122
const { spliter, verifyOrder } = useSplitter();
126123
127-
const propagateClicked = (idx: number, e: MouseEvent) => {
128-
emits("clicked", idx, e);
129-
};
130-
131-
const propagateMenuOpen = (idx: number, e: MouseEvent) => {
132-
emits("contexted", idx, e);
133-
};
134-
135-
// Handlers for list view - convert album object to index
124+
// Handlers for list view - emit album ID directly
136125
const propagateClickedFromList = (e: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource) => {
137-
const idx = props.albums.findIndex((a) => a.id === album.id);
138-
if (idx !== -1) {
139-
emits("clicked", idx + props.idxShift, e);
140-
}
126+
emits("clicked", album.id, e);
141127
};
142128
143129
const propagateMenuOpenFromList = (e: MouseEvent, album: App.Http.Resources.Models.ThumbAlbumResource) => {
144-
const idx = props.albums.findIndex((a) => a.id === album.id);
145-
if (idx !== -1) {
146-
emits("contexted", idx + props.idxShift, e);
147-
}
130+
emits("contexted", album.id, e);
148131
};
149132
150133
const albumsTimeLine = computed<SplitData<App.Http.Resources.Models.ThumbAlbumResource>[]>(() =>
Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<template>
2-
<template v-for="(album, idx) in props.albums" :key="`album-thumb-${idx + props.iter + props.idxShift}`">
2+
<template v-for="album in props.albums" :key="`album-thumb-${album.id}`">
33
<AlbumThumb
44
v-if="!album.is_nsfw || are_nsfw_visible"
55
:album="album"
66
:cover_id="null"
77
:is-selected="props.selectedAlbums.includes(album.id)"
8-
@click="maySelect(idx + props.iter + props.idxShift, $event)"
9-
@contextmenu.prevent="menuOpen(idx + props.iter + props.idxShift, $event)"
8+
@click="(e: MouseEvent) => maySelect(album.id, e)"
9+
@contextmenu.prevent="(e: MouseEvent) => menuOpen(album.id, e)"
1010
/>
1111
</template>
1212
</template>
@@ -20,28 +20,27 @@ const { are_nsfw_visible } = storeToRefs(lycheeStore);
2020
2121
const props = defineProps<{
2222
albums: App.Http.Resources.Models.ThumbAlbumResource[];
23-
iter: number;
24-
idxShift: number;
23+
isInteractive?: boolean;
2524
selectedAlbums: string[];
2625
}>();
2726
2827
// bubble up.
2928
const emits = defineEmits<{
30-
clicked: [idx: number, event: MouseEvent];
31-
contexted: [idx: number, event: MouseEvent];
29+
clicked: [id: string, event: MouseEvent];
30+
contexted: [id: string, event: MouseEvent];
3231
}>();
3332
34-
const maySelect = (idx: number, e: MouseEvent) => {
35-
if (props.idxShift < 0) {
33+
const maySelect = (id: string, e: MouseEvent) => {
34+
if (props.isInteractive === false) {
3635
return;
3736
}
38-
emits("clicked", idx, e);
37+
emits("clicked", id, e);
3938
};
4039
41-
const menuOpen = (idx: number, e: MouseEvent) => {
42-
if (props.idxShift < 0) {
40+
const menuOpen = (id: string, e: MouseEvent) => {
41+
if (props.isInteractive === false) {
4342
return;
4443
}
45-
emits("contexted", idx, e);
44+
emits("contexted", id, e);
4645
};
4746
</script>

resources/js/components/gallery/albumModule/PhotoThumbPanel.vue

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@
77
v-if="isTimeline === false"
88
:photos="props.photos"
99
:selected-photos="props.selectedPhotos"
10-
:iter="0"
1110
:group-idx="0"
1211
:is-timeline="false"
13-
@clicked="propagateClicked"
14-
@selected="propagateSelected"
15-
@contexted="propagateMenuOpen"
16-
@toggle-buy-me="propagateToggleBuyMe"
12+
@clicked="(id, e) => emits('clicked', id, e)"
13+
@selected="(id, e) => emits('selected', id, e)"
14+
@contexted="(id, e) => emits('contexted', id, e)"
15+
@toggle-buy-me="(id) => emits('toggleBuyMe', id)"
1716
/>
1817
<template v-else>
1918
<Timeline
@@ -36,13 +35,12 @@
3635
<PhotoThumbPanelList
3736
:photos="slotProps.item.data"
3837
:selected-photos="props.selectedPhotos"
39-
:iter="slotProps.item.iter"
4038
:group-idx="slotProps.index"
4139
:is-timeline="true"
42-
@contexted="propagateMenuOpen"
43-
@selected="propagateSelected"
44-
@clicked="propagateClicked"
45-
@toggle-buy-me="propagateToggleBuyMe"
40+
@contexted="(id, e) => emits('contexted', id, e)"
41+
@selected="(id, e) => emits('selected', id, e)"
42+
@clicked="(id, e) => emits('clicked', id, e)"
43+
@toggle-buy-me="(id) => emits('toggleBuyMe', id)"
4644
/>
4745
</div>
4846
</template>
@@ -61,13 +59,12 @@
6159
<PhotoThumbPanelList
6260
:photos="photoTimeline.data"
6361
:selected-photos="props.selectedPhotos"
64-
:iter="photoTimeline.iter"
6562
:group-idx="idx"
6663
:is-timeline="true"
67-
@contexted="propagateMenuOpen"
68-
@selected="propagateSelected"
69-
@clicked="propagateClicked"
70-
@toggle-buy-me="propagateToggleBuyMe"
64+
@contexted="(id, e) => emits('contexted', id, e)"
65+
@selected="(id, e) => emits('selected', id, e)"
66+
@clicked="(id, e) => emits('clicked', id, e)"
67+
@toggle-buy-me="(id) => emits('toggleBuyMe', id)"
7168
/>
7269
</div>
7370
</template>
@@ -110,28 +107,12 @@ const isLeftBorderVisible = computed(() => is_timeline_left_border_visible.value
110107
111108
// bubble up.
112109
const emits = defineEmits<{
113-
clicked: [idx: number, event: MouseEvent];
114-
selected: [idx: number, event: MouseEvent];
115-
contexted: [idx: number, event: MouseEvent];
116-
toggleBuyMe: [idx: string];
110+
clicked: [id: string, event: MouseEvent];
111+
selected: [id: string, event: MouseEvent];
112+
contexted: [id: string, event: MouseEvent];
113+
toggleBuyMe: [id: string];
117114
}>();
118115
119-
const propagateSelected = (idx: number, e: MouseEvent) => {
120-
emits("selected", idx, e);
121-
};
122-
123-
const propagateClicked = (idx: number, e: MouseEvent) => {
124-
emits("clicked", idx, e);
125-
};
126-
127-
const propagateMenuOpen = (idx: number, e: MouseEvent) => {
128-
emits("contexted", idx, e);
129-
};
130-
131-
const propagateToggleBuyMe = (idx: string) => {
132-
emits("toggleBuyMe", idx);
133-
};
134-
135116
function onIntersectionObserver([entry]: IntersectionObserverEntry[]) {
136117
if (entry.isIntersecting) {
137118
const section = entry?.target as HTMLElement;

resources/js/components/gallery/albumModule/PhotoThumbPanelList.vue

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<template>
22
<div :id="'photoListing' + props.groupIdx" class="relative flex flex-wrap flex-row shrink w-full justify-start align-top">
3-
<template v-for="(photo, idx) in props.photos" :key="photo.id">
3+
<template v-for="photo in props.photos" :key="photo.id">
44
<PhotoThumb
55
:photo="photo"
66
:is-selected="props.selectedPhotos.includes(photo.id)"
7-
:is-lazy="idx + props.iter > 10"
87
:is-cover-id="albumStore.modelAlbum?.cover_id === photo.id"
98
:is-header-id="albumStore.modelAlbum?.header_id === photo.id"
10-
@click="maySelect(idx + props.iter, $event)"
11-
@contextmenu.prevent="menuOpen(idx + props.iter, $event)"
9+
@click="(e: MouseEvent) => maySelect(photo.id, e)"
10+
@contextmenu.prevent="(e: MouseEvent) => menuOpen(photo.id, e)"
1211
:is-buyable="isBuyable"
1312
@toggleBuyMe="emits('toggleBuyMe', photo.id)"
1413
/>
@@ -31,7 +30,6 @@ import { useCatalogStore } from "@/stores/CatalogState";
3130
const props = defineProps<{
3231
photos: App.Http.Resources.Models.PhotoResource[];
3332
selectedPhotos: string[];
34-
iter: number;
3533
groupIdx: number;
3634
isTimeline?: boolean;
3735
}>();
@@ -52,21 +50,21 @@ const timelineData: TimelineData = {
5250
};
5351
5452
const emits = defineEmits<{
55-
clicked: [idx: number, event: MouseEvent];
56-
selected: [idx: number, event: MouseEvent];
57-
contexted: [idx: number, event: MouseEvent];
58-
toggleBuyMe: [idx: string];
53+
clicked: [id: string, event: MouseEvent];
54+
selected: [id: string, event: MouseEvent];
55+
contexted: [id: string, event: MouseEvent];
56+
toggleBuyMe: [id: string];
5957
}>();
6058
61-
function maySelect(idx: number, e: MouseEvent) {
59+
function maySelect(id: string, e: MouseEvent) {
6260
if (ctrlKeyState.value || metaKeyState.value || shiftKeyState.value) {
63-
emits("selected", idx, e);
61+
emits("selected", id, e);
6462
return;
6563
}
66-
emits("clicked", idx, e);
64+
emits("clicked", id, e);
6765
}
68-
function menuOpen(idx: number, e: MouseEvent) {
69-
emits("contexted", idx, e);
66+
function menuOpen(id: string, e: MouseEvent) {
67+
emits("contexted", id, e);
7068
}
7169
7270
// Layouts stuff

resources/js/components/gallery/albumModule/thumbs/PhotoThumb.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"
3434
data-overlay="false"
3535
draggable="false"
36-
:loading="props.isLazy ? 'lazy' : 'eager'"
36+
loading="lazy"
3737
@load="onImageLoad"
3838
/>
3939
</span>
@@ -112,7 +112,6 @@ const { getNoImageIcon, getPlayIcon } = useImageHelpers();
112112
113113
const props = defineProps<{
114114
isSelected: boolean;
115-
isLazy: boolean;
116115
isCoverId: boolean;
117116
isHeaderId: boolean;
118117
photo: App.Http.Resources.Models.PhotoResource;

0 commit comments

Comments
 (0)