import React, { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { Euler, Quaternion } from 'three' import { API } from '@xrengine/client-core/src/API' import { PortalDetail } from '@xrengine/common/src/interfaces/PortalInterface' import { getComponent } from '@xrengine/engine/src/ecs/functions/ComponentFunctions' import { NameComponent } from '@xrengine/engine/src/scene/components/NameComponent' import { PortalComponent, PortalEffects, PortalPreviewTypes } from '@xrengine/engine/src/scene/components/PortalComponent' import { UUIDComponent } from '@xrengine/engine/src/scene/components/UUIDComponent' import { TransformComponent } from '@xrengine/engine/src/transform/components/TransformComponent' import MeetingRoomIcon from '@mui/icons-material/MeetingRoom' import { uploadCubemapBakeToServer } from '../../functions/uploadEnvMapBake' import BooleanInput from '../inputs/BooleanInput' import { Button } from '../inputs/Button' import EulerInput from '../inputs/EulerInput' import InputGroup from '../inputs/InputGroup' import SelectInput from '../inputs/SelectInput' import StringInput, { ControlledStringInput } from '../inputs/StringInput' import Vector3Input from '../inputs/Vector3Input' import NodeEditor from './NodeEditor' import { EditorComponentType, updateProperties, updateProperty } from './Util' type PortalOptions = { name: string value: string } type PortalFilterOption = { label: string value: string data: PortalOptions } const rotation = new Quaternion() /** * PortalNodeEditor provides the editor for properties of PortalNode. * * @type {class component} */ export const PortalNodeEditor: EditorComponentType = (props) => { const [portals, setPortals] = useState>([]) const { t } = useTranslation() const portalName = getComponent(props.entity, NameComponent) const transformComponent = getComponent(props.entity, TransformComponent) useEffect(() => { loadPortals() }, []) const loadPortals = async () => { const portalsDetail: PortalDetail[] = [] try { portalsDetail.push(...(await API.instance.client.service('portal').find()).data) console.log('portalsDetail', portalsDetail, getComponent(props.entity, UUIDComponent)) } catch (error) { throw new Error(error) } setPortals( portalsDetail .filter((portal) => portal.portalEntityId !== getComponent(props.entity, UUIDComponent)) .map(({ portalEntityId, portalEntityName, sceneName }) => { return { value: portalEntityId, label: sceneName + ': ' + portalEntityName } }) ) } const bakeCubemap = async () => { const url = await uploadCubemapBakeToServer(portalName, transformComponent.position) loadPortals() updateProperties(PortalComponent, { previewImageURL: url }, [props.entity]) } const changeSpawnRotation = (value: Euler) => { rotation.setFromEuler(value) updateProperties(PortalComponent, { spawnRotation: rotation }) } const changePreviewType = (val) => { updateProperties(PortalComponent, { previewType: val }) loadPortals() } const portalComponent = getComponent(props.entity, PortalComponent) return ( { return { value: val, label: val } })} value={portalComponent.effectType} onChange={updateProperty(PortalComponent, 'effectType')} /> { return { value: val, label: val } })} value={portalComponent.previewType} onChange={changePreviewType} /> ) } PortalNodeEditor.iconComponent = MeetingRoomIcon export default PortalNodeEditor