223bb530dd
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 2m20s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 2m28s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 3m21s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 3m49s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 5m18s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 5m41s
CI/CD Pipeline / Integration Tests (push) Successful in 2m25s
CI/CD Pipeline / Unit Tests (push) Failing after 10m1s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 12m34s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 30s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 33s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m37s
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Staging E2E Tests (push) Failing after 5m1s
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com> Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
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 > 0 ? Math.max(...config.items.map((i) => i.z_index)) + 1 : 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,
|
|
}
|
|
}
|