diff --git a/public/workers/message_worker.js b/public/workers/message_worker.js index cfc2666..f8fef7a 100644 --- a/public/workers/message_worker.js +++ b/public/workers/message_worker.js @@ -9,7 +9,7 @@ onmessage = async(e) => { const request = { ApplicationState: state }; - const dataParsed = JSON.stringify(request, GetCircularReplacer()); + const dataParsed = JSON.stringify(request, GetCircularReplacerKeepDataStructure()); fetch(url, { method: 'POST', headers: new Headers({ @@ -26,25 +26,13 @@ onmessage = async(e) => { }); }; -function GetCircularReplacer() +function GetCircularReplacerKeepDataStructure() { return (key, value) => { if (key === 'parent') { return; } - if (key === 'containers') { - return Array.from(value.entries()); - } - - if (key === 'symbols') { - return Array.from(value.entries()); - } - - if (key === 'linkedContainers') { - return Array.from(value); - } - return value; }; } diff --git a/src/Components/Messages/Messages.tsx b/src/Components/Messages/Messages.tsx index fb78de3..139a123 100644 --- a/src/Components/Messages/Messages.tsx +++ b/src/Components/Messages/Messages.tsx @@ -4,6 +4,8 @@ import { FixedSizeList as List } from 'react-window'; import { MessageType } from '../../Enums/MessageType'; import { IHistoryState } from '../../Interfaces/IHistoryState'; import { IMessage } from '../../Interfaces/IMessage'; +import { DISABLE_API } from '../../utils/default'; +import { GetCircularReplacerKeepDataStructure } from '../../utils/saveload'; import { TITLE_BAR_HEIGHT } from '../Sidebar/Sidebar'; interface IMessagesProps { diff --git a/src/Components/MessagesSidebar/Messages.tsx b/src/Components/MessagesSidebar/Messages.tsx new file mode 100644 index 0000000..8422a36 --- /dev/null +++ b/src/Components/MessagesSidebar/Messages.tsx @@ -0,0 +1,131 @@ +import * as React from 'react'; +import { FixedSizeList as List } from 'react-window'; +import { API_GET_FEEDBACK_URL } from '../../../public/svgld-settings'; +import { MessageType } from '../../Enums/MessageType'; +import { IGetFeedbackRequest } from '../../Interfaces/IGetFeedbackRequest'; +import { IGetFeedbackResponse } from '../../Interfaces/IGetFeedbackResponse'; +import { IHistoryState } from '../../Interfaces/IHistoryState'; +import { IMessage } from '../../Interfaces/IMessage'; +import { DISABLE_API } from '../../utils/default'; +import { GetCircularReplacerKeepDataStructure } from '../../utils/saveload'; +import { TITLE_BAR_HEIGHT } from '../Sidebar/Sidebar'; + +interface IMessagesSidebarProps { + historyState: IHistoryState +} + +// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions +const myWorker = window.Worker && new Worker('workers/message_worker.js'); + +function UseWorker( + state: IHistoryState, + setMessages: React.Dispatch> +): void { + React.useEffect(() => { + // use webworker for the stringify to avoid freezing + myWorker.postMessage({ + state, + url: API_GET_FEEDBACK_URL + }); + + return () => { + }; + }, [state]); + + React.useEffect(() => { + myWorker.onmessage = (event) => { + setMessages(event.data as IMessage[]); + }; + }, [setMessages]); +} + +function UseAsync( + state: IHistoryState, + setMessages: React.Dispatch> +): void { + React.useEffect(() => { + const request: IGetFeedbackRequest = { + // eslint-disable-next-line @typescript-eslint/naming-convention + ApplicationState: state + }; + const dataParsed = JSON.stringify(request, GetCircularReplacerKeepDataStructure()); + fetch(API_GET_FEEDBACK_URL, { + method: 'POST', + headers: new Headers({ + // eslint-disable-next-line @typescript-eslint/naming-convention + 'Content-Type': 'application/json' + }), + body: dataParsed + }) + .then(async(response) => + await response.json() + ) + .then(async(json: IGetFeedbackResponse) => { + setMessages(json.messages); + }); + }, [state]); +} + +export function MessagesSidebar(props: IMessagesSidebarProps): JSX.Element { + const [messages, setMessages] = React.useState([]); + + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + if (window.Worker && !DISABLE_API) { + UseWorker( + props.historyState, + setMessages + ); + } else if (!DISABLE_API) { + UseAsync( + props.historyState, + setMessages + ); + } + + function Row({ index, style }: {index: number, style: React.CSSProperties}): JSX.Element { + const reversedIndex = (messages.length - 1) - index; + const message = messages[reversedIndex]; + let classType = ''; + switch (message.type) { + case MessageType.Success: + classType = 'bg-green-400 hover:bg-green-400/60'; + break; + + case MessageType.Warning: + classType = 'bg-yellow-400 hover:bg-yellow-400/60'; + break; + + case MessageType.Error: + classType = 'bg-red-400 hover:bg-red-400/60'; + break; + } + return (

+ {message.text} +

); + } + + return ( + // + // + + {Row} + + ); +}; diff --git a/src/Components/UI/UseWorker.tsx b/src/Components/UI/UseWorker.tsx index bede445..7f8a904 100644 --- a/src/Components/UI/UseWorker.tsx +++ b/src/Components/UI/UseWorker.tsx @@ -3,7 +3,7 @@ import { IHistoryState } from '../../Interfaces/IHistoryState'; import { IGetFeedbackRequest } from '../../Interfaces/IGetFeedbackRequest'; import { IGetFeedbackResponse } from '../../Interfaces/IGetFeedbackResponse'; import { IMessage } from '../../Interfaces/IMessage'; -import { GetCircularReplacer } from '../../utils/saveload'; +import { GetCircularReplacerKeepDataStructure } from '../../utils/saveload'; import { API_GET_FEEDBACK_URL } from '../../../public/svgld-settings'; // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions @@ -37,7 +37,7 @@ export function UseAsync( // eslint-disable-next-line @typescript-eslint/naming-convention ApplicationState: state }; - const dataParsed = JSON.stringify(request, GetCircularReplacer()); + const dataParsed = JSON.stringify(request, GetCircularReplacerKeepDataStructure()); fetch(API_GET_FEEDBACK_URL, { method: 'POST', headers: new Headers({ diff --git a/src/utils/saveload.ts b/src/utils/saveload.ts index 6259d18..5d7681f 100644 --- a/src/utils/saveload.ts +++ b/src/utils/saveload.ts @@ -60,7 +60,7 @@ export function GetCircularReplacer(): (key: any, value: object | Map).entries()); }