@fy-/fws-vue 2.3.21 → 2.3.22
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/ui/DefaultGallery.vue +42 -65
- package/package.json +1 -1
|
@@ -46,8 +46,6 @@ const { width: windowWidth, height: windowHeight } = useWindowSize()
|
|
|
46
46
|
const { height: topControlsHeight } = useElementSize(topControlsRef)
|
|
47
47
|
const { height: infoPanelHeight } = useElementSize(infoPanelRef)
|
|
48
48
|
|
|
49
|
-
// We no longer need derived measurements as we use CSS variables instead
|
|
50
|
-
|
|
51
49
|
// Use VueUse's useFullscreen for better fullscreen handling
|
|
52
50
|
const { isFullscreen: isElementFullscreen, enter: enterFullscreen, exit: exitFullscreen } = useFullscreen(galleryRef)
|
|
53
51
|
|
|
@@ -131,33 +129,27 @@ const currentImage = computed(() => {
|
|
|
131
129
|
const imageCount = computed(() => props.images.length)
|
|
132
130
|
const currentIndex = computed(() => modelValue.value + 1)
|
|
133
131
|
|
|
134
|
-
//
|
|
135
|
-
function updateInfoHeight() {
|
|
136
|
-
if (!infoPanelRef.value) return
|
|
137
|
-
|
|
138
|
-
const height = infoPanelRef.value.offsetHeight || 0
|
|
139
|
-
document.documentElement.style.setProperty('--info-height', `${height}px`)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function updateControlsHeight() {
|
|
143
|
-
if (!topControlsRef.value) return
|
|
144
|
-
|
|
145
|
-
const height = topControlsRef.value.offsetHeight || 0
|
|
146
|
-
document.documentElement.style.setProperty('--controls-height', `${height}px`)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// CSS variable-based image sizing
|
|
132
|
+
// Simple but effective image sizing function
|
|
150
133
|
const updateImageSizes = useDebounceFn(() => {
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
//
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
134
|
+
// Only target main image for sizing
|
|
135
|
+
const mainImage = document.querySelector('.image-display img') as HTMLImageElement
|
|
136
|
+
if (!mainImage) return
|
|
137
|
+
|
|
138
|
+
// Simple, direct calculation of available space
|
|
139
|
+
const topHeight = topControlsRef.value?.offsetHeight || 0
|
|
140
|
+
const infoHeight = infoPanel.value && infoPanelRef.value ? infoPanelRef.value.offsetHeight : 0
|
|
141
|
+
const availableHeight = windowHeight.value - topHeight - infoHeight - 32
|
|
142
|
+
|
|
143
|
+
// Apply size directly to fill available space
|
|
144
|
+
mainImage.style.maxHeight = `${availableHeight}px`
|
|
145
|
+
mainImage.style.width = 'auto'
|
|
146
|
+
|
|
147
|
+
// Handle width constraints
|
|
148
|
+
const sidebarWidth = sidePanel.value ? 256 : 0
|
|
149
|
+
mainImage.style.maxWidth = windowWidth.value <= 768
|
|
150
|
+
? '85vw'
|
|
151
|
+
: `${windowWidth.value - sidebarWidth - 48}px`
|
|
152
|
+
}, 50)
|
|
161
153
|
|
|
162
154
|
// Modal controls
|
|
163
155
|
function setModal(value: boolean) {
|
|
@@ -225,6 +217,11 @@ function goNextImage() {
|
|
|
225
217
|
modelValue.value = 0
|
|
226
218
|
}
|
|
227
219
|
resetControlsTimer()
|
|
220
|
+
|
|
221
|
+
// Force image sizing update after navigation
|
|
222
|
+
nextTick(() => {
|
|
223
|
+
updateImageSizes()
|
|
224
|
+
})
|
|
228
225
|
}
|
|
229
226
|
|
|
230
227
|
function goPrevImage() {
|
|
@@ -237,6 +234,11 @@ function goPrevImage() {
|
|
|
237
234
|
modelValue.value = props.images.length - 1 > 0 ? props.images.length - 1 : 0
|
|
238
235
|
}
|
|
239
236
|
resetControlsTimer()
|
|
237
|
+
|
|
238
|
+
// Force image sizing update after navigation
|
|
239
|
+
nextTick(() => {
|
|
240
|
+
updateImageSizes()
|
|
241
|
+
})
|
|
240
242
|
}
|
|
241
243
|
|
|
242
244
|
// UI control functions
|
|
@@ -440,9 +442,6 @@ onMounted(() => {
|
|
|
440
442
|
eventBus.on(`${props.id}Gallery`, openGalleryImage)
|
|
441
443
|
eventBus.on(`${props.id}GalleryClose`, closeGallery)
|
|
442
444
|
|
|
443
|
-
// Initialize CSS variables
|
|
444
|
-
updateImageSizes()
|
|
445
|
-
|
|
446
445
|
// Set up observers for dynamic resizing
|
|
447
446
|
if (topControlsRef.value) {
|
|
448
447
|
useResizeObserver(topControlsRef.value, updateImageSizes)
|
|
@@ -567,7 +566,8 @@ onUnmounted(() => {
|
|
|
567
566
|
>
|
|
568
567
|
<!-- Main Image Area - Fills available space -->
|
|
569
568
|
<div
|
|
570
|
-
class="relative flex-1 h-full flex items-center justify-center
|
|
569
|
+
class="relative flex-1 h-full flex items-center justify-center"
|
|
570
|
+
:style="{ paddingTop: `${topControlsHeight}px` }"
|
|
571
571
|
:class="{ 'lg:pr-64': sidePanel, 'lg:max-w-[calc(100%-16rem)]': sidePanel }"
|
|
572
572
|
style="max-width: 100%;"
|
|
573
573
|
>
|
|
@@ -617,14 +617,15 @@ onUnmounted(() => {
|
|
|
617
617
|
<component
|
|
618
618
|
:is="videoComponent"
|
|
619
619
|
:src="isVideo(images[modelValue])"
|
|
620
|
-
class="shadow max-w-full video-component
|
|
620
|
+
class="shadow max-w-full h-auto object-contain video-component"
|
|
621
|
+
@load="updateImageSizes"
|
|
621
622
|
/>
|
|
622
623
|
</ClientOnly>
|
|
623
624
|
</template>
|
|
624
625
|
<template v-else>
|
|
625
626
|
<img
|
|
626
627
|
v-if="modelValueSrc && imageComponent === 'img'"
|
|
627
|
-
class="shadow max-w-full
|
|
628
|
+
class="shadow max-w-full h-auto object-contain"
|
|
628
629
|
:src="modelValueSrc"
|
|
629
630
|
:alt="`Gallery image ${modelValue + 1}`"
|
|
630
631
|
@load="updateImageSizes"
|
|
@@ -632,11 +633,14 @@ onUnmounted(() => {
|
|
|
632
633
|
<component
|
|
633
634
|
:is="imageComponent"
|
|
634
635
|
v-else-if="modelValueSrc && imageComponent"
|
|
635
|
-
|
|
636
|
-
class="shadow max-w-full gallery-image"
|
|
637
636
|
:image="modelValueSrc.image"
|
|
638
637
|
:variant="modelValueSrc.variant"
|
|
639
638
|
:alt="modelValueSrc.alt"
|
|
639
|
+
class="shadow max-w-full h-auto object-contain"
|
|
640
|
+
:likes="modelValueSrc.likes"
|
|
641
|
+
:show-likes="modelValueSrc.showLikes"
|
|
642
|
+
:is-author="modelValueSrc.isAuthor"
|
|
643
|
+
:user-uuid="modelValueSrc.userUUID"
|
|
640
644
|
/>
|
|
641
645
|
</template>
|
|
642
646
|
</div>
|
|
@@ -680,7 +684,6 @@ onUnmounted(() => {
|
|
|
680
684
|
v-if="infoPanel && images[modelValue]"
|
|
681
685
|
ref="infoPanelRef"
|
|
682
686
|
class="info-panel absolute bottom-0 left-0 right-0 px-4 py-3 backdrop-blur-md bg-fv-neutral-900/70 z-45"
|
|
683
|
-
@transitionend="updateImageSizes"
|
|
684
687
|
>
|
|
685
688
|
<slot :value="images[modelValue]" />
|
|
686
689
|
</div>
|
|
@@ -699,7 +702,8 @@ onUnmounted(() => {
|
|
|
699
702
|
<div
|
|
700
703
|
v-if="sidePanel"
|
|
701
704
|
ref="sidePanelRef"
|
|
702
|
-
class="side-panel hidden lg:block absolute right-0 top-0 bottom-0 w-64 backdrop-blur-md overflow-y-auto z-40 cool-scroll
|
|
705
|
+
class="side-panel hidden lg:block absolute right-0 top-0 bottom-0 w-64 bg-fv-neutral-800/90 backdrop-blur-md overflow-y-auto z-40 cool-scroll"
|
|
706
|
+
:style="{ paddingTop: `${topControlsHeight + 8}px` }"
|
|
703
707
|
>
|
|
704
708
|
<!-- Paging Controls if needed -->
|
|
705
709
|
<div v-if="paging" class="flex items-center justify-center pt-2">
|
|
@@ -901,13 +905,6 @@ onUnmounted(() => {
|
|
|
901
905
|
</template>
|
|
902
906
|
|
|
903
907
|
<style scoped>
|
|
904
|
-
/* CSS variables for dimensions */
|
|
905
|
-
:root {
|
|
906
|
-
--controls-height: 0px;
|
|
907
|
-
--info-height: 0px;
|
|
908
|
-
--sidebar-width: 16rem;
|
|
909
|
-
}
|
|
910
|
-
|
|
911
908
|
/* Ensure controls stay fixed at top */
|
|
912
909
|
.controls-bar {
|
|
913
910
|
height: auto;
|
|
@@ -938,26 +935,6 @@ onUnmounted(() => {
|
|
|
938
935
|
border-top-right-radius: 0.5rem;
|
|
939
936
|
}
|
|
940
937
|
|
|
941
|
-
/* Image sizing in different contexts - simplified approach like old component */
|
|
942
|
-
.gallery-image {
|
|
943
|
-
height: auto;
|
|
944
|
-
object-fit: contain;
|
|
945
|
-
max-width: 92vw;
|
|
946
|
-
max-height: calc(80vh - var(--controls-height) - var(--info-height, 0px));
|
|
947
|
-
transition: max-height 0.3s ease-out, max-width 0.3s ease-out;
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
@media (min-width: 1024px) {
|
|
951
|
-
.gallery-image {
|
|
952
|
-
max-width: calc(92vw - var(--sidebar-width) - 48px);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
/* Fullscreen mode sizing */
|
|
957
|
-
:is(.gallery-container[style*="fullscreen"]) .gallery-image {
|
|
958
|
-
max-height: calc(92vh - var(--controls-height) - var(--info-height, 0px));
|
|
959
|
-
}
|
|
960
|
-
|
|
961
938
|
/* Transition styles for next (right) navigation */
|
|
962
939
|
.slide-next-enter-active,
|
|
963
940
|
.slide-next-leave-active {
|