관리자 미디어 선택 상태 분리

This commit is contained in:
2026-07-27 18:30:19 +09:00
parent b3f3cbd0ec
commit a122ef46ac
12 changed files with 661 additions and 266 deletions

View File

@@ -5,6 +5,7 @@ import {
isPostCardThumbnailUrl,
withGeneratedImageCacheVersion
} from './post-card-thumbnail-url.js'
import { serializeImageMarkdown } from './markdown-image.js'
import {
formatUploadSizeLimit,
getMaxUploadBytesForKind,
@@ -290,6 +291,96 @@ export const createMediaBlockMarkdown = (blockType, item) => {
]
}
/**
* 미디어 항목을 이미지 삽입용 데이터로 변환한다.
* @param {Object} item - 미디어 항목
* @returns {{ url: string, useAlt: boolean, caption: string }} 이미지 데이터
*/
export const createMediaImageInsertData = (item) => ({
url: item.url,
useAlt: false,
caption: ''
})
/**
* 선택된 미디어를 에디터 본문에 적용할 계획으로 변환한다.
* @param {Object} options - 계획 옵션
* @param {string} options.target - 미디어 선택 대상
* @param {Object[]} options.selectedItems - 선택된 미디어 항목
* @param {number|null} options.liveSlashLine - 슬래시 명령으로 삽입할 줄
* @returns {{ kind: 'none' }|{ kind: 'insert-at-line', line: number, lines: string[] }|{ kind: 'image', image: { url: string, useAlt: boolean, caption: string } }|{ kind: 'active-gallery', images: Array<{ url: string, useAlt: boolean, caption: string }> }|{ kind: 'gallery', images: Array<{ url: string, useAlt: boolean, caption: string }> }|{ kind: 'block', lines: string[] }} 적용 계획
*/
export const createSelectedMediaInsertPlan = ({
target,
selectedItems,
liveSlashLine
}) => {
const items = (Array.isArray(selectedItems) ? selectedItems : []).filter((item) => item?.url)
const line = Number.isFinite(liveSlashLine) ? Math.max(0, Math.floor(liveSlashLine)) : null
if (line !== null) {
if (target === 'image' && items[0]) {
return {
kind: 'insert-at-line',
line,
lines: [serializeImageMarkdown(createMediaImageInsertData(items[0]))]
}
}
if (target === 'gallery' && items.length) {
return {
kind: 'insert-at-line',
line,
lines: [
':::gallery',
...items.map((item) => serializeImageMarkdown(createMediaImageInsertData(item))),
':::'
]
}
}
if (['video', 'audio', 'file'].includes(target) && items[0]) {
return {
kind: 'insert-at-line',
line,
lines: createMediaBlockMarkdown(target, items[0])
}
}
return { kind: 'none' }
}
if (target === 'image' && items[0]) {
return {
kind: 'image',
image: createMediaImageInsertData(items[0])
}
}
if (target === 'active-gallery' && items.length) {
return {
kind: 'active-gallery',
images: items.map(createMediaImageInsertData)
}
}
if (target === 'gallery' && items.length) {
return {
kind: 'gallery',
images: items.map(createMediaImageInsertData)
}
}
if (['video', 'audio', 'file'].includes(target) && items[0]) {
return {
kind: 'block',
lines: createMediaBlockMarkdown(target, items[0])
}
}
return { kind: 'none' }
}
/**
* 갤러리 미디어 선택 순서를 반환한다.
* @param {string[]} selectedUrls - 선택된 URL 목록