39948-vm/frontend/src/hooks/useTransitionCreation.ts
2026-04-05 18:46:16 +04:00

135 lines
3.2 KiB
TypeScript

/**
* useTransitionCreation Hook
*
* Encapsulates transition creation form state and actions.
* Used in the constructor to manage the "Create Transition" form.
*/
import { useState, useCallback, useEffect } from 'react';
import type { AssetOption } from '../types/constructor';
export interface TransitionCreationState {
/** Transition name */
name: string;
/** Video URL/storage key */
videoUrl: string;
/** Whether transition supports reverse playback */
supportsReverse: boolean;
/** Whether transition is being created */
isCreating: boolean;
}
export interface TransitionCreationActions {
/** Set transition name */
setName: (name: string) => void;
/** Set video URL */
setVideoUrl: (url: string) => void;
/** Set supports reverse flag */
setSupportsReverse: (value: boolean) => void;
/** Create the transition */
create: () => void;
/** Reset form to initial state */
reset: () => void;
}
export interface UseTransitionCreationOptions {
/** Available transition video options */
videoOptions: AssetOption[];
/** Callback to create transition */
onCreate: (params: {
name: string;
videoUrl: string;
supportsReverse: boolean;
durationSec?: number;
}) => Promise<void>;
/** Get duration of video URL */
getDuration?: (url: string) => number | undefined;
}
export interface UseTransitionCreationResult
extends TransitionCreationState,
TransitionCreationActions {}
/**
* Hook to manage transition creation form state.
*
* @example
* ```typescript
* const {
* name,
* videoUrl,
* supportsReverse,
* isCreating,
* setName,
* setVideoUrl,
* setSupportsReverse,
* create,
* } = useTransitionCreation({
* videoOptions: transitionVideoAssetOptions,
* onCreate: handleCreateTransition,
* getDuration,
* });
* ```
*/
export function useTransitionCreation({
videoOptions,
onCreate,
getDuration,
}: UseTransitionCreationOptions): UseTransitionCreationResult {
const [name, setName] = useState('');
const [videoUrl, setVideoUrl] = useState('');
const [supportsReverse, setSupportsReverse] = useState(true);
const [isCreating, setIsCreating] = useState(false);
// Auto-select first video option when available
useEffect(() => {
if (videoUrl) return;
if (!videoOptions.length) return;
setVideoUrl(videoOptions[0].value);
}, [videoUrl, videoOptions]);
const create = useCallback(async () => {
if (isCreating) return;
if (!videoUrl) return;
setIsCreating(true);
try {
const durationSec = getDuration?.(videoUrl);
await onCreate({
name,
videoUrl,
supportsReverse,
durationSec,
});
// Reset form on success
setName('');
setSupportsReverse(true);
} finally {
setIsCreating(false);
}
}, [isCreating, name, videoUrl, supportsReverse, getDuration, onCreate]);
const reset = useCallback(() => {
setName('');
setVideoUrl(videoOptions[0]?.value || '');
setSupportsReverse(true);
setIsCreating(false);
}, [videoOptions]);
return {
// State
name,
videoUrl,
supportsReverse,
isCreating,
// Actions
setName,
setVideoUrl,
setSupportsReverse,
create,
reset,
};
}
export default useTransitionCreation;