From 8590baf89741286b6c11eff7e8eed0398d13dfc5 Mon Sep 17 00:00:00 2001 From: Luis Felix Date: Wed, 25 Sep 2024 11:33:05 -0400 Subject: [PATCH 1/2] OV-416: * remove folders of functions of helpers, change sanitizeJsonString to remove with regrex everithing form the first bracket to the last --- .../generate-script-message-template.ts | 0 .../components/video-modal-content/helpers/helpers.ts | 4 ++-- .../video-modal-content/helpers/sanitize-json-string.ts | 6 ++++++ .../helpers/sanitize-json-string/sanitize-json-string.ts | 6 ------ 4 files changed, 8 insertions(+), 8 deletions(-) rename frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/{generate-script-message-template => }/generate-script-message-template.ts (100%) create mode 100644 frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string.ts delete mode 100644 frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string/sanitize-json-string.ts diff --git a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/generate-script-message-template/generate-script-message-template.ts b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/generate-script-message-template.ts similarity index 100% rename from frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/generate-script-message-template/generate-script-message-template.ts rename to frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/generate-script-message-template.ts diff --git a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/helpers.ts b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/helpers.ts index f35afb2a4..f5a767408 100644 --- a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/helpers.ts +++ b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/helpers.ts @@ -1,2 +1,2 @@ -export { getVideoScriptMessageFromPayload } from './generate-script-message-template/generate-script-message-template.js'; -export { sanitizeJsonString } from './sanitize-json-string/sanitize-json-string.js'; +export { getVideoScriptMessageFromPayload } from './generate-script-message-template.js'; +export { sanitizeJsonString } from './sanitize-json-string.js'; diff --git a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string.ts b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string.ts new file mode 100644 index 000000000..145fcc521 --- /dev/null +++ b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string.ts @@ -0,0 +1,6 @@ +const sanitizeJsonString = (input: string): string => { + const match = input.match(/\[.*]/s); + return match ? match[0].trim() : input.trim(); +}; + +export { sanitizeJsonString }; diff --git a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string/sanitize-json-string.ts b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string/sanitize-json-string.ts deleted file mode 100644 index 3695afce1..000000000 --- a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/helpers/sanitize-json-string/sanitize-json-string.ts +++ /dev/null @@ -1,6 +0,0 @@ -const sanitizeJsonString = (input: string): string => { - const sanitized = input.replaceAll('`', '').replaceAll('json', ''); - return sanitized.trim(); -}; - -export { sanitizeJsonString }; From d2f012a067d8d69ece0da083c53b2cadc6943214 Mon Sep 17 00:00:00 2001 From: Luis Felix Date: Wed, 25 Sep 2024 13:02:54 -0400 Subject: [PATCH 2/2] OV-416: * changes to manage video scripts in redux and show message on error --- frontend/src/bundles/chat/helpers/helpers.ts | 1 + .../chat/helpers/sanitize-json-string.ts | 6 +++ frontend/src/bundles/chat/store/slice.ts | 44 ++++++++++++++++++- .../generate-script-placeholder.tsx | 26 +++++++---- .../generate-script-view.tsx | 42 +++--------------- .../src/bundles/common/constants/constants.ts | 2 +- shared/src/constants/constants.ts | 1 + .../constants/last-element-index.constant.ts | 3 ++ shared/src/index.ts | 2 +- 9 files changed, 79 insertions(+), 48 deletions(-) create mode 100644 frontend/src/bundles/chat/helpers/helpers.ts create mode 100644 frontend/src/bundles/chat/helpers/sanitize-json-string.ts create mode 100644 shared/src/constants/last-element-index.constant.ts diff --git a/frontend/src/bundles/chat/helpers/helpers.ts b/frontend/src/bundles/chat/helpers/helpers.ts new file mode 100644 index 000000000..446326709 --- /dev/null +++ b/frontend/src/bundles/chat/helpers/helpers.ts @@ -0,0 +1 @@ +export { sanitizeJsonString } from './sanitize-json-string.js'; diff --git a/frontend/src/bundles/chat/helpers/sanitize-json-string.ts b/frontend/src/bundles/chat/helpers/sanitize-json-string.ts new file mode 100644 index 000000000..145fcc521 --- /dev/null +++ b/frontend/src/bundles/chat/helpers/sanitize-json-string.ts @@ -0,0 +1,6 @@ +const sanitizeJsonString = (input: string): string => { + const match = input.match(/\[.*]/s); + return match ? match[0].trim() : input.trim(); +}; + +export { sanitizeJsonString }; diff --git a/frontend/src/bundles/chat/store/slice.ts b/frontend/src/bundles/chat/store/slice.ts index 937b925d6..ff5105ee2 100644 --- a/frontend/src/bundles/chat/store/slice.ts +++ b/frontend/src/bundles/chat/store/slice.ts @@ -1,29 +1,67 @@ import { createSlice } from '@reduxjs/toolkit'; import { MessageSender } from '~/bundles/chat/enums/enums.js'; +import { sanitizeJsonString } from '~/bundles/chat/helpers/helpers.js'; import { type GenerateTextRequestDto, type Message, } from '~/bundles/chat/types/types.js'; +import { + EMPTY_VALUE, + LAST_ELEMENT_INDEX, +} from '~/bundles/common/constants/constants.js'; import { DataStatus } from '~/bundles/common/enums/enums.js'; -import { type ValueOf } from '~/bundles/common/types/types.js'; +import { + type ValueOf, + type VideoScript, +} from '~/bundles/common/types/types.js'; import { deleteChat, sendMessage } from './actions.js'; type State = { messages: Message[]; + videoScripts: VideoScript[]; + videoScriptErrorMessage: string; dataStatus: ValueOf; }; const initialState: State = { messages: [], + videoScripts: [], + videoScriptErrorMessage: '', dataStatus: DataStatus.IDLE, }; const { reducer, actions, name } = createSlice({ initialState, name: 'chat', - reducers: {}, + reducers: { + generateVideoScript(state) { + const messages = state.messages.filter( + (message) => message.sender === MessageSender.AI, + ); + + if (!messages || messages.length === EMPTY_VALUE) { + return; + } + + const lastMessage = messages.at(LAST_ELEMENT_INDEX); + if (!lastMessage) { + return; + } + + try { + const sanitizedJson = sanitizeJsonString(lastMessage.text); + const videoScripts: VideoScript[] = JSON.parse(sanitizedJson); + state.videoScripts = videoScripts; + state.videoScriptErrorMessage = ''; + } catch { + state.videoScripts = []; + state.videoScriptErrorMessage = + 'There was an error Generating the Script, please Re-Generate'; + } + }, + }, extraReducers(builder) { builder.addCase(sendMessage.pending, (state) => { state.dataStatus = DataStatus.PENDING; @@ -60,6 +98,8 @@ const { reducer, actions, name } = createSlice({ }); builder.addCase(deleteChat.fulfilled, (state) => { state.messages = []; + state.videoScripts = []; + state.videoScriptErrorMessage = ''; state.dataStatus = DataStatus.FULFILLED; }); builder.addCase(deleteChat.rejected, (state) => { diff --git a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-placeholder/generate-script-placeholder.tsx b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-placeholder/generate-script-placeholder.tsx index 5c82c370d..de2e2afd6 100644 --- a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-placeholder/generate-script-placeholder.tsx +++ b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-placeholder/generate-script-placeholder.tsx @@ -3,20 +3,18 @@ import { EMPTY_VALUE } from '~/bundles/common/constants/constants.js'; import { DataStatus } from '~/bundles/common/enums/data-status.enum.js'; import { useAppSelector } from '~/bundles/common/hooks/hooks.js'; import { IconName } from '~/bundles/common/icons/icons.js'; -import { type VideoScript } from '~/bundles/common/types/types.js'; import { GenerateScriptPlaceholderContent } from '../generate-script-placeholder-content/generate-script-placeholder-content.js'; import { GenerateScriptScene } from '../generate-script-scene/generate-script-scene.js'; import styles from './styles.module.css'; -type Properties = { - videoScripts: VideoScript[]; -}; - -const GenerateScriptPlaceholder: React.FC = ({ videoScripts }) => { - const { dataStatus } = useAppSelector(({ chat }) => ({ - dataStatus: chat.dataStatus, - })); +const GenerateScriptPlaceholder: React.FC = () => { + const { dataStatus, videoScripts, videoScriptErrorMessage } = + useAppSelector(({ chat }) => ({ + dataStatus: chat.dataStatus, + videoScripts: chat.videoScripts, + videoScriptErrorMessage: chat.videoScriptErrorMessage, + })); const renderLoadingState = (): React.ReactNode => ( @@ -31,6 +29,13 @@ const GenerateScriptPlaceholder: React.FC = ({ videoScripts }) => { /> ); + const renderErrorMessage = (): React.ReactNode => ( + + ); + const renderScripts = (): React.ReactNode => ( <> {videoScripts.map((videoScript, index) => ( @@ -43,6 +48,9 @@ const GenerateScriptPlaceholder: React.FC = ({ videoScripts }) => { if (dataStatus === DataStatus.PENDING) { return renderLoadingState(); } + if (videoScriptErrorMessage) { + return renderErrorMessage(); + } if (videoScripts.length === EMPTY_VALUE) { return renderEmptyState(); } diff --git a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-view/generate-script-view.tsx b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-view/generate-script-view.tsx index 42d61de69..a8cf385e1 100644 --- a/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-view/generate-script-view.tsx +++ b/frontend/src/bundles/common/components/video-modal/components/video-modal-content/components/generate-script-view/generate-script-view.tsx @@ -10,18 +10,12 @@ import { TabPanels, Tabs, } from '~/bundles/common/components/components.js'; -import { - getVideoScriptMessageFromPayload, - sanitizeJsonString, -} from '~/bundles/common/components/video-modal/components/video-modal-content/helpers/helpers.js'; -import { EMPTY_VALUE } from '~/bundles/common/constants/constants.js'; +import { getVideoScriptMessageFromPayload } from '~/bundles/common/components/video-modal/components/video-modal-content/helpers/helpers.js'; import { useAppDispatch, useAppSelector, useCallback, - useMemo, } from '~/bundles/common/hooks/hooks.js'; -import { type VideoScript } from '~/bundles/common/types/video-script.type.js'; import { type GenerateVideoScriptRequestDto } from '~/bundles/video-scripts/video-scripts.js'; import { GenerateScriptForm } from '../generate-script-form/generate-script-form.js'; @@ -41,35 +35,15 @@ const GenerateScriptView: React.FC = () => { const sendMessageRequest: GenerateTextRequestDto = { message: getVideoScriptMessageFromPayload(payload, messages), }; - void dispatch(chatActions.sendMessage(sendMessageRequest)); + void dispatch(chatActions.sendMessage(sendMessageRequest)).then( + () => { + dispatch(chatActions.generateVideoScript()); + }, + ); }, [messages, dispatch], ); - const lastGeneratedScript: VideoScript[] = useMemo(() => { - if (!messages || messages.length === EMPTY_VALUE) { - return []; - } - - const lastMessage = messages.at(-1); - if (!lastMessage) { - return []; - } - - try { - const sanitizedJson = sanitizeJsonString(lastMessage.text); - const videoScripts: VideoScript[] = JSON.parse(sanitizedJson); - return videoScripts; - } catch { - return [ - { - title: 'Scene', - description: lastMessage.text, - }, - ]; - } - }, [messages]); - return ( <> @@ -94,9 +68,7 @@ const GenerateScriptView: React.FC = () => { - + diff --git a/frontend/src/bundles/common/constants/constants.ts b/frontend/src/bundles/common/constants/constants.ts index 12338b873..748eb8254 100644 --- a/frontend/src/bundles/common/constants/constants.ts +++ b/frontend/src/bundles/common/constants/constants.ts @@ -1,3 +1,3 @@ export { FPS } from './fps.constant.js'; export { SOCKET_TRANSPORT_WEBSOCKETS } from './socket-trasnport.constants.js'; -export { EMPTY_VALUE } from 'shared'; +export { EMPTY_VALUE, LAST_ELEMENT_INDEX } from 'shared'; diff --git a/shared/src/constants/constants.ts b/shared/src/constants/constants.ts index ca6a5b8f4..5d0e2a015 100644 --- a/shared/src/constants/constants.ts +++ b/shared/src/constants/constants.ts @@ -1 +1,2 @@ export { EMPTY_VALUE } from './empty-length.constant.js'; +export { LAST_ELEMENT_INDEX } from './last-element-index.constant.js'; diff --git a/shared/src/constants/last-element-index.constant.ts b/shared/src/constants/last-element-index.constant.ts new file mode 100644 index 000000000..357e39f66 --- /dev/null +++ b/shared/src/constants/last-element-index.constant.ts @@ -0,0 +1,3 @@ +const LAST_ELEMENT_INDEX = -1; + +export { LAST_ELEMENT_INDEX }; diff --git a/shared/src/index.ts b/shared/src/index.ts index c5397d697..f6c44e738 100644 --- a/shared/src/index.ts +++ b/shared/src/index.ts @@ -77,7 +77,7 @@ export { VideosApiPath, VideoValidationMessage, } from './bundles/videos/videos.js'; -export { EMPTY_VALUE } from './constants/constants.js'; +export { EMPTY_VALUE, LAST_ELEMENT_INDEX } from './constants/constants.js'; export { ApiPath, AppEnvironment,