Skip to content

Commit

Permalink
Merge branch 'master' into jameskane05-feature/troika-text
Browse files Browse the repository at this point in the history
  • Loading branch information
netpro2k authored Mar 15, 2022
2 parents 6aedba5 + f30cbd6 commit 8f1e1be
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 73 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
node_modules
2 changes: 0 additions & 2 deletions .env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,5 @@ RETICULUM_SERVER="dev.reticulum.io"
THUMBNAIL_SERVER="nearspark-dev.reticulum.io"
NON_CORS_PROXY_DOMAINS="hubs.local,localhost"
CORS_PROXY_SERVER="hubs-proxy.com"
GITHUB_ORG="mozilla"
GITHUB_REPO="spoke"
GITHUB_PUBLIC_TOKEN="de8cbfb4cc0281c7b731c891df431016c29b0ace"
IS_MOZ="false"
2 changes: 0 additions & 2 deletions .env.prod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@ FARSPARK_SERVER="farspark.reticulum.io"
CORS_PROXY="hubs-proxy.com"
NON_CORS_PROXY_DOMAINS="hubs.mozilla.com,reticulum.io"
ROUTER_BASE_PATH="/spoke"
GITHUB_ORG="mozilla"
GITHUB_REPO="spoke"
GITHUB_PUBLIC_TOKEN="de8cbfb4cc0281c7b731c891df431016c29b0ace"
IS_MOZ="false"
15 changes: 15 additions & 0 deletions .github/workflows/spoke-RetPageOrigin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: spoke
on:
push:
branches:
paths-ignore: ["README.md"]
workflow_dispatch:

jobs:
turkeyGitops:
uses: mozilla/hubs-ops/.github/workflows/turkeyGitops.yml@master
with:
registry: mozillareality
dockerfile: RetPageOriginDockerfile
secrets:
DOCKER_HUB_PWD: ${{ secrets.DOCKER_HUB_PWD }}
30 changes: 30 additions & 0 deletions RetPageOriginDockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
###
# this dockerfile produces image/container that serves customly packaged spoke static files
# the result container should serve reticulum as "spoke_page_origin" on (path) "/spoke/pages"
###
from node:16.13 as builder
run mkdir /spoke && cd /spoke
copy package.json ./
copy yarn.lock ./
run yarn install --frozen-lockfile
copy . .
env BASE_ASSETS_PATH="{{rawspoke-base-assets-path}}"
# TODO we should be setting BUILD_VERSION, probably pass in git sha or run number as an ARG
run yarn build 1> /dev/null
run mkdir -p dist/pages && mv dist/*.html dist/pages
# TODO can't we just move this directly from dist to /www ?
run mkdir /spoke/rawspoke && mv dist/pages /spoke/rawspoke && mv dist/assets /spoke/rawspoke

from alpine/openssl as ssl
run mkdir /ssl && openssl req -x509 -newkey rsa:2048 -sha256 -days 36500 -nodes -keyout /ssl/key -out /ssl/cert -subj '/CN=spoke'

from nginx:alpine
run apk add bash
run mkdir /ssl && mkdir -p /www/spoke && mkdir -p /www/spoke/pages && mkdir -p /www/spoke/assets
copy --from=ssl /ssl /ssl
copy --from=builder /spoke/rawspoke/pages /www/spoke/pages
copy --from=builder /spoke/rawspoke/assets /www/spoke/assets
copy scripts/docker/nginx.config /etc/nginx/conf.d/default.conf
copy scripts/docker/run.sh /run.sh
run chmod +x /run.sh && cat /run.sh
cmd bash /run.sh
4 changes: 2 additions & 2 deletions docs/creating-custom-elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The constructor will be the constructor for the `Object3D` that we are applying

We'll stop there for now with the node class and move onto the node editor.

Create a new file, `SpinningCubeEditor` in `src/ui/properties`.
Create a new file, `SpinningCubeNodeEditor` in `src/ui/properties`.

This file will be a React component that should use the `<NodeEditor>` component as it's root element. The rest of the editor properties will be added as children of this element.

Expand Down Expand Up @@ -805,4 +805,4 @@ That will set Spoke to properly publish to the dev server and open the scene in

Start Spoke back up with `yarn start`. Then open your project back up, make sure theres some spinning cubes in it and publish the scene. You can then click view scene and it should open up in your locally running Hubs client. In the Hubs room you should see the spinning textured cubes!

With these concepts you can create your own custom Spoke elements and deploy them to your Hubs Cloud instance or contribute them back to Spoke and Hubs in a PR. We can't wait to see what you come up with! Be sure to share your creations in the Hubs Discord, we love seeing what people are working on!
With these concepts you can create your own custom Spoke elements and deploy them to your Hubs Cloud instance or contribute them back to Spoke and Hubs in a PR. We can't wait to see what you come up with! Be sure to share your creations in the Hubs Discord, we love seeing what people are working on!
17 changes: 17 additions & 0 deletions scripts/docker/nginx.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
server {
listen 8080 ssl;
ssl_certificate /ssl/cert;
ssl_certificate_key /ssl/key;
location / {
root /www;
autoindex off;
add_header 'Access-Control-Allow-Origin' '*';
}
}

server {
listen 1111;
location =/_healthz {
return 200 ;
}
}
13 changes: 13 additions & 0 deletions scripts/docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
find /www/spoke/ -type f -name *.html -exec sed -i "s~{{rawspoke-base-assets-path}}\/~${turkeyCfg_base_assets_path}~g" {} \;
find /www/spoke/ -type f -name *.html -exec sed -i "s~{{rawspoke-base-assets-path}}~${turkeyCfg_base_assets_path}~g" {} \;
find /www/spoke/ -type f -name *.css -exec sed -i "s~{{rawspoke-base-assets-path}}\/~${turkeyCfg_base_assets_path}~g" {} \;
find /www/spoke/ -type f -name *.css -exec sed -i "s~{{rawspoke-base-assets-path}}~${turkeyCfg_base_assets_path}~g" {} \;

anchor="<!-- DO NOT REMOVE\/EDIT THIS COMMENT - META_TAGS -->"
for f in /www/spoke/pages/*.html; do
for var in $(printenv); do
var=$(echo $var | cut -d"=" -f1 ); prefix="turkeyCfg_";
[[ $var == $prefix* ]] && sed -i "s/$anchor/ <meta name=\"env:${var#$prefix}\" content=\"${!var//\//\\\/}\"\/> $anchor/" $f;
done
done
nginx -g "daemon off;"
4 changes: 4 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import ScenePreviewCameraNode from "./editor/nodes/ScenePreviewCameraNode";
import ScenePreviewCameraNodeEditor from "./ui/properties/ScenePreviewCameraNodeEditor";
import AudioZoneNode from "./editor/nodes/AudioZoneNode";
import AudioZoneNodeEditor from "./ui/properties/AudioZoneNodeEditor";
import MirrorNode from "./editor/nodes/MirrorNode";
import MirrorNodeEditor from "./ui/properties/MirrorNodeEditor";

import MediaFrameNode from "./editor/nodes/MediaFrameNode";
import MediaFrameNodeEditor from "./ui/properties/MediaFrameNodeEditor";
Expand Down Expand Up @@ -97,6 +99,8 @@ export function createEditor(api, settings) {
editor.registerNode(MediaFrameNode, MediaFrameNodeEditor);
editor.registerNode(AudioZoneNode, AudioZoneNodeEditor);
editor.registerNode(TroikaTextNode, TroikaTextNodeEditor);
editor.registerNode(MirrorNode, MirrorNodeEditor);


editor.registerSource(new ElementsSource(editor));
editor.registerSource(new MyAssetsSource(editor));
Expand Down
48 changes: 48 additions & 0 deletions src/editor/nodes/MirrorNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Mirror from "../objects/Mirror";
import EditorNodeMixin from "./EditorNodeMixin";

export default class MirrorNode extends EditorNodeMixin(Mirror) {
static componentName = "mirror";

static nodeName = "Mirror";

static async deserialize(editor, json) {
const node = await super.deserialize(editor, json);

const { color } = json.components.find(c => c.name === MirrorNode.componentName).props;

node.color = color;

return node;
}

constructor(editor) {
super(editor);

this.color = "#7f7f7f";
}

copy(source, recursive = true) {
super.copy(source, recursive);

return this;
}

serialize() {
return super.serialize({
[MirrorNode.componentName]: {
color: this.color
}
});
}

prepareForExport() {
super.prepareForExport();

this.addGLTFComponent("mirror", {
color: this.color
});

this.replaceObject();
}
}
39 changes: 39 additions & 0 deletions src/editor/objects/Mirror.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Object3D, PlaneBufferGeometry, Color } from "three";
import { Reflector } from "three/examples/jsm/objects/Reflector";

export default class Mirror extends Object3D {
constructor(color) {
super();

this.mesh = new Reflector(new PlaneBufferGeometry(), { color });
this.add(this.mesh);
}

get color() {
return this.mesh.material.uniforms.color.value;
}

set color(value) {
this.mesh.material.uniforms.color.value = new Color(value);
}

copy(source, recursive = true) {
if (recursive) {
this.remove(this.mesh);
}

super.copy(source, recursive);

if (recursive) {
const _meshIndex = source.children.indexOf(source.mesh);

if (_meshIndex !== -1) {
this.mesh = this.children[_meshIndex];
}
}

this.color = source.color;

return this;
}
}
30 changes: 30 additions & 0 deletions src/ui/properties/MirrorNodeEditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import PropTypes from "prop-types";
import { Mirror } from "styled-icons/octicons/Mirror";

import useSetPropertySelected from "./useSetPropertySelected";
import NodeEditor from "./NodeEditor";
import InputGroup from "../inputs/InputGroup";
import ColorInput from "../inputs/ColorInput";

export default function MirrorNodeEditor(props) {
const { node, editor } = props;
const onChangeColor = useSetPropertySelected(editor, "color");

return (
<NodeEditor {...props} description={MirrorNodeEditor.description}>
<InputGroup name="Color">
<ColorInput value={node.color} onChange={onChangeColor} />
</InputGroup>
</NodeEditor>
);
}

MirrorNodeEditor.propTypes = {
editor: PropTypes.object,
node: PropTypes.object
};

MirrorNodeEditor.iconComponent = Mirror;

MirrorNodeEditor.description = "Renders a plane mirror.";
12 changes: 2 additions & 10 deletions src/ui/whats-new/WhatsNewPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,13 @@ export default class WhatsNewPage extends Component {

this.state = {
updates: [],
loading: false,
hasMore: true
};

this.updatesIterator = getUpdates(30);
}

onLoadMore = async () => {
this.setState({ loading: true });

const { value: updates, done } = await this.updatesIterator.next();

let nextUpdates;
Expand All @@ -127,7 +124,7 @@ export default class WhatsNewPage extends Component {
nextUpdates = this.state.updates;
}

this.setState({ updates: nextUpdates, loading: false, hasMore: !done });
this.setState({ updates: nextUpdates, hasMore: !done });
};

render() {
Expand All @@ -142,12 +139,7 @@ export default class WhatsNewPage extends Component {
<WhatsNewContainer>
<WhatsNewContent>
<WhatsNewTitle>What&apos;s New</WhatsNewTitle>
<InfiniteScroll
pageStart={0}
loadMore={this.onLoadMore}
hasMore={!this.state.loading && this.state.hasMore}
loader={loader}
>
<InfiniteScroll loadMore={this.onLoadMore} hasMore={this.state.hasMore} loader={loader}>
{this.state.updates.map((update, i) => {
return (
<Update key={i}>
Expand Down
76 changes: 20 additions & 56 deletions src/ui/whats-new/whats-new-utils.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,47 @@
import markdownit from "markdown-it";
const markdown = markdownit();

function formatBody(body) {
const paragraphs = body.split("\r\n\r\n").filter(l => l.trim());

const paraAndImage = [paragraphs[0]];
if (paragraphs[1] && paragraphs[1].includes("![")) {
paraAndImage.push(paragraphs[1]);
}

return markdown.render(paraAndImage.join("\r\n\r\n"));
}

function formatDate(value) {
return value && new Date(value).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
}

export async function* getUpdates(perPage = 30) {
export async function* getUpdates() {
let cursor = null;
let hasMore = true;

do {
const cursorStr = cursor ? `, after: "${cursor}"` : "";

const query = `query {
repository(owner: "${process.env.GITHUB_ORG}", name: "${process.env.GITHUB_REPO}") {
pullRequests(labels: ["whats new"], states: [MERGED], first: ${perPage}, orderBy: { field: UPDATED_AT, direction: DESC }${cursorStr}) {
edges {
node {
title
url
mergedAt
body
}
cursor
}
}
}
}`;
const response = await fetch(
`/api/v1/whats-new?source=${process.env.GITHUB_REPO}&${cursor ? `cursor=${cursor}` : ""}`
);

// Read-only, public access token.
const token = process.env.GITHUB_PUBLIC_TOKEN;
let pullRequests = [];

const response = await fetch("https://api.github.com/graphql", {
method: "POST",
body: JSON.stringify({ query }),
headers: { authorization: `token ${token}` }
});
try {
const resp = await response.json();

const json = await response.json();
const moreCursor = resp.moreCursor;
pullRequests = resp.pullRequests;

if (json.errors) {
let message = "Error fetching pull requests from GitHub:";

for (const error of json.errors) {
message += "\n" + error.message;
if (moreCursor) {
cursor = moreCursor;
} else {
hasMore = false;
}

throw new Error(message);
}

const edges = json.data.repository.pullRequests.edges;

if (edges.length < perPage) {
} catch (e) {
console.error("Error when fetching whats-new", e);
hasMore = false;
} else {
cursor = edges[perPage - 1].cursor;
}

yield edges.map(({ node }) => ({
...node,
formattedMergedAt: formatDate(node.mergedAt),
formattedBody: formatBody(node.body)
yield pullRequests.map(pullRequest => ({
...pullRequest,
formattedMergedAt: formatDate(pullRequest.mergedAt),
formattedBody: markdown.render(pullRequest.body)
}));
} while (hasMore);
}

export function getLatestUpdate() {
return getUpdates(1)
return getUpdates()
.next()
.then(result => (result.value && result.value.length > 0 ? result.value[0] : null));
}
Binary file modified test/integration/snapshots/Editor.test.js.snap
Binary file not shown.
Loading

0 comments on commit 8f1e1be

Please sign in to comment.