diff --git a/frontend/src/pages/constructor.tsx b/frontend/src/pages/constructor.tsx index e23a675..7beb01c 100644 --- a/frontend/src/pages/constructor.tsx +++ b/frontend/src/pages/constructor.tsx @@ -109,7 +109,7 @@ type TransitionPreviewState = { title: string; }; -type EditorMenuItem = 'none' | 'background_image' | 'background_video' | 'background_audio'; +type EditorMenuItem = 'none' | 'background_image' | 'background_video' | 'background_audio' | 'create_transition'; const parseJsonObject = (value?: string, fallback?: T): T => { if (!value) return (fallback || ({} as T)) as T; @@ -334,6 +334,12 @@ const ConstructorPage = () => { return String(value || ''); }, [router.query.pageId]); + const sourceTypeFromRoute = useMemo(() => { + const value = router.query.sourceType; + if (Array.isArray(value)) return value[0] || ''; + return String(value || ''); + }, [router.query.sourceType]); + const [pages, setPages] = useState([]); const [assets, setAssets] = useState([]); const [activePageId, setActivePageId] = useState(''); @@ -369,6 +375,7 @@ const ConstructorPage = () => { const transitionVideoRef = useRef(null); const reverseAnimationFrame = useRef(null); const didSetInitialCanvasFocus = useRef(false); + const didHandleSourceType = useRef(false); const activePage = useMemo(() => pages.find((item) => item.id === activePageId) || null, [activePageId, pages]); const pageNameById = useMemo(() => { @@ -527,6 +534,18 @@ const ConstructorPage = () => { }); }, [isAuthReady, isLoading, router.isReady]); + useEffect(() => { + if (!router.isReady || isLoading) return; + if (didHandleSourceType.current) return; + + didHandleSourceType.current = true; + if (sourceTypeFromRoute !== 'transition') return; + + setSelectedElementId(''); + setSelectedMenuItem('create_transition'); + setIsMenuOpen(true); + }, [isLoading, router.isReady, sourceTypeFromRoute]); + useEffect(() => { if (!activePage) { setElements([]); @@ -1051,6 +1070,50 @@ const ConstructorPage = () => { return getElementButtonTitle(element); }; + const renderCreateTransitionForm = () => ( +
+

Create next page transition

+ setNewTransitionName(event.target.value)} + /> + + + setNewTransitionDurationSec(Number(event.target.value || 0.7))} + /> + +
+ ); + const canvasBackgroundStyle: React.CSSProperties = {}; const backgroundImageSrc = resolveAssetPlaybackUrl(backgroundImageUrl); const backgroundVideoSrc = resolveAssetPlaybackUrl(backgroundVideoUrl); @@ -1070,7 +1133,9 @@ const ConstructorPage = () => { ? 'Background video' : selectedMenuItem === 'background_audio' ? 'Background audio' - : selectedElement?.label || 'Element editor'; + : selectedMenuItem === 'create_transition' + ? 'Create transition' + : selectedElement?.label || 'Element editor'; if (backgroundImageSrc) { canvasBackgroundStyle.backgroundImage = `url("${backgroundImageSrc}")`; @@ -1339,6 +1404,8 @@ const ConstructorPage = () => { )} + {selectedMenuItem === 'create_transition' && renderCreateTransitionForm()} + {selectedElement && (
@@ -1447,52 +1514,7 @@ const ConstructorPage = () => { openTransitionPreview('forward')} /> openTransitionPreview('back')} />
-
-

Create next page transition

- setNewTransitionName(event.target.value)} - /> - - - setNewTransitionDurationSec(Number(event.target.value || 0.7))} - /> - -
+ {renderCreateTransitionForm()} )} @@ -1729,6 +1751,10 @@ const ConstructorPage = () => { Add Navigation +