mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
83 lines
2.1 KiB
TypeScript
83 lines
2.1 KiB
TypeScript
// Copyright (C) 2012-2026 Zammad Foundation, https://zammad-foundation.org/
|
|
|
|
import { onMounted, ref } from 'vue'
|
|
|
|
import { waitForImagesToLoad } from '#shared/utils/dom.ts'
|
|
import { waitForAnimationFrame } from '#shared/utils/helpers.ts'
|
|
|
|
export const useArticleToggleMore = () => {
|
|
const MIN_HEIGHT = 60
|
|
const MAX_HEIGHT = 320
|
|
let heightHidden = 0
|
|
|
|
const bubbleElement = ref<HTMLDivElement>()
|
|
const hasShowMore = ref(true)
|
|
const shownMore = ref(false)
|
|
|
|
const getSignatureMarker = (element: HTMLElement): HTMLElement | null => {
|
|
const marker = element.querySelector('.js-signatureMarker') as HTMLElement
|
|
if (marker) return marker
|
|
|
|
return element.querySelector('div [data-signature=true]')
|
|
}
|
|
|
|
const setHeight = async () => {
|
|
if (!bubbleElement.value) return
|
|
|
|
const styles = bubbleElement.value.style
|
|
styles.height = ''
|
|
|
|
await waitForAnimationFrame()
|
|
|
|
// it's possible it was remounted somehow
|
|
if (!bubbleElement.value) return
|
|
|
|
const height = bubbleElement.value.clientHeight
|
|
|
|
const signatureMarker = getSignatureMarker(bubbleElement.value)
|
|
|
|
const offsetTop = signatureMarker?.offsetTop || 0
|
|
|
|
if (offsetTop > 0 && offsetTop < MAX_HEIGHT) {
|
|
heightHidden = offsetTop < MIN_HEIGHT ? MIN_HEIGHT : offsetTop
|
|
hasShowMore.value = true
|
|
} else if (height > MAX_HEIGHT) {
|
|
heightHidden = MAX_HEIGHT
|
|
hasShowMore.value = true
|
|
} else {
|
|
hasShowMore.value = false
|
|
heightHidden = 0
|
|
}
|
|
|
|
if (heightHidden) {
|
|
styles.height = `${heightHidden}px`
|
|
}
|
|
}
|
|
|
|
onMounted(async () => {
|
|
if (!bubbleElement.value) return
|
|
|
|
// Wait for inline images to load before calculating height
|
|
// Resolved immediately if no images are present
|
|
await waitForImagesToLoad(bubbleElement)
|
|
|
|
await setHeight()
|
|
})
|
|
|
|
const toggleShowMore = () => {
|
|
if (!bubbleElement.value) return
|
|
|
|
shownMore.value = !shownMore.value
|
|
|
|
const styles = bubbleElement.value.style
|
|
|
|
styles.height = shownMore.value ? 'auto' : `${heightHidden}px`
|
|
}
|
|
|
|
return {
|
|
toggleShowMore,
|
|
hasShowMore,
|
|
shownMore,
|
|
bubbleElement,
|
|
}
|
|
}
|