132 lines
3.8 KiB
TypeScript
132 lines
3.8 KiB
TypeScript
import React, { Dispatch, SetStateAction, useCallback, useContext, useEffect, useRef, useState } from 'react';
|
|
import { UseCustomEvents } from '../../Events/AppEvents';
|
|
import { MainMenu } from '../MainMenu/MainMenu';
|
|
import { ContainerModel, IContainerModel } 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, FAST_BOOT } from '../../utils/default';
|
|
import { AppState } from '../../Enums/AppState';
|
|
import { Loader } from '../Loader/Loader';
|
|
import { LanguageContext } from '../LanguageProvider/LanguageProvider';
|
|
|
|
// App will never have props
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
interface IAppProps {
|
|
root: Element | Document
|
|
}
|
|
|
|
function UseHTTPGETStatePreloading(
|
|
appState: AppState,
|
|
setEditorState: Dispatch<SetStateAction<IEditorState>>,
|
|
setAppState: Dispatch<SetStateAction<AppState>>
|
|
): void {
|
|
useEffect(() => {
|
|
const queryString = window.location.search;
|
|
const urlParams = new URLSearchParams(queryString);
|
|
const state = urlParams.get('state');
|
|
|
|
if (state === null) {
|
|
return;
|
|
}
|
|
|
|
if (appState !== AppState.Loaded) {
|
|
fetch(state)
|
|
.then(
|
|
async(response) => await response.json(),
|
|
(error) => { throw new Error(error); }
|
|
)
|
|
.then((data: IEditorState) => {
|
|
LoadState(data, setEditorState, setAppState);
|
|
}, (error) => { throw new Error(error); });
|
|
}
|
|
});
|
|
};
|
|
|
|
export function App(props: IAppProps): JSX.Element {
|
|
const [appState, setAppState] = useState<AppState>(FAST_BOOT);
|
|
const appRef = useRef<HTMLDivElement>(null);
|
|
const languageContext = useContext(LanguageContext);
|
|
|
|
const defaultMainContainer = new ContainerModel(
|
|
DEFAULT_MAINCONTAINER_PROPS
|
|
);
|
|
const containers = new Map<string, IContainerModel>();
|
|
containers.set(defaultMainContainer.properties.id, defaultMainContainer);
|
|
|
|
const [editorState, setEditorState] = useState<IEditorState>({
|
|
configuration: DEFAULT_CONFIG,
|
|
history: [{
|
|
lastAction: '',
|
|
mainContainer: defaultMainContainer.properties.id,
|
|
containers,
|
|
selectedContainerId: defaultMainContainer.properties.id,
|
|
typeCounters: {},
|
|
symbols: new Map(),
|
|
selectedSymbolId: ''
|
|
}],
|
|
historyCurrentStep: 0
|
|
});
|
|
|
|
UseCustomEvents(
|
|
props.root,
|
|
appRef,
|
|
languageContext,
|
|
setEditorState,
|
|
setAppState
|
|
);
|
|
|
|
UseHTTPGETStatePreloading(appState, setEditorState, setAppState);
|
|
|
|
switch (appState) {
|
|
case AppState.Loaded:
|
|
return (
|
|
<div
|
|
ref={appRef}
|
|
className='App'
|
|
>
|
|
<Editor
|
|
root={props.root}
|
|
configuration={editorState.configuration}
|
|
history={editorState.history}
|
|
historyCurrentStep={editorState.historyCurrentStep}
|
|
/>
|
|
</div>
|
|
);
|
|
case AppState.Loading:
|
|
return (
|
|
<div
|
|
ref={appRef}
|
|
className='App mainmenu-bg'
|
|
>
|
|
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
|
<Loader />
|
|
</div>
|
|
</div>
|
|
);
|
|
default:
|
|
return (
|
|
<div
|
|
ref={appRef}
|
|
className='App mainmenu-bg'
|
|
>
|
|
<MainMenu
|
|
newEditor={() => {
|
|
setAppState(AppState.Loading);
|
|
NewEditor(
|
|
editorState,
|
|
(newEditor) => setEditorState(newEditor),
|
|
() => setAppState(AppState.Loaded)
|
|
);
|
|
}}
|
|
loadEditor={(files: FileList | null) => LoadEditor(
|
|
files,
|
|
setEditorState,
|
|
setAppState
|
|
)}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
};
|