@fy-/fws-vue 2.1.6 → 2.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/fws/CmsArticleBoxed.vue +23 -20
- package/components/fws/CmsArticleSingle.vue +74 -68
- package/components/fws/DataTable.vue +132 -125
- package/components/fws/FilterData.vue +99 -101
- package/components/fws/UserData.vue +33 -32
- package/components/fws/UserFlow.vue +163 -155
- package/components/fws/UserOAuth2.vue +73 -72
- package/components/fws/UserProfile.vue +98 -101
- package/components/fws/UserProfileStrict.vue +65 -64
- package/components/ssr/ClientOnly.ts +7 -7
- package/components/ui/DefaultBreadcrumb.vue +13 -13
- package/components/ui/DefaultConfirm.vue +35 -34
- package/components/ui/DefaultDateSelection.vue +19 -17
- package/components/ui/DefaultDropdown.vue +25 -25
- package/components/ui/DefaultDropdownLink.vue +15 -14
- package/components/ui/DefaultGallery.vue +179 -168
- package/components/ui/DefaultInput.vue +121 -126
- package/components/ui/DefaultLoader.vue +17 -17
- package/components/ui/DefaultModal.vue +35 -33
- package/components/ui/DefaultNotif.vue +50 -52
- package/components/ui/DefaultPaging.vue +92 -95
- package/components/ui/DefaultSidebar.vue +29 -25
- package/components/ui/DefaultTagInput.vue +121 -119
- package/components/ui/transitions/CollapseTransition.vue +1 -1
- package/components/ui/transitions/ExpandTransition.vue +1 -1
- package/components/ui/transitions/FadeTransition.vue +1 -1
- package/components/ui/transitions/ScaleTransition.vue +1 -1
- package/components/ui/transitions/SlideTransition.vue +3 -3
- package/composables/event-bus.ts +10 -8
- package/composables/rest.ts +59 -56
- package/composables/seo.ts +111 -95
- package/composables/ssr.ts +64 -62
- package/composables/templating.ts +57 -57
- package/composables/translations.ts +13 -13
- package/env.d.ts +6 -4
- package/index.ts +101 -98
- package/package.json +7 -7
- package/stores/serverRouter.ts +25 -25
- package/stores/user.ts +79 -72
- package/types.d.ts +65 -65
|
@@ -1,209 +1,215 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { useEventBus } from "../../composables/event-bus";
|
|
2
|
+
import type { Component } from 'vue'
|
|
3
|
+
import type { APIPaging } from '../../composables/rest'
|
|
4
|
+
import { Dialog, DialogPanel, TransitionRoot } from '@headlessui/vue'
|
|
6
5
|
import {
|
|
7
|
-
XCircleIcon,
|
|
8
|
-
ChevronDoubleRightIcon,
|
|
9
6
|
ArrowLeftCircleIcon,
|
|
10
7
|
ArrowRightCircleIcon,
|
|
11
8
|
ChevronDoubleLeftIcon,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
ChevronDoubleRightIcon,
|
|
10
|
+
XCircleIcon,
|
|
11
|
+
} from '@heroicons/vue/24/solid'
|
|
12
|
+
import { computed, h, onMounted, onUnmounted, reactive, ref } from 'vue'
|
|
13
|
+
import { useEventBus } from '../../composables/event-bus'
|
|
14
|
+
import DefaultPaging from './DefaultPaging.vue'
|
|
15
15
|
|
|
16
|
-
const isGalleryOpen = ref<boolean>(false)
|
|
17
|
-
const eventBus = useEventBus()
|
|
18
|
-
const sidePanel = ref<boolean>(true)
|
|
16
|
+
const isGalleryOpen = ref<boolean>(false)
|
|
17
|
+
const eventBus = useEventBus()
|
|
18
|
+
const sidePanel = ref<boolean>(true)
|
|
19
19
|
|
|
20
20
|
const props = withDefaults(
|
|
21
21
|
defineProps<{
|
|
22
|
-
id: string
|
|
23
|
-
images: Array<any
|
|
24
|
-
title?: string
|
|
25
|
-
getImageUrl?: Function
|
|
26
|
-
getThumbnailUrl?: Function
|
|
27
|
-
onOpen?: Function
|
|
28
|
-
onClose?: Function
|
|
29
|
-
closeIcon?:
|
|
30
|
-
gridHeight?: number
|
|
31
|
-
mode:
|
|
32
|
-
paging?: APIPaging | undefined
|
|
33
|
-
buttonText?: string
|
|
34
|
-
buttonType?: string
|
|
35
|
-
modelValue: number
|
|
36
|
-
borderColor?: Function
|
|
37
|
-
imageLoader: string
|
|
38
|
-
videoComponent?: Component | string
|
|
39
|
-
imageComponent?: Component | string
|
|
40
|
-
isVideo?: Function
|
|
41
|
-
ranking?: boolean
|
|
22
|
+
id: string
|
|
23
|
+
images: Array<any>
|
|
24
|
+
title?: string
|
|
25
|
+
getImageUrl?: Function
|
|
26
|
+
getThumbnailUrl?: Function
|
|
27
|
+
onOpen?: Function
|
|
28
|
+
onClose?: Function
|
|
29
|
+
closeIcon?: object
|
|
30
|
+
gridHeight?: number
|
|
31
|
+
mode: 'mason' | 'grid' | 'button' | 'hidden' | 'custom'
|
|
32
|
+
paging?: APIPaging | undefined
|
|
33
|
+
buttonText?: string
|
|
34
|
+
buttonType?: string
|
|
35
|
+
modelValue: number
|
|
36
|
+
borderColor?: Function
|
|
37
|
+
imageLoader: string
|
|
38
|
+
videoComponent?: Component | string
|
|
39
|
+
imageComponent?: Component | string
|
|
40
|
+
isVideo?: Function
|
|
41
|
+
ranking?: boolean
|
|
42
42
|
}>(),
|
|
43
43
|
{
|
|
44
44
|
modelValue: 0,
|
|
45
|
-
imageComponent:
|
|
46
|
-
mode:
|
|
45
|
+
imageComponent: 'img',
|
|
46
|
+
mode: 'grid',
|
|
47
47
|
gridHeight: 4,
|
|
48
48
|
closeIcon: () => h(XCircleIcon),
|
|
49
49
|
images: () => [],
|
|
50
|
-
isVideo: (
|
|
50
|
+
isVideo: () => false,
|
|
51
51
|
getImageUrl: (image: any) => image.image_url,
|
|
52
52
|
getThumbnailUrl: (image: any) => `${image.image_url}?s=250x250&m=autocrop`,
|
|
53
53
|
paging: undefined,
|
|
54
54
|
borderColor: undefined,
|
|
55
55
|
ranking: false,
|
|
56
56
|
},
|
|
57
|
-
)
|
|
57
|
+
)
|
|
58
58
|
|
|
59
|
-
const emit = defineEmits([
|
|
59
|
+
const emit = defineEmits(['update:modelValue'])
|
|
60
60
|
const modelValue = computed({
|
|
61
61
|
get: () => props.modelValue,
|
|
62
62
|
set: (i) => {
|
|
63
|
-
emit(
|
|
63
|
+
emit('update:modelValue', i)
|
|
64
64
|
},
|
|
65
|
-
})
|
|
65
|
+
})
|
|
66
66
|
|
|
67
|
-
const direction = ref<
|
|
67
|
+
const direction = ref<'next' | 'prev'>('next')
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
function setModal(value: boolean) {
|
|
70
70
|
if (value === true) {
|
|
71
|
-
if (props.onOpen) props.onOpen()
|
|
72
|
-
} else {
|
|
73
|
-
if (props.onClose) props.onClose();
|
|
71
|
+
if (props.onOpen) props.onOpen()
|
|
74
72
|
}
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
else {
|
|
74
|
+
if (props.onClose) props.onClose()
|
|
75
|
+
}
|
|
76
|
+
isGalleryOpen.value = value
|
|
77
|
+
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
if (index === undefined)
|
|
79
|
+
function openGalleryImage(index: number | undefined) {
|
|
80
|
+
if (index === undefined) {
|
|
81
|
+
modelValue.value = 0
|
|
82
|
+
}
|
|
80
83
|
else {
|
|
81
|
-
modelValue.value = parseInt(index.toString())
|
|
84
|
+
modelValue.value = Number.parseInt(index.toString())
|
|
82
85
|
}
|
|
83
|
-
setModal(true)
|
|
84
|
-
}
|
|
86
|
+
setModal(true)
|
|
87
|
+
}
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
direction.value =
|
|
89
|
+
function goNextImage() {
|
|
90
|
+
direction.value = 'next'
|
|
88
91
|
if (modelValue.value < props.images.length - 1) {
|
|
89
|
-
modelValue.value
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
+
modelValue.value++
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
modelValue.value = 0
|
|
92
96
|
}
|
|
93
|
-
}
|
|
97
|
+
}
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
direction.value =
|
|
99
|
+
function goPrevImage() {
|
|
100
|
+
direction.value = 'prev'
|
|
97
101
|
if (modelValue.value > 0) {
|
|
98
|
-
modelValue.value
|
|
99
|
-
} else {
|
|
100
|
-
modelValue.value =
|
|
101
|
-
props.images.length - 1 > 0 ? props.images.length - 1 : 0;
|
|
102
|
+
modelValue.value--
|
|
102
103
|
}
|
|
103
|
-
|
|
104
|
+
else {
|
|
105
|
+
modelValue.value
|
|
106
|
+
= props.images.length - 1 > 0 ? props.images.length - 1 : 0
|
|
107
|
+
}
|
|
108
|
+
}
|
|
104
109
|
|
|
105
110
|
const modelValueSrc = computed(() => {
|
|
106
|
-
if (props.images.length
|
|
107
|
-
if (props.images[modelValue.value]
|
|
108
|
-
return props.getImageUrl(props.images[modelValue.value])
|
|
109
|
-
})
|
|
111
|
+
if (props.images.length === 0) return false
|
|
112
|
+
if (props.images[modelValue.value] === undefined) return false
|
|
113
|
+
return props.getImageUrl(props.images[modelValue.value])
|
|
114
|
+
})
|
|
110
115
|
|
|
111
|
-
const start = reactive({ x: 0, y: 0 })
|
|
116
|
+
const start = reactive({ x: 0, y: 0 })
|
|
112
117
|
|
|
113
|
-
|
|
114
|
-
const touch = event.touches[0]
|
|
115
|
-
const targetElement = touch.target as HTMLElement
|
|
118
|
+
function touchStart(event: TouchEvent) {
|
|
119
|
+
const touch = event.touches[0]
|
|
120
|
+
const targetElement = touch.target as HTMLElement
|
|
116
121
|
|
|
117
122
|
// Check if the touch started on an interactive element
|
|
118
|
-
if (targetElement.closest(
|
|
119
|
-
return
|
|
123
|
+
if (targetElement.closest('button, a, input, textarea, select')) {
|
|
124
|
+
return // Don't handle swipe if interacting with an interactive element
|
|
120
125
|
}
|
|
121
126
|
|
|
122
|
-
start.x = touch.screenX
|
|
123
|
-
start.y = touch.screenY
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const touch = event.changedTouches[0]
|
|
127
|
-
const targetElement = touch.target as HTMLElement
|
|
127
|
+
start.x = touch.screenX
|
|
128
|
+
start.y = touch.screenY
|
|
129
|
+
}
|
|
130
|
+
function touchEnd(event: TouchEvent) {
|
|
131
|
+
const touch = event.changedTouches[0]
|
|
132
|
+
const targetElement = touch.target as HTMLElement
|
|
128
133
|
|
|
129
134
|
// Check if the touch ended on an interactive element
|
|
130
|
-
if (targetElement.closest(
|
|
131
|
-
return
|
|
135
|
+
if (targetElement.closest('button, a, input, textarea, select')) {
|
|
136
|
+
return // Don't handle swipe if interacting with an interactive element
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
const end = { x: touch.screenX, y: touch.screenY }
|
|
139
|
+
const end = { x: touch.screenX, y: touch.screenY }
|
|
135
140
|
|
|
136
|
-
const diffX = start.x - end.x
|
|
137
|
-
const diffY = start.y - end.y
|
|
141
|
+
const diffX = start.x - end.x
|
|
142
|
+
const diffY = start.y - end.y
|
|
138
143
|
|
|
139
144
|
// Add a threshold to prevent accidental swipes
|
|
140
145
|
if (Math.abs(diffX) > Math.abs(diffY) && Math.abs(diffX) > 50) {
|
|
141
146
|
if (diffX > 0) {
|
|
142
|
-
direction.value =
|
|
143
|
-
goNextImage()
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
direction.value = 'next'
|
|
148
|
+
goNextImage()
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
direction.value = 'prev'
|
|
152
|
+
goPrevImage()
|
|
147
153
|
}
|
|
148
154
|
}
|
|
149
|
-
}
|
|
155
|
+
}
|
|
150
156
|
|
|
151
|
-
|
|
157
|
+
function getBorderColor(i: any) {
|
|
152
158
|
if (props.borderColor !== undefined) {
|
|
153
|
-
return props.borderColor(i)
|
|
159
|
+
return props.borderColor(i)
|
|
154
160
|
}
|
|
155
|
-
return
|
|
156
|
-
}
|
|
161
|
+
return ''
|
|
162
|
+
}
|
|
157
163
|
|
|
158
|
-
const isKeyPressed = ref<boolean>(false)
|
|
164
|
+
const isKeyPressed = ref<boolean>(false)
|
|
159
165
|
|
|
160
|
-
|
|
161
|
-
if (isKeyPressed.value) return
|
|
166
|
+
function handleKeyboardInput(event: KeyboardEvent) {
|
|
167
|
+
if (isKeyPressed.value) return
|
|
162
168
|
switch (event.key) {
|
|
163
|
-
case
|
|
164
|
-
isKeyPressed.value = true
|
|
165
|
-
direction.value =
|
|
166
|
-
goNextImage()
|
|
167
|
-
break
|
|
168
|
-
case
|
|
169
|
-
isKeyPressed.value = true
|
|
170
|
-
direction.value =
|
|
171
|
-
goPrevImage()
|
|
172
|
-
break
|
|
169
|
+
case 'ArrowRight':
|
|
170
|
+
isKeyPressed.value = true
|
|
171
|
+
direction.value = 'next'
|
|
172
|
+
goNextImage()
|
|
173
|
+
break
|
|
174
|
+
case 'ArrowLeft':
|
|
175
|
+
isKeyPressed.value = true
|
|
176
|
+
direction.value = 'prev'
|
|
177
|
+
goPrevImage()
|
|
178
|
+
break
|
|
173
179
|
default:
|
|
174
|
-
break
|
|
180
|
+
break
|
|
175
181
|
}
|
|
176
|
-
}
|
|
182
|
+
}
|
|
177
183
|
|
|
178
|
-
|
|
179
|
-
if (event.key ===
|
|
180
|
-
isKeyPressed.value = false
|
|
184
|
+
function handleKeyboardRelease(event: KeyboardEvent) {
|
|
185
|
+
if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
|
|
186
|
+
isKeyPressed.value = false
|
|
181
187
|
}
|
|
182
|
-
}
|
|
188
|
+
}
|
|
183
189
|
|
|
184
|
-
|
|
185
|
-
setModal(false)
|
|
186
|
-
}
|
|
190
|
+
function closeGallery() {
|
|
191
|
+
setModal(false)
|
|
192
|
+
}
|
|
187
193
|
|
|
188
194
|
onMounted(() => {
|
|
189
|
-
eventBus.on(`${props.id}GalleryImage`, openGalleryImage)
|
|
190
|
-
eventBus.on(`${props.id}Gallery`, openGalleryImage)
|
|
191
|
-
eventBus.on(`${props.id}GalleryClose`, closeGallery)
|
|
195
|
+
eventBus.on(`${props.id}GalleryImage`, openGalleryImage)
|
|
196
|
+
eventBus.on(`${props.id}Gallery`, openGalleryImage)
|
|
197
|
+
eventBus.on(`${props.id}GalleryClose`, closeGallery)
|
|
192
198
|
if (window !== undefined && !import.meta.env.SSR) {
|
|
193
|
-
window.addEventListener(
|
|
194
|
-
window.addEventListener(
|
|
199
|
+
window.addEventListener('keydown', handleKeyboardInput)
|
|
200
|
+
window.addEventListener('keyup', handleKeyboardRelease)
|
|
195
201
|
}
|
|
196
|
-
})
|
|
202
|
+
})
|
|
197
203
|
|
|
198
204
|
onUnmounted(() => {
|
|
199
|
-
eventBus.off(`${props.id}Gallery`, openGalleryImage)
|
|
200
|
-
eventBus.off(`${props.id}GalleryImage`, openGalleryImage)
|
|
201
|
-
eventBus.off(`${props.id}GalleryClose`, closeGallery)
|
|
205
|
+
eventBus.off(`${props.id}Gallery`, openGalleryImage)
|
|
206
|
+
eventBus.off(`${props.id}GalleryImage`, openGalleryImage)
|
|
207
|
+
eventBus.off(`${props.id}GalleryClose`, closeGallery)
|
|
202
208
|
if (window !== undefined && !import.meta.env.SSR) {
|
|
203
|
-
window.removeEventListener(
|
|
204
|
-
window.removeEventListener(
|
|
209
|
+
window.removeEventListener('keydown', handleKeyboardInput)
|
|
210
|
+
window.removeEventListener('keyup', handleKeyboardRelease)
|
|
205
211
|
}
|
|
206
|
-
})
|
|
212
|
+
})
|
|
207
213
|
</script>
|
|
208
214
|
|
|
209
215
|
<template>
|
|
@@ -220,9 +226,9 @@ onUnmounted(() => {
|
|
|
220
226
|
>
|
|
221
227
|
<Dialog
|
|
222
228
|
:open="isGalleryOpen"
|
|
223
|
-
@close="setModal"
|
|
224
229
|
class="fixed bg-fv-neutral-900 text-white inset-0 max-w-[100vw] overflow-y-auto overflow-x-hidden"
|
|
225
230
|
style="z-index: 37"
|
|
231
|
+
@close="setModal"
|
|
226
232
|
>
|
|
227
233
|
<DialogPanel
|
|
228
234
|
class="relative w-full max-w-full flex flex-col justify-center items-center"
|
|
@@ -232,8 +238,8 @@ onUnmounted(() => {
|
|
|
232
238
|
<div class="flex-grow h-[100vh] flex items-center relative">
|
|
233
239
|
<button
|
|
234
240
|
class="btn w-9 h-9 rounded-full absolute top-4 left-2"
|
|
235
|
-
@click="setModal(false)"
|
|
236
241
|
style="z-index: 39"
|
|
242
|
+
@click="setModal(false)"
|
|
237
243
|
>
|
|
238
244
|
<component :is="closeIcon" class="w-8 h-8" />
|
|
239
245
|
</button>
|
|
@@ -245,8 +251,8 @@ onUnmounted(() => {
|
|
|
245
251
|
class="hidden lg:relative z-[2] lg:flex w-10 flex-shrink-0 items-center justify-center flex-0"
|
|
246
252
|
>
|
|
247
253
|
<button
|
|
248
|
-
class="btn p-1 rounded-full"
|
|
249
254
|
v-if="images.length > 1"
|
|
255
|
+
class="btn p-1 rounded-full"
|
|
250
256
|
@click="goPrevImage()"
|
|
251
257
|
>
|
|
252
258
|
<ArrowLeftCircleIcon class="w-8 h-8" />
|
|
@@ -282,13 +288,13 @@ onUnmounted(() => {
|
|
|
282
288
|
</template>
|
|
283
289
|
<template v-else>
|
|
284
290
|
<img
|
|
291
|
+
v-if="modelValueSrc && imageComponent === 'img'"
|
|
285
292
|
class="shadow max-w-full h-auto object-contain max-h-[85vh]"
|
|
286
293
|
:src="modelValueSrc"
|
|
287
|
-
|
|
288
|
-
/>
|
|
294
|
+
>
|
|
289
295
|
<component
|
|
290
|
-
v-else-if="modelValueSrc && imageComponent"
|
|
291
296
|
:is="imageComponent"
|
|
297
|
+
v-else-if="modelValueSrc && imageComponent"
|
|
292
298
|
:image="modelValueSrc.image"
|
|
293
299
|
:variant="modelValueSrc.variant"
|
|
294
300
|
:alt="modelValueSrc.alt"
|
|
@@ -299,7 +305,7 @@ onUnmounted(() => {
|
|
|
299
305
|
<div
|
|
300
306
|
class="flex-0 py-2 flex items-center justify-center max-w-full w-full relative !z-[3]"
|
|
301
307
|
>
|
|
302
|
-
<slot :value="images[modelValue]"
|
|
308
|
+
<slot :value="images[modelValue]" />
|
|
303
309
|
</div>
|
|
304
310
|
</div>
|
|
305
311
|
</transition>
|
|
@@ -316,13 +322,13 @@ onUnmounted(() => {
|
|
|
316
322
|
style="z-index: 39"
|
|
317
323
|
@click="() => (sidePanel = !sidePanel)"
|
|
318
324
|
>
|
|
319
|
-
<ChevronDoubleRightIcon class="w-7 h-7"
|
|
320
|
-
<ChevronDoubleLeftIcon class="w-7 h-7"
|
|
325
|
+
<ChevronDoubleRightIcon v-if="sidePanel" class="w-7 h-7" />
|
|
326
|
+
<ChevronDoubleLeftIcon v-else class="w-7 h-7" />
|
|
321
327
|
</button>
|
|
322
328
|
<button
|
|
329
|
+
v-if="images.length > 1"
|
|
323
330
|
class="btn p-1 rounded-full"
|
|
324
331
|
@click="goNextImage()"
|
|
325
|
-
v-if="images.length > 1"
|
|
326
332
|
>
|
|
327
333
|
<ArrowRightCircleIcon class="w-8 h-8" />
|
|
328
334
|
</button>
|
|
@@ -343,7 +349,7 @@ onUnmounted(() => {
|
|
|
343
349
|
>
|
|
344
350
|
<!-- Side panel content -->
|
|
345
351
|
<div v-if="paging" class="flex items-center justify-center">
|
|
346
|
-
<DefaultPaging :
|
|
352
|
+
<DefaultPaging :id="id" :items="paging" />
|
|
347
353
|
</div>
|
|
348
354
|
<div class="grid grid-cols-2 gap-2 p-2">
|
|
349
355
|
<div
|
|
@@ -352,27 +358,27 @@ onUnmounted(() => {
|
|
|
352
358
|
class="hover:!brightness-100"
|
|
353
359
|
:style="{
|
|
354
360
|
filter:
|
|
355
|
-
i - 1
|
|
361
|
+
i - 1 === modelValue ? 'brightness(1)' : 'brightness(0.5)',
|
|
356
362
|
}"
|
|
357
363
|
>
|
|
358
364
|
<img
|
|
359
|
-
|
|
365
|
+
v-if="imageComponent === 'img'"
|
|
360
366
|
:class="`h-auto max-w-full rounded-lg cursor-pointer shadow ${getBorderColor(
|
|
361
367
|
images[i - 1],
|
|
362
368
|
)}`"
|
|
363
369
|
:src="getThumbnailUrl(images[i - 1])"
|
|
364
|
-
v-if="imageComponent == 'img'"
|
|
365
|
-
/>
|
|
366
|
-
<component
|
|
367
|
-
v-else
|
|
368
370
|
@click="$eventBus.emit(`${id}GalleryImage`, i - 1)"
|
|
371
|
+
>
|
|
372
|
+
<component
|
|
369
373
|
:is="imageComponent"
|
|
374
|
+
v-else
|
|
370
375
|
:image="getThumbnailUrl(images[i - 1]).image"
|
|
371
376
|
:variant="getThumbnailUrl(images[i - 1]).variant"
|
|
372
377
|
:alt="getThumbnailUrl(images[i - 1]).alt"
|
|
373
378
|
:class="`h-auto max-w-full rounded-lg cursor-pointer shadow ${getBorderColor(
|
|
374
379
|
images[i - 1],
|
|
375
380
|
)}`"
|
|
381
|
+
@click="$eventBus.emit(`${id}GalleryImage`, i - 1)"
|
|
376
382
|
/>
|
|
377
383
|
</div>
|
|
378
384
|
</div>
|
|
@@ -382,81 +388,85 @@ onUnmounted(() => {
|
|
|
382
388
|
</Dialog>
|
|
383
389
|
</TransitionRoot>
|
|
384
390
|
|
|
385
|
-
<template v-if="mode
|
|
391
|
+
<template v-if="mode === 'grid' || mode === 'mason' || mode === 'custom'">
|
|
386
392
|
<div
|
|
387
393
|
:class="{
|
|
388
394
|
'grid grid-cols-2 md:grid-cols-4 xl:grid-cols-6 gap-4 items-start':
|
|
389
|
-
mode
|
|
395
|
+
mode === 'mason',
|
|
390
396
|
'grid grid-cols-2 md:grid-cols-4 xl:grid-cols-6 gap-4 items-center':
|
|
391
|
-
mode
|
|
392
|
-
'custom-grid': mode
|
|
397
|
+
mode === 'grid',
|
|
398
|
+
'custom-grid': mode === 'custom',
|
|
393
399
|
}"
|
|
394
400
|
>
|
|
395
401
|
<slot name="thumbnail" />
|
|
396
402
|
<template v-for="i in images.length" :key="`g_${id}_${i}`">
|
|
397
|
-
<template v-if="mode
|
|
403
|
+
<template v-if="mode === 'mason'">
|
|
398
404
|
<div
|
|
405
|
+
v-if="i + (1 % gridHeight) === 0"
|
|
399
406
|
class="grid gap-4 items-start relative"
|
|
400
|
-
v-if="i + (1 % gridHeight) == 0"
|
|
401
407
|
>
|
|
402
|
-
<div v-if="ranking" class="img-gallery-ranking">
|
|
408
|
+
<div v-if="ranking" class="img-gallery-ranking">
|
|
409
|
+
{{ i }}
|
|
410
|
+
</div>
|
|
403
411
|
|
|
404
412
|
<template v-for="j in gridHeight" :key="`gi_${id}_${i + j}`">
|
|
405
413
|
<div>
|
|
406
414
|
<img
|
|
407
|
-
|
|
415
|
+
v-if="i + j - 2 < images.length && imageComponent === 'img'"
|
|
408
416
|
class="h-auto max-w-full rounded-lg cursor-pointer"
|
|
409
|
-
v-if="i + j - 2 < images.length && imageComponent == 'img'"
|
|
410
417
|
:src="getThumbnailUrl(images[i + j - 2])"
|
|
411
|
-
|
|
418
|
+
@click="$eventBus.emit(`${id}GalleryImage`, i + j - 2)"
|
|
419
|
+
>
|
|
412
420
|
<component
|
|
413
|
-
v-else-if="i + j - 2 < images.length"
|
|
414
421
|
:is="imageComponent"
|
|
422
|
+
v-else-if="i + j - 2 < images.length"
|
|
415
423
|
:image="getThumbnailUrl(images[i + j - 2]).image"
|
|
416
424
|
:variant="getThumbnailUrl(images[i + j - 2]).variant"
|
|
417
425
|
:alt="getThumbnailUrl(images[i + j - 2]).alt"
|
|
418
426
|
:class="`h-auto max-w-full rounded-lg cursor-pointer ${getBorderColor(
|
|
419
427
|
images[i + j - 2],
|
|
420
428
|
)}`"
|
|
421
|
-
@click="$eventBus.emit(`${id}GalleryImage`, i + j - 2)"
|
|
422
429
|
:likes="getThumbnailUrl(images[i + j - 2]).likes"
|
|
423
430
|
:show-likes="getThumbnailUrl(images[i + j - 2]).showLikes"
|
|
424
|
-
:
|
|
431
|
+
:is-author="getThumbnailUrl(images[i + j - 2]).isAuthor"
|
|
425
432
|
:user-uuid="getThumbnailUrl(images[i + j - 2]).userUUID"
|
|
433
|
+
@click="$eventBus.emit(`${id}GalleryImage`, i + j - 2)"
|
|
426
434
|
/>
|
|
427
435
|
</div>
|
|
428
436
|
</template>
|
|
429
437
|
</div>
|
|
430
438
|
</template>
|
|
431
|
-
<div class="relative"
|
|
432
|
-
<div v-if="ranking" class="img-gallery-ranking">
|
|
439
|
+
<div v-else class="relative">
|
|
440
|
+
<div v-if="ranking" class="img-gallery-ranking">
|
|
441
|
+
{{ i }}
|
|
442
|
+
</div>
|
|
433
443
|
<img
|
|
434
|
-
|
|
444
|
+
v-if="imageComponent === 'img'"
|
|
435
445
|
class="h-auto max-w-full rounded-lg cursor-pointer"
|
|
436
446
|
:src="getThumbnailUrl(images[i - 1])"
|
|
437
|
-
|
|
438
|
-
|
|
447
|
+
@click="$eventBus.emit(`${id}GalleryImage`, i - 1)"
|
|
448
|
+
>
|
|
439
449
|
<component
|
|
440
|
-
v-else-if="imageComponent"
|
|
441
450
|
:is="imageComponent"
|
|
451
|
+
v-else-if="imageComponent"
|
|
442
452
|
:image="getThumbnailUrl(images[i - 1]).image"
|
|
443
453
|
:variant="getThumbnailUrl(images[i - 1]).variant"
|
|
444
454
|
:alt="getThumbnailUrl(images[i - 1]).alt"
|
|
445
455
|
:class="`h-auto max-w-full rounded-lg cursor-pointer ${getBorderColor(
|
|
446
456
|
images[i - 1],
|
|
447
457
|
)}`"
|
|
448
|
-
@click="$eventBus.emit(`${id}GalleryImage`, i - 1)"
|
|
449
458
|
:likes="getThumbnailUrl(images[i - 1]).likes"
|
|
450
459
|
:show-likes="getThumbnailUrl(images[i - 1]).showLikes"
|
|
451
|
-
:
|
|
460
|
+
:is-author="getThumbnailUrl(images[i - 1]).isAuthor"
|
|
452
461
|
:user-uuid="getThumbnailUrl(images[i - 1]).userUUID"
|
|
462
|
+
@click="$eventBus.emit(`${id}GalleryImage`, i - 1)"
|
|
453
463
|
/>
|
|
454
464
|
</div>
|
|
455
465
|
</template>
|
|
456
466
|
</div>
|
|
457
467
|
</template>
|
|
458
468
|
<button
|
|
459
|
-
v-if="mode
|
|
469
|
+
v-if="mode === 'button'"
|
|
460
470
|
:class="`btn ${buttonType ? buttonType : 'primary'} defaults`"
|
|
461
471
|
@click="openGalleryImage(0)"
|
|
462
472
|
>
|
|
@@ -464,6 +474,7 @@ onUnmounted(() => {
|
|
|
464
474
|
</button>
|
|
465
475
|
</div>
|
|
466
476
|
</template>
|
|
477
|
+
|
|
467
478
|
<style scoped>
|
|
468
479
|
/* Transition styles for next (right) navigation */
|
|
469
480
|
.slide-next-enter-active,
|