refactor(editing-planner): Phase 1 - extract constants and selectors #900
@@ -63,19 +63,15 @@ import SaveModal from "./components/SaveModal"
|
||||
import type { SubtitleStyleConfig } from "./types/subtitle"
|
||||
import { DEFAULT_SUBTITLE_STYLE } from "./types/subtitle"
|
||||
import { DEFAULT_BGM_MIX_CONFIG, type BgmMixConfig } from "@/api/bgm"
|
||||
import { MODE_LIST, FILTER_CATEGORIES } from "./constants"
|
||||
import {
|
||||
calculateTotalDuration,
|
||||
getCurrentTemplate,
|
||||
getFilteredTemplates,
|
||||
getSelectedClip,
|
||||
} from "./utils/selectors"
|
||||
import "./EditingPlanner.css"
|
||||
|
||||
/* ──────────── 常量 ──────────── */
|
||||
|
||||
const MODE_LIST: { key: TemplateMode; label: string; icon: string }[] = [
|
||||
{ key: "pip", label: "混剪", icon: "🖼️" },
|
||||
{ key: "voice_over", label: "人物口播", icon: "🎙️" },
|
||||
{ key: "one_take", label: "一镜到底", icon: "🎥" },
|
||||
{ key: "voice_pip", label: "口播+混剪", icon: "🎭" },
|
||||
]
|
||||
|
||||
const FILTER_CATEGORIES = ["全部", "种草", "知识", "日常", "推荐"]
|
||||
|
||||
/* ──────────── 组件 ──────────── */
|
||||
|
||||
const EditingPlanner: React.FC = () => {
|
||||
@@ -449,9 +445,9 @@ const EditingPlanner: React.FC = () => {
|
||||
|
||||
/* ──────────── 计算 ──────────── */
|
||||
|
||||
const currentTemplate = templates.find((t) => t.id === loadedTemplateId)
|
||||
const totalDuration = clips.reduce((sum, c) => sum + c.duration, 0)
|
||||
const selectedClip = clips.find((c) => c.id === selectedClipId) || null
|
||||
const currentTemplate = getCurrentTemplate(templates, loadedTemplateId)
|
||||
const totalDuration = calculateTotalDuration(clips)
|
||||
const selectedClip = getSelectedClip(clips, selectedClipId)
|
||||
|
||||
/* rAF 帧推进 — 播放时平滑更新播放头位置 */
|
||||
useEffect(() => {
|
||||
@@ -478,11 +474,7 @@ const EditingPlanner: React.FC = () => {
|
||||
}
|
||||
}, [isPlaying, totalDuration])
|
||||
|
||||
const filteredTemplates = templates.filter((t) => {
|
||||
if (currentFilter !== "全部" && t.category !== currentFilter) return false
|
||||
if (searchQuery && !t.name.toLowerCase().includes(searchQuery.toLowerCase())) return false
|
||||
return true
|
||||
})
|
||||
const filteredTemplates = getFilteredTemplates(templates, currentFilter, searchQuery)
|
||||
|
||||
/* ──────────── 事件 ──────────── */
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { TemplateMode } from "@/api/editing-planner"
|
||||
|
||||
/* ──────────── 常量 ──────────── */
|
||||
|
||||
export const MODE_LIST: { key: TemplateMode; label: string; icon: string }[] = [
|
||||
{ key: "pip", label: "混剪", icon: "🖼️" },
|
||||
{ key: "voice_over", label: "人物口播", icon: "🎙️" },
|
||||
{ key: "one_take", label: "一镜到底", icon: "🎥" },
|
||||
{ key: "voice_pip", label: "口播+混剪", icon: "🎭" },
|
||||
]
|
||||
|
||||
export const FILTER_CATEGORIES = ["全部", "种草", "知识", "日常", "推荐"]
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { EditingTemplate } from "@/api/editing-planner"
|
||||
import type { ClipData } from "../types"
|
||||
|
||||
/**
|
||||
* 计算所有片段的总时长
|
||||
*/
|
||||
export function calculateTotalDuration(clips: ClipData[]): number {
|
||||
return clips.reduce((sum, c) => sum + c.duration, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前选中的模板
|
||||
*/
|
||||
export function getCurrentTemplate(
|
||||
templates: EditingTemplate[],
|
||||
loadedTemplateId: string | null,
|
||||
): EditingTemplate | undefined {
|
||||
return templates.find((t) => t.id === loadedTemplateId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类和搜索词筛选模板
|
||||
*/
|
||||
export function getFilteredTemplates(
|
||||
templates: EditingTemplate[],
|
||||
currentFilter: string,
|
||||
searchQuery: string,
|
||||
): EditingTemplate[] {
|
||||
return templates.filter((t) => {
|
||||
if (currentFilter !== "全部" && t.category !== currentFilter) return false
|
||||
if (searchQuery && !t.name.toLowerCase().includes(searchQuery.toLowerCase())) return false
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前选中的片段
|
||||
*/
|
||||
export function getSelectedClip(clips: ClipData[], selectedClipId: string | null): ClipData | null {
|
||||
return clips.find((c) => c.id === selectedClipId) || null
|
||||
}
|
||||
Regular → Executable
+6
@@ -8,6 +8,12 @@ import { describe, it, expect } from "vitest"
|
||||
// 主组件
|
||||
import "@/pages/editing-planner/EditingPlanner"
|
||||
|
||||
// 常量
|
||||
import "@/pages/editing-planner/constants"
|
||||
|
||||
// 工具函数
|
||||
import "@/pages/editing-planner/utils/selectors"
|
||||
|
||||
// 子组件
|
||||
import "@/pages/editing-planner/components/BgmSelector"
|
||||
import "@/pages/editing-planner/components/ClipPropertiesPanel"
|
||||
|
||||
Reference in New Issue
Block a user