From 051eae157ca6d6bb6aa3382539ebdfe4cb741de7 Mon Sep 17 00:00:00 2001 From: Jiatong Yao Date: Wed, 14 Aug 2024 12:28:01 -0500 Subject: [PATCH] add modal and fix update duplicated prefab --- .../dialogs/CreatePrefabPanelDialog.tsx | 259 ++++++++++-------- 1 file changed, 151 insertions(+), 108 deletions(-) diff --git a/packages/editor/src/components/dialogs/CreatePrefabPanelDialog.tsx b/packages/editor/src/components/dialogs/CreatePrefabPanelDialog.tsx index 94a889a7b0..1c416a0c55 100644 --- a/packages/editor/src/components/dialogs/CreatePrefabPanelDialog.tsx +++ b/packages/editor/src/components/dialogs/CreatePrefabPanelDialog.tsx @@ -36,6 +36,7 @@ import { removeEntity, setComponent } from '@etherealengine/ecs' +import { updateModelResource } from '@etherealengine/engine/src/assets/functions/resourceLoaderFunctions' import { GLTFDocumentState } from '@etherealengine/engine/src/gltf/GLTFDocumentState' import { ModelComponent } from '@etherealengine/engine/src/scene/components/ModelComponent' import { SourceComponent } from '@etherealengine/engine/src/scene/components/SourceComponent' @@ -60,7 +61,8 @@ export default function CreatePrefabPanel({ entity }: { entity: Entity }) { const prefabName = useHookstate('prefab') const prefabTag = useHookstate([]) const { t } = useTranslation() - + const isOverwriteModalVisible = useHookstate(false) + const isOverwriteConfirmed = useHookstate(false) const onExportPrefab = async () => { const editorState = getState(EditorState) const fileName = defaultPrefabFolder.value + '/' + prefabName.value + '.gltf' @@ -68,122 +70,163 @@ export default function CreatePrefabPanel({ entity }: { entity: Entity }) { const fileURL = pathJoin(config.client.fileServer, 'projects', srcProject, fileName) try { const parentEntity = getComponent(entity, EntityTreeComponent).parentEntity - const prefabEntity = createEntity() - const obj = new Scene() - addObjectToGroup(prefabEntity, obj) - proxifyParentChildRelationships(obj) - setComponent(prefabEntity, EntityTreeComponent, { parentEntity }) - setComponent(prefabEntity, NameComponent, prefabName.value) - const entityTransform = getComponent(entity, TransformComponent) - const position = entityTransform.position.clone() - const rotation = entityTransform.rotation.clone() - const scale = entityTransform.scale.clone() - setComponent(prefabEntity, TransformComponent, { - position, - rotation, - scale - }) - setComponent(entity, TransformComponent, { - position: new Vector3(0, 0, 0), - rotation: new Quaternion().identity(), - scale: new Vector3(1, 1, 1) - }) - setComponent(entity, EntityTreeComponent, { parentEntity: prefabEntity }) - getMutableState(SelectionState).selectedEntities.set([]) - await exportRelativeGLTF(prefabEntity, srcProject, fileName) - - const resources = await Engine.instance.api.service(staticResourcePath).find({ + const resourcesold = await Engine.instance.api.service(staticResourcePath).find({ query: { key: 'projects/' + srcProject + '/' + fileName } }) - if (resources.data.length === 0) { - throw new Error('User not found') - } - const resource = resources.data[0] - const tags = [...prefabTag.value] - await Engine.instance.api.service(staticResourcePath).patch(resource.id, { tags: tags, project: srcProject }) + if (resourcesold.data.length !== 0 && !isOverwriteConfirmed.value) { + //throw new Error('Duplicate file') + console.log('this name already exist, click confirm to overwrite the prefab') + await isOverwriteModalVisible.set(true) + } else { + const prefabEntity = createEntity() + const obj = new Scene() + addObjectToGroup(prefabEntity, obj) + proxifyParentChildRelationships(obj) + setComponent(prefabEntity, EntityTreeComponent, { parentEntity }) + setComponent(prefabEntity, NameComponent, prefabName.value) + const entityTransform = getComponent(entity, TransformComponent) + const position = entityTransform.position.clone() + const rotation = entityTransform.rotation.clone() + const scale = entityTransform.scale.clone() + setComponent(prefabEntity, TransformComponent, { + position, + rotation, + scale + }) + setComponent(entity, TransformComponent, { + position: new Vector3(0, 0, 0), + rotation: new Quaternion().identity(), + scale: new Vector3(1, 1, 1) + }) + setComponent(entity, EntityTreeComponent, { parentEntity: prefabEntity }) - removeEntity(prefabEntity) - EditorControlFunctions.removeObject([entity]) - const sceneID = getComponent(parentEntity, SourceComponent) - const reactor = startReactor(() => { - const documentState = useHookstate(getMutableState(GLTFDocumentState)) - const nodes = documentState[sceneID].nodes - useEffect(() => { - if (!entityExists(entity)) { - const { entityUUID } = EditorControlFunctions.createObjectFromSceneElement( - [ - { name: ModelComponent.jsonID, props: { src: fileURL } }, - { name: TransformComponent.jsonID, props: { position, rotation, scale } } - ], - parentEntity - ) - getMutableState(SelectionState).selectedEntities.set([entityUUID]) - reactor.stop() - } else { - console.log('Entity not removed') - } - }, [nodes]) - return null - }) - PopoverState.hidePopupover() - defaultPrefabFolder.set('assets/custom-prefabs') - prefabName.set('prefab') - prefabTag.set([]) + await exportRelativeGLTF(prefabEntity, srcProject, fileName).then(() => { + updateModelResource(fileURL) + }) + + const resources = await Engine.instance.api.service(staticResourcePath).find({ + query: { key: 'projects/' + srcProject + '/' + fileName } + }) + if (resources.data.length === 0) { + throw new Error('User not found') + } + const resource = resources.data[0] + const tags = [...prefabTag.value] + await Engine.instance.api.service(staticResourcePath).patch(resource.id, { tags: tags, project: srcProject }) + + removeEntity(prefabEntity) + await EditorControlFunctions.removeObject([entity]) + //await EditorControlFunctions.removeObject([prefabEntity]) + const sceneID = getComponent(parentEntity, SourceComponent) + const reactor = startReactor(() => { + const documentState = useHookstate(getMutableState(GLTFDocumentState)) + const nodes = documentState[sceneID].nodes + useEffect(() => { + if (!entityExists(entity)) { + const { entityUUID } = EditorControlFunctions.createObjectFromSceneElement( + [ + { name: ModelComponent.jsonID, props: { src: fileURL } }, + { name: TransformComponent.jsonID, props: { position, rotation, scale } } + ], + parentEntity + ) + + updateModelResource(fileURL) + getMutableState(SelectionState).selectedEntities.set([entityUUID]) + reactor.stop() + } else { + console.log('Entity not removed') + } + }, [nodes]) + + return null + }) + + PopoverState.hidePopupover() + defaultPrefabFolder.set('assets/custom-prefabs') + prefabName.set('prefab') + prefabTag.set([]) + isOverwriteModalVisible.set(false) + isOverwriteConfirmed.set(false) + } } catch (e) { console.error(e) } } return ( - - defaultPrefabFolder.set(event.target.value)} - label="Default Save Folder" - /> - prefabName.set(event.target.value)} label="Name" /> + <> + {!isOverwriteModalVisible.value && !isOverwriteConfirmed.value && ( + + defaultPrefabFolder.set(event.target.value)} + label="Default Save Folder" + /> + prefabName.set(event.target.value)} label="Name" /> - -
- {(prefabTag.value ?? []).map((tag, index) => ( -
- { - const tags = [...prefabTag.value] - tags[index] = event.target.value - prefabTag.set(tags) - }} - value={prefabTag.value[index]} - /> - + +
+ {(prefabTag.value ?? []).map((tag, index) => ( +
+ { + const tags = [...prefabTag.value] + tags[index] = event.target.value + prefabTag.set(tags) + }} + value={prefabTag.value[index]} + /> + +
+ ))} +
+ + )} + {/* Overwrite Confirmation Modal */} + {isOverwriteModalVisible.value && ( + { + isOverwriteConfirmed.set(true) + isOverwriteModalVisible.set(false) + onExportPrefab() + }} + onClose={() => { + isOverwriteConfirmed.set(false) + isOverwriteModalVisible.set(false) + }} + > +
+

Prefab with this name already exists. You will overwrite it.

- ))} -
- + + )} + ) }