diff --git a/app/api.tsx b/app/api.tsx index 5d04a78034..3851beab92 100644 --- a/app/api.tsx +++ b/app/api.tsx @@ -25,4 +25,9 @@ export const getMediaFileByToken = (fileToken: string) => `${apiHost}/v1/media_files/file/${fileToken}`; // Upload File -export const uploadMedia = `${apiHost}/v1/media_files/upload` \ No newline at end of file +export const uploadMedia = `${apiHost}/v1/media_files/upload`; + +// Scenes +export const uploadNewScene = `${apiHost}/v1/media_files/upload/new_scene`; +export const updateExistingScene = (sceneToken:string)=>`${apiHost}/v1/media_files/upload/saved_scene/${sceneToken}` +export const renameScene = (sceneToken:string)=>`${apiHost}/v1/media_files/rename/${sceneToken}` \ No newline at end of file diff --git a/app/contexts/EngineProvider.tsx b/app/contexts/EngineProvider.tsx index e8f07bdd56..b7b6e411d0 100644 --- a/app/contexts/EngineProvider.tsx +++ b/app/contexts/EngineProvider.tsx @@ -8,10 +8,12 @@ import { signalScene } from "~/store"; import Editor from "~/pages/PageEnigma/js/editor"; interface Props { + sceneToken?: string children: ReactNode; } export const EngineProvider = ({ + sceneToken, children, }: Props) => { const [editor, setEditor] = useState(null); @@ -35,6 +37,14 @@ export const EngineProvider = ({ // } }, [dispatchAppUiState, authState]); + useEffect(() => { + if (editor && editor.can_initialize) { + editor.initialize({ + sceneToken: sceneToken || ""} + ); + } + }, [editor, sceneToken]); + return ( {children} ); diff --git a/app/modules/TopBar/SceneTitleInput.tsx b/app/modules/TopBar/SceneTitleInput.tsx new file mode 100644 index 0000000000..b4e85e932f --- /dev/null +++ b/app/modules/TopBar/SceneTitleInput.tsx @@ -0,0 +1,86 @@ +import { useState, useContext } from 'react'; +import { twMerge } from 'tailwind-merge'; +import { useSignals } from "@preact/signals-react/runtime"; +import { AuthenticationContext } from "~/contexts/Authentication"; +import { faSpinnerThird } from '@fortawesome/pro-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +import { scene, signalScene } from "~/store"; +import { + showErrorDialog, + errorDialogMessage, + errorDialogTitle, +} from "~/pages/PageEnigma/store"; + +import { Input } from '~/components'; +import { renameScene } from './utilities'; + +export const SceneTitleInput = ()=>{ + useSignals(); + const { authState } = useContext(AuthenticationContext); + + const [{isValid, isSaving}, setState] = useState<{isValid:boolean; isSaving:boolean}>({isValid:true, isSaving:false}); + const setIsValid = (val:boolean)=>{ + setState((curr)=>({...curr, isValid:val})); + }; + const setIsSaving = (val:boolean)=>{ + setState((curr)=>({...curr, isSaving:val})); + }; + + const handleShowErrorDialog = () => { + errorDialogTitle.value = "Error"; + errorDialogMessage.value = "Scene name can not be empty."; + showErrorDialog.value = true; + }; + + const handleChangeSceneTitle = (e: React.ChangeEvent)=>{ + signalScene({ + ...scene.value, + title : e.target.value, + }); + if (scene.value.title !== "") { + setIsValid(true); + } + } + const validateSceneTitle = (e: React.FocusEvent)=>{ + if (scene.value.title === "") { + setIsValid(false); + handleShowErrorDialog(); + e.target.focus(); + }else if(scene.value.token && authState.sessionToken){ + setIsSaving(true); + renameScene( + scene.value.title!, //guarunteed by input + scene.value.token, + authState.sessionToken, + ).then((res)=>{ + // console.log(res); + //TODO: HANDLE ERROR + setIsSaving(false); + }); + } + }; + + return( +
+ + {isSaving && + + } +
+); +} \ No newline at end of file diff --git a/app/modules/TopBar/TopBar.tsx b/app/modules/TopBar/TopBar.tsx index 686fef35ab..8f20d38a33 100644 --- a/app/modules/TopBar/TopBar.tsx +++ b/app/modules/TopBar/TopBar.tsx @@ -1,17 +1,10 @@ -import { useState } from 'react'; -import { useLocation, useParams } from "@remix-run/react"; -import { useSignals } from "@preact/signals-react/runtime"; -import { faChevronLeft } from "@fortawesome/pro-solid-svg-icons"; -import { ButtonLink, Input } from "~/components"; -import { AuthButtons } from "./AuthButtons"; -import { scene } from "~/store"; -import { - showErrorDialog, - errorDialogMessage, - errorDialogTitle, -} from "~/pages/PageEnigma/store"; -import { MyMoviesButton } from "~/modules/TopBar/MyMoviesButton"; +import { useLocation, useParams } from "@remix-run/react"; +import { faChevronLeft } from "@fortawesome/pro-solid-svg-icons"; +import { ButtonLink } from "~/components"; +import { AuthButtons } from "./AuthButtons"; +import { SceneTitleInput } from "./SceneTitleInput"; +import { MyMoviesButton } from "~/modules/TopBar/MyMoviesButton"; import { getCurrentLocationWithoutParams } from '~/utilities'; function isEditorPath(path:string){ @@ -24,28 +17,8 @@ interface Props { } export const TopBar = ({ pageName }: Props) => { - useSignals(); const currentLocation = getCurrentLocationWithoutParams(useLocation().pathname, useParams()); - const [isValid, setIsValid] = useState(true); - const handleShowErrorDialog = () => { - errorDialogTitle.value = "Error"; - errorDialogMessage.value = "Scene name can not be empty."; - showErrorDialog.value = true; - }; - const handleChangeSceneTitle = (e: React.ChangeEvent)=>{ - scene.value.title = e.target.value; - if (scene.value.title !== "") { - setIsValid(true); - } - } - const validateSceneTitle = (e: React.FocusEvent)=>{ - if (scene.value.title === "") { - setIsValid(false); - handleShowErrorDialog(); - e.target.focus(); - } - }; return (