From 7a45dcdb96bf0497dcd2393fcbc4388302a2188c Mon Sep 17 00:00:00 2001 From: Christopher Oliphant Date: Mon, 8 Apr 2024 06:42:06 -0400 Subject: [PATCH] Some code refactoring --- .../comps/Timeline/utils/useQueueHandler.ts | 214 +++--------------- .../contexts/TrackContext/TrackProvider.tsx | 15 +- .../TrackContext/utils/useUpdateKeyframe.ts | 1 + app/pages/PageEnigma/store/audioGroup.ts | 18 ++ app/pages/PageEnigma/store/cameraGroup.ts | 16 ++ .../store/characterGroups/addCharacter.ts | 28 +++ .../{ => characterGroups}/characterGroups.ts | 111 --------- .../PageEnigma/store/characterGroups/index.ts | 4 + .../characterGroups/loadCharacterData.ts | 89 ++++++++ .../store/characterGroups/updateCharacters.ts | 94 ++++++++ .../PageEnigma/store/objectGroup/index.ts | 3 + .../store/objectGroup/loadObjectData.ts | 48 ++++ .../store/{ => objectGroup}/objectGroup.ts | 66 +----- .../store/objectGroup/updateObjectGroup.ts | 59 +++++ 14 files changed, 403 insertions(+), 363 deletions(-) create mode 100644 app/pages/PageEnigma/store/characterGroups/addCharacter.ts rename app/pages/PageEnigma/store/{ => characterGroups}/characterGroups.ts (67%) create mode 100644 app/pages/PageEnigma/store/characterGroups/index.ts create mode 100644 app/pages/PageEnigma/store/characterGroups/loadCharacterData.ts create mode 100644 app/pages/PageEnigma/store/characterGroups/updateCharacters.ts create mode 100644 app/pages/PageEnigma/store/objectGroup/index.ts create mode 100644 app/pages/PageEnigma/store/objectGroup/loadObjectData.ts rename app/pages/PageEnigma/store/{ => objectGroup}/objectGroup.ts (72%) create mode 100644 app/pages/PageEnigma/store/objectGroup/updateObjectGroup.ts diff --git a/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts b/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts index 9fb7d82c95..5017af70ae 100644 --- a/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts +++ b/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts @@ -2,23 +2,19 @@ import { fromEngineActions } from "~/pages/PageEnigma/Queue/fromEngineActions"; import { useSignals } from "@preact/signals-react/runtime"; import { useCallback, useContext, useEffect } from "react"; import { - audioGroup, - cameraGroup, - characterGroups, + addNewCharacter, currentTime, - objectGroup, + loadAudioData, + loadCameraData, + loadCharacterData, + loadObjectData, } 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 { - CharacterGroup, - Clip, ClipGroup, - ClipType, - Keyframe, MediaItem, - ObjectTrack, QueueClip, QueueKeyframe, UpdateTime, @@ -32,65 +28,12 @@ interface Arguments { data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[] | MediaItem; } -function addCharacter(item: ClipUI) { - const existingCharacter = characterGroups.value.find( - (character) => character.id === item.object_uuid, - ); - - if (existingCharacter) { - return existingCharacter; - } - - const newCharacter = { - id: item.object_uuid, - name: item.object_name, - muted: false, - animationClips: [], - positionKeyframes: [], - lipSyncClips: [], - } as CharacterGroup; - - characterGroups.value = [ - ...characterGroups.value.filter( - (character) => character.id !== item.object_uuid, - ), - newCharacter, - ].sort((charA, charB) => (charA.id < charB.id ? -1 : 1)); - - return characterGroups.value.find( - (character) => character.id === item.object_uuid, - ) as CharacterGroup; -} - -function addObject(item: ClipUI) { - const existingObject = objectGroup.value.objects.find( - (obj) => obj.object_uuid === item.object_uuid, - ); - - if (existingObject) { - return existingObject; - } - - const newObject = { - object_uuid: item.object_uuid, - name: item.object_name, - keyframes: [] as Keyframe[], - } as ObjectTrack; - - objectGroup.value = { - id: "OB1", - objects: [ - ...objectGroup.value.objects.filter( - (obj) => obj.object_uuid !== item.object_uuid, - ), - newObject, - ].sort((objA, objB) => (objA.object_uuid < objB.object_uuid ? -1 : 1)), - }; - - return objectGroup.value.objects.find( - (obj) => obj.object_uuid === item.object_uuid, - ) as ObjectTrack; -} +const LOADING_FUNCTIONS: Record void> = { + [ClipGroup.CHARACTER]: loadCharacterData, + [ClipGroup.OBJECT]: loadObjectData, + [ClipGroup.CAMERA]: loadCameraData, + [ClipGroup.GLOBAL_AUDIO]: loadAudioData, +}; export function useQueueHandler() { useSignals(); @@ -103,120 +46,12 @@ export function useQueueHandler() { currentTime.value = (data as UpdateTime).currentTime; break; case fromEngineActions.UPDATE_TIME_LINE: - console.log(data); (data as ClipUI[]).forEach((item) => { - if (item.group === ClipGroup.CHARACTER) { - const existingCharacter = addCharacter(item); - if (item.type === ClipType.ANIMATION) { - const newItem = { - version: item.version, - clip_uuid: item.clip_uuid, - type: item.type, - group: item.group, - object_uuid: item.object_uuid, - media_id: item.media_id, - name: item.name, - offset: item.offset, - length: item.length, - } as Clip; - existingCharacter.animationClips.push(newItem); - existingCharacter.animationClips.sort( - (clipA, clipB) => clipA.offset - clipB.offset, - ); - } - if (item.type === ClipType.TRANSFORM) { - const newKeyframe = { - version: item.version, - keyframe_uuid: item.clip_uuid, - group: item.group, - object_uuid: item.object_uuid, - offset: item.keyframe_offset, - } as Keyframe; - existingCharacter.positionKeyframes.push(newKeyframe); - existingCharacter.positionKeyframes.sort( - (keyframeA, keyframeB) => keyframeA.offset - keyframeB.offset, - ); - } - if (item.type === ClipType.AUDIO) { - const newItem = { - version: item.version, - clip_uuid: item.clip_uuid, - type: item.type, - group: item.group, - object_uuid: item.object_uuid, - media_id: item.media_id, - name: item.name, - offset: item.offset, - length: item.length, - } as Clip; - existingCharacter.lipSyncClips.push(newItem); - existingCharacter.lipSyncClips.sort( - (clipA, clipB) => clipA.offset - clipB.offset, - ); - } - } - if (item.group === ClipGroup.OBJECT) { - const existingObject = addObject(item); - const newKeyframe = { - version: item.version, - keyframe_uuid: item.clip_uuid, - group: item.group, - object_uuid: item.object_uuid, - offset: item.keyframe_offset, - } as Keyframe; - existingObject.keyframes.push(newKeyframe); - existingObject.keyframes.sort( - (keyframeA, keyframeB) => keyframeA.offset - keyframeB.offset, - ); - } - if (item.group === ClipGroup.CAMERA) { - const existingCamera = cameraGroup.value; - const newKeyframe = { - version: item.version, - keyframe_uuid: item.clip_uuid, - group: item.group, - object_uuid: item.object_uuid, - offset: item.keyframe_offset, - } as Keyframe; - existingCamera.keyframes.push(newKeyframe); - existingCamera.keyframes.sort( - (keyframeA, keyframeB) => keyframeA.offset - keyframeB.offset, - ); - // cameraGroup.value = { ...cameraGroup.value }; - } - if (item.group === ClipGroup.GLOBAL_AUDIO) { - const existingAudio = audioGroup.value; - const newItem = { - version: item.version, - clip_uuid: item.clip_uuid, - type: item.type, - group: item.group, - object_uuid: item.object_uuid, - media_id: item.media_id, - name: item.name, - offset: item.offset, - length: item.length, - } as Clip; - existingAudio.clips.push(newItem); - existingAudio.clips.sort( - (clipA, clipB) => clipA.offset - clipB.offset, - ); - } + LOADING_FUNCTIONS[item.group](item); }); break; case fromEngineActions.UPDATE_CHARACTER_ID: { - const newCharacter = { - id: (data as MediaItem).object_uuid, - name: (data as MediaItem).name, - muted: false, - animationClips: [], - positionKeyframes: [], - lipSyncClips: [], - } as CharacterGroup; - - characterGroups.value = [...characterGroups.value, newCharacter].sort( - (charA, charB) => (charA.id < charB.id ? -1 : 1), - ); + addNewCharacter(data as MediaItem); break; } default: @@ -224,16 +59,19 @@ export function useQueueHandler() { } }, []); - const handleToTimelineActions = useCallback(({ action, data }: Arguments) => { - console.log("TO TIMELINE", action, data); - switch (action) { - case toTimelineActions.ADD_KEYFRAME: - addKeyframe(data as QueueKeyframe, currentTime.value); - break; - default: - throw new Error(`Unknown action ${action}`); - } - }, []); + const handleToTimelineActions = useCallback( + ({ action, data }: Arguments) => { + console.log("TO TIMELINE", action, data); + switch (action) { + case toTimelineActions.ADD_KEYFRAME: + addKeyframe(data as QueueKeyframe, currentTime.value); + break; + default: + throw new Error(`Unknown action ${action}`); + } + }, + [addKeyframe], + ); useEffect(() => { Queue.subscribe(QueueNames.FROM_ENGINE, handleFromEngineActions); diff --git a/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx b/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx index d251604506..f216c0f859 100644 --- a/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx +++ b/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx @@ -26,12 +26,9 @@ export const TrackProvider = ({ children }: Props) => { // cross group functions const dropClip = useCallback(() => { - console.log(`${JSON.stringify(dragItem)}`); - - if (dragItem.value != null && dragItem != null) { - // should be able to drag into the timeline ... TODO FIX? - - if (dragItem.value.type === AssetType.CHARACTER) { + if (dragItem.value) { + const mediaItem = dragItem.value; + if (mediaItem.type === AssetType.CHARACTER) { addCharacter(dragItem.value); } // if (dragItem.value.type === AssetType.CAMERA) { @@ -48,7 +45,7 @@ export const TrackProvider = ({ children }: Props) => { if (canDrop.value && dragItem.value) { if (dragItem.value.type === AssetType.ANIMATION) { addCharacterAnimation({ - dragItem: dragItem.value!, + dragItem: dragItem.value, characterId: dropId.value, offset: dropOffset.value, }); @@ -56,12 +53,12 @@ export const TrackProvider = ({ children }: Props) => { if (dragItem.value.type === AssetType.AUDIO) { console.log("add audio", dropId.value); addCharacterAudio({ - dragItem: dragItem.value!, + dragItem: dragItem.value, characterId: dropId.value, offset: dropOffset.value, }); addGlobalAudio({ - dragItem: dragItem.value!, + dragItem: dragItem.value, audioId: dropId.value, offset: dropOffset.value, }); diff --git a/app/pages/PageEnigma/contexts/TrackContext/utils/useUpdateKeyframe.ts b/app/pages/PageEnigma/contexts/TrackContext/utils/useUpdateKeyframe.ts index cd74478149..0aaad00d35 100644 --- a/app/pages/PageEnigma/contexts/TrackContext/utils/useUpdateKeyframe.ts +++ b/app/pages/PageEnigma/contexts/TrackContext/utils/useUpdateKeyframe.ts @@ -28,6 +28,7 @@ const DELETE_KEYFRAME: Record void> = { export default function useUpdateKeyframe() { const addKeyframe = useCallback((keyframe: QueueKeyframe, offset: number) => { + console.log("k", keyframe); ADD_KEYFRAME[keyframe.group](keyframe, offset); }, []); diff --git a/app/pages/PageEnigma/store/audioGroup.ts b/app/pages/PageEnigma/store/audioGroup.ts index 9a6d7fc2dd..630778507c 100644 --- a/app/pages/PageEnigma/store/audioGroup.ts +++ b/app/pages/PageEnigma/store/audioGroup.ts @@ -10,6 +10,7 @@ import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; import * as uuid from "uuid"; import { signal } from "@preact/signals-core"; +import { ClipUI } from "~/pages/PageEnigma/datastructures/clips/clip_ui"; export const audioGroup = signal({ id: "AG-1", @@ -140,3 +141,20 @@ export function deleteAudioClip(clip: Clip) { ], }; } + +export function loadAudioData(item: ClipUI) { + const existingAudio = audioGroup.value; + const newItem = { + version: item.version, + clip_uuid: item.clip_uuid, + type: item.type, + group: item.group, + object_uuid: item.object_uuid, + media_id: item.media_id, + name: item.name, + offset: item.offset, + length: item.length, + } as Clip; + existingAudio.clips.push(newItem); + existingAudio.clips.sort((clipA, clipB) => clipA.offset - clipB.offset); +} diff --git a/app/pages/PageEnigma/store/cameraGroup.ts b/app/pages/PageEnigma/store/cameraGroup.ts index 029a8b6810..72bf56aad1 100644 --- a/app/pages/PageEnigma/store/cameraGroup.ts +++ b/app/pages/PageEnigma/store/cameraGroup.ts @@ -8,6 +8,7 @@ import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; import * as uuid from "uuid"; import { signal } from "@preact/signals-core"; +import { ClipUI } from "~/pages/PageEnigma/datastructures/clips/clip_ui"; // import { toast } from "react-hot-toast"; export const cameraGroup = signal({ id: "CG1", keyframes: [] }); @@ -112,3 +113,18 @@ export function deleteCameraKeyframe(deleteKeyframe: Keyframe) { ], }; } + +export function loadCameraData(item: ClipUI) { + const existingCamera = cameraGroup.value; + const newKeyframe = { + version: item.version, + keyframe_uuid: item.clip_uuid, + group: item.group, + object_uuid: item.object_uuid, + offset: item.keyframe_offset, + } as Keyframe; + existingCamera.keyframes.push(newKeyframe); + existingCamera.keyframes.sort( + (keyframeA, keyframeB) => keyframeA.offset - keyframeB.offset, + ); +} diff --git a/app/pages/PageEnigma/store/characterGroups/addCharacter.ts b/app/pages/PageEnigma/store/characterGroups/addCharacter.ts new file mode 100644 index 0000000000..c68a300002 --- /dev/null +++ b/app/pages/PageEnigma/store/characterGroups/addCharacter.ts @@ -0,0 +1,28 @@ +import { CharacterGroup, MediaItem } from "~/pages/PageEnigma/models"; +import Queue from "~/pages/PageEnigma/Queue/Queue"; +import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; +import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; +import { characterGroups } from "~/pages/PageEnigma/store"; + +export function addCharacter(character: MediaItem) { + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.ADD_CHARACTER, + data: character, + }); +} + +export function addNewCharacter(data: MediaItem) { + const newCharacter = { + id: data.object_uuid, + name: data.name, + muted: false, + animationClips: [], + positionKeyframes: [], + lipSyncClips: [], + } as CharacterGroup; + + characterGroups.value = [...characterGroups.value, newCharacter].sort( + (charA, charB) => (charA.id < charB.id ? -1 : 1), + ); +} diff --git a/app/pages/PageEnigma/store/characterGroups.ts b/app/pages/PageEnigma/store/characterGroups/characterGroups.ts similarity index 67% rename from app/pages/PageEnigma/store/characterGroups.ts rename to app/pages/PageEnigma/store/characterGroups/characterGroups.ts index ecc977611f..b7be79cfc1 100644 --- a/app/pages/PageEnigma/store/characterGroups.ts +++ b/app/pages/PageEnigma/store/characterGroups/characterGroups.ts @@ -15,95 +15,6 @@ import * as uuid from "uuid"; export const characterGroups = signal([]); -export function updateCharacters({ - type, - id, - offset, - length, -}: { - type: ClipType; - id: string; - length?: number; - offset: number; -}) { - const oldCharacterGroups = characterGroups.value; - if (type === ClipType.ANIMATION) { - characterGroups.value = oldCharacterGroups.map((character) => { - const newAnimationClips = [...character.animationClips]; - const clipIndex = newAnimationClips.findIndex( - (row) => row.clip_uuid === id, - ); - if (clipIndex === -1) { - return { ...character }; - } - const clip = newAnimationClips[clipIndex]; - clip.offset = offset; - clip.length = length!; - - Queue.publish({ - queueName: QueueNames.TO_ENGINE, - action: toEngineActions.UPDATE_CLIP, - data: clip, - }); - - return { - ...character, - animationClips: newAnimationClips, - }; - }); - } - - if (type === ClipType.TRANSFORM) { - characterGroups.value = oldCharacterGroups.map((character) => { - const newPositionKeyframes = [...character.positionKeyframes]; - const keyframeIndex = newPositionKeyframes.findIndex( - (row) => row.keyframe_uuid === id, - ); - if (keyframeIndex === -1) { - return { ...character }; - } - const keyframe = newPositionKeyframes[keyframeIndex]; - keyframe.offset = offset; - - Queue.publish({ - queueName: QueueNames.TO_ENGINE, - action: toEngineActions.UPDATE_CLIP, - data: keyframe, - }); - - return { - ...character, - positionKeyframes: newPositionKeyframes, - }; - }); - } - if (type === ClipType.AUDIO) { - characterGroups.value = oldCharacterGroups.map((character) => { - const newLipSyncClips = [...character.lipSyncClips]; - const clipIndex = newLipSyncClips.findIndex( - (row) => row.clip_uuid === id, - ); - if (clipIndex === -1) { - return { ...character }; - } - const clip = newLipSyncClips[clipIndex]; - clip.offset = offset; - clip.length = length!; - - Queue.publish({ - queueName: QueueNames.TO_ENGINE, - action: toEngineActions.UPDATE_CLIP, - data: clip, - }); - - return { - ...character, - lipSyncClips: newLipSyncClips, - }; - }); - } -} - export function addCharacterAnimation({ dragItem, characterId, @@ -326,25 +237,3 @@ export function deleteCharacterKeyframe(keyframe: Keyframe) { }), })); } - -// probably not to much to send imo -export function addCharacter(character: MediaItem) { - //{"version":1,"media_id":"m_r7w1tmkx2jg8nznr3hyzj4k6zhfh7d ", - // "type":"character","name":"Female Doll", - // "thumbnail":"resources/characters/img03.png"} - Queue.publish({ - queueName: QueueNames.TO_ENGINE, - action: toEngineActions.ADD_CHARACTER, - data: character, - }); -} -export function addObject(object: MediaItem) { - //{"version":1,"media_id":"m_r7w1tmkx2jg8nznr3hyzj4k6zhfh7d ", - // "type":"character","name":"Female Doll", - // "thumbnail":"resources/characters/img03.png"} - Queue.publish({ - queueName: QueueNames.TO_ENGINE, - action: toEngineActions.ADD_OBJECT, - data: object, - }); -} diff --git a/app/pages/PageEnigma/store/characterGroups/index.ts b/app/pages/PageEnigma/store/characterGroups/index.ts new file mode 100644 index 0000000000..eb200150c0 --- /dev/null +++ b/app/pages/PageEnigma/store/characterGroups/index.ts @@ -0,0 +1,4 @@ +export * from "./addCharacter"; +export * from "./characterGroups"; +export * from "./loadCharacterData"; +export * from "./updateCharacters"; diff --git a/app/pages/PageEnigma/store/characterGroups/loadCharacterData.ts b/app/pages/PageEnigma/store/characterGroups/loadCharacterData.ts new file mode 100644 index 0000000000..db7722abe1 --- /dev/null +++ b/app/pages/PageEnigma/store/characterGroups/loadCharacterData.ts @@ -0,0 +1,89 @@ +import { ClipUI } from "~/pages/PageEnigma/datastructures/clips/clip_ui"; +import { + CharacterGroup, + Clip, + ClipType, + Keyframe, +} from "~/pages/PageEnigma/models"; +import { characterGroups } from "~/pages/PageEnigma/store"; + +function getAddCharacter(item: ClipUI) { + const existingCharacter = characterGroups.value.find( + (character) => character.id === item.object_uuid, + ); + + if (existingCharacter) { + return existingCharacter; + } + + const newCharacter = { + id: item.object_uuid, + name: item.object_name, + muted: false, + animationClips: [], + positionKeyframes: [], + lipSyncClips: [], + } as CharacterGroup; + + characterGroups.value = [ + ...characterGroups.value.filter( + (character) => character.id !== item.object_uuid, + ), + newCharacter, + ].sort((charA, charB) => (charA.id < charB.id ? -1 : 1)); + + return characterGroups.value.find( + (character) => character.id === item.object_uuid, + ) as CharacterGroup; +} + +export function loadCharacterData(item: ClipUI) { + const existingCharacter = getAddCharacter(item); + if (item.type === ClipType.ANIMATION) { + const newItem = { + version: item.version, + clip_uuid: item.clip_uuid, + type: item.type, + group: item.group, + object_uuid: item.object_uuid, + media_id: item.media_id, + name: item.name, + offset: item.offset, + length: item.length, + } as Clip; + existingCharacter.animationClips.push(newItem); + existingCharacter.animationClips.sort( + (clipA, clipB) => clipA.offset - clipB.offset, + ); + } + if (item.type === ClipType.TRANSFORM) { + const newKeyframe = { + version: item.version, + keyframe_uuid: item.clip_uuid, + group: item.group, + object_uuid: item.object_uuid, + offset: item.keyframe_offset, + } as Keyframe; + existingCharacter.positionKeyframes.push(newKeyframe); + existingCharacter.positionKeyframes.sort( + (keyframeA, keyframeB) => keyframeA.offset - keyframeB.offset, + ); + } + if (item.type === ClipType.AUDIO) { + const newItem = { + version: item.version, + clip_uuid: item.clip_uuid, + type: item.type, + group: item.group, + object_uuid: item.object_uuid, + media_id: item.media_id, + name: item.name, + offset: item.offset, + length: item.length, + } as Clip; + existingCharacter.lipSyncClips.push(newItem); + existingCharacter.lipSyncClips.sort( + (clipA, clipB) => clipA.offset - clipB.offset, + ); + } +} diff --git a/app/pages/PageEnigma/store/characterGroups/updateCharacters.ts b/app/pages/PageEnigma/store/characterGroups/updateCharacters.ts new file mode 100644 index 0000000000..93de4af12a --- /dev/null +++ b/app/pages/PageEnigma/store/characterGroups/updateCharacters.ts @@ -0,0 +1,94 @@ +import { ClipType } from "~/pages/PageEnigma/models"; +import Queue from "~/pages/PageEnigma/Queue/Queue"; +import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; +import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; +import { characterGroups } from "~/pages/PageEnigma/store"; + +export function updateCharacters({ + type, + id, + offset, + length, +}: { + type: ClipType; + id: string; + length?: number; + offset: number; +}) { + const oldCharacterGroups = characterGroups.value; + if (type === ClipType.ANIMATION) { + characterGroups.value = oldCharacterGroups.map((character) => { + const newAnimationClips = [...character.animationClips]; + const clipIndex = newAnimationClips.findIndex( + (row) => row.clip_uuid === id, + ); + if (clipIndex === -1) { + return { ...character }; + } + const clip = newAnimationClips[clipIndex]; + clip.offset = offset; + clip.length = length!; + + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.UPDATE_CLIP, + data: clip, + }); + + return { + ...character, + animationClips: newAnimationClips, + }; + }); + } + + if (type === ClipType.TRANSFORM) { + characterGroups.value = oldCharacterGroups.map((character) => { + const newPositionKeyframes = [...character.positionKeyframes]; + const keyframeIndex = newPositionKeyframes.findIndex( + (row) => row.keyframe_uuid === id, + ); + if (keyframeIndex === -1) { + return { ...character }; + } + const keyframe = newPositionKeyframes[keyframeIndex]; + keyframe.offset = offset; + + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.UPDATE_CLIP, + data: keyframe, + }); + + return { + ...character, + positionKeyframes: newPositionKeyframes, + }; + }); + } + if (type === ClipType.AUDIO) { + characterGroups.value = oldCharacterGroups.map((character) => { + const newLipSyncClips = [...character.lipSyncClips]; + const clipIndex = newLipSyncClips.findIndex( + (row) => row.clip_uuid === id, + ); + if (clipIndex === -1) { + return { ...character }; + } + const clip = newLipSyncClips[clipIndex]; + clip.offset = offset; + clip.length = length!; + + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.UPDATE_CLIP, + data: clip, + }); + + return { + ...character, + lipSyncClips: newLipSyncClips, + }; + }); + } +} diff --git a/app/pages/PageEnigma/store/objectGroup/index.ts b/app/pages/PageEnigma/store/objectGroup/index.ts new file mode 100644 index 0000000000..43c1cdb480 --- /dev/null +++ b/app/pages/PageEnigma/store/objectGroup/index.ts @@ -0,0 +1,3 @@ +export * from "./loadObjectData"; +export * from "./objectGroup"; +export * from "./updateObjectGroup"; diff --git a/app/pages/PageEnigma/store/objectGroup/loadObjectData.ts b/app/pages/PageEnigma/store/objectGroup/loadObjectData.ts new file mode 100644 index 0000000000..8831681799 --- /dev/null +++ b/app/pages/PageEnigma/store/objectGroup/loadObjectData.ts @@ -0,0 +1,48 @@ +import { ClipUI } from "~/pages/PageEnigma/datastructures/clips/clip_ui"; +import { Keyframe, ObjectTrack } from "~/pages/PageEnigma/models"; +import { objectGroup } from "~/pages/PageEnigma/store"; + +function getAddObject(item: ClipUI) { + const existingObject = objectGroup.value.objects.find( + (obj) => obj.object_uuid === item.object_uuid, + ); + + if (existingObject) { + return existingObject; + } + + const newObject = { + object_uuid: item.object_uuid, + name: item.object_name, + keyframes: [] as Keyframe[], + } as ObjectTrack; + + objectGroup.value = { + id: "OB1", + objects: [ + ...objectGroup.value.objects.filter( + (obj) => obj.object_uuid !== item.object_uuid, + ), + newObject, + ].sort((objA, objB) => (objA.object_uuid < objB.object_uuid ? -1 : 1)), + }; + + return objectGroup.value.objects.find( + (obj) => obj.object_uuid === item.object_uuid, + ) as ObjectTrack; +} + +export function loadObjectData(item: ClipUI) { + const existingObject = getAddObject(item); + const newKeyframe = { + version: item.version, + keyframe_uuid: item.clip_uuid, + group: item.group, + object_uuid: item.object_uuid, + offset: item.keyframe_offset, + } as Keyframe; + existingObject.keyframes.push(newKeyframe); + existingObject.keyframes.sort( + (keyframeA, keyframeB) => keyframeA.offset - keyframeB.offset, + ); +} diff --git a/app/pages/PageEnigma/store/objectGroup.ts b/app/pages/PageEnigma/store/objectGroup/objectGroup.ts similarity index 72% rename from app/pages/PageEnigma/store/objectGroup.ts rename to app/pages/PageEnigma/store/objectGroup/objectGroup.ts index bcb83cd51d..80b4b8118f 100644 --- a/app/pages/PageEnigma/store/objectGroup.ts +++ b/app/pages/PageEnigma/store/objectGroup/objectGroup.ts @@ -1,13 +1,16 @@ import { signal } from "@preact/signals-core"; import { Keyframe, + MediaItem, ObjectGroup, + ObjectTrack, QueueKeyframe, } from "~/pages/PageEnigma/models"; import * as uuid from "uuid"; import Queue from "~/pages/PageEnigma/Queue/Queue"; import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; +import { ClipUI } from "~/pages/PageEnigma/datastructures/clips/clip_ui"; // import { toast } from "react-hot-toast"; export const objectGroup = signal({ @@ -15,61 +18,6 @@ export const objectGroup = signal({ objects: [], }); -export function updateObject({ - id, - offset, -}: { - id: string; - offset: number; -}): void { - const oldObjectGroup = objectGroup.value; - const obj = oldObjectGroup.objects.find((objectTrack) => - objectTrack.keyframes.some((row) => row.keyframe_uuid === id), - ); - - if (!obj) { - return; - } - - const existingKeyframe = obj.keyframes.some((row) => { - return row.offset === offset && row.keyframe_uuid !== id; - }); - - if (existingKeyframe) { - //toast.error("There can only be one keyframe at this offset."); - return; - } - - objectGroup.value = { - id: oldObjectGroup.id, - objects: oldObjectGroup.objects.map((object) => ({ - object_uuid: object.object_uuid, - name: object.name, - keyframes: object.keyframes.map((keyframe) => { - if (keyframe.keyframe_uuid !== id) { - return { - ...keyframe, - }; - } - - Queue.publish({ - queueName: QueueNames.TO_ENGINE, - action: toEngineActions.UPDATE_KEYFRAME, - data: { - ...keyframe, - offset, - }, - }); - - return { - ...keyframe, - offset, - }; - }), - })), - }; -} - export function addObjectKeyframe(keyframe: QueueKeyframe, offset: number) { const oldObjectGroup = objectGroup.value; const obj = oldObjectGroup.objects.find( @@ -166,3 +114,11 @@ export function deleteObjectKeyframe(keyframe: Keyframe) { ], }; } + +export function addObject(object: MediaItem) { + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.ADD_OBJECT, + data: object, + }); +} diff --git a/app/pages/PageEnigma/store/objectGroup/updateObjectGroup.ts b/app/pages/PageEnigma/store/objectGroup/updateObjectGroup.ts new file mode 100644 index 0000000000..0db35259af --- /dev/null +++ b/app/pages/PageEnigma/store/objectGroup/updateObjectGroup.ts @@ -0,0 +1,59 @@ +import Queue from "~/pages/PageEnigma/Queue/Queue"; +import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; +import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; +import { objectGroup } from "~/pages/PageEnigma/store"; + +export function updateObject({ + id, + offset, +}: { + id: string; + offset: number; +}): void { + const oldObjectGroup = objectGroup.value; + const obj = oldObjectGroup.objects.find((objectTrack) => + objectTrack.keyframes.some((row) => row.keyframe_uuid === id), + ); + + if (!obj) { + return; + } + + const existingKeyframe = obj.keyframes.some((row) => { + return row.offset === offset && row.keyframe_uuid !== id; + }); + + if (existingKeyframe) { + //toast.error("There can only be one keyframe at this offset."); + return; + } + + objectGroup.value = { + id: oldObjectGroup.id, + objects: oldObjectGroup.objects.map((object) => ({ + object_uuid: object.object_uuid, + name: object.name, + keyframes: object.keyframes.map((keyframe) => { + if (keyframe.keyframe_uuid !== id) { + return { + ...keyframe, + }; + } + + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.UPDATE_KEYFRAME, + data: { + ...keyframe, + offset, + }, + }); + + return { + ...keyframe, + offset, + }; + }), + })), + }; +}