diff --git a/packages/client-core/src/admin/common/Location/ConfirmSubmitDialog.tsx b/packages/client-core/src/admin/common/Location/ConfirmSubmitDialog.tsx
new file mode 100644
index 00000000000..4babf86741b
--- /dev/null
+++ b/packages/client-core/src/admin/common/Location/ConfirmSubmitDialog.tsx
@@ -0,0 +1,61 @@
+/*
+CPAL-1.0 License
+
+The contents of this file are subject to the Common Public Attribution License
+Version 1.0. (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE.
+The License is based on the Mozilla Public License Version 1.1, but Sections 14
+and 15 have been added to cover use of software over a computer network and
+provide for limited attribution for the Original Developer. In addition,
+Exhibit A has been modified to be consistent with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
+specific language governing rights and limitations under the License.
+
+The Original Code is Ethereal Engine.
+
+The Original Developer is the Initial Developer. The Initial Developer of the
+Original Code is the Ethereal Engine team.
+
+All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023
+Ethereal Engine. All Rights Reserved.
+*/
+
+import React from 'react'
+
+import Button from '@etherealengine/ui/src/primitives/mui/Button'
+import Container from '@etherealengine/ui/src/primitives/mui/Container'
+import DialogActions from '@etherealengine/ui/src/primitives/mui/DialogActions'
+import DialogTitle from '@etherealengine/ui/src/primitives/mui/DialogTitle'
+
+import styles from '../../old-styles/admin.module.scss'
+import DrawerView from '../DrawerView'
+
+interface Props {
+ open: boolean
+ onConfirm: () => void
+ onClose: () => void
+ handleCancel: () => void
+}
+
+const ConfirmSubmitDialog = ({ open, onConfirm, handleCancel, onClose }: Props) => {
+ return (
+
+
+ Publish Scene?
+
+
+
+
+
+
+ )
+}
+
+export default ConfirmSubmitDialog
diff --git a/packages/client-core/src/admin/common/Location/LocationDrawer.tsx b/packages/client-core/src/admin/common/Location/LocationDrawer.tsx
index 5a899961671..6479f5c9355 100644
--- a/packages/client-core/src/admin/common/Location/LocationDrawer.tsx
+++ b/packages/client-core/src/admin/common/Location/LocationDrawer.tsx
@@ -37,7 +37,7 @@ import {
LocationType
} from '@etherealengine/common/src/schema.type.module'
import { AssetType } from '@etherealengine/common/src/schemas/assets/asset.schema'
-import { getMutableState, NO_PROXY, useHookstate } from '@etherealengine/hyperflux'
+import { getMutableState, getState, NO_PROXY, useHookstate } from '@etherealengine/hyperflux'
import { useFind, useGet, useMutation } from '@etherealengine/spatial/src/common/functions/FeathersHooks'
import Button from '@etherealengine/ui/src/primitives/mui/Button'
import Container from '@etherealengine/ui/src/primitives/mui/Container'
@@ -45,11 +45,15 @@ import DialogActions from '@etherealengine/ui/src/primitives/mui/DialogActions'
import DialogTitle from '@etherealengine/ui/src/primitives/mui/DialogTitle'
import Grid from '@etherealengine/ui/src/primitives/mui/Grid'
+import { EntityUUID } from '@etherealengine/ecs'
+import { EditorState } from '@etherealengine/editor/src/services/EditorServices'
+import { saveSceneGLTF, setCurrentEditorScene } from '../../../../../editor/src/functions/sceneFunctions'
import { NotificationService } from '../../../common/services/NotificationService'
import { AuthState } from '../../../user/services/AuthService'
import styles from '../../old-styles/admin.module.scss'
import DrawerView from '../DrawerView'
import { validateForm } from '../validation/formValidation'
+import ConfirmSubmitDialog from './ConfirmSubmitDialog'
export enum LocationDrawerMode {
Create,
@@ -87,6 +91,7 @@ const LocationDrawer = ({ open, mode, selectedLocation, selectedScene, onClose }
const { t } = useTranslation()
const editMode = useHookstate(false)
const state = useHookstate({ ...defaultState })
+ const confirmWindowOpen = useHookstate(false)
const scenes = useFind(assetPath)
// const locationTypes = useFind(locationTypePath).data
@@ -153,6 +158,14 @@ const LocationDrawer = ({ open, mode, selectedLocation, selectedScene, onClose }
} else handleClose()
}
+ const handleConfirmWindowOpen = () => {
+ confirmWindowOpen.set(true)
+ }
+
+ const handleConfirmCancel = () => {
+ confirmWindowOpen.set(false)
+ }
+
const handleClose = () => {
onClose()
state.set({ ...defaultState })
@@ -181,8 +194,54 @@ const LocationDrawer = ({ open, mode, selectedLocation, selectedScene, onClose }
state.merge({ [name]: value })
}
- const handleSubmit = () => {
- const data: LocationData = {
+ const handleSubmit = async () => {
+ confirmWindowOpen.set(false)
+
+ state.formErrors.merge({
+ name: state.name.value ? '' : t('admin:components.location.nameCantEmpty'),
+ maxUsers: state.maxUsers.value ? '' : t('admin:components.location.maxUserCantEmpty'),
+ scene: state.scene.value ? '' : t('admin:components.location.sceneCantEmpty'),
+ type: state.type.value ? '' : t('admin:components.location.typeCantEmpty')
+ })
+
+ if (!validateForm(state.value, state.formErrors.value)) {
+ NotificationService.dispatchNotify(t('admin:components.common.fillRequiredFields'), { variant: 'error' })
+ return
+ }
+
+ // TODO: new checkbox
+ const isBaked = true
+
+ // TODO: Present blocking modal to user "Are you sure you want to Publish?"
+
+ await publishScene(isBaked)
+
+ // TODO: After publish succeeds or fails, restore original scene and close blocking modal
+
+ handleClose()
+ }
+
+ const publishScene = async (bake: boolean) => {
+ // TODO: Save current scene in place, and create new version to publish
+ const { sceneAssetID, projectName, sceneName, scenePath } = getState(EditorState)
+
+ if (projectName && sceneName && scenePath) {
+ const sceneQuery = useFind(assetPath, { query: { assetURL: scenePath ?? '' } }).data
+ const sceneURL = sceneQuery?.[0]?.assetURL
+ const abortController = new AbortController()
+
+ // TODO: Bake implementation
+ if (bake) {
+ await saveSceneGLTF(sceneAssetID, projectName, sceneName + '-optimized', abortController.signal)
+ }
+
+ setCurrentEditorScene(sceneURL, sceneQuery[0].id! as EntityUUID)
+ }
+
+ // TODO: In duplicated scene, perform mesh baking to de-reference all models in the scene (saving scene as GLTF & fuse/compress scenes)
+ // TODO: Publish the duplicated scene
+
+ const locationData: LocationData = {
name: state.name.value,
slugifiedName: '',
sceneId: state.scene.value,
@@ -202,28 +261,13 @@ const LocationDrawer = ({ open, mode, selectedLocation, selectedScene, onClose }
isFeatured: false //state.isFeatured.value
}
- state.formErrors.merge({
- name: state.name.value ? '' : t('admin:components.location.nameCantEmpty'),
- maxUsers: state.maxUsers.value ? '' : t('admin:components.location.maxUserCantEmpty'),
- scene: state.scene.value ? '' : t('admin:components.location.sceneCantEmpty'),
- type: state.type.value ? '' : t('admin:components.location.typeCantEmpty')
- })
+ const onError = (error) => NotificationService.dispatchNotify(error.message, { variant: 'error' })
- if (validateForm(state.value, state.formErrors.value)) {
- if (mode === LocationDrawerMode.Create) {
- locationMutation.create(data).catch((error) => {
- NotificationService.dispatchNotify(error.message, { variant: 'error' })
- })
- } else if (selectedLocation) {
- locationMutation.patch(selectedLocation.id, data).catch((error) => {
- NotificationService.dispatchNotify(error.message, { variant: 'error' })
- })
- editMode.set(false)
- }
-
- handleClose()
- } else {
- NotificationService.dispatchNotify(t('admin:components.common.fillRequiredFields'), { variant: 'error' })
+ if (mode === LocationDrawerMode.Create) {
+ await locationMutation.create(locationData).catch(onError)
+ } else if (selectedLocation) {
+ await locationMutation.patch(selectedLocation.id, locationData).catch(onError)
+ editMode.set(false)
}
}
@@ -308,7 +352,7 @@ const LocationDrawer = ({ open, mode, selectedLocation, selectedScene, onClose }
{t('admin:components.common.cancel')}
{(mode === LocationDrawerMode.Create || editMode.value) && (
-