@fy-/fws-vue 2.3.20 → 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 +41 -67
- 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,30 +617,31 @@ 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
|
-
v-if="modelValueSrc"
|
|
627
|
-
class="shadow max-w-full
|
|
627
|
+
v-if="modelValueSrc && imageComponent === 'img'"
|
|
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"
|
|
631
632
|
>
|
|
632
|
-
|
|
633
|
+
<component
|
|
633
634
|
:is="imageComponent"
|
|
634
635
|
v-else-if="modelValueSrc && imageComponent"
|
|
635
636
|
:image="modelValueSrc.image"
|
|
636
637
|
:variant="modelValueSrc.variant"
|
|
637
638
|
:alt="modelValueSrc.alt"
|
|
638
|
-
class="shadow max-w-full
|
|
639
|
+
class="shadow max-w-full h-auto object-contain"
|
|
639
640
|
:likes="modelValueSrc.likes"
|
|
640
641
|
:show-likes="modelValueSrc.showLikes"
|
|
641
642
|
:is-author="modelValueSrc.isAuthor"
|
|
642
643
|
:user-uuid="modelValueSrc.userUUID"
|
|
643
|
-
/>
|
|
644
|
+
/>
|
|
644
645
|
</template>
|
|
645
646
|
</div>
|
|
646
647
|
</transition>
|
|
@@ -683,7 +684,6 @@ onUnmounted(() => {
|
|
|
683
684
|
v-if="infoPanel && images[modelValue]"
|
|
684
685
|
ref="infoPanelRef"
|
|
685
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"
|
|
686
|
-
@transitionend="updateImageSizes"
|
|
687
687
|
>
|
|
688
688
|
<slot :value="images[modelValue]" />
|
|
689
689
|
</div>
|
|
@@ -702,7 +702,8 @@ onUnmounted(() => {
|
|
|
702
702
|
<div
|
|
703
703
|
v-if="sidePanel"
|
|
704
704
|
ref="sidePanelRef"
|
|
705
|
-
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` }"
|
|
706
707
|
>
|
|
707
708
|
<!-- Paging Controls if needed -->
|
|
708
709
|
<div v-if="paging" class="flex items-center justify-center pt-2">
|
|
@@ -904,13 +905,6 @@ onUnmounted(() => {
|
|
|
904
905
|
</template>
|
|
905
906
|
|
|
906
907
|
<style scoped>
|
|
907
|
-
/* CSS variables for dimensions */
|
|
908
|
-
:root {
|
|
909
|
-
--controls-height: 0px;
|
|
910
|
-
--info-height: 0px;
|
|
911
|
-
--sidebar-width: 16rem;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
908
|
/* Ensure controls stay fixed at top */
|
|
915
909
|
.controls-bar {
|
|
916
910
|
height: auto;
|
|
@@ -941,26 +935,6 @@ onUnmounted(() => {
|
|
|
941
935
|
border-top-right-radius: 0.5rem;
|
|
942
936
|
}
|
|
943
937
|
|
|
944
|
-
/* Image sizing in different contexts - simplified approach like old component */
|
|
945
|
-
.gallery-image {
|
|
946
|
-
height: auto;
|
|
947
|
-
object-fit: contain;
|
|
948
|
-
max-width: 92vw;
|
|
949
|
-
max-height: calc(80vh - var(--controls-height) - var(--info-height, 0px));
|
|
950
|
-
transition: max-height 0.3s ease-out, max-width 0.3s ease-out;
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
@media (min-width: 1024px) {
|
|
954
|
-
.gallery-image {
|
|
955
|
-
max-width: calc(92vw - var(--sidebar-width) - 48px);
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
/* Fullscreen mode sizing */
|
|
960
|
-
:is(.gallery-container[style*="fullscreen"]) .gallery-image {
|
|
961
|
-
max-height: calc(92vh - var(--controls-height) - var(--info-height, 0px));
|
|
962
|
-
}
|
|
963
|
-
|
|
964
938
|
/* Transition styles for next (right) navigation */
|
|
965
939
|
.slide-next-enter-active,
|
|
966
940
|
.slide-next-leave-active {
|