import { useEffect, useLayoutEffect, useState } from 'react'; import { useMitt } from '@/plugins/MittContext'; import useLocalSettingsStore from '@/stores/localSettingsStore'; import useMediaStore from '@/stores/MediaStore'; import useVideoEditorStore from '@/stores/VideoEditorStore'; // Import fonts first - this loads all Fontsource packages import '@/modules/editor/fonts'; import EditNavSidebar from './partials/edit-nav-sidebar'; import EditSidebar from './partials/edit-sidebar'; import EditorAISheet from './partials/editor-ai-sheet'; import EditorCanvas from './partials/editor-canvas'; import EditorControls from './partials/editor-controls'; import EditorHeader from './partials/editor-header'; import TextSidebar from './partials/text-sidebar'; import { calculateOptimalMaxWidth, calculateResponsiveWidth } from './utils/layout-constants'; // Hook to detect if viewport is below minimum width const useViewportDetection = (minWidth = 320) => { const [isBelowMinWidth, setIsBelowMinWidth] = useState(false); useLayoutEffect(() => { setIsBelowMinWidth(window.innerWidth < minWidth); }, [minWidth]); useEffect(() => { const checkViewport = () => { setIsBelowMinWidth(window.innerWidth < minWidth); }; checkViewport(); window.addEventListener('resize', checkViewport); window.addEventListener('orientationchange', checkViewport); let resizeObserver; if (window.ResizeObserver) { resizeObserver = new ResizeObserver(checkViewport); resizeObserver.observe(document.body); } return () => { window.removeEventListener('resize', checkViewport); window.removeEventListener('orientationchange', checkViewport); if (resizeObserver) resizeObserver.disconnect(); }; }, [minWidth]); return isBelowMinWidth; }; // Hook for responsive dimensions const useResponsiveDimensions = () => { const [dimensions, setDimensions] = useState(() => ({ maxWidth: calculateOptimalMaxWidth(), responsiveWidth: calculateResponsiveWidth(), })); useLayoutEffect(() => { const newMaxWidth = calculateOptimalMaxWidth(); const newResponsiveWidth = calculateResponsiveWidth(); setDimensions({ maxWidth: newMaxWidth, responsiveWidth: newResponsiveWidth, }); }, []); useEffect(() => { const handleResize = () => { const newMaxWidth = calculateOptimalMaxWidth(); const newResponsiveWidth = calculateResponsiveWidth(); setDimensions({ maxWidth: newMaxWidth, responsiveWidth: newResponsiveWidth, }); }; window.addEventListener('resize', handleResize); window.addEventListener('orientationchange', handleResize); let resizeObserver; if (window.ResizeObserver) { resizeObserver = new ResizeObserver(handleResize); resizeObserver.observe(document.body); } let mutationObserver; if (window.MutationObserver) { mutationObserver = new MutationObserver(() => { setTimeout(handleResize, 50); }); mutationObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['style'], }); } return () => { window.removeEventListener('resize', handleResize); window.removeEventListener('orientationchange', handleResize); if (resizeObserver) resizeObserver.disconnect(); if (mutationObserver) mutationObserver.disconnect(); }; }, []); return dimensions; }; const Editor = () => { const { init } = useMediaStore(); const { getSetting } = useLocalSettingsStore(); const { setSelectedTextElement } = useVideoEditorStore(); const emitter = useMitt(); const [isEditNavSidebarOpen, setIsEditNavSidebarOpen] = useState(false); const [isEditSidebarOpen, setIsEditSidebarOpen] = useState(false); const [isTextSidebarOpen, setIsTextSidebarOpen] = useState(false); const [isMuted, setIsMuted] = useState(true); // Video starts muted by default const { maxWidth, responsiveWidth } = useResponsiveDimensions(); const isBelowMinWidth = useViewportDetection(320); useEffect(() => { init(); }, []); // Listen for text element selection (but don't auto-open sidebar) useEffect(() => { const handleTextElementSelected = (textElement) => { setSelectedTextElement(textElement); // Remove automatic sidebar opening - user will click the button instead }; emitter.on('text-element-selected', handleTextElementSelected); return () => { emitter.off('text-element-selected', handleTextElementSelected); }; }, [emitter, setSelectedTextElement]); const handleEditNavClick = () => { setIsEditNavSidebarOpen(!isEditNavSidebarOpen); }; const handleEditNavClose = () => { setIsEditNavSidebarOpen(false); }; const handleEditClick = () => { setIsEditSidebarOpen(!isEditSidebarOpen); }; const handleEditClose = () => { setIsEditSidebarOpen(false); }; const handleTextSidebarOpen = () => { setIsTextSidebarOpen(true); // Close other sidebars when text sidebar opens setIsEditSidebarOpen(false); setIsEditNavSidebarOpen(false); }; const handleTextSidebarClose = () => { setIsTextSidebarOpen(false); setSelectedTextElement(null); }; // Toggle mute functionality const handleToggleMute = () => { setIsMuted(!isMuted); }; return ( <>
{getSetting('genAlphaSlang') ? 'Not gonna lie, using on a potato screen is giving L vibes. Desktop hits different - that experience is straight fire, bet!' : 'You seem to be using a potato-sized screen. Please continue with desktop for a more refined experience!'}