diff --git a/src/bit-systems/mixer-animatable.ts b/src/bit-systems/mixer-animatable.ts index 05874c1d35..8609a277a1 100644 --- a/src/bit-systems/mixer-animatable.ts +++ b/src/bit-systems/mixer-animatable.ts @@ -1,4 +1,4 @@ -import { addComponent, defineQuery, enterQuery, exitQuery, removeComponent } from "bitecs"; +import { addComponent, defineQuery, enterQuery, entityExists, exitQuery, removeComponent } from "bitecs"; import { AnimationMixer } from "three"; import { MixerAnimatable, MixerAnimatableInitialize, MixerAnimatableData, Object3DTag } from "../bit-components"; import { HubsWorld } from "../app"; @@ -10,6 +10,10 @@ const mixerExitQuery = exitQuery(mixerQuery); export function mixerAnimatableSystem(world: HubsWorld): void { initializeEnterQuery(world).forEach(eid => { + if (entityExists(world, eid)) { + console.warn("Skipping nonexistant entity."); // TODO Why does this happen? + return; + } addComponent(world, MixerAnimatable, eid); const object = world.eid2obj.get(eid)!; diff --git a/src/bit-systems/object-menu.ts b/src/bit-systems/object-menu.ts index 3aaba8597c..73eec83705 100644 --- a/src/bit-systems/object-menu.ts +++ b/src/bit-systems/object-menu.ts @@ -205,7 +205,7 @@ function updateVisibility(world: HubsWorld, menu: EntityID, frozen: boolean) { world.eid2obj.get(ObjectMenu.unpinButtonRef[menu])!.visible = visible && isPinned(target); world.eid2obj.get(ObjectMenu.pinButtonRef[menu])!.visible = - visible && !isPinned(target) && canPin(APP.hubChannel!, world, target); + visible && !isPinned(target) && canPin(APP.hubChannel!, target); [ ObjectMenu.cameraFocusButtonRef[menu], diff --git a/src/bit-systems/object-spawner.ts b/src/bit-systems/object-spawner.ts index 46bc6f0c07..7c6713974d 100644 --- a/src/bit-systems/object-spawner.ts +++ b/src/bit-systems/object-spawner.ts @@ -4,7 +4,7 @@ import { FloatyObject, Held, HeldRemoteRight, Interacted, ObjectSpawner } from " import { FLOATY_OBJECT_FLAGS } from "../systems/floaty-object-system"; import { sleep } from "../utils/async-utils"; import { coroutine } from "../utils/coroutine"; -import { createNetworkedEntity } from "../utils/create-networked-entity"; +import { createNetworkedMedia } from "../utils/create-networked-entity"; import { EntityID } from "../utils/networking-types"; import { setMatrixWorld } from "../utils/three-utils"; import { animateScale, waitForMediaLoaded } from "./media-loading"; @@ -15,8 +15,8 @@ export enum OBJECT_SPAWNER_FLAGS { } function* spawnObjectJob(world: HubsWorld, spawner: EntityID) { - const spawned = createNetworkedEntity(world, "media", { - src: APP.getString(ObjectSpawner.src[spawner]), + const spawned = createNetworkedMedia(world, { + src: APP.getString(ObjectSpawner.src[spawner])!, recenter: false, resize: false, animateLoad: false, diff --git a/src/load-media-on-paste-or-drop.ts b/src/load-media-on-paste-or-drop.ts index 4d354d5f0e..9c47f90696 100644 --- a/src/load-media-on-paste-or-drop.ts +++ b/src/load-media-on-paste-or-drop.ts @@ -1,4 +1,4 @@ -import { createNetworkedEntity } from "./utils/create-networked-entity"; +import { createNetworkedMedia } from "./utils/create-networked-entity"; import { upload, parseURL } from "./utils/media-utils"; import { guessContentType } from "./utils/media-url-utils"; import { AElement } from "aframe"; @@ -23,7 +23,7 @@ export function spawnFromUrl(text: string) { console.warn(`Could not parse URL. Ignoring pasted text:\n${text}`); return; } - const eid = createNetworkedEntity(APP.world, "media", { + const eid = createNetworkedMedia(APP.world, { src: text, recenter: true, resize: !qsTruthy("noResize"), @@ -62,12 +62,11 @@ export async function spawnFromFileList(files: FileList) { recenter: true, resize: !qsTruthy("noResize"), animateLoad: true, - fileId: null, isObjectMenuTarget: true }; }); - const eid = createNetworkedEntity(APP.world, "media", params); + const eid = createNetworkedMedia(APP.world, params); const avatarPov = (document.querySelector("#avatar-pov-node")! as AElement).object3D; const obj = APP.world.eid2obj.get(eid)!; obj.position.copy(avatarPov.localToWorld(new Vector3(0, 0, -1.5))); diff --git a/src/utils/bit-pinning-helper.ts b/src/utils/bit-pinning-helper.ts index ee625aa0c0..55333ca8d9 100644 --- a/src/utils/bit-pinning-helper.ts +++ b/src/utils/bit-pinning-helper.ts @@ -33,10 +33,12 @@ const _signInAndPinOrUnpinElement = (hubChannel: HubChannel, world: HubsWorld, e action(); }; -export const canPin = (hubChannel: HubChannel, world: HubsWorld, eid: EntityID): boolean => { - const { - initialData: { fileId } - } = createMessageDatas.get(eid)!; +export const canPin = (hubChannel: HubChannel, eid: EntityID): boolean => { + const createMessageData = createMessageDatas.get(eid)!; + if (createMessageData.prefabName !== "media") { + return false; + } + const fileId = createMessageData.initialData.fileId; const hasFile = !!fileId; const hasPromotableFile = hasFile && APP.store.state.uploadPromotionTokens.some((upload: any) => upload.fileId === fileId); diff --git a/src/utils/chat-commands.ts b/src/utils/chat-commands.ts index f5951b521f..5cd037ddf7 100644 --- a/src/utils/chat-commands.ts +++ b/src/utils/chat-commands.ts @@ -3,7 +3,7 @@ import { Object3D } from "three"; import { HubsWorld } from "../app"; import { moveToSpawnPoint } from "../bit-systems/waypoint"; import { CharacterControllerSystem } from "../systems/character-controller-system"; -import { createNetworkedEntity } from "./create-networked-entity"; +import { createNetworkedMedia } from "./create-networked-entity"; import qsTruthy from "./qs_truthy"; function checkFlag(args: string[], flag: string) { @@ -51,7 +51,7 @@ export function add(world: HubsWorld, avatarPov: Object3D, args: string[]) { isObjectMenuTarget: !checkFlag(args, FLAG_NO_OBJECT_MENU) }; console.log("Adding media", initialData); - const eid = createNetworkedEntity(world, "media", initialData); + const eid = createNetworkedMedia(world, initialData); const obj = APP.world.eid2obj.get(eid)!; obj.position.copy(avatarPov.localToWorld(new THREE.Vector3(0, 0, -1.5))); obj.lookAt(avatarPov.getWorldPosition(new THREE.Vector3())); diff --git a/src/utils/create-networked-entity.ts b/src/utils/create-networked-entity.ts index ae2945fbb7..60ebeb05a8 100644 --- a/src/utils/create-networked-entity.ts +++ b/src/utils/create-networked-entity.ts @@ -2,6 +2,7 @@ import { hasComponent } from "bitecs"; import { HubsWorld } from "../app"; import { Networked } from "../bit-components"; import { createMessageDatas } from "../bit-systems/networking"; +import { MediaLoaderParams } from "../inflators/media-loader"; import { PrefabName, prefabs } from "../prefabs/prefabs"; import { renderAsEntity } from "../utils/jsx-entity"; import { hasPermissionToSpawn } from "../utils/permissions"; @@ -9,6 +10,10 @@ import { takeOwnership } from "../utils/take-ownership"; import { setNetworkedDataWithRoot } from "./assign-network-ids"; import type { ClientID, InitialData, NetworkID } from "./networking-types"; +export function createNetworkedMedia(world: HubsWorld, initialData: MediaLoaderParams) { + return createNetworkedEntity(world, "media", initialData); +} + export function createNetworkedEntity(world: HubsWorld, prefabName: PrefabName, initialData: InitialData) { if (!hasPermissionToSpawn(NAF.clientId, prefabName)) throw new Error(`You do not have permission to spawn ${prefabName}`); diff --git a/src/utils/networking-types.ts b/src/utils/networking-types.ts index af8465d320..766f090173 100644 --- a/src/utils/networking-types.ts +++ b/src/utils/networking-types.ts @@ -1,7 +1,8 @@ +import { MediaLoaderParams } from "../inflators/media-loader"; import { PrefabName } from "../prefabs/prefabs"; export type EntityID = number; -export type InitialData = any; +export type InitialData = MediaLoaderParams | any; export interface CreateMessageData { prefabName: PrefabName; initialData: InitialData;