Skip to content
Snippets Groups Projects
media-utils.js 2.26 KiB
Newer Older
const whitelistedHosts = [/^.*\.reticulum\.io$/, /^.*hubs\.mozilla\.com$/, /^hubs\.local$/];
const isHostWhitelisted = hostname => !!whitelistedHosts.filter(r => r.test(hostname)).length;
let mediaAPIEndpoint = "/api/v1/media";
if (process.env.NODE_ENV === "development") {
  mediaAPIEndpoint = `https://${process.env.DEV_RETICULUM_SERVER}${mediaAPIEndpoint}`;
const resolveMediaCache = new Map();
export const resolveMedia = async url => {
  const parsedUrl = new URL(url);
  if (resolveMediaCache.has(url)) return resolveMediaCache.get(url);
  const resolved =
    (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") || isHostWhitelisted(parsedUrl.hostname)
      ? { raw: url, origin: url }
      : await fetch(mediaAPIEndpoint, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ media: { url } })
        }).then(r => r.json());
  resolveMediaCache.set(url, resolved);
  return resolved;
let interactableId = 0;
export const addMedia = (src, resize = false) => {
  const scene = AFRAME.scenes[0];
joni's avatar
joni committed

  const entity = document.createElement("a-entity");
netpro2k's avatar
netpro2k committed
  entity.id = "interactable-media-" + interactableId++;
  entity.setAttribute("networked", { template: "#interactable-media" });
  entity.setAttribute("media-loader", { resize, src: typeof src === "string" ? src : "" });
joni's avatar
joni committed
  scene.appendChild(entity);

  if (typeof src === "object") {
    const uploadResponse = upload(src).then(response => {
      const src = response.raw;
      const contentType = response.meta.expected_content_type;
      const token = response.meta.access_token;
      entity.setAttribute("media-loader", { src, contentType, token });
    });
  }

export const upload = file => {
  const formData = new FormData();
  formData.append("media", file);
  return fetch(mediaAPIEndpoint, {
    method: "POST",
    body: formData

    // We do NOT specify a Content-Type header like so
    //     headers: { "Content-Type" : "multipart/form-data" },
    // because we want the browser to automatically add
    //     "Content-Type" : "multipart/form-data; boundary=...--------------<boundary_size>",
    // See https://stanko.github.io/uploading-files-using-fetch-multipart-form-data/ for details.
  }).then(r => r.json());
};