Fix scrubber position

This commit is contained in:
Christopher Oliphant committed 2024-04-14 10:03:23 -04:00
1 parent dcd5a54350
commit 326fe2c497
12 files changed
+141 -205

No files matched your search

+77 -73
View File
@@ -1,78 +1,81 @@
import { useEffect, useState } from 'react';
import { Transition } from '@headlessui/react';
import { twMerge } from 'tailwind-merge';
import { useEffect, useRef, useState } from "react";
import { Transition } from "@headlessui/react";
import { twMerge } from "tailwind-merge";
import { loadingBarData, loadingBarIsShowing } from "~/store/loadingBar";
import { useSignals } from "@preact/signals-react/runtime";
interface LoadingBarProps{
interface LoadingBarProps {
id?: string;
wrapperClassName?:string;
wrapperClassName?: string;
innerWrapperClassName?: string;
progressBackgroundClassName?: string;
progressClassName?: string;
label?: string;
progress?: number;
isShowing?: boolean;
variant?: string;
message?: string;
useFakeTimer?: number;
}
export const LoadingBar = ({
wrapperClassName : propsWrapperClassName,
wrapperClassName: propsWrapperClassName,
innerWrapperClassName: propsInnerWrapperClassName,
progressBackgroundClassName: propsProgressBackgroundClassName,
progressClassName : propsProgressClassName,
label,
progress: propsProgress = 0,
isShowing = true,
variant = 'primary',
message,
useFakeTimer,
progressClassName: propsProgressClassName,
variant = "primary",
...rest
}: LoadingBarProps) => {
const [progress, setProgress] = useState<number>(propsProgress);
useSignals();
const [progress, setProgress] = useState<number>(
loadingBarData.value.progress,
);
const [loop, setLoop] = useState<NodeJS.Timeout | null>(null);
// this takes the real progress coming from parent
useEffect(()=>{
setProgress(propsProgress);
}, [propsProgress]);
// this sets a fake progress, it goes to 96%
// in the amount of miliseconds provided by the flag
useEffect(()=>{
let loop: NodeJS.Timeout;
if(useFakeTimer){
if(useFakeTimer >= 30000){
// this math produce 96 cuts so the progress bar updates more
loop = setInterval(function step(){
setProgress((curr)=>{
if(curr<96){
return curr + 3
}else{
clearInterval(loop);
return curr;
}
})
},Math.round(useFakeTimer/96)*3);
}else{
// this math produce less cuts if useFakeTimer predicts
// a shorter load time, shorter thatn 30s
const progressPerInterval = useFakeTimer/500
loop = loop = setInterval(function step(){
setProgress((curr)=>{
if(curr + progressPerInterval < 96){
return curr + progressPerInterval
}else if (curr< 96 && curr + progressPerInterval >= 96){
return 96;
}else{
clearInterval(loop);
return curr;
}
})
}, 300);
}
const useFakeTimer = useRef(0);
if (useFakeTimer.current !== loadingBarData.value.useFakeTimer) {
useFakeTimer.current = loadingBarData.value.useFakeTimer;
if (loop) {
clearInterval(loop);
}
return () => clearInterval(loop);
}, []);
if (loadingBarData.value.useFakeTimer > 0) {
if (loadingBarData.value.useFakeTimer >= 30000) {
// this math produce 96 cuts so the progress bar updates more
setLoop(
setInterval(
function step() {
setProgress((curr) => {
if (curr < 96) {
return curr + 3;
} else {
clearInterval(loop!);
return curr;
}
});
},
Math.round(loadingBarData.value.useFakeTimer / 96) * 3,
),
);
}
// this math produce less cuts if useFakeTimer predicts
// a shorter load time, shorter than 30s
const progressPerInterval = loadingBarData.value.useFakeTimer / 500;
setLoop(
setInterval(function step() {
setProgress((curr) => {
if (curr + progressPerInterval < 96) {
return curr + progressPerInterval;
} else if (curr < 96 && curr + progressPerInterval >= 96) {
return 96;
} else {
clearInterval(loop!);
return curr;
}
});
}, 300),
);
}
}
const oldProgress = useRef(loadingBarData.value.progress);
if (oldProgress.current !== loadingBarData.value.progress) {
oldProgress.current = loadingBarData.value.progress;
setProgress(loadingBarData.value.progress);
}
function getVariantClassNames(variant: string) {
switch (variant) {
@@ -89,43 +92,44 @@ export const LoadingBar = ({
const wrapperClassName = twMerge(
"w-full h-full relative bg-ui-background",
propsWrapperClassName,
)
);
const innerWrapperClassName = twMerge(
"w-full h-full p-4 gap-4 m-auto flex flex-col justify-center items-center",
propsInnerWrapperClassName,
);
const progressBackgroundClassName = twMerge(
"w-full bg-gray-500 rounded-full h-2.5",
propsProgressBackgroundClassName
propsProgressBackgroundClassName,
);
const progressClassName = twMerge(
"h-2.5 rounded-full transition-all duration-1000",
getVariantClassNames(variant),
propsProgressClassName
propsProgressClassName,
);
return (
<Transition
className={wrapperClassName}
show={isShowing}
show={loadingBarIsShowing.value}
enter="transition-opacity duration-150"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity duration-1000"
leaveFrom="opacity-100"
leaveTo="opacity-0"
{...rest}
>
{...rest}>
<div className={innerWrapperClassName}>
{label && <label>{label}</label>}
{loadingBarData.value.label && (
<label>{loadingBarData.value.label}</label>
)}
<div className={progressBackgroundClassName}>
<div
className={progressClassName}
style={{width: progress + '%'}}
<div
className={progressClassName}
style={{ width: progress + "%" }}
/>
</div>
{message && <p>{message}</p>}
{loadingBarData.value.message && <p>{loadingBarData.value.message}</p>}
</div>
</Transition>
);
}
};
+1 -10
View File
@@ -1,6 +1,6 @@
import React, { useContext } from "react";
import { LoadingBar, LoadingDots } from "~/components";
import { LoadingDots } from "~/components";
import { SidePanel } from "~/modules/SidePanel";
import { Controls3D } from "./comps/Controls3D";
@@ -109,15 +109,6 @@ export const PageEditor = ({ setPage }: Props) => {
type="bricks"
message={appUiState.showEditorLoader.message}
/>
<LoadingBar
id="editor-loading-bar"
wrapperClassName="absolute top-0 left-0"
innerWrapperClassName="max-w-screen-sm"
isShowing={appUiState.showEditorLoadingBar.isShowing}
message={appUiState.showEditorLoadingBar.message}
label={appUiState.showEditorLoadingBar.label}
progress={appUiState.showEditorLoadingBar.progress}
/>
</div>
</div>
{/* Side panel */}
+7
View File
@@ -3,6 +3,8 @@ import { TrackProvider } from "~/pages/PageEnigma/contexts/TrackContext/TrackPro
import { DragComponent } from "~/pages/PageEnigma/comps/DragComponent/DragComponent";
import { EngineProvider } from "~/contexts/EngineProvider";
import { useInferenceJobManager } from "~/hooks";
import { LoadingBar } from "~/components";
export const PageEnigma = () => {
useInferenceJobManager();
return (
@@ -11,6 +13,11 @@ export const PageEnigma = () => {
<PageEnigmaComponent />
<DragComponent />
</EngineProvider>
<LoadingBar
id="editor-loading-bar"
wrapperClassName="absolute top-0 left-0"
innerWrapperClassName="max-w-screen-sm"
/>
</TrackProvider>
);
};
+21 -20
View File
@@ -5,7 +5,7 @@ import {
faArrowsRotate,
faFilm,
} from "@fortawesome/pro-solid-svg-icons";
import { Button, LoadingBar } from "~/components";
import { Button } from "~/components";
import { StyleSelection } from "~/pages/PageEnigma/comps/StyleSelection";
import { TimerGrid } from "~/pages/PageEnigma/comps/Timeline/TimerGrid";
import { Scrubber } from "~/pages/PageEnigma/comps/Timeline/Scrubber";
@@ -17,20 +17,22 @@ import {
currentTime,
filmLength,
scale,
timelineHeight,
timelineScrollX,
} from "~/pages/PageEnigma/store";
import Queue from "~/pages/PageEnigma/Queue/Queue";
import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames";
import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions";
import { pageWidth } from "~/store";
import { RowHeaders } from "~/pages/PageEnigma/comps/Timeline/RowHeaders";
interface Props {
setPage: (page: string) => void;
}
import { AppUiContext } from "~/contexts/AppUiContext";
export const PageStyling = ({ setPage }: Props) => {
useSignals();
const editorEngine = useContext(EngineContext);
const [appUiState] = useContext(AppUiContext);
const generateFrame = async () => {
await editorEngine?.generateFrame();
@@ -52,6 +54,7 @@ export const PageStyling = ({ setPage }: Props) => {
const onTimelineClick = useCallback(
(event: React.PointerEvent<HTMLDivElement>) => {
if (event.button === 0) {
console.log("click", event.clientX, event.pageX, timelineScrollX.value);
const newTime = Math.round(
(event.clientX + timelineScrollX.value - 92) / 4 / scale.value,
);
@@ -62,7 +65,7 @@ export const PageStyling = ({ setPage }: Props) => {
Queue.publish({
queueName: QueueNames.TO_ENGINE,
action: toEngineActions.UPDATE_TIME,
data: { currentTime: Math.round(newTime) },
data: { currentTime: newTime },
});
}
},
@@ -97,30 +100,28 @@ export const PageStyling = ({ setPage }: Props) => {
</div>
</div>
</div>
<div className="fixed bottom-0 left-0 w-full">
<div className="relative flex h-[80px] w-full gap-5 border-t border-t-action-600 bg-ui-panel">
<div className="w-screen overflow-x-auto" onScroll={onScroll}>
<div
className="fixed bottom-0 left-0 w-full border-t border-t-action-600 bg-ui-panel"
onClick={onTimelineClick}>
<TimerGrid />
<div className="flex w-full ">
<div className="block h-[30px] w-[88px]" />
<div
className="h-[30px] overflow-x-auto overflow-y-hidden"
onScroll={onScroll}
style={{
width: pageWidth.value,
}}>
<div
style={{
width: filmLength.value * 60 * 4 * scale.value,
width: filmLength.value * 60 * 4 * scale.value + 90,
height: 60,
}}
onClick={onTimelineClick}>
<TimerGrid />
}}>
<Scrubber />
</div>
</div>
</div>
</div>
<LoadingBar
id="editor-loading-bar"
wrapperClassName="absolute top-0 left-0"
innerWrapperClassName="max-w-screen-sm"
isShowing={appUiState.showEditorLoadingBar.isShowing}
message={appUiState.showEditorLoadingBar.message}
label={appUiState.showEditorLoadingBar.label}
progress={appUiState.showEditorLoadingBar.progress}
/>
</div>
);
};
@@ -14,11 +14,10 @@ export const Scrubber = () => {
const { onPointerDown, time } = useMouseEventsScrubber();
const displayTime = time === -1 ? currentTime.value : time;
if (displayTime * 4 * scale.value + 84 - timelineScrollX.value < 84) {
if (displayTime * 4 * scale.value - timelineScrollX.value < 0) {
return null;
}
console.log(currentTime.value, displayTime, timelineScrollX.value);
return (
<div
className="absolute flex cursor-ew-resize flex-col items-center text-brand-primary"
@@ -92,8 +92,7 @@ export const Timeline = () => {
style={{
width: 88,
height: timelineHeight.value - 54,
}}
>
}}>
<RowHeaders />
</div>
<div
@@ -102,11 +101,9 @@ export const Timeline = () => {
style={{
width: pageWidth.value - 90,
height: timelineHeight.value - 54,
}}
>
}}>
<div
style={{ width: filmLength.value * 60 * 4 * scale.value + 32 }}
>
style={{ width: filmLength.value * 60 * 4 * scale.value + 32 }}>
<Characters />
<div className="pb-4 pr-8">
<Camera />
@@ -36,6 +36,7 @@ export const useMouseEventsScrubber = () => {
(event.clientX - clientX) / 4 / scale.value + currentTime.value,
);
if (isActive) {
console.log("1111");
event.stopPropagation();
event.preventDefault();
if (delta < 0 || delta > max) {
+14 -28
View File
@@ -31,7 +31,7 @@ import Queue from "~/pages/PageEnigma/Queue/Queue";
import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames";
import { fromEngineActions } from "~/pages/PageEnigma/Queue/fromEngineActions";
import { AssetType, MediaItem } from "~/pages/PageEnigma/models";
import { LoadingBar } from "~/components";
import { loadingBarData, loadingBarIsShowing } from "~/store/loadingBar";
// Main editor class that will call everything else all you need to call is " initialize() ".
class Editor {
@@ -362,18 +362,11 @@ class Editor {
this.loadScene(sceneToken);
}
this.dispatchAppUiState({
type: APPUI_ACTION_TYPES.UPDATE_EDITOR_LOADINGBAR,
payload: {
showEditorLoadingBar: {
progress: 100,
},
},
});
this.dispatchAppUiState({
type: APPUI_ACTION_TYPES.HIDE_EDITOR_LOADINGBAR,
});
loadingBarData.value = {
...loadingBarData.value,
progress: 100,
};
loadingBarIsShowing.value = false;
}
// Token comes in from the front end to load the scene from the site.
@@ -565,27 +558,20 @@ class Editor {
}
async showLoading() {
this.dispatchAppUiState({
type: APPUI_ACTION_TYPES.SHOW_EDITOR_LOADINGBAR,
});
loadingBarIsShowing.value = true;
}
async updateLoad(progress: number, message: string) {
this.dispatchAppUiState({
type: APPUI_ACTION_TYPES.UPDATE_EDITOR_LOADINGBAR,
payload: {
showEditorLoadingBar: {
progress: progress,
message: message,
},
},
});
loadingBarData.value = {
...loadingBarData.value,
progress: progress,
message: message,
};
}
async endLoading() {
this.dispatchAppUiState({
type: APPUI_ACTION_TYPES.HIDE_EDITOR_LOADINGBAR,
});
console.log("stop loading");
loadingBarIsShowing.value = false;
}
async _test_demo() {
-27
View File
@@ -64,33 +64,6 @@ export function reducer(state: State, action: Action): State {
},
};
}
case ACTION_TYPES.SHOW_EDITOR_LOADINGBAR: {
return {
...state,
showEditorLoadingBar: {
...action.payload?.showEditorLoadingBar,
isShowing: true,
},
};
}
case ACTION_TYPES.UPDATE_EDITOR_LOADINGBAR: {
return {
...state,
showEditorLoadingBar: {
...state.showEditorLoadingBar,
...action.payload?.showEditorLoadingBar,
},
};
}
case ACTION_TYPES.HIDE_EDITOR_LOADINGBAR: {
return {
...state,
showEditorLoadingBar: {
...state.showEditorLoadingBar,
isShowing: false,
},
};
}
case ACTION_TYPES.ON_TIMELINE_RESIZE: {
return {
...state,
+1 -33
View File
@@ -26,17 +26,10 @@ export type State = {
isShowing: boolean;
message?: string;
};
showEditorLoadingBar: {
isShowing: boolean;
label?: string;
message?: string;
progress?: number;
useFakeTimer?: number;
};
controlPanel: ControlPanel;
diagloueTts: {
isOpen: boolean;
}
};
};
export enum ACTION_TYPES {
@@ -44,9 +37,6 @@ export enum ACTION_TYPES {
ON_CHANGE_VIEW_MODE = "on_change_view_mode",
SHOW_EDITOR_LOADER = "show_editor_loader",
HIDE_EDITOR_LOADER = "hide_editor_loader",
SHOW_EDITOR_LOADINGBAR = "show_editor_loadingbar",
UPDATE_EDITOR_LOADINGBAR = "update_editor_loadingbar",
HIDE_EDITOR_LOADINGBAR = "hide_editor_loadingbar",
SHOW_CONTROLPANELS_SCENEOBJECT = "show_controlpanels_sceneobject",
UPDATE_CONTROLPANELS_SCENEOBJECT = "update_controlpanels_sceneobject",
HIDE_CONTROLPANELS_SCENEOBJECT = "hide_controlpanels_sceneobject",
@@ -75,28 +65,6 @@ export type Action =
};
};
}
| { type: ACTION_TYPES.HIDE_EDITOR_LOADINGBAR }
| {
type: ACTION_TYPES.SHOW_EDITOR_LOADINGBAR;
payload?: {
showEditorLoadingBar: {
label?: string;
message?: string;
progress?: number;
useFakeTimer?: number;
};
};
}
| {
type: ACTION_TYPES.UPDATE_EDITOR_LOADINGBAR;
payload: {
showEditorLoadingBar: {
label?: string;
message?: string;
progress?: number;
};
};
}
| {
type: ACTION_TYPES.ON_TIMELINE_RESIZE;
payload: {
+1 -6
View File
@@ -8,11 +8,6 @@ export const initialStateValues: State = {
isShowing: false,
message: "Loading Editor Engine 🦊",
},
showEditorLoadingBar: {
isShowing: true,
progress: 5,
message: "Loading Editor Engine 🦊",
},
controlPanel: {
isShowing: false,
currentSceneObject: {
@@ -27,5 +22,5 @@ export const initialStateValues: State = {
},
},
},
diagloueTts:{isOpen:false}
diagloueTts: { isOpen: false },
};
+14
View File
@@ -0,0 +1,14 @@
import { signal } from "@preact/signals-core";
export const loadingBarIsShowing = signal(true);
export const loadingBarData = signal<{
label: string;
message: string;
progress: number;
useFakeTimer: number;
}>({
label: "",
progress: 5,
message: "Loading Editor Engine 🦊",
useFakeTimer: 0,
});