Skip to content

Commit

Permalink
Merge pull request #346 from 3DStreet/metadata-and-notifications
Browse files Browse the repository at this point in the history
Metadata and notifications
  • Loading branch information
kfarr committed Sep 11, 2023
2 parents 463082f + 5937130 commit e679571
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 104 deletions.
115 changes: 12 additions & 103 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
renderer="colorManagement: true; physicallyCorrectLights: true;"
inspector="url: //3dstreet.app/dist/3dstreet-editor.js"
notify
metadata
>
<a-assets>
<!-- uncomment the line below to load assets from local github submodule -->
Expand Down Expand Up @@ -74,6 +75,10 @@
</a-scene>
</body>
<script>

document.getElementById('inputfile')
.addEventListener('change', fileJSON);

// only show VR button if headset connected
AFRAME.registerComponent('vr-mode-ui-if-headset', {
dependencies: ['vr-mode-ui'],
Expand All @@ -84,52 +89,6 @@
}
})

AFRAME.registerComponent('set-loader-from-hash', {
dependencies: ['streetmix-loader'],
schema: {
defaultURL: { type: 'string' }
},
init: function () {
// get hash from window
const streetURL = window.location.hash.substring(1);
if (!streetURL) {
return;
}
if (streetURL.includes('//streetmix.net')) {
console.log('[set-loader-from-hash]','Set streetmix-loader streetmixStreetURL to', streetURL)
this.el.setAttribute('streetmix-loader', 'streetmixStreetURL', streetURL);
} else {
// try to load JSON file from remote resource
console.log('[set-loader-from-hash]','Load 3DStreet scene with fetchJSON from', streetURL)
this.fetchJSON(streetURL);
}
// else {
// console.log('[set-loader-from-hash]','Using default URL', this.data.defaultURL)
// this.el.setAttribute('streetmix-loader', 'streetmixStreetURL', this.data.defaultURL);
// }
},
fetchJSON: function (requestURL) {
const request = new XMLHttpRequest();
request.open('GET', requestURL, true);
request.onload = function () {
if (this.status >= 200 && this.status < 400) {
// Connection success
// remove 'set-loader-from-hash' component from json data
const jsonData = JSON.parse(this.response,
(key, value) => (key === 'set-loader-from-hash') ? undefined : value );

console.log('[set-loader-from-hash]', '200 response received and JSON parsed, now createElementsFromJSON');
createElementsFromJSON(jsonData);
}
};
request.onerror = function () {
// There was a connection error of some sort
console.log('Loading Error: There was a connection error during JSON loading');
};
request.send();
}
});

function buttonScreenshotTock() {
const screenshotEl = document.getElementById('screenshot');
screenshotEl.play(); // double check playing in case we're in editor mode
Expand All @@ -142,64 +101,14 @@
sceneEl.components.inspector.openInspector();
document.querySelector('.viewer-header-wrapper').style.display = 'none';
}
// uncomment the below to autostart the editor within 2 seconds of page load
// setTimeout(() => {
// startEditor();
// }, "2000")

function inputStreetmix() {
streetmixURL = prompt("Please enter a Streetmix URL", "https://streetmix.net/kfarr/3/example-street");
setTimeout(function() { window.location.hash = streetmixURL; });
streetContainerEl = document.getElementById('street-container');
while (streetContainerEl.firstChild) {
streetContainerEl.removeChild(streetContainerEl.lastChild);
AFRAME.registerComponent('timed-inspector', {
init: function() {
setTimeout( function () {
window.postMessage('INJECT_AFRAME_INSPECTOR')
}, this.data * 1000)
}
streetContainerEl.innerHTML = '<a-entity street streetmix-loader="streetmixStreetURL: '+streetmixURL+'""></a-entity>';
}

// JSON loading starts here
function getValidJSON(stringJSON) {
// Preserve newlines, etc. - use valid JSON
// Remove non-printable and other non-valid JSON characters
return stringJSON.replace(/\'/g, "")
.replace(/\n/g, "")
.replace(/[\u0000-\u0019]+/g,"");
}

function createElementsFromJSON(streetJSON) {
let streetObject = {};
if (typeof streetJSON == 'string') {
const validJSONString = getValidJSON(streetJSON);
streetObject = JSON.parse(validJSONString);
} else if (typeof streetJSON == 'object') {
streetObject = streetJSON;
}

streetContainerEl = document.getElementById('street-container');
while (streetContainerEl.firstChild) {
streetContainerEl.removeChild(streetContainerEl.lastChild);
}

createEntities(streetObject.data, streetContainerEl);
AFRAME.scenes[0].components['notify'].message('Scene loaded from JSON', 'success')
}

function inputJSON() {
const stringJSON = prompt("Please paste 3DStreet JSON string");
if (stringJSON) {
createElementsFromJSON(stringJSON);
}
}

function fileJSON() {
let reader=new FileReader();
reader.onload=function(){
createElementsFromJSON(reader.result);
}
reader.readAsText(this.files[0]);
}

document.getElementById('inputfile')
.addEventListener('change', fileJSON);
});

</script>
</html>
2 changes: 1 addition & 1 deletion src/components/notify.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var { Notyf } = require('../lib/notyf.min.js');

AFRAME.registerComponent('notify', {
schema: {
duration: { type: 'number', default: 2000 },
duration: { type: 'number', default: 6000 },
ripple: { type: 'boolean', default: true },
position: {
type: 'string',
Expand Down
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,15 @@ AFRAME.registerComponent('streetmix-loader', {
const streetmixResponseObject = JSON.parse(this.response);
const streetmixSegments = streetmixResponseObject.data.street.segments;
const streetmixName = streetmixResponseObject.name;
console.log('streetmixName', streetmixName)
el.setAttribute('streetmix-loader', 'name', streetmixName);

let currentSceneTitle = AFRAME.scenes[0].getAttribute('metadata').sceneTitle;
if (!currentSceneTitle) { // only set title from streetmix if none exists
AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', streetmixName);
console.log('therefore setting metadata sceneTitle as streetmixName', streetmixName)
}

if (data.showBuildings) {
el.setAttribute('street', 'right', streetmixResponseObject.data.street.rightBuildingVariant);
el.setAttribute('street', 'left', streetmixResponseObject.data.street.leftBuildingVariant);
Expand Down
147 changes: 147 additions & 0 deletions src/json-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,3 +368,150 @@ function createEntityFromObj (entityData, parentEl) {
}
}
}

/*
Code imported from index.html, mix of save load utils and some ui functions
*/


AFRAME.registerComponent('metadata', {
schema: {
sceneTitle: {default: ''},
sceneId: {default: ''}
},
init: function() {
}
})

AFRAME.registerComponent('set-loader-from-hash', {
dependencies: ['streetmix-loader'],
schema: {
defaultURL: { type: 'string' }
},
init: function () {
// get hash from window
const streetURL = window.location.hash.substring(1);
if (!streetURL) {
return;
}
if (streetURL.includes('//streetmix.net')) {
console.log('[set-loader-from-hash]','Set streetmix-loader streetmixStreetURL to', streetURL)
this.el.setAttribute('streetmix-loader', 'streetmixStreetURL', streetURL);
} else {
// try to load JSON file from remote resource
console.log('[set-loader-from-hash]','Load 3DStreet scene with fetchJSON from', streetURL)
this.fetchJSON(streetURL);
}
// else {
// console.log('[set-loader-from-hash]','Using default URL', this.data.defaultURL)
// this.el.setAttribute('streetmix-loader', 'streetmixStreetURL', this.data.defaultURL);
// }
},
fetchJSON: function (requestURL) {
let sceneId = getUUIDFromPath(requestURL);
if (sceneId) {
console.log('sceneId from fetchJSON from url hash loader', sceneId);
AFRAME.scenes[0].setAttribute('metadata', 'sceneId', sceneId);
}
const request = new XMLHttpRequest();
request.open('GET', requestURL, true);
request.onload = function () {
if (this.status >= 200 && this.status < 400) {
// Connection success
// remove 'set-loader-from-hash' component from json data
const jsonData = JSON.parse(this.response,
(key, value) => (key === 'set-loader-from-hash') ? undefined : value );

console.log('[set-loader-from-hash]', '200 response received and JSON parsed, now createElementsFromJSON');
createElementsFromJSON(jsonData);
let sceneId = getUUIDFromPath(requestURL);
if (sceneId) {
console.log('sceneId from fetchJSON from url hash loader', sceneId);
AFRAME.scenes[0].setAttribute('metadata', 'sceneId', sceneId);
}
}
};
request.onerror = function () {
// There was a connection error of some sort
console.log('Loading Error: There was a connection error during JSON loading');
};
request.send();
}
});

function getUUIDFromPath(path) {
// UUID regex pattern: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
const uuidPattern = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/;

const match = path.match(uuidPattern);
if (match) {
return match[0];
}

return null; // return null or whatever default value you prefer if no UUID found
}

// this use os text input prompt, delete current scene, then load streetmix file
function inputStreetmix() {
streetmixURL = prompt("Please enter a Streetmix URL", "https://streetmix.net/kfarr/3/example-street");
setTimeout(function() { window.location.hash = streetmixURL; });
streetContainerEl = document.getElementById('street-container');
while (streetContainerEl.firstChild) {
streetContainerEl.removeChild(streetContainerEl.lastChild);
}
AFRAME.scenes[0].setAttribute('metadata', 'sceneId', '');
AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', '');
streetContainerEl.innerHTML = '<a-entity street streetmix-loader="streetmixStreetURL: '+streetmixURL+'""></a-entity>';
}

// JSON loading starts here
function getValidJSON(stringJSON) {
// Preserve newlines, etc. - use valid JSON
// Remove non-printable and other non-valid JSON characters
return stringJSON.replace(/\'/g, "")
.replace(/\n/g, "")
.replace(/[\u0000-\u0019]+/g,"");
}

function createElementsFromJSON(streetJSON) {
let streetObject = {};
if (typeof streetJSON == 'string') {
const validJSONString = getValidJSON(streetJSON);
streetObject = JSON.parse(validJSONString);
} else if (typeof streetJSON == 'object') {
streetObject = streetJSON;
}

let sceneTitle = streetObject.title;
if (sceneTitle) {
console.log('sceneTitle from createElementsFromJSON', sceneTitle);
AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', sceneTitle);
}

streetContainerEl = document.getElementById('street-container');
while (streetContainerEl.firstChild) {
streetContainerEl.removeChild(streetContainerEl.lastChild);
}

createEntities(streetObject.data, streetContainerEl);
AFRAME.scenes[0].components['notify'].message('Scene loaded from JSON', 'success')
}

// viewer widget click to paste json string of 3dstreet scene
function inputJSON() {
const stringJSON = prompt("Please paste 3DStreet JSON string");
if (stringJSON) {
createElementsFromJSON(stringJSON);
}
}

// handle viewer widget click to open 3dstreet json scene
function fileJSON() {
let reader=new FileReader();
reader.onload=function(){
AFRAME.scenes[0].setAttribute('metadata', 'sceneId', '');
AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', '');
createElementsFromJSON(reader.result);
}
reader.readAsText(this.files[0]);
}
8 changes: 8 additions & 0 deletions src/viewer-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ body {
margin: 0;
}

/* notification hack */
.notyf__message { font-size: 20px !important; }

/* notification width hack */
.notyf__toast {
max-width: 66.66vw !important; /* 2/3rds of viewport width */
width: auto !important; /* Resetting any specific width, if set */
}

/********* viewer header css *********/

Expand Down

0 comments on commit e679571

Please sign in to comment.