From 64d9d695216a6c07bca47b6edcd59aea7634ddbd Mon Sep 17 00:00:00 2001
From: netpro2k <netpro2k@gmail.com>
Date: Mon, 16 Jul 2018 17:55:38 -0700
Subject: [PATCH] Cleanup of media-loader

---
 src/components/media-loader.js | 62 ++++++++++++++++++++++
 src/hub.js                     |  1 +
 src/utils/media-utils.js       | 95 ++--------------------------------
 3 files changed, 66 insertions(+), 92 deletions(-)
 create mode 100644 src/components/media-loader.js

diff --git a/src/components/media-loader.js b/src/components/media-loader.js
new file mode 100644
index 000000000..1ee8e20a2
--- /dev/null
+++ b/src/components/media-loader.js
@@ -0,0 +1,62 @@
+import { getBox, getCenterAndHalfExtents, getScaleCoefficient } from "../utils/auto-box-collider";
+import { resolveFarsparkUrl } from "../utils/media-utils";
+
+const fetchContentType = async url => fetch(url, { method: "HEAD" }).then(r => r.headers.get("content-type"));
+
+AFRAME.registerComponent("media-loader", {
+  schema: {
+    src: { type: "string" }
+  },
+
+  setShapeAndScale(didInflate) {
+    const mesh = this.el.getObject3D("mesh");
+    const boxRoot = didInflate ? mesh.parent : mesh;
+    const box = getBox(this.el, boxRoot);
+    const scaleCoefficient = getScaleCoefficient(0.5, box);
+    if (this.el.body && this.el.body.shapes.length > 1) {
+      this.el.removeAttribute("shape");
+    } else {
+      const center = new THREE.Vector3();
+      const halfExtents = new THREE.Vector3();
+      getCenterAndHalfExtents(this.el, box, center, halfExtents);
+      boxRoot.position.sub(center);
+      this.el.setAttribute("shape", {
+        shape: "box",
+        halfExtents: halfExtents
+      });
+    }
+    const scale = this.el.object3D.scale;
+    this.el.setAttribute("scale", {
+      x: scale.x * scaleCoefficient,
+      y: scale.y * scaleCoefficient,
+      z: scale.z * scaleCoefficient
+    });
+  },
+
+  // TODO: correctly handle case where src changes
+  async update() {
+    try {
+      const url = this.data.src;
+
+      // show loading mesh
+      this.el.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial()));
+      this.setShapeAndScale();
+
+      const { raw, origin, meta } = await resolveFarsparkUrl(url);
+      console.log("resolved", url, raw, origin, meta);
+
+      const contentType = (meta && meta.expected_content_type) || (await fetchContentType(raw));
+      if (contentType.startsWith("image/") || contentType.startsWith("video/")) {
+        this.el.setAttribute("image-plus", { src: raw, contentType });
+      } else if (contentType.startsWith("model/gltf") || url.endsWith(".gltf") || url.endsWith(".glb")) {
+        this.el.addEventListener("model-loaded", evt => this.setShapeAndScale(evt.detail.didInflate), { once: true });
+        this.el.setAttribute("gltf-model-plus", { src: raw, basePath: THREE.LoaderUtils.extractUrlBase(origin) });
+      } else {
+        throw new Error(`Unsupported content type: ${contentType}`);
+      }
+    } catch (e) {
+      console.error("Error adding media", e);
+      this.el.setAttribute("image-plus", { src: "error" });
+    }
+  }
+});
diff --git a/src/hub.js b/src/hub.js
index 674361330..65f541357 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -73,6 +73,7 @@ import "./components/auto-scale-cannon-physics-body";
 import "./components/position-at-box-shape-border";
 import "./components/remove-networked-object-button";
 import "./components/destroy-at-extreme-distances";
+import "./components/media-loader";
 
 import ReactDOM from "react-dom";
 import React from "react";
diff --git a/src/utils/media-utils.js b/src/utils/media-utils.js
index 5749035d5..5c0efb2ba 100644
--- a/src/utils/media-utils.js
+++ b/src/utils/media-utils.js
@@ -1,4 +1,3 @@
-import { getBox, getCenterAndHalfExtents, getScaleCoefficient } from "./auto-box-collider";
 const whitelistedHosts = [/^.*\.reticulum\.io$/, /^.*hubs\.mozilla\.com$/, /^hubs\.local$/];
 const isHostWhitelisted = hostname => !!whitelistedHosts.filter(r => r.test(hostname)).length;
 let resolveMediaUrl = "/api/v1/media";
@@ -18,108 +17,20 @@ export const resolveFarsparkUrl = async url => {
   }).then(r => r.json());
 };
 
-const fetchContentType = async url => fetch(url, { method: "HEAD" }).then(r => r.headers.get("content-type"));
-
 let interactableId = 0;
 const offset = { x: 0, y: 0, z: -1.5 };
-export const spawnNetworkedImage = (entity, src, contentType) => {
-  entity.id = "interactable-image-" + interactableId++;
-  // entity.setAttribute("networked", { template: "#interactable-image" });
-  // entity.addEventListener("image-loaded", function onBodyLoaded() {
-  //   entity.removeEventListener("image-loaded", onBodyLoaded);
-  // });
-  entity.setAttribute("image-plus", { src, contentType });
-  return entity;
-};
-
-export const spawnNetworkedInteractable = (entity, src, basePath) => {
-  entity.id = "interactable-model-" + interactableId++;
-  // entity.setAttribute("networked", { template: "#interactable-model" });
-  entity.addEventListener("model-loaded", function onModelLoaded(evt) {
-    entity.removeEventListener("model-loaded", onModelLoaded);
-    setShapeAndScale(entity, evt.detail.didInflate);
-  });
-  entity.setAttribute("gltf-model-plus", { src: src, basePath: basePath });
-  return entity;
-};
-
-AFRAME.registerComponent("media-loader", {
-  schema: {
-    src: { type: "string" }
-  },
-
-  async update() {
-    const entity = this.el;
-    const url = this.data.src;
-
-    try {
-      // show loading mesh
-      entity.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial()));
-      setShapeAndScale(entity);
-
-      const { raw, origin, meta } = await resolveFarsparkUrl(url);
-      console.log("resolved", url, raw, origin, meta);
-
-      const contentType = (meta && meta.expected_content_type) || (await fetchContentType(raw));
-      if (contentType.startsWith("image/") || contentType.startsWith("video/")) {
-        return spawnNetworkedImage(entity, raw, contentType);
-      } else if (contentType.startsWith("model/gltf") || url.endsWith(".gltf") || url.endsWith(".glb")) {
-        return spawnNetworkedInteractable(entity, raw, THREE.LoaderUtils.extractUrlBase(origin));
-      } else {
-        throw new Error(`Unsupported content type: ${contentType}`);
-      }
-    } catch (e) {
-      console.error("Error adding media", e);
-      return spawnNetworkedImage(entity, "error");
-    }
-  }
-});
-
-export const addMedia = url => {
+export const addMedia = src => {
   const scene = AFRAME.scenes[0];
 
   const entity = document.createElement("a-entity");
+  entity.id = "interactable-media-" + interactableId++;
   entity.setAttribute("networked", { template: "#interactable-media" });
-  // entity.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial()));
-  // entity.classList.add("interactable");
-  // entity.setAttribute("body", { type: "dynamic", shape: "none", mass: "1" });
-  // entity.setAttribute("grabbable", "");
-  // entity.setAttribute("hoverable", "");
-  // entity.setAttribute("stretchable", { useWorldPosition: true, usePhysics: "never" });
-  // entity.setAttribute("sticky-object", { autoLockOnRelease: true, autoLockOnLoad: true });
-  // entity.setAttribute("destroy-at-extreme-distances", "");
+  entity.setAttribute("media-loader", { src });
   entity.setAttribute("offset-relative-to", {
     target: "#player-camera",
     offset: offset,
     selfDestruct: true
   });
-  entity.setAttribute("media-loader", { src: url });
-  // setShapeAndScale(entity);
   scene.appendChild(entity);
   return entity;
 };
-
-function setShapeAndScale(entity, didInflate) {
-  const mesh = entity.getObject3D("mesh");
-  const boxRoot = didInflate ? mesh.parent : mesh;
-  const box = getBox(entity, boxRoot);
-  const scaleCoefficient = getScaleCoefficient(0.5, box);
-  if (entity.components.body && entity.components.body.body && entity.components.body.body.shapes.length > 1) {
-    entity.removeAttribute("shape");
-  } else {
-    const center = new THREE.Vector3();
-    const halfExtents = new THREE.Vector3();
-    getCenterAndHalfExtents(entity, box, center, halfExtents);
-    boxRoot.position.sub(center);
-    entity.setAttribute("shape", {
-      shape: "box",
-      halfExtents: halfExtents
-    });
-  }
-  const scale = entity.object3D.scale;
-  entity.setAttribute("scale", {
-    x: scale.x * scaleCoefficient,
-    y: scale.y * scaleCoefficient,
-    z: scale.z * scaleCoefficient
-  });
-}
-- 
GitLab