공개 본문 라이트박스 상태 분리
This commit is contained in:
@@ -44,6 +44,7 @@ import { getInArticleAdAfterBlockIds } from '../../lib/content-in-article-ad.js'
|
||||
import { getContentLightboxImages, getGalleryRows } from '../../lib/content-gallery-images.js'
|
||||
import { parseMarkdownBlocks } from '../../lib/markdown-block-parser.js'
|
||||
import { createHeadingIdFactory } from '../../lib/markdown-toc.js'
|
||||
import { useContentMarkdownLightbox } from '../../composables/useContentMarkdownLightbox.js'
|
||||
import ContentMarkdownCodeBlockEditor from './ContentMarkdownCodeBlockEditor.vue'
|
||||
import ProseCodeBlock from './ProseCodeBlock.vue'
|
||||
import ProseHtml from './ProseHtml.vue'
|
||||
@@ -100,8 +101,6 @@ const emit = defineEmits([
|
||||
const LIVE_IMAGE_DRAG_MIME = 'application/x-sori-live-image'
|
||||
/** @type {string} 본문 리스트 마커 색상 */
|
||||
const CONTENT_LIST_MARKER_COLOR = '#2eb6ea'
|
||||
const activeLightboxImages = ref([])
|
||||
const activeLightboxIndex = ref(0)
|
||||
/** @type {import('vue').Ref<Record<string, number>>} 갤러리 이미지 자연 비율 */
|
||||
const galleryImageAspectRatios = ref({})
|
||||
/** @type {import('vue').Ref<{ kind: 'image'|'gallery', sourceLine?: number, startLine?: number, endLine?: number, blockId: string, imageIndex?: number, image?: Object }|null>} */
|
||||
@@ -124,6 +123,15 @@ const rawEditingSourceLines = ref(new Set())
|
||||
/** @type {number} 문단 분리 연속 호출 방지 */
|
||||
let lastParagraphSplitAt = 0
|
||||
|
||||
const {
|
||||
activeLightboxImages,
|
||||
activeLightboxImage,
|
||||
openContentLightbox: openContentLightboxFromImages,
|
||||
closeLightbox,
|
||||
showPreviousImage,
|
||||
showNextImage
|
||||
} = useContentMarkdownLightbox()
|
||||
|
||||
/**
|
||||
* 빈 줄 공백 블록 높이를 반환한다.
|
||||
* @param {Object} block - 렌더링 블록
|
||||
@@ -202,8 +210,6 @@ const tailInsertBeforeLine = computed(() => {
|
||||
|
||||
return (props.content || '').split('\n').length
|
||||
})
|
||||
const activeLightboxImage = computed(() => activeLightboxImages.value[activeLightboxIndex.value])
|
||||
|
||||
const contentLightboxImages = computed(() => getContentLightboxImages(blocks.value))
|
||||
|
||||
/**
|
||||
@@ -1629,58 +1635,13 @@ const onMergeWithPreviousLine = (lineIndex, payload) => {
|
||||
emit('merge-with-previous-line', { lineIndex, mergedLine })
|
||||
}
|
||||
|
||||
/**
|
||||
* 라이트박스를 연다
|
||||
* @param {Array<Object>} images - 이미지 목록
|
||||
* @param {number} index - 시작 인덱스
|
||||
* @returns {void}
|
||||
*/
|
||||
const openLightbox = (images, index) => {
|
||||
activeLightboxImages.value = images
|
||||
activeLightboxIndex.value = index
|
||||
}
|
||||
|
||||
/**
|
||||
* 본문 전체 이미지 목록에서 지정 이미지를 라이트박스로 연다.
|
||||
* @param {string} lightboxKey - 이미지 식별 키
|
||||
* @returns {void}
|
||||
*/
|
||||
const openContentLightbox = (lightboxKey) => {
|
||||
const images = contentLightboxImages.value
|
||||
const index = images.findIndex((image) => image.lightboxKey === lightboxKey)
|
||||
|
||||
if (index < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
openLightbox(images, index)
|
||||
}
|
||||
|
||||
/**
|
||||
* 라이트박스를 닫는다
|
||||
* @returns {void}
|
||||
*/
|
||||
const closeLightbox = () => {
|
||||
activeLightboxImages.value = []
|
||||
activeLightboxIndex.value = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 라이트박스 이전 이미지로 이동
|
||||
* @returns {void}
|
||||
*/
|
||||
const showPreviousImage = () => {
|
||||
activeLightboxIndex.value = activeLightboxIndex.value === 0
|
||||
? activeLightboxImages.value.length - 1
|
||||
: activeLightboxIndex.value - 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 라이트박스 다음 이미지로 이동
|
||||
* @returns {void}
|
||||
*/
|
||||
const showNextImage = () => {
|
||||
activeLightboxIndex.value = (activeLightboxIndex.value + 1) % activeLightboxImages.value.length
|
||||
openContentLightboxFromImages(contentLightboxImages.value, lightboxKey)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2110,55 +2071,6 @@ const onGalleryDrop = (event, block, targetIndex) => {
|
||||
clearLiveImageDragUi()
|
||||
}
|
||||
|
||||
/**
|
||||
* 라이트박스 키보드 조작(Esc 닫기, 좌우 이전·다음)
|
||||
* @param {KeyboardEvent} event - 키보드 이벤트
|
||||
* @returns {void}
|
||||
*/
|
||||
const handleLightboxKeydown = (event) => {
|
||||
if (!activeLightboxImage.value) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.key === 'Escape') {
|
||||
event.preventDefault()
|
||||
closeLightbox()
|
||||
return
|
||||
}
|
||||
|
||||
if (activeLightboxImages.value.length <= 1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowLeft') {
|
||||
event.preventDefault()
|
||||
showPreviousImage()
|
||||
return
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowRight') {
|
||||
event.preventDefault()
|
||||
showNextImage()
|
||||
}
|
||||
}
|
||||
|
||||
watch(activeLightboxImage, (image) => {
|
||||
if (!import.meta.client) {
|
||||
return
|
||||
}
|
||||
|
||||
if (image) {
|
||||
window.addEventListener('keydown', handleLightboxKeydown)
|
||||
} else {
|
||||
window.removeEventListener('keydown', handleLightboxKeydown)
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (import.meta.client) {
|
||||
window.removeEventListener('keydown', handleLightboxKeydown)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
Reference in New Issue
Block a user