Files
xiaoxia-saas/apps/web/src/pages/editing-planner/hooks/useTemplateManagement.ts
T

207 lines
4.9 KiB
TypeScript

import { useState, useCallback, type Dispatch, type SetStateAction } from "react"
import type { TemplateMode } from "@/api/editing-planner"
import type { MediaAsset, TitleConfig } from "@/api/template-editor"
import type {
ClipData,
WatermarkConfig,
IntroOutroConfig,
PipConfig,
FilterConfig,
ChromaKeyConfig,
StickerConfig,
CoverConfig,
} from "../types"
import type { SubtitleStyleConfig } from "../types/subtitle"
import type { BgmMixConfig } from "@/api/bgm"
import { useTemplateList } from "./template-management/useTemplateList"
import { useTemplateDetail } from "./template-management/useTemplateDetail"
import { usePlanLoading } from "./template-management/usePlanLoading"
import { useTemplateSave } from "./template-management/useTemplateSave"
import { FILTER_CATEGORIES } from "../constants"
interface UseTemplateManagementParams {
urlTemplateId: string
urlPlanId: string
resetClips: (clips: ClipData[]) => void
setClips: (updater: (prev: ClipData[]) => ClipData[]) => void
setSelectedClipId: (id: string | null) => void
setMediaAssets: (assets: MediaAsset[]) => void
setTitleConfig: Dispatch<SetStateAction<TitleConfig>>
setSubtitleSettings: Dispatch<SetStateAction<SubtitleStyleConfig>>
setBgmSettings: Dispatch<SetStateAction<BgmMixConfig>>
setCoverConfig: Dispatch<SetStateAction<CoverConfig>>
clips: ClipData[]
totalDuration: number
titleConfig: TitleConfig
subtitleSettings: SubtitleStyleConfig
bgmSettings: BgmMixConfig
watermarkSettings: WatermarkConfig
introOutroSettings: IntroOutroConfig
pipSettings: PipConfig
filterSettings: FilterConfig
chromaKeySettings: ChromaKeyConfig
stickerSettings: StickerConfig
coverConfig: CoverConfig
}
/**
* 模板管理 Hook
* 模板列表/分类/加载/保存/模式切换/筛选搜索
*/
export const useTemplateManagement = (params: UseTemplateManagementParams) => {
const {
urlTemplateId,
urlPlanId,
resetClips,
setClips,
setSelectedClipId,
setMediaAssets,
setTitleConfig,
setSubtitleSettings,
setBgmSettings,
setCoverConfig,
clips,
totalDuration,
titleConfig,
subtitleSettings,
bgmSettings,
watermarkSettings,
introOutroSettings,
pipSettings,
filterSettings,
chromaKeySettings,
stickerSettings,
coverConfig,
} = params
const [currentMode, setCurrentMode] = useState<TemplateMode>("pip")
const [loadedPlanId] = useState<string | null>(urlPlanId || null)
/* ── 模板列表 ── */
const {
templates,
categories,
loadingTemplates,
loadedTemplateId,
setLoadedTemplateId,
currentFilter,
setCurrentFilter,
searchQuery,
setSearchQuery,
filteredTemplates,
currentTemplate,
loadTemplates,
} = useTemplateList(setMediaAssets, urlTemplateId || null)
/* ── 保存 ── */
const {
saveModalOpen,
setSaveModalOpen,
draftName,
setDraftName,
draftCategory,
setDraftCategory,
draftTags,
setDraftTags,
saveLoading,
handleOpenSaveModal,
handleSave,
} = useTemplateSave({
currentMode,
clips,
totalDuration,
titleConfig,
subtitleSettings,
bgmSettings,
watermarkSettings,
introOutroSettings,
pipSettings,
filterSettings,
chromaKeySettings,
stickerSettings,
coverConfig,
loadedTemplateId,
loadTemplates,
})
/* ── 模板详情加载 ── */
useTemplateDetail({
loadedTemplateId,
resetClips,
setCurrentMode,
setTitleConfig,
setSubtitleSettings,
setBgmSettings,
setDraftName,
setDraftCategory,
setDraftTags,
})
/* ── 计划草稿加载 ── */
usePlanLoading({
loadedPlanId,
resetClips,
setLoadedTemplateId,
setDraftName,
setTitleConfig,
setSubtitleSettings,
setBgmSettings,
setCoverConfig,
})
/* ── 事件 ── */
const handleLoadTemplate = useCallback(
(templateId: string) => {
setLoadedTemplateId(templateId)
setSelectedClipId(null)
},
[setLoadedTemplateId, setSelectedClipId],
)
const handleModeChange = useCallback(
(mode: TemplateMode) => {
setCurrentMode(mode)
if (mode === "voice_over") {
setClips((prev) => prev.map((c) => ({ ...c, type: "voice" as const })))
} else if (mode === "pip") {
setClips((prev) => prev.map((c) => ({ ...c, type: "pip" as const })))
}
},
[setClips],
)
return {
// state
templates,
categories,
loadingTemplates,
loadedTemplateId,
setLoadedTemplateId,
currentMode,
setCurrentMode,
currentFilter,
setCurrentFilter,
searchQuery,
setSearchQuery,
saveModalOpen,
setSaveModalOpen,
draftName,
setDraftName,
draftCategory,
setDraftCategory,
draftTags,
setDraftTags,
saveLoading,
filteredTemplates,
currentTemplate,
// methods
loadTemplates,
handleLoadTemplate,
handleModeChange,
handleOpenSaveModal,
handleSave,
}
}
export { FILTER_CATEGORIES }