diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 4956279b61..16955dec9e 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -12,11 +12,16 @@ export const Button = ({ icon, children, className: propsClassName, - variant = "primary", + variant: propsVariant = "primary", + disabled, ...rest }: ButtonPropsI) => { + const variant = disabled ? 'disabled' : propsVariant; function getVariantClassNames(variant: string) { switch (variant) { + case "disabled":{ + return "bg-brand-secondary-500 text-brand-secondary-300" + } case "secondary": { return " bg-brand-secondary hover:bg-brand-secondary-900 text-white focus-visible:outline-brand-secondary"; } @@ -34,7 +39,7 @@ export const Button = ({ ); return ( - diff --git a/app/components/ItemPicker.tsx b/app/components/ItemPicker.tsx index a0949916ec..8e80dd2742 100644 --- a/app/components/ItemPicker.tsx +++ b/app/components/ItemPicker.tsx @@ -25,7 +25,7 @@ export const ItemPicker = ({ onClick={handleSelected} > -
+

{label}

) diff --git a/app/components/LoadingBar.tsx b/app/components/LoadingBar.tsx new file mode 100644 index 0000000000..90a112df5c --- /dev/null +++ b/app/components/LoadingBar.tsx @@ -0,0 +1,54 @@ +import { twMerge } from 'tailwind-merge'; +import { H4 } from '.'; + +interface LoadingBarProps{ + label?: string; + progress?: number; + variant?: string; + message?: string; + wrapperClassName?: string; + useFakeTimer?: number; +} +export const LoadingBar = ({ + label, + progress = 0, + variant = 'primary', + message, + wrapperClassName : propsWrapperClassName, + useFakeTimer = (1000 * 60) //defaults to 1min +}: LoadingBarProps) => { + + function getVariantClassNames(variant: string) { + switch (variant) { + case "secondary": { + return " bg-brand-secondary text-white "; + } + case "primary": + default: { + return " bg-brand-primary text-white "; + } + } + } + + const wrapperClassName = twMerge( + "w-full h-full flex flex-col justify-center items-center bg-ui-background p-4 gap-4", + propsWrapperClassName, + ) + const progressClassName = twMerge( + "h-2.5 rounded-full transition-all duration-1000", + getVariantClassNames(variant), + ); + + return ( +
+ {label && } +
+
+
+ {message &&

{message}

} +
+ ); +} \ No newline at end of file diff --git a/app/components/LoadingDots.tsx b/app/components/LoadingDots.tsx index 4d622587ba..23caa8ab95 100644 --- a/app/components/LoadingDots.tsx +++ b/app/components/LoadingDots.tsx @@ -55,6 +55,11 @@ function LoadingDots({ } else { setState('completed'); } + }else{ + setState((curr) => { + if (curr!=='loading') return 'loading'; + else return curr; + }); } }, [show, transition]); diff --git a/app/components/index.tsx b/app/components/index.tsx index 28c7eb3efc..2065c8c20c 100644 --- a/app/components/index.tsx +++ b/app/components/index.tsx @@ -6,6 +6,7 @@ import { Input } from "./Input"; import { H4 } from "./H4"; import { ItemPicker } from "./ItemPicker"; import { Textarea } from "./Textarea"; +import { LoadingBar } from "./LoadingBar"; import { LoadingDotsBricks, LoadingDotsTyping } from "./LoadingDots"; export { @@ -17,6 +18,7 @@ export { ItemPicker, Textarea, Input, + LoadingBar, LoadingDotsBricks, LoadingDotsTyping, }; diff --git a/app/modules/Tabs/Tabs.tsx b/app/modules/Tabs/Tabs.tsx index 321d038e04..3a83dfbd65 100644 --- a/app/modules/Tabs/Tabs.tsx +++ b/app/modules/Tabs/Tabs.tsx @@ -20,7 +20,7 @@ export const Tabs = ({ tabs: tabProps }: { tabs: TabType[] }) => { return (
- + {tabs.map((tab, idx) => ( { const [appUiState, dispatchAppUiState] = useReducer(reducer, initialState); - - const canvasRef = useRef(null); + useEffect(()=>{ setTimeout(()=>dispatchAppUiState({ type: ACTION_TYPES.HIDE_EDITOR_LOADER }), 3000); },[]); + return (
- - + +
{/* Engine section/side panel */}
{
{ {/* Timeline */}
- - + +
); }; diff --git a/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx b/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx index 65af5650f3..39082ebb35 100644 --- a/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx +++ b/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx @@ -6,16 +6,22 @@ import { EngineContext } from "../../contexts/EngineContext"; export const ControlsTopButtons = () => { const editorEngine = useContext(EngineContext); const [sceneName, setSceneName] = useState(""); + const [sceneToken, setSceneToken] = useState(""); const handleButtonSave = () => { console.log(`SceneName is ${sceneName}`); - // editorEngine?.save(); + editorEngine?.save(); }; - const handleButtonCameraView = () => { - editorEngine?.change_camera_view(); + const handleButtonLoadScene = () => { + console.log(`Scene Token is ${sceneToken}`); + // editorEngine?.dosomething(); }; + // const handleButtonCameraView = () => { + // editorEngine?.change_camera_view(); + // }; + const handleButtonPlayBack = () => { editorEngine?.start_playback(); }; @@ -24,16 +30,31 @@ export const ControlsTopButtons = () => { }; const handleButtonRender = () => { console.log("Saving GLB to server for reference"); - editorEngine._upload_for_testing(); + editorEngine?._upload_for_testing(); //editorEngine?.togglePlayback(); }; const handleButtonPlay = () => {}; return ( -
- +
+
+ + {setSceneToken(e.target.value)}} + /> + { onClick: handleButtonSave, }} > - + {setSceneName(e.target.value)}} + /> - -

Do you need help?

-

Ask Michael about this project

-

Ask Miles about ThreeJS

-

Ask Wil about React

-
+ +

Do you need help?

+

Ask Michael about this project

+

Ask Miles about ThreeJS

+

Ask Wil about React

+
+
-
+
+ +
+
diff --git a/app/pages/PageEnigma/contexts/EngineProvider.tsx b/app/pages/PageEnigma/contexts/EngineProvider.tsx index 7f40dc4976..c10b04eb6e 100644 --- a/app/pages/PageEnigma/contexts/EngineProvider.tsx +++ b/app/pages/PageEnigma/contexts/EngineProvider.tsx @@ -1,30 +1,49 @@ -import { ReactNode, useEffect, useRef, useState } from "react"; -import { EngineContext } from "./EngineContext"; +import { ReactNode, useContext, useEffect, useState } from "react"; + import Editor from "~/pages/PageEnigma/js/editor"; +import { EngineContext } from "./EngineContext"; +import { AppUiContext } from "./AppUiContext"; + + interface Props { children: ReactNode; } export const EngineProvider = ({ children }: Props) => { const [editor, setEditor] = useState(null); + const [appUiState, dispatchAppUiState] = useContext(AppUiContext); useEffect(() => { //componentDidMount - if (editor !== null) { - console.warn("Editor Engine already exist"); - } else if (document.getElementById("video-scene") === null) { + if (document.getElementById("video-scene") === null) { console.error( - 'Editor Engine need a target cavas with the id "video-scene"', + 'Editor Engine need a target canvas with the id "video-scene"', ); - } else { - const editor = new Editor(); - editor.initialize(); - setEditor(editor); + } else { + setEditor((curr)=>{ + if(curr!==null){ + console.warn("Editor Engine already exist"); + return curr; + }else{ + return new Editor(); + } + }); } }, []); + useEffect(()=>{ + if (editor && editor.can_initailize && dispatchAppUiState!==null){ + console.log("initializing Editor"); + editor.initialize({ + dispatchAppUiState + }); + } + }, [editor, dispatchAppUiState]); + return ( - {children} + + {children} + ); }; diff --git a/app/pages/PageEnigma/js/editor.js b/app/pages/PageEnigma/js/editor.js index c8b2b04515..055eff14a6 100644 --- a/app/pages/PageEnigma/js/editor.js +++ b/app/pages/PageEnigma/js/editor.js @@ -22,6 +22,7 @@ import { LipSync } from "./lipsync.js"; import { LipSyncEngine } from "./lip_sync_engine.ts"; import { AnimationEngine } from "./animation_engine.ts"; import { faL } from "@fortawesome/pro-solid-svg-icons"; +import { ACTION_TYPES } from "../reducer"; if (typeof window !== "undefined") { import("ccapture.js") @@ -114,13 +115,23 @@ class Editor { this.test_box_uuid = null; this.current_frame = 0; this.test_playback = false; + + //Reactland Callbacks + this.dispatchAppUiState = null; } // Initializes the main scene and ThreeJS essentials. - initialize() { + /* + config :{ + dispatchAppUiState: dispatch function to react app + } + */ + initialize(config) { if (this.can_initailize == false) { return; } + this.can_initailize == false; + // Gets the canvas. this.canvReference = document.getElementById("video-scene"); // Base width and height. @@ -164,6 +175,8 @@ class Editor { this.timeline.scene = this.activeScene; + //setup reactland Callbacks + this.dispatchAppUiState = config.dispatchAppUiState this._test_demo() } @@ -377,6 +390,15 @@ class Editor { //this.audio_engine.playClip("m_f7jnwt3d1ddchatdk5vaqt0n4mb1hg"); //console.log(this.selected); + this.dispatchAppUiState({ + type: ACTION_TYPES.SHOW_EDITOR_LOADER + }); + + + // this.dispatchAppUiState({ + // type: ACTION_TYPES.HIDE_EDITOR_LOADER + // }); + if (this.selected == null) { return; } diff --git a/app/routes/ComponentLibrary.tsx b/app/routes/ComponentLibrary.tsx index 41bbfb7f8d..acc2188c52 100644 --- a/app/routes/ComponentLibrary.tsx +++ b/app/routes/ComponentLibrary.tsx @@ -1,11 +1,72 @@ -import { Button } from "~/components/Button"; -import { ButtonLink } from "~/components/ButtonLink"; +import { useState, useEffect } from "react"; +import { + Button, + ButtonLink, + H4, + LoadingBar, + LoadingDotsTyping, + LoadingDotsBricks, +} from "~/components"; + export default function ComponentLibrary () { + const [progress, setProgress] = useState(0); + useEffect(()=>{ + if(progress === 0){ + const loop = setInterval(function timer(){ + setProgress((curr)=>{ + if (curr < 100){ + return curr+10; + }else{ + clearTimeout(loop); + return curr; + } + })} + , 3000); + } + }, [progress]); + return( - <> - - Button with Link - +
+ +
+

Buttons

+
+ + + +
+
+ +
+

ButtonLink

+ Back to / +
+ +
+

Loading Dots

+
+
+ +
+
+ +
+
+
+ +
+

Loading Bar

+
+ + +
+ +
+
); }; \ No newline at end of file