From 0f22ff85f03f2b3684aa5eccd9fa166a4872269d Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Wed, 10 May 2023 16:29:07 +0200 Subject: [PATCH] bitECS object list support This commit adds bitECS object list support. **Basic Strategy** Reuse the existing A-Frame based code as much as possible for now. In the related functions that take A-Frame element, take Object3D instead. Object3D has a reference to A-Frame element in the A-Frame based implementation and has a reference to Entity ID in the bitECS. The functions process with A-Frame element or Entity ID depending on whether new loader enabled. Explicitly use shouldUseNewLoader() and/or make two functions, one for A-Frame based and another one for bitECS based implementation, if different logics are needed between A-Frame based and bitECS based implementations. Duplicated codes may not be perfectly removed but it would be simpler to follow the code rather than the new loader pretends the old one. And it would be easier to edit the code when we will get rid of A-Frame. **Changes** - Introduce MediaInfo component and save url and content type into it when loading media in media-loader. The info is used in the object list - Fire listed_media_changed event when media is loaded via media-loader and when the loaded media entity is removed - Take Object3D instead of A-Frame element in the related functions - Use shouldUseNewLoader() and/or make two separated functions for A-Frame and bitECS where the different logics are needed **Future TODOs** - Support avatars - Support Pinning --- src/bit-components.js | 6 + src/bit-systems/media-loading.ts | 10 ++ src/components/media-loader.js | 4 +- src/components/super-spawner.js | 2 +- src/prefabs/media.tsx | 1 + .../room/hooks/useObjectList.js | 104 +++++++++++++----- src/react-components/room/object-hooks.js | 50 +++++++-- src/systems/camera-system.js | 58 +++++++--- src/utils/auto-box-collider.js | 16 +-- src/utils/jsx-entity.ts | 6 +- src/utils/media-sorting.js | 51 +++++---- 11 files changed, 219 insertions(+), 89 deletions(-) diff --git a/src/bit-components.js b/src/bit-components.js index e81d24954a..284451de9c 100644 --- a/src/bit-components.js +++ b/src/bit-components.js @@ -161,6 +161,12 @@ export const LoadedByMediaLoader = defineComponent(); export const MediaContentBounds = defineComponent({ bounds: [Types.f32, 3] }); +export const MediaInfo = defineComponent({ + accessibleUrl: Types.ui32, + contentType: Types.ui32 +}); +MediaInfo.accessibleUrl[$isStringType] = true; +MediaInfo.contentType[$isStringType] = true; // MediaImageLoaderData and MediaVideoLoaderData are // for parameters that are set at glTF inflators diff --git a/src/bit-systems/media-loading.ts b/src/bit-systems/media-loading.ts index 9195112acb..a2ce7803cf 100644 --- a/src/bit-systems/media-loading.ts +++ b/src/bit-systems/media-loading.ts @@ -6,6 +6,7 @@ import { LoadedByMediaLoader, MediaContentBounds, MediaImageLoaderData, + MediaInfo, MediaLoaded, MediaLoader, MediaVideoLoaderData, @@ -223,6 +224,9 @@ function* loadMedia(world: HubsWorld, eid: EntityID) { const urlData = (yield resolveMediaInfo(src)) as MediaInfo; media = yield* loadByMediaType(world, eid, urlData); addComponent(world, MediaLoaded, media); + addComponent(world, MediaInfo, media); + MediaInfo.accessibleUrl[media] = APP.getSid(urlData.accessibleUrl); + MediaInfo.contentType[media] = APP.getSid(urlData.contentType); } catch (e) { console.error(e); media = renderAsEntity(world, ErrorObject()); @@ -268,6 +272,9 @@ const jobs = new JobRunner(); const mediaLoaderQuery = defineQuery([MediaLoader]); const mediaLoaderEnterQuery = enterQuery(mediaLoaderQuery); const mediaLoaderExitQuery = exitQuery(mediaLoaderQuery); +const mediaLoadedQuery = defineQuery([MediaLoaded]); +const mediaLoadedEnterQuery = enterQuery(mediaLoadedQuery); +const mediaLoadedExitQuery = exitQuery(mediaLoadedQuery); export function mediaLoadingSystem(world: HubsWorld) { mediaLoaderEnterQuery(world).forEach(function (eid) { jobs.add(eid, clearRollbacks => loadAndAnimateMedia(world, eid, clearRollbacks)); @@ -285,5 +292,8 @@ export function mediaLoadingSystem(world: HubsWorld) { } }); + mediaLoadedEnterQuery(world).forEach(() => APP.scene?.emit("listed_media_changed")); + mediaLoadedExitQuery(world).forEach(() => APP.scene?.emit("listed_media_changed")); + jobs.tick(); } diff --git a/src/components/media-loader.js b/src/components/media-loader.js index 0c63121385..e76eb88354 100644 --- a/src/components/media-loader.js +++ b/src/components/media-loader.js @@ -111,7 +111,7 @@ AFRAME.registerComponent("media-loader", { setMatrixWorld(mesh, originalMeshMatrix); } else { // Move the mesh such that the center of its bounding box is in the same position as the parent matrix position - const box = getBox(this.el, mesh); + const box = getBox(this.el.object3D, mesh); const scaleCoefficient = fitToBox ? getScaleCoefficient(0.5, box) : 1; const { min, max } = box; center.addVectors(min, max).multiplyScalar(0.5 * scaleCoefficient); @@ -283,7 +283,7 @@ AFRAME.registerComponent("media-loader", { } // TODO this does duplicate work in some cases, but finish() is the only consistent place to do it - const contentBounds = getBox(this.el, this.el.getObject3D("mesh")).getSize(new THREE.Vector3()); + const contentBounds = getBox(this.el.object3D, this.el.getObject3D("mesh")).getSize(new THREE.Vector3()); addComponent(APP.world, MediaContentBounds, el.eid); MediaContentBounds.bounds[el.eid].set(contentBounds.toArray()); diff --git a/src/components/super-spawner.js b/src/components/super-spawner.js index 2c17fb5cef..7843bc0e80 100644 --- a/src/components/super-spawner.js +++ b/src/components/super-spawner.js @@ -111,7 +111,7 @@ AFRAME.registerComponent("super-spawner", { ? 1 : 0.5; - const scaleCoefficient = getScaleCoefficient(boxSize, getBox(spawnedEntity, spawnedEntity.object3D)); + const scaleCoefficient = getScaleCoefficient(boxSize, getBox(spawnedEntity.object3D, spawnedEntity.object3D)); this.spawnedMediaScale.divideScalar(scaleCoefficient); }, diff --git a/src/prefabs/media.tsx b/src/prefabs/media.tsx index 6718c5a239..cacb88ef5c 100644 --- a/src/prefabs/media.tsx +++ b/src/prefabs/media.tsx @@ -28,6 +28,7 @@ export function MediaPrefab(params: MediaLoaderParams): EntityDef { collisionMask: COLLISION_LAYERS.HANDS }} scale={[1, 1, 1]} + inspectable /> ); } diff --git a/src/react-components/room/hooks/useObjectList.js b/src/react-components/room/hooks/useObjectList.js index 26367bdb85..79e9f7c77f 100644 --- a/src/react-components/room/hooks/useObjectList.js +++ b/src/react-components/room/hooks/useObjectList.js @@ -1,11 +1,21 @@ import React, { useState, useEffect, useContext, createContext, useCallback, Children, cloneElement } from "react"; import PropTypes from "prop-types"; -import { mediaSort, getMediaType } from "../../../utils/media-sorting.js"; +import { mediaSort, mediaSortAframe, getMediaType, getMediaTypeAframe } from "../../../utils/media-sorting.js"; +import { shouldUseNewLoader } from "../../../utils/bit-utils"; +import { defineQuery, hasComponent } from "bitecs"; +import { MediaInfo } from "../../../bit-components.js"; -function getDisplayString(el) { +function getUrl(eid) { + return hasComponent(APP.world, MediaInfo, eid) ? APP.getString(MediaInfo.accessibleUrl[eid]) : ""; +} + +function getUrlAframe(el) { // Having a listed-media component does not guarantee the existence of a media-loader component, // so don't crash if there isn't one. - const url = (el.components["media-loader"] && el.components["media-loader"].data.src) || ""; + return (el.components["media-loader"] && el.components["media-loader"].data.src) || ""; +} + +function getDisplayString(url) { const split = url.split("/"); const resourceName = split[split.length - 1].split("?")[0]; let httpIndex = -1; @@ -46,12 +56,14 @@ function handleInspect(scene, object, callback) { callback(object); - if (object.el.object3D !== cameraSystem.inspectable) { + const object3D = shouldUseNewLoader() ? APP.world.eid2obj.get(object.eid) : object.el.object3D; + + if (object3D !== cameraSystem.inspectable) { if (cameraSystem.inspectable) { cameraSystem.uninspect(false); } - cameraSystem.inspect(object.el, 1.5, false); + cameraSystem.inspect(object3D, 1.5, false); } } @@ -63,10 +75,12 @@ function handleDeselect(scene, object, callback) { cameraSystem.uninspect(false); if (object) { - cameraSystem.inspect(object.el, 1.5, false); + const object3D = shouldUseNewLoader() ? APP.world.eid2obj.get(object.eid) : object.el.object3D; + cameraSystem.inspect(object3D, 1.5, false); } } +const queryListedMedia = defineQuery([MediaInfo]); export function ObjectListProvider({ scene, children }) { const [objects, setObjects] = useState([]); const [focusedObject, setFocusedObject] = useState(null); // The object currently shown in the viewport @@ -76,14 +90,26 @@ export function ObjectListProvider({ scene, children }) { useEffect(() => { function updateMediaEntities() { - const objects = scene.systems["listed-media"].els.sort(mediaSort).map(el => ({ - id: el.object3D.id, - name: getDisplayString(el), - type: getMediaType(el), - el - })); - - setObjects(objects); + if (shouldUseNewLoader()) { + const objects = queryListedMedia(APP.world) + .sort(mediaSort) + .map(eid => ({ + id: APP.world.eid2obj.get(eid)?.id, + name: getDisplayString(getUrl(eid)), + type: getMediaType(eid), + eid: eid + })); + setObjects(objects); + } else { + const objects = scene.systems["listed-media"].els.sort(mediaSortAframe).map(el => ({ + id: el.object3D.id, + name: getDisplayString(getUrlAframe(el)), + type: getMediaTypeAframe(el), + eid: el.eid, + el + })); + setObjects(objects); + } } let timeout; @@ -108,23 +134,45 @@ export function ObjectListProvider({ scene, children }) { function onInspectTargetChanged() { const cameraSystem = scene.systems["hubs-systems"].cameraSystem; - const inspectedEl = cameraSystem.inspectable && cameraSystem.inspectable.el; - - if (inspectedEl) { - const object = objects.find(o => o.el === inspectedEl); - - if (object) { - setSelectedObject(object); + if (shouldUseNewLoader()) { + const inspectedEid = cameraSystem.inspectable && cameraSystem.inspectable.eid; + + if (inspectedEid) { + const object = objects.find(o => o.eid === inspectedEid); + + if (object) { + setSelectedObject(object); + } else { + setSelectedObject({ + id: APP.world.eid2obj.get(inspectedEid)?.id, + name: getDisplayString(getUrl(inspectedEid)), + type: getMediaType(inspectedEid), + eid: inspectedEid + }); + } } else { - setSelectedObject({ - id: inspectedEl.object3D.id, - name: getDisplayString(inspectedEl), - type: getMediaType(inspectedEl), - el: inspectedEl - }); + setSelectedObject(null); } } else { - setSelectedObject(null); + const inspectedEl = cameraSystem.inspectable && cameraSystem.inspectable.el; + + if (inspectedEl) { + const object = objects.find(o => o.el === inspectedEl); + + if (object) { + setSelectedObject(object); + } else { + setSelectedObject({ + id: inspectedEl.object3D.id, + name: getDisplayString(getUrlAframe(inspectedEl)), + type: getMediaTypeAframe(inspectedEl), + eid: inspectedEl.eid, + el: inspectedEl + }); + } + } else { + setSelectedObject(null); + } } } diff --git a/src/react-components/room/object-hooks.js b/src/react-components/room/object-hooks.js index 1cc4861c6a..50553a5966 100644 --- a/src/react-components/room/object-hooks.js +++ b/src/react-components/room/object-hooks.js @@ -1,24 +1,36 @@ import { useEffect, useState, useCallback, useMemo } from "react"; import { removeNetworkedObject } from "../../utils/removeNetworkedObject"; +import { shouldUseNewLoader } from "../../utils/bit-utils"; import { rotateInPlaceAroundWorldUp, affixToWorldUp } from "../../utils/three-utils"; import { getPromotionTokenForFile } from "../../utils/media-utils"; import { hasComponent } from "bitecs"; -import { Static } from "../../bit-components"; import { isPinned as getPinnedState } from "../../bit-systems/networking"; +import { MediaInfo, Static } from "../../bit-components"; +import { deleteTheDeletableAncestor } from "../../bit-systems/delete-entity-system"; export function isMe(object) { - return object.el.id === "avatar-rig"; + return object.id === "avatar-rig"; } export function isPlayer(object) { - return !!object.el.components["networked-avatar"]; + if (shouldUseNewLoader()) { + // TODO Add when networked avatar is migrated + return false; + } else { + return !!object.el.components["networked-avatar"]; + } } export function getObjectUrl(object) { - const mediaLoader = object.el.components["media-loader"]; - - const url = - mediaLoader && ((mediaLoader.data.mediaOptions && mediaLoader.data.mediaOptions.href) || mediaLoader.data.src); + let url; + if (shouldUseNewLoader()) { + const urlSid = MediaInfo.accessibleUrl[object.eid]; + url = APP.getString(urlSid); + } else { + const mediaLoader = object.el.components["media-loader"]; + url = + mediaLoader && ((mediaLoader.data.mediaOptions && mediaLoader.data.mediaOptions.href) || mediaLoader.data.src); + } if (url && !url.startsWith("hubs://")) { return url; @@ -28,7 +40,7 @@ export function getObjectUrl(object) { } export function usePinObject(hubChannel, scene, object) { - const [isPinned, setIsPinned] = useState(getPinnedState(object.el.eid)); + const [isPinned, setIsPinned] = useState(getPinnedState(object.eid)); const pinObject = useCallback(() => { const el = object.el; @@ -51,6 +63,11 @@ export function usePinObject(hubChannel, scene, object) { }, [isPinned, pinObject, unpinObject]); useEffect(() => { + // TODO Add when pinning is migrated + if (shouldUseNewLoader()) { + return; + } + const el = object.el; function onPinStateChanged() { @@ -65,6 +82,11 @@ export function usePinObject(hubChannel, scene, object) { }; }, [object]); + if (shouldUseNewLoader()) { + // TODO Add when pinning is migrated + return false; + } + const el = object.el; let userOwnsFile = false; @@ -114,16 +136,20 @@ export function useGoToSelectedObject(scene, object) { export function useRemoveObject(hubChannel, scene, object) { const removeObject = useCallback(() => { - removeNetworkedObject(scene, object.el); + if (shouldUseNewLoader()) { + deleteTheDeletableAncestor(APP.world, object.eid); + } else { + removeNetworkedObject(scene, object.el); + } }, [scene, object]); - const el = object.el; + const eid = object.eid; const canRemoveObject = !!( scene.is("entered") && !isPlayer(object) && - !getPinnedState(el.eid) && - !hasComponent(APP.world, Static, el.eid) && + !getPinnedState(eid) && + !hasComponent(APP.world, Static, eid) && hubChannel.can("spawn_and_move_media") ); diff --git a/src/systems/camera-system.js b/src/systems/camera-system.js index ee6cdbeee7..332d6b2d1d 100644 --- a/src/systems/camera-system.js +++ b/src/systems/camera-system.js @@ -8,8 +8,19 @@ import { qsGet } from "../utils/qs_truthy"; const customFOV = qsGet("fov"); const enableThirdPersonMode = qsTruthy("thirdPerson"); import { Layers } from "../camera-layers"; +import { Inspectable } from "../bit-components"; +import { findAncestorWithComponent, shouldUseNewLoader } from "../utils/bit-utils"; + +function getInspectableInHierarchy(eid) { + let inspectable = findAncestorWithComponent(APP.world, Inspectable, eid); + if (!inspectable) { + console.warn("could not find inspectable in hierarchy"); + inspectable = eid; + } + return APP.world.eid2obj.get(inspectable); +} -function getInspectableInHierarchy(el) { +function getInspectableInHierarchyAframe(el) { let inspectable = el; while (inspectable) { if (isTagged(inspectable, "inspectable")) { @@ -36,8 +47,14 @@ function pivotFor(el) { return child.object3D; } -export function getInspectableAndPivot(el) { - const inspectable = getInspectableInHierarchy(el); +function getInspectableAndPivot(eid) { + const inspectable = getInspectableInHierarchy(eid); + // TODO Add support for pivotFor (avatars only) + return { inspectable, pivot: inspectable }; +} + +function getInspectableAndPivotAframe(el) { + const inspectable = getInspectableInHierarchyAframe(el); const pivot = pivotFor(inspectable.el); return { inspectable, pivot }; } @@ -119,22 +136,16 @@ const moveRigSoCameraLooksAtPivot = (function () { decompose(camera.matrixWorld, cwp, cwq); rig.getWorldQuaternion(cwq); - const box = getBox(inspectable.el, inspectable.el.getObject3D("mesh") || inspectable, true); + const box = getBox(inspectable, inspectable, true); if (box.min.x === Infinity) { // fix edgecase where inspectable object has no mesh / dimensions box.min.subVectors(owp, defaultBoxMax); box.max.addVectors(owp, defaultBoxMax); } box.getCenter(center); - const vrMode = inspectable.el.sceneEl.is("vr-mode"); + const vrMode = APP.scene.is("vr-mode"); const dist = - calculateViewingDistance( - inspectable.el.sceneEl.camera.fov, - inspectable.el.sceneEl.camera.aspect, - box, - center, - vrMode - ) * distanceMod; + calculateViewingDistance(APP.scene.camera.fov, APP.scene.camera.aspect, box, center, vrMode) * distanceMod; target.position.addVectors( owp, oForw @@ -252,15 +263,19 @@ export class CameraSystem { this.mode = NEXT_MODES[this.mode] || 0; } - inspect(el, distanceMod, fireChangeEvent = true) { - const { inspectable, pivot } = getInspectableAndPivot(el); - + inspect(obj, distanceMod, fireChangeEvent = true) { this.verticalDelta = 0; this.horizontalDelta = 0; this.inspectZoom = 0; + if (this.mode === CAMERA_MODE_INSPECT) { return; } + + const { inspectable, pivot } = shouldUseNewLoader() + ? getInspectableAndPivot(obj.eid) + : getInspectableAndPivotAframe(obj.el); + const scene = AFRAME.scenes[0]; scene.object3D.traverse(ensureLightsAreSeenByCamera); scene.classList.add("hand-cursor"); @@ -282,7 +297,16 @@ export class CameraSystem { this.viewingCamera.updateMatrices(); this.snapshot.matrixWorld.copy(this.viewingRig.object3D.matrixWorld); - this.snapshot.audio = !(inspectable.el && isTagged(inspectable.el, "preventAudioBoost")) && getAudio(inspectable); + let preventAudioBoost; + + if (shouldUseNewLoader()) { + // TODO Add when avatar is migrated + preventAudioBoost = false; + } else { + preventAudioBoost = inspectable.el && isTagged(inspectable.el, "preventAudioBoost"); + } + + this.snapshot.audio = !preventAudioBoost && getAudio(inspectable); if (this.snapshot.audio) { this.snapshot.audio.updateMatrices(); this.snapshot.audioTransform.copy(this.snapshot.audio.matrixWorld); @@ -427,7 +451,7 @@ export class CameraSystem { const hoverEl = this.interaction.state.rightRemote.hovered || this.interaction.state.leftRemote.hovered; if (hoverEl) { - this.inspect(hoverEl, 1.5); + this.inspect(hoverEl.object3D, 1.5); } } else if (this.mode === CAMERA_MODE_INSPECT && this.userinput.get(paths.actions.stopInspecting)) { scene.emit("uninspect"); diff --git a/src/utils/auto-box-collider.js b/src/utils/auto-box-collider.js index 689c598c68..c6f5e852a2 100644 --- a/src/utils/auto-box-collider.js +++ b/src/utils/auto-box-collider.js @@ -90,13 +90,13 @@ export const computeObjectAABB = (function () { })(); const rotation = new THREE.Euler(); -export function getBox(entity, boxRoot, worldSpace) { +export function getBox(obj, boxRoot, worldSpace) { const box = new THREE.Box3(); - rotation.copy(entity.object3D.rotation); - entity.object3D.rotation.set(0, 0, 0); + rotation.copy(obj.rotation); + obj.rotation.set(0, 0, 0); - entity.object3D.updateMatrices(true, true); + obj.updateMatrices(true, true); boxRoot.updateMatrices(true, true); boxRoot.updateMatrixWorld(true); @@ -104,11 +104,11 @@ export function getBox(entity, boxRoot, worldSpace) { if (!box.isEmpty()) { if (!worldSpace) { - entity.object3D.worldToLocal(box.min); - entity.object3D.worldToLocal(box.max); + obj.worldToLocal(box.min); + obj.worldToLocal(box.max); } - entity.object3D.rotation.copy(rotation); - entity.object3D.matrixNeedsUpdate = true; + obj.rotation.copy(rotation); + obj.matrixNeedsUpdate = true; } boxRoot.matrixWorldNeedsUpdate = true; diff --git a/src/utils/jsx-entity.ts b/src/utils/jsx-entity.ts index 524a95fca8..f28210286d 100644 --- a/src/utils/jsx-entity.ts +++ b/src/utils/jsx-entity.ts @@ -38,8 +38,8 @@ import { MaterialTag, VideoTextureSource, Quack, - Mirror, - MixerAnimatableInitialize + MixerAnimatableInitialize, + Inspectable } from "../bit-components"; import { inflateMediaLoader } from "../inflators/media-loader"; import { inflateMediaFrame } from "../inflators/media-frame"; @@ -359,6 +359,7 @@ export interface JSXComponentData extends ComponentData { waypointPreview?: boolean; pdf?: PDFParams; loopAnimation?: LoopAnimationParams; + inspectable?: boolean; } export interface GLTFComponentData extends ComponentData { @@ -464,6 +465,7 @@ const jsxInflators: Required<{ [K in keyof JSXComponentData]: InflatorFn }> = { quack: createDefaultInflator(Quack), mixerAnimatable: createDefaultInflator(MixerAnimatableInitialize), loopAnimation: inflateLoopAnimationInitialize, + inspectable: createDefaultInflator(Inspectable), // inflators that create Object3Ds object3D: addObject3DComponent, slice9: inflateSlice9, diff --git a/src/utils/media-sorting.js b/src/utils/media-sorting.js index 7cf1d44015..f3b237fb99 100644 --- a/src/utils/media-sorting.js +++ b/src/utils/media-sorting.js @@ -1,9 +1,5 @@ -import { faVideo } from "@fortawesome/free-solid-svg-icons/faVideo"; -import { faMusic } from "@fortawesome/free-solid-svg-icons/faMusic"; -import { faImage } from "@fortawesome/free-solid-svg-icons/faImage"; -import { faNewspaper } from "@fortawesome/free-solid-svg-icons/faNewspaper"; -import { faQuestion } from "@fortawesome/free-solid-svg-icons/faQuestion"; -import { faCube } from "@fortawesome/free-solid-svg-icons/faCube"; +import { hasComponent } from "bitecs"; +import { GLTFModel, MediaImage, MediaInfo, MediaPDF, MediaVideo } from "../bit-components"; export const SORT_ORDER_VIDEO = 0; export const SORT_ORDER_AUDIO = 1; @@ -12,7 +8,24 @@ export const SORT_ORDER_PDF = 3; export const SORT_ORDER_MODEL = 4; export const SORT_ORDER_UNIDENTIFIED = 5; -export function mediaSortOrder(el) { +function mediaSortOrder(eid) { + if (hasComponent(APP.world, MediaVideo, eid)) { + if (hasComponent(APP.world, MediaInfo, eid)) { + const contentTypeSid = MediaInfo.contentType[eid]; + const contentType = APP.getString(contentTypeSid); + if (contentType.startsWith("audio/")) { + return SORT_ORDER_AUDIO; + } + } + return SORT_ORDER_VIDEO; + } + if (hasComponent(APP.world, MediaImage, eid)) return SORT_ORDER_IMAGE; + if (hasComponent(APP.world, MediaPDF, eid)) return SORT_ORDER_PDF; + if (hasComponent(APP.world, GLTFModel, eid)) return SORT_ORDER_MODEL; + return SORT_ORDER_UNIDENTIFIED; +} + +function mediaSortOrderAframe(el) { if (el.components["media-video"] && el.components["media-video"].data.contentType.startsWith("audio/")) { return SORT_ORDER_AUDIO; } @@ -23,18 +36,13 @@ export function mediaSortOrder(el) { return SORT_ORDER_UNIDENTIFIED; } -export function mediaSort(el1, el2) { - return mediaSortOrder(el1) - mediaSortOrder(el2); +export function mediaSort(eid1, eid2) { + return mediaSortOrder(eid1) - mediaSortOrder(eid2); } -export const DISPLAY_IMAGE = new Map([ - [SORT_ORDER_VIDEO, faVideo], - [SORT_ORDER_AUDIO, faMusic], - [SORT_ORDER_IMAGE, faImage], - [SORT_ORDER_PDF, faNewspaper], - [SORT_ORDER_UNIDENTIFIED, faQuestion], - [SORT_ORDER_MODEL, faCube] -]); +export function mediaSortAframe(el1, el2) { + return mediaSortOrderAframe(el1) - mediaSortOrderAframe(el2); +} const SORT_ORDER_TO_TYPE = { [SORT_ORDER_VIDEO]: "video", @@ -44,7 +52,12 @@ const SORT_ORDER_TO_TYPE = { [SORT_ORDER_MODEL]: "model" }; -export function getMediaType(el) { - const order = mediaSortOrder(el); +export function getMediaType(eid) { + const order = mediaSortOrder(eid); + return SORT_ORDER_TO_TYPE[order]; +} + +export function getMediaTypeAframe(el) { + const order = mediaSortOrderAframe(el); return SORT_ORDER_TO_TYPE[order]; }