diff --git a/app/modules/LowerPanel/LowerPanel.tsx b/app/modules/LowerPanel/LowerPanel.tsx index 966cd1715d..2a9d5e147b 100644 --- a/app/modules/LowerPanel/LowerPanel.tsx +++ b/app/modules/LowerPanel/LowerPanel.tsx @@ -1,10 +1,6 @@ import React from "react"; import { useMouseEventsTimeline } from "~/pages/PageEnigma/comps/Timeline/utils/useMouseEventsTimeline"; -import { - dndTimelineHeight, - overTimeline, - timelineHeight, -} from "~/pages/PageEnigma/store"; +import { dndTimelineHeight, timelineHeight } from "~/pages/PageEnigma/store"; import useTimelineClick from "~/pages/PageEnigma/comps/Timeline/utils/useTimelineClick"; import { Pages } from "~/pages/PageEnigma/constants/page"; @@ -25,17 +21,13 @@ export const LowerPanel = ({ children }: LowerPanelPropsI) => { return ( <>
{ - overTimeline.value = true; - }} - onPointerLeave={() => (overTimeline.value = false)} onClick={onTimelineClick}> {children}
diff --git a/app/pages/PageEnigma/DragAndDrop/DndAsset.ts b/app/pages/PageEnigma/DragAndDrop/DndAsset.ts new file mode 100644 index 0000000000..5d4e0a42ac --- /dev/null +++ b/app/pages/PageEnigma/DragAndDrop/DndAsset.ts @@ -0,0 +1,139 @@ +import React from "react"; +import { AssetType, MediaItem } from "~/pages/PageEnigma/models"; +import { + addCharacter, + addCharacterAnimation, + addCharacterAudio, + addGlobalAudio, + addObject, + canDrop, + currPosition, + dragItem, + overTimeline, + timelineHeight, +} from "~/pages/PageEnigma/store"; +import { pageHeight } from "~/store"; +import { addShape } from "~/pages/PageEnigma/store/shape"; + +class DndAsset { + public dropId: string = ""; + public overElement: DOMRect | null = null; + public dropOffset = 0; + public initX = 0; + public initY = 0; + public notDropText = ""; + + constructor() { + this.onPointerMove = this.onPointerMove.bind(this); + this.onPointerUp = this.onPointerUp.bind(this); + } + + onPointerDown(event: React.PointerEvent, item: MediaItem) { + if (event.button === 0) { + dragItem.value = item; + currPosition.value = { + currX: event.pageX, + currY: event.pageY, + }; + this.initX = event.pageX; + this.initY = event.pageY; + canDrop.value = false; + this.notDropText = ""; + window.addEventListener("pointerup", this.onPointerUp); + window.addEventListener("pointermove", this.onPointerMove); + } + } + + endDrag() { + if (dragItem.value) { + dragItem.value = null; + canDrop.value = false; + this.overElement = null; + overTimeline.value = false; + this.notDropText = ""; + } + } + + onPointerUp() { + window.removeEventListener("pointerup", this.onPointerUp); + window.removeEventListener("pointermove", this.onPointerMove); + if (!canDrop.value) { + this.endDrag(); + return; + } + + if (dragItem.value) { + const mediaItem = dragItem.value; + if (mediaItem.type === AssetType.CHARACTER) { + addCharacter(dragItem.value); + } + // if (dragItem.value.type === AssetType.CAMERA) { + // console.log("Dragged In Camera Type") + // } + if (dragItem.value.type === AssetType.OBJECT) { + addObject(dragItem.value); + } + + if (dragItem.value.type === AssetType.SHAPE) { + addShape(dragItem.value); + } + } + + if (canDrop.value && dragItem.value) { + if (dragItem.value.type === AssetType.ANIMATION) { + addCharacterAnimation({ + dragItem: dragItem.value, + characterId: this.dropId, + offset: this.dropOffset, + }); + } + if (dragItem.value.type === AssetType.AUDIO) { + addCharacterAudio({ + dragItem: dragItem.value, + characterId: this.dropId, + offset: this.dropOffset, + }); + addGlobalAudio({ + dragItem: dragItem.value, + audioId: this.dropId, + offset: this.dropOffset, + }); + } + } + this.endDrag(); + } + + onPointerMove(event: MouseEvent) { + if (dragItem.value) { + event.stopPropagation(); + event.preventDefault(); + const deltaX = event.pageX - this.initX; + const deltaY = event.pageY - this.initY; + currPosition.value = { + currX: this.initX + deltaX, + currY: this.initY + deltaY, + }; + overTimeline.value = + event.pageY > pageHeight.value - timelineHeight.value; + if (this.overElement) { + const pos = this.overElement; + const eventY = event.pageY; + const inHeight = eventY >= pos.top && eventY <= pos.top + pos.height; + const eventX = event.pageX; + const inWidth = eventX >= pos.left && eventX <= pos.left + pos.width; + + if (inHeight && inWidth) { + return; + } + canDrop.value = false; + this.dropId = ""; + this.overElement = null; + this.notDropText = ""; + } + } + } +} + +const dragAndDrop = new DndAsset(); + +export default dragAndDrop; diff --git a/app/pages/PageEnigma/PageEditor.tsx b/app/pages/PageEnigma/PageEditor.tsx index f1ffcd3abb..6cef9c1438 100644 --- a/app/pages/PageEnigma/PageEditor.tsx +++ b/app/pages/PageEnigma/PageEditor.tsx @@ -18,15 +18,19 @@ import { sidePanelVisible, dndSidePanelWidth, dndTimelineHeight, - dragItem, canDrop, + dragItem, } from "~/pages/PageEnigma/store"; import { useSignals } from "@preact/signals-react/runtime"; import { AppUiContext } from "~/contexts/AppUiContext"; import { pageHeight, pageWidth } from "~/store"; import { TopBar } from "~/modules/TopBar"; import { AssetType } from "./models/assets"; -import { editorState, EditorStates, previewSrc } from "~/pages/PageEnigma/store/engine"; +import { + editorState, + EditorStates, + previewSrc, +} from "~/pages/PageEnigma/store/engine"; export const PageEditor = () => { useSignals(); @@ -105,13 +109,18 @@ export const PageEditor = () => { }} /> {editorState.value === EditorStates.PREVIEW && ( - + )}
diff --git a/app/pages/PageEnigma/comps/DragComponent/DragComponent.tsx b/app/pages/PageEnigma/comps/DragComponent/DragComponent.tsx index bde6aa8bee..b83ad85ae7 100644 --- a/app/pages/PageEnigma/comps/DragComponent/DragComponent.tsx +++ b/app/pages/PageEnigma/comps/DragComponent/DragComponent.tsx @@ -4,66 +4,105 @@ import { dragItem, overTimeline, scale, + timelineHeight, } from "~/pages/PageEnigma/store"; import { useSignals } from "@preact/signals-react/runtime"; import "./DragComponent.scss"; +import DndAsset from "~/pages/PageEnigma/DragAndDrop/DndAsset"; export const DragComponent = () => { useSignals(); - const { currX, currY } = currPosition.value; - if (!dragItem.value) { return null; } + const { currX, currY } = currPosition.value; const thumbnail = dragItem.value.thumbnail ? dragItem.value.thumbnail : `/resources/images/default-covers/${dragItem.value.imageIndex}.webp`; - return ( - <> - {overTimeline.value ? ( -
- ) : ( -
- +
- {dragItem.value.name || dragItem.value.media_id} -
-
- )} - + id={`ani-dnd-${dragItem.value.media_id}`} + className={[ + "absolute p-2", + "rounded opacity-60", + "bg-dnd-timeGrid border-2-dnd-timeGridBorder border", + ].join(" ")} + style={{ + bottom: timelineHeight.value - 60, + left: currX + 1, + zIndex: 10000, + width: (dragItem.value.length ?? 0) * 4 * scale.value, + height: 16, + }} + /> + + ); + } + return ( +
+ {DndAsset.notDropText || "Cannot drop here"} +
+ ); + } + + return ( +
+ {dragItem.value.name} +
+ {dragItem.value.name || dragItem.value.media_id} +
+
); }; diff --git a/app/pages/PageEnigma/comps/GenerateModals/GenerateModals.tsx b/app/pages/PageEnigma/comps/GenerateModals/GenerateModals.tsx index ee4f57cf1f..cb6b6cea10 100644 --- a/app/pages/PageEnigma/comps/GenerateModals/GenerateModals.tsx +++ b/app/pages/PageEnigma/comps/GenerateModals/GenerateModals.tsx @@ -13,8 +13,6 @@ export function GenerateModals() { const [mediaFile, setMediaFile] = useState(null); const { addToast } = useContext(ToasterContext); - console.log(1, mediaFile); - useEffect(() => { if (!mediaFile) { setMovieId(""); diff --git a/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElement.tsx b/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElement.tsx index 2c98881a41..5d8ead6764 100644 --- a/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElement.tsx +++ b/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElement.tsx @@ -1,26 +1,18 @@ -import { useCallback, useContext, useEffect } from "react"; import { useSignals } from "@preact/signals-react/runtime"; -import { WaveformPlayer } from "~/components"; +import { WaveformPlayer, H5, H6 } from "~/components"; import { AudioMediaItem } from "~/pages/PageEnigma/models"; -import { TrackContext } from "~/pages/PageEnigma/contexts/TrackContext/TrackContext"; -import { - canDrop, - currPosition, - dragItem, - initPosition, -} from "~/pages/PageEnigma/store"; -import { H5, H6 } from "~/components"; -import { AudioTypePill } from "./audioTypePills" +import { AudioTypePill } from "./audioTypePills"; import { cancelNewFromAudioItem, updateAudioItemLength, updateDemoAudioItemLength, } from "~/pages/PageEnigma/store"; +import DndAsset from "~/pages/PageEnigma/DragAndDrop/DndAsset"; function getGcsUrl(bucketRelativePath: string | undefined | null): string { - let bucket = "vocodes-public"; + const bucket = "vocodes-public"; let path = bucketRelativePath; if (path !== undefined && path !== null && !path.startsWith("/")) { path = "/" + path; @@ -34,61 +26,16 @@ interface Props { export const AudioItemElement = ({ item }: Props) => { useSignals(); - const { startDrag, endDrag } = useContext(TrackContext); - - const { initX, initY } = initPosition.value; - - useEffect(() => { - const onPointerUp = () => { - if (dragItem.value) { - endDrag(); - } - }; - - const onMouseMove = (event: MouseEvent) => { - if (dragItem.value) { - event.stopPropagation(); - event.preventDefault(); - const deltaX = event.pageX - initX; - const deltaY = event.pageY - initY; - currPosition.value = { currX: initX + deltaX, currY: initY + deltaY }; - } - }; - - window.addEventListener("pointerup", onPointerUp); - window.addEventListener("pointermove", onMouseMove); - - return () => { - window.removeEventListener("pointerup", onPointerUp); - window.removeEventListener("pointermove", onMouseMove); - }; - }, [startDrag, endDrag, initX, initY]); - - const onPointerDown = useCallback( - (event: React.PointerEvent) => { - if(item.isNew) { - cancelNewFromAudioItem(item.media_id); - } - if (event.button === 0) { - startDrag(item); - currPosition.value = { - currX: event.pageX, - currY: event.pageY, - }; - initPosition.value = { - initX: event.pageX, - initY: event.pageY, - }; - canDrop.value = false; - } - }, - [item, startDrag], - ); return (
+ onPointerDown={(event) => { + if (item.isNew) { + cancelNewFromAudioItem(item.media_id); + } + DndAsset.onPointerDown(event, item); + }}>
@@ -100,18 +47,18 @@ export const AudioItemElement = ({ item }: Props) => { { - // only do this for items that doesn't have a length - if(item.category === "demo"){ - updateDemoAudioItemLength(item.media_id, duration * 60); - } - else{ - updateAudioItemLength(item.media_id, duration * 60); - } - } - } + onLoad={ + item.length + ? undefined + : ({ duration }) => { + // only do this for items that doesn't have a length + if (item.category === "demo") { + updateDemoAudioItemLength(item.media_id, duration * 60); + } else { + updateAudioItemLength(item.media_id, duration * 60); + } + } + } /> )} diff --git a/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElements.tsx b/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElements.tsx index 6ad775e679..74dcbd4302 100644 --- a/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElements.tsx +++ b/app/pages/PageEnigma/comps/SidePanelTabs/AudioTab/audioItemElements.tsx @@ -1,4 +1,3 @@ - import { useSignals } from "@preact/signals-react/runtime"; import { isRetreivingAudioItems } from "~/pages/PageEnigma/store"; import { AudioItemElement } from "./audioItemElement"; @@ -13,26 +12,21 @@ interface Props { items: AudioMediaItem[]; } -export const AudioItemElements = ({ - currentPage, - pageSize, - items, -}: Props) => { +export const AudioItemElements = ({ currentPage, pageSize, items }: Props) => { useSignals(); return (
- {isRetreivingAudioItems.value && -
- + {isRetreivingAudioItems.value && ( +
+
Retreiving New Audio Items
- } + )} {items - .slice(currentPage*pageSize, (currentPage+1)*pageSize) + .slice(currentPage * pageSize, (currentPage + 1) * pageSize) .map((item) => ( - )) - } + ))}
); }; diff --git a/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ItemElement.tsx b/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ItemElement.tsx index b076321cff..8a1c9101b5 100644 --- a/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ItemElement.tsx +++ b/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ItemElement.tsx @@ -1,13 +1,6 @@ -import { useCallback, useContext, useEffect } from "react"; import { MediaItem } from "~/pages/PageEnigma/models"; -import { TrackContext } from "~/pages/PageEnigma/contexts/TrackContext/TrackContext"; -import { - canDrop, - currPosition, - dragItem, - initPosition, -} from "~/pages/PageEnigma/store"; import { useSignals } from "@preact/signals-react/runtime"; +import DndAsset from "~/pages/PageEnigma/DragAndDrop/DndAsset"; interface Props { debug?: string; @@ -16,60 +9,14 @@ interface Props { export const ItemElement = ({ item }: Props) => { useSignals(); - const { startDrag, endDrag } = useContext(TrackContext); - const { initX, initY } = initPosition.value; const thumbnail = item.thumbnail ? item.thumbnail : `/resources/images/default-covers/${item.imageIndex}.webp`; - useEffect(() => { - const onPointerUp = () => { - if (dragItem.value) { - endDrag(); - } - }; - - const onMouseMove = (event: MouseEvent) => { - if (dragItem.value) { - event.stopPropagation(); - event.preventDefault(); - const deltaX = event.pageX - initX; - const deltaY = event.pageY - initY; - currPosition.value = { currX: initX + deltaX, currY: initY + deltaY }; - } - }; - - window.addEventListener("pointerup", onPointerUp); - window.addEventListener("pointermove", onMouseMove); - - return () => { - window.removeEventListener("pointerup", onPointerUp); - window.removeEventListener("pointermove", onMouseMove); - }; - }, [startDrag, endDrag, initX, initY]); - - const onPointerDown = useCallback( - (event: React.PointerEvent) => { - if (event.button === 0) { - startDrag(item); - currPosition.value = { - currX: event.pageX, - currY: event.pageY, - }; - initPosition.value = { - initX: event.pageX, - initY: event.pageY, - }; - canDrop.value = false; - } - }, - [item, startDrag], - ); - return (
+ onPointerDown={(event) => DndAsset.onPointerDown(event, item)}> { if (minimized) { return (