refactor(StickerPanel): 提取核心逻辑Hook
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import { useState, useCallback, useMemo } from "react"
|
||||
import type { StickerConfig, StickerItem, StickerType } from "../../types"
|
||||
import { DEFAULT_STICKER_CONFIG, DEFAULT_STICKER_ITEM } from "../../types"
|
||||
import { genStickerId } from "../constants"
|
||||
|
||||
interface UseStickerPanelOptions {
|
||||
config: StickerConfig
|
||||
onChange: (config: StickerConfig) => void
|
||||
totalDuration: number
|
||||
}
|
||||
|
||||
export const useStickerPanel = ({ config, onChange, totalDuration }: UseStickerPanelOptions) => {
|
||||
const [selectedId, setSelectedId] = useState<string | null>(null)
|
||||
const [activeTab, setActiveTab] = useState<StickerType>("emoji")
|
||||
const [textInput, setTextInput] = useState("")
|
||||
|
||||
const selectedSticker = useMemo(
|
||||
() => config.items.find((s) => s.id === selectedId) ?? null,
|
||||
[config.items, selectedId],
|
||||
)
|
||||
|
||||
/** 更新单个贴纸 */
|
||||
const updateItem = useCallback(
|
||||
(id: string, partial: Partial<StickerItem>) => {
|
||||
onChange({
|
||||
...config,
|
||||
items: config.items.map((s) => (s.id === id ? { ...s, ...partial } : s)),
|
||||
})
|
||||
},
|
||||
[config, onChange],
|
||||
)
|
||||
|
||||
/** 添加贴纸 */
|
||||
const addSticker = useCallback(
|
||||
(type: StickerType, content: string) => {
|
||||
const newItem: StickerItem = {
|
||||
...DEFAULT_STICKER_ITEM,
|
||||
id: genStickerId(),
|
||||
type,
|
||||
content,
|
||||
duration: totalDuration > 0 ? totalDuration : 5,
|
||||
z_index: config.items.length + 1,
|
||||
}
|
||||
onChange({
|
||||
...config,
|
||||
enabled: true,
|
||||
items: [...config.items, newItem],
|
||||
})
|
||||
setSelectedId(newItem.id)
|
||||
},
|
||||
[config, onChange, totalDuration],
|
||||
)
|
||||
|
||||
/** 删除贴纸 */
|
||||
const removeSticker = useCallback(
|
||||
(id: string) => {
|
||||
onChange({
|
||||
...config,
|
||||
items: config.items.filter((s) => s.id !== id),
|
||||
})
|
||||
if (selectedId === id) setSelectedId(null)
|
||||
},
|
||||
[config, onChange, selectedId],
|
||||
)
|
||||
|
||||
/** 重置所有 */
|
||||
const handleReset = useCallback(() => {
|
||||
onChange({ ...DEFAULT_STICKER_CONFIG, enabled: config.enabled })
|
||||
setSelectedId(null)
|
||||
}, [config.enabled, onChange])
|
||||
|
||||
return {
|
||||
selectedId,
|
||||
setSelectedId,
|
||||
selectedSticker,
|
||||
activeTab,
|
||||
setActiveTab,
|
||||
textInput,
|
||||
setTextInput,
|
||||
updateItem,
|
||||
addSticker,
|
||||
removeSticker,
|
||||
handleReset,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user