Skip to content

Commit

Permalink
use play instead of init for loading from hash; also lint fixes
Browse files Browse the repository at this point in the history
around line 416 in json-utils.js
this ensures that scene has loaded
  • Loading branch information
kfarr committed Sep 12, 2023
1 parent 717be03 commit 7c5b2b8
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 86 deletions.
8 changes: 4 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ AFRAME.registerComponent('streetmix-loader', {
const streetmixResponseObject = JSON.parse(this.response);
const streetmixSegments = streetmixResponseObject.data.street.segments;
const streetmixName = streetmixResponseObject.name;
console.log('streetmixName', streetmixName)
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
const 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)
console.log('therefore setting metadata sceneTitle as streetmixName', streetmixName);
}

if (data.showBuildings) {
Expand Down
224 changes: 142 additions & 82 deletions src/json-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,25 @@ function getAttributes (entity) {
}

function toPropString (propData) {
if (typeof propData === 'string' || typeof propData === 'number' || typeof propData === 'boolean' ||
Array.isArray(propData)) {
return (propData).toString();
}
if (propData.isVector3 || propData.isVector2 || propData.isVector4 ||
propData.hasOwnProperty('x') && propData.hasOwnProperty('y')) {
if (
typeof propData === 'string' ||
typeof propData === 'number' ||
typeof propData === 'boolean' ||
Array.isArray(propData)
) {
return propData.toString();
}
if (
propData.isVector3 ||
propData.isVector2 ||
propData.isVector4 ||
(propData.hasOwnProperty('x') && propData.hasOwnProperty('y'))
) {
return AFRAME.utils.coordinates.stringify(propData);
}
if (typeof propData === 'object') {
return Object.entries(propData).map(
([key, value]) => {
return Object.entries(propData)
.map(([key, value]) => {
if (key == 'src') {
if (value.id) {
return `${key}: #${value.id}`;
Expand All @@ -104,8 +112,8 @@ function toPropString (propData) {
} else {
return `${key}: ${toPropString(value)}`;
}
}
).join('; ');
})
.join('; ');
}
}

Expand Down Expand Up @@ -155,8 +163,10 @@ function filterJSONstreet (removeProps, renameProps, streetJSON) {
const attrNames = Object.keys(removeVal);
for (var attrName of attrNames) {
const attrVal = removeVal[attrName];
if (Object.prototype.hasOwnProperty.call(compAttributes, attrName) &&
removeValueCheck(attrVal, compAttributes[attrName])) {
if (
Object.prototype.hasOwnProperty.call(compAttributes, attrName) &&
removeValueCheck(attrVal, compAttributes[attrName])
) {
delete value[attrName];
}
}
Expand Down Expand Up @@ -211,8 +221,10 @@ function getMixedValue (component, propertyName, source) {
}

function shallowEqual (object1, object2) {
if (typeof object1 === 'string' && typeof object2 === 'string' ||
typeof object1 === 'number' && typeof object2 === 'number') {
if (
(typeof object1 === 'string' && typeof object2 === 'string') ||
(typeof object1 === 'number' && typeof object2 === 'number')
) {
return object1 === object2;
}
const keys1 = Object.keys(object1);
Expand Down Expand Up @@ -246,7 +258,11 @@ function getModifiedProperty (entity, componentName) {
const defaultData = entity.components[componentName].schema;

// component's data, that exists in the element's mixin
const [mixinCompName, mixinsData] = getMixedValue(entity.components[componentName], null, entity);
const [mixinCompName, mixinsData] = getMixedValue(
entity.components[componentName],
null,
entity
);

const mixinSkipProps = ['src', 'atlas-uvs', 'gltf-model', 'gltf-part'];
if (mixinsData && mixinSkipProps.includes(mixinCompName)) {
Expand All @@ -262,9 +278,7 @@ function getModifiedProperty (entity, componentName) {
return null;
}

if ((currentValue || defaultValue) &&
currentValue !== defaultValue
) {
if ((currentValue || defaultValue) && currentValue !== defaultValue) {
return data;
}
}
Expand All @@ -273,11 +287,18 @@ function getModifiedProperty (entity, componentName) {
const defaultValue = defaultData[key].default;
const currentValue = data[key];

if (mixinsData && mixinsData[key] && shallowEqual(mixinsData[key], data[key])) {
if (
mixinsData &&
mixinsData[key] &&
shallowEqual(mixinsData[key], data[key])
) {
continue;
}
// Some parameters could be null and '' like mergeTo
if ((currentValue || defaultValue) && !AFRAME.utils.deepEqual(currentValue, defaultValue)) {
if (
(currentValue || defaultValue) &&
!AFRAME.utils.deepEqual(currentValue, defaultValue)
) {
diff[key] = data[key];
}
}
Expand All @@ -288,10 +309,12 @@ function createEntities (entitiesData, parentEl) {
const sceneElement = document.querySelector('a-scene');
const removeEntities = ['environment', 'reference-layers'];
for (const entityData of entitiesData) {
if (entityData.id === 'street-container' &&
entityData.children &&
entityData.children[0].id === 'default-street' &&
entityData.children[0].components.hasOwnProperty('set-loader-from-hash')) {
if (
entityData.id === 'street-container' &&
entityData.children &&
entityData.children[0].id === 'default-street' &&
entityData.children[0].components.hasOwnProperty('set-loader-from-hash')
) {
delete entityData.children[0].components['set-loader-from-hash'];
}

Expand Down Expand Up @@ -325,7 +348,8 @@ Add a new entity with a list of components and children (if exists)
* @return {Element} Entity created
*/
function createEntityFromObj (entityData, parentEl) {
const entity = entityData.entityElement || document.createElement(entityData.element);
const entity =
entityData.entityElement || document.createElement(entityData.element);

if (!entity.parentEl && parentEl) {
parentEl.appendChild(entity);
Expand Down Expand Up @@ -373,58 +397,79 @@ 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: ''}
sceneTitle: { default: '' },
sceneId: { default: '' }
},
init: function() {
}
})
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);
this.runOnce = false;
},
play: function () {
// using play instead of init method so scene loads before setting its metadata component
if (!this.runOnce) {
this.runOnce = true;
// 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);
// }
}
// 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 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');
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);
const sceneId = getUUIDFromPath(requestURL);
if (sceneId) {
console.log('sceneId from fetchJSON from url hash loader', sceneId);
AFRAME.scenes[0].setAttribute('metadata', 'sceneId', sceneId);
Expand All @@ -433,15 +478,18 @@ AFRAME.registerComponent('set-loader-from-hash', {
};
request.onerror = function () {
// There was a connection error of some sort
console.log('Loading Error: There was a connection error during JSON loading');
console.log(
'Loading Error: There was a connection error during JSON loading'
);
};
request.send();
}
});

function getUUIDFromPath(path) {
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 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) {
Expand All @@ -452,37 +500,46 @@ function getUUIDFromPath(path) {
}

// 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; });
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>';
streetContainerEl.innerHTML =
'<a-entity street streetmix-loader="streetmixStreetURL: ' +
streetmixURL +
'""></a-entity>';
}

// JSON loading starts here
function getValidJSON(stringJSON) {
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,"");
return stringJSON
.replace(/\'/g, '')
.replace(/\n/g, '')
.replace(/[\u0000-\u0019]+/g, '');
}

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

const sceneTitle = streetObject.title;
if (sceneTitle) {
console.log('sceneTitle from createElementsFromJSON', sceneTitle);
AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', sceneTitle);
Expand All @@ -492,26 +549,29 @@ function createElementsFromJSON(streetJSON) {
while (streetContainerEl.firstChild) {
streetContainerEl.removeChild(streetContainerEl.lastChild);
}

createEntities(streetObject.data, streetContainerEl);
AFRAME.scenes[0].components['notify'].message('Scene loaded from JSON', 'success')
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");
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(){
function fileJSON () {
const 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]);
}

0 comments on commit 7c5b2b8

Please sign in to comment.