Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions .defaults.env
Original file line number Diff line number Diff line change
@@ -1,36 +1,8 @@
# To override these variables, create a .env file containing the overrides.

# Domain for short links
SHORTLINK_DOMAIN="hub.link"

# The Reticulum backend to connect to. Used for storing information about active hubs.
# See here for the server code: https://github.com/mozilla/reticulum
RETICULUM_SERVER="hubs.local:4000"

# CORS proxy.
CORS_PROXY_SERVER="cors-proxy.jel.app,cors-proxy-1.jel.app,cors-proxy-2.jel.app,cors-proxy-3.jel.app,cors-proxy-4.jel.app,cors-proxy-5.jel.app,cors-proxy-6.jel.app,cors-proxy-7.jel.app,cors-proxy-8.jel.app,cors-proxy-9.jel.app"

# The thumbnailing backend to connect to.
# See here for the server code: https://github.com/MozillaReality/farspark or https://github.com/MozillaReality/nearspark
THUMBNAIL_SERVER="nearspark-dev.reticulum.io"

# The root URL under which Hubs expects environment GLTF bundles to be served.
ASSET_BUNDLE_SERVER="https://asset-bundles-prod.reticulum.io"

# Terra server serving terrains.
TERRA_SERVER="arweave.net/BK4k7-aBjxWkQLANR7AmwHte2bROgUulsQuq5D6Zqd0"

# Comma-separated list of domains which are known to not need CORS proxying
NON_CORS_PROXY_DOMAINS="hubs.local,dev.reticulum.io"

# The root URL under which Hubs expects static assets to be served.
BASE_ASSETS_PATH=/

# The default scene to use. Note the example scene id is only availible on dev.reticulum.io
DEFAULT_SCENE_SID="JGLt8DP"

MIXPANEL_TOKEN="9bc3e675ed764e6ecf48a440d932ebd8"

# Uncomment to load the app config from the reticulum server in development.
# Useful when testing the admin panel.
# LOAD_APP_CONFIG=true
11 changes: 1 addition & 10 deletions src/utils/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,7 @@ import sceneEditorLogo from "../assets/images/editor-logo.png";
const configs = {};
let isAdmin = false;

[
"RETICULUM_SERVER",
"THUMBNAIL_SERVER",
"TERRA_SERVER",
"SENTRY_DSN",
"GA_TRACKING_ID",
"MIXPANEL_TOKEN",
"SHORTLINK_DOMAIN",
"BASE_ASSETS_PATH"
].forEach(x => {
["RETICULUM_SERVER", "TERRA_SERVER", "BASE_ASSETS_PATH"].forEach(x => {
const el = document.querySelector(`meta[name='env:${x.toLowerCase()}']`);
configs[x] = el ? el.getAttribute("content") : process.env[x];

Expand Down
101 changes: 0 additions & 101 deletions src/utils/phoenix-utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Socket, Presence } from "phoenix";
import configs from "./configs";
import { getDefaultWorldColorPreset } from "./world-color-presets";

Expand All @@ -9,10 +8,6 @@ export function hasReticulumServer() {
return !!configs.RETICULUM_SERVER;
}

export function isLocalClient() {
return hasReticulumServer() && document.location.host !== configs.RETICULUM_SERVER;
}

const resolverLink = document.createElement("a");

export function getReticulumFetchUrl(path, absolute = false, host = null, port = null) {
Expand All @@ -26,79 +21,6 @@ export function getReticulumFetchUrl(path, absolute = false, host = null, port =
}
}

let directReticulumHostAndPort;

async function refreshDirectReticulumHostAndPort() {
const qs = new URLSearchParams(location.search);
let host = qs.get("phx_host");
host = "hubs.local";
const port = "4000";
directReticulumHostAndPort = { host, port };
}

export function getDirectReticulumFetchUrl(path, absolute = false) {
if (!directReticulumHostAndPort) {
console.warn("Cannot call getDirectReticulumFetchUrl before connectToReticulum. Returning non-direct url.");
return getReticulumFetchUrl(path, absolute);
}

const { host, port } = directReticulumHostAndPort;
return getReticulumFetchUrl(path, absolute, host, port);
}

export async function connectToReticulum(debug = false, params = null, socketClass = Socket, existingSocket = null) {
const qs = new URLSearchParams(location.search);

const getNewSocketUrl = async () => {
await refreshDirectReticulumHostAndPort();
const { host, port } = directReticulumHostAndPort;
const protocol =
qs.get("phx_protocol") ||
configs.RETICULUM_SOCKET_PROTOCOL ||
(document.location.protocol === "https:" ? "wss:" : "ws:");

return `${protocol}//${host}${port ? `:${port}` : ""}`;
};

const socketUrl = await getNewSocketUrl();
console.log(`Phoenix Socket URL: ${socketUrl}`);

const socketSettings = {};

if (debug) {
socketSettings.logger = (kind, msg, data) => {
console.log(`${kind}: ${msg}`, data);
};
}

let socket = existingSocket;

if (!socket) {
if (params) {
socketSettings.params = params;
}

socket = new socketClass(`${socketUrl}/socket`, socketSettings);

socket.onError(async () => {
const endPointPath = new URL(socket.endPoint).pathname;
const newSocketUrl = await getNewSocketUrl();
const newEndPoint = `${newSocketUrl}${endPointPath}`;
console.log(`Socket error, changed endpoint to ${newEndPoint}`);
socket.endPoint = newEndPoint;
});
}

socket.connect();

return socket;
}

export function getLandingPageForPhoto(photoUrl) {
const parsedUrl = new URL(photoUrl);
return getReticulumFetchUrl(parsedUrl.pathname.replace(".png", ".html") + parsedUrl.search, true);
}

export function fetchReticulumAuthenticated(url, method = "GET", payload) {
const { token } = window.APP.store.state.credentials;
const retUrl = getReticulumFetchUrl(url);
Expand Down Expand Up @@ -230,26 +152,3 @@ export function getPresenceContextForSession(presences, sessionId) {
export function getPresenceProfileForSession(presences, sessionId) {
return (getPresenceEntryForSession(presences, sessionId) || {}).profile || {};
}

// Unbinds presence, and returns a function that must be passed the new channel to rebind.
export function unbindPresence(presence) {
if (!presence) return () => presence;

const presenceBindings = {
onJoin: presence.caller.onJoin,
onLeave: presence.caller.onLeave,
onSync: presence.caller.onSync
};

presence.onJoin(function() {});
presence.onLeave(function() {});
presence.onSync(function() {});

return channel => {
const presence = new Presence(channel);
presence.onJoin(presenceBindings.onJoin);
presence.onLeave(presenceBindings.onLeave);
presence.onSync(presenceBindings.onSync);
return presence;
};
}
79 changes: 6 additions & 73 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const path = require("path");
const webpack = require("webpack");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const TOML = require("@iarna/toml");
const fetch = require("node-fetch");

function createDefaultAppConfig() {
const schemaPath = path.join(__dirname, "src", "schema.toml");
Expand Down Expand Up @@ -40,50 +39,6 @@ function createDefaultAppConfig() {
return appConfig;
}

async function fetchAppConfigAndEnvironmentVars() {
if (!fs.existsSync(".ret.credentials")) {
throw new Error("Not logged in to Hubs Cloud. Run `npm run login` first.");
}

const { host, token } = JSON.parse(fs.readFileSync(".ret.credentials"));

const headers = {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
};

// Load the Hubs Cloud instance's app config in development
const appConfigsResponse = await fetch(`https://${host}/api/v1/app_configs`, { headers });

if (!appConfigsResponse.ok) {
throw new Error(`Error fetching Hubs Cloud config "${appConfigsResponse.statusText}"`);
}

const appConfig = await appConfigsResponse.json();

// dev.reticulum.io doesn't run ita
if (host === "dev.reticulum.io") {
return appConfig;
}

const hubsConfigsResponse = await fetch(`https://${host}/api/ita/configs/hubs`, { headers });

const hubsConfigs = await hubsConfigsResponse.json();

if (!hubsConfigsResponse.ok) {
throw new Error(`Error fetching Hubs Cloud config "${hubsConfigsResponse.statusText}"`);
}

const { shortlink_domain, thumbnail_server, terra_server } = hubsConfigs.general;

process.env.RETICULUM_SERVER = host;
process.env.SHORTLINK_DOMAIN = shortlink_domain;
process.env.THUMBNAIL_SERVER = thumbnail_server;
process.env.TERRA_SERVER = terra_server;

return appConfig;
}

const threeExamplesDir = path.resolve(__dirname, "node_modules", "three", "examples");
const basisTranscoderPath = path.resolve(threeExamplesDir, "js", "libs", "basis", "basis_transcoder.js");
const basisWasmPath = path.resolve(threeExamplesDir, "js", "libs", "basis", "basis_transcoder.wasm");
Expand All @@ -100,34 +55,18 @@ module.exports = async (env, argv) => {
let appConfig = undefined;

/**
* Initialize the Webpack build envrionment for the provided environment.
* Initialize the Webpack build environment for the provided environment.
*/

if (argv.mode !== "production" || env.bundleAnalyzer) {
if (env.loadAppConfig || process.env.LOAD_APP_CONFIG) {
if (!env.localDev) {
// Load and set the app config and environment variables from the remote server.
// A Hubs Cloud server or dev.reticulum.io can be used.
appConfig = await fetchAppConfigAndEnvironmentVars();
}
} else {
// Use the default app config with all featured enabled.
appConfig = createDefaultAppConfig();
}

Object.assign(process.env, {
HOST: "hubs.local"
});
// Use the default app config with all featured enabled.
appConfig = createDefaultAppConfig();

if (env.localDev) {
// Local Dev Environment (npm run local)
Object.assign(process.env, {
HOST: "hubs.local",
RETICULUM_SOCKET_SERVER: "hubs.local",
BASE_ASSETS_PATH: "http://localhost:8001/",
RETICULUM_SERVER: "hubs.local:4000",
POSTGREST_SERVER: "",
ITA_SERVER: ""
RETICULUM_SERVER: "hubs.local:4000"
});
}
}
Expand All @@ -143,12 +82,12 @@ module.exports = async (env, argv) => {
alias: {
// aframe and networked-aframe are still using commonjs modules. this will resolve yjs
yjs$: path.resolve(__dirname, "./node_modules/yjs/dist/yjs.mjs"),
// aframe and networked-aframe are still using commonjs modules. three and bitecs are peer dependanciees
// aframe and networked-aframe are still using commonjs modules. three and bitecs are peer dependences
// but they are "smart" and have builds for both ESM and CJS depending on if import or require is used.
// This forces the ESM version to be used otherwise we end up with multiple instances of the libraries,
// and for example AFRAME.THREE.Object3D !== THREE.Object3D in Hubs code, which breaks many things.
three$: path.resolve(__dirname, "./node_modules/three/build/three.module.js"),
// TODO these aliases are reequired because `three` only "exports" stuff in examples/jsm
// TODO these aliases are required because `three` only "exports" stuff in examples/jsm
"three/examples/js/libs/basis/basis_transcoder.js": basisTranscoderPath,
"three/examples/js/libs/basis/basis_transcoder.wasm": basisWasmPath
},
Expand Down Expand Up @@ -304,15 +243,9 @@ module.exports = async (env, argv) => {
new webpack.DefinePlugin({
"process.env": JSON.stringify({
NODE_ENV: argv.mode,
SHORTLINK_DOMAIN: process.env.SHORTLINK_DOMAIN,
RETICULUM_SERVER: process.env.RETICULUM_SERVER,
RETICULUM_SOCKET_SERVER: process.env.RETICULUM_SOCKET_SERVER,
THUMBNAIL_SERVER: process.env.THUMBNAIL_SERVER,
TERRA_SERVER: process.env.TERRA_SERVER,
BUILD_VERSION: process.env.BUILD_VERSION,
SENTRY_DSN: process.env.SENTRY_DSN,
MIXPANEL_TOKEN: process.env.MIXPANEL_TOKEN,
GA_TRACKING_ID: process.env.GA_TRACKING_ID,
POSTGREST_SERVER: process.env.POSTGREST_SERVER,
BASE_ASSETS_PATH: process.env.BASE_ASSETS_PATH,
APP_CONFIG: appConfig
Expand Down