import React, { Dispatch, SetStateAction, useEffect, useRef, useState } from 'react'; import { events as EVENTS } from '../../Events/AppEvents'; import { MainMenu } from '../MainMenu/MainMenu'; import { ContainerModel } from '../../Interfaces/IContainerModel'; import { Editor } from '../Editor/Editor'; import { IEditorState } from '../../Interfaces/IEditorState'; import { LoadState } from './Actions/Load'; import { LoadEditor, NewEditor } from './Actions/MenuActions'; import { DEFAULT_CONFIG, DEFAULT_MAINCONTAINER_PROPS } from '../../utils/default'; // App will never have props // eslint-disable-next-line @typescript-eslint/no-empty-interface interface IAppProps { root: Element | Document } function UseHTTPGETStatePreloading( isLoaded: boolean, setEditorState: Dispatch>, setLoaded: Dispatch> ): void { useEffect(() => { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const state = urlParams.get('state'); if (state === null) { return; } if (!isLoaded) { fetch(state) .then( async(response) => await response.json(), (error) => { throw new Error(error); } ) .then((data: IEditorState) => { LoadState(data, setEditorState, setLoaded); }, (error) => { throw new Error(error); }); } }); }; function UseCustomEvents( root: Element | Document, appRef: React.RefObject, setEditor: (newState: IEditorState) => void, setLoaded: (loaded: boolean) => void ): void { useEffect(() => { const funcs = new Map void>(); for (const event of EVENTS) { function Func(eventInitDict?: CustomEventInit): void { return event.func( root, setEditor, setLoaded, eventInitDict ); } appRef.current?.addEventListener(event.name, Func); funcs.set(event.name, Func); } return () => { for (const event of EVENTS) { const func = funcs.get(event.name); if (func === undefined) { continue; } appRef.current?.removeEventListener(event.name, func); } }; }); } export function App(props: IAppProps): JSX.Element { const [isLoaded, setLoaded] = useState(false); const appRef = useRef(null); const defaultMainContainer = new ContainerModel( null, DEFAULT_MAINCONTAINER_PROPS ); const [editorState, setEditorState] = useState({ configuration: DEFAULT_CONFIG, history: [{ lastAction: '', mainContainer: defaultMainContainer, selectedContainerId: defaultMainContainer.properties.id, typeCounters: {}, symbols: new Map(), selectedSymbolId: '' }], historyCurrentStep: 0 }); UseCustomEvents( props.root, appRef, setEditorState, setLoaded ); UseHTTPGETStatePreloading(isLoaded, setEditorState, setLoaded); if (isLoaded) { return (
); } return (
NewEditor( setEditorState, setLoaded )} loadEditor={(files: FileList | null) => LoadEditor( files, setEditorState, setLoaded )} />
); };