9a51cad137
CI/CD Pipeline / Frontend Lint (push) Successful in 48s
CI/CD Pipeline / Validate - Code Quality (push) Failing after 2m24s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 2m25s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 2m27s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 3m8s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 3m16s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m20s
CI/CD Pipeline / Integration Tests (push) Successful in 3m53s
CI/CD Pipeline / Unit Tests (push) Failing after 7m53s
CI/CD Pipeline / Build Staging API Image (push) Successful in 11m29s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m13s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 26s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 1m3s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m15s
CI/CD Pipeline / Production Browser E2E (push) Failing after 1294h4m36s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 1294h5m22s
CI/CD Pipeline / Build Production Web Image (push) Failing after 1294h5m22s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 1294h7m45s
CI/CD Pipeline / PR Build Web Image (push) Failing after 1294h7m47s
CI/CD Pipeline / PR Build API Image (push) Failing after 1294h7m47s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 1294h7m49s
CI/CD Pipeline / Deploy Production (push) Failing after 1294h37m5s
CI/CD Pipeline / Build Production API Image (push) Failing after 1294h37m51s
82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
/**
|
|
* Step 6 封面设置 Hook
|
|
* 封装封面设置的交互逻辑
|
|
*/
|
|
import { useCallback } from "react"
|
|
import type { CoverConfig } from "../../editing-planner/types"
|
|
import { COVER_MODE_LABELS, COVER_MODE_ICONS, DEFAULT_COVER_SETTINGS } from "../constants"
|
|
|
|
interface UseStep6CoverProps {
|
|
coverSettings: CoverConfig
|
|
onCoverSettingsChange: (settings: CoverConfig) => void
|
|
duration: number
|
|
}
|
|
|
|
export function useStep6Cover({
|
|
coverSettings,
|
|
onCoverSettingsChange,
|
|
duration,
|
|
}: UseStep6CoverProps) {
|
|
const formatTime = useCallback((seconds: number) => {
|
|
const m = Math.floor(seconds / 60)
|
|
const s = Math.floor(seconds % 60)
|
|
const ms = Math.floor((seconds % 1) * 10)
|
|
return `${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}.${ms}`
|
|
}, [])
|
|
|
|
const toggleEnabled = useCallback(
|
|
(enabled: boolean) => {
|
|
onCoverSettingsChange({ ...coverSettings, enabled })
|
|
},
|
|
[coverSettings, onCoverSettingsChange],
|
|
)
|
|
|
|
const setMode = useCallback(
|
|
(mode: CoverConfig["mode"]) => {
|
|
onCoverSettingsChange({ ...coverSettings, mode })
|
|
},
|
|
[coverSettings, onCoverSettingsChange],
|
|
)
|
|
|
|
const setFrameTime = useCallback(
|
|
(frameTime: number) => {
|
|
onCoverSettingsChange({ ...coverSettings, frame_time: frameTime })
|
|
},
|
|
[coverSettings, onCoverSettingsChange],
|
|
)
|
|
|
|
const handleUpload = useCallback(
|
|
(file: File) => {
|
|
const reader = new FileReader()
|
|
reader.onload = (ev) => {
|
|
const url = ev.target?.result as string
|
|
onCoverSettingsChange({
|
|
...coverSettings,
|
|
upload_url: url,
|
|
thumbnail_url: url,
|
|
mode: "upload",
|
|
})
|
|
}
|
|
reader.readAsDataURL(file)
|
|
},
|
|
[coverSettings, onCoverSettingsChange],
|
|
)
|
|
|
|
const totalDuration = duration || 30
|
|
|
|
return {
|
|
coverSettings,
|
|
formatTime,
|
|
toggleEnabled,
|
|
setMode,
|
|
setFrameTime,
|
|
handleUpload,
|
|
totalDuration,
|
|
COVER_MODE_LABELS,
|
|
COVER_MODE_ICONS,
|
|
DEFAULT_COVER_SETTINGS,
|
|
}
|
|
}
|
|
|
|
export default useStep6Cover
|