From 2a3680f55126d4b7b9e280361e129ab0fde6edec Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 23 Apr 2021 15:16:28 -0400 Subject: [PATCH 01/67] Add doc for Group.js --- src/myr/Group.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/src/myr/Group.js b/src/myr/Group.js index 332c87b5..a1e668b5 100644 --- a/src/myr/Group.js +++ b/src/myr/Group.js @@ -1,4 +1,11 @@ +/** Class representing a Group in MYR */ class Group { + /** + * Instantiate a new Group class + * + * @param {Myr} originalMyr MYR instance + * @param {string} id ID assigned for this Group + */ constructor(originalMyr, id) { this.els = []; this.entity = true; @@ -6,14 +13,23 @@ class Group { this.id = id; } + /** + * Add new MYR entity to the Group + * + * @param {(Group|string)} id Instance of Group or ID of MYR entity + */ add = (id) => { if (id instanceof Group) { this.els.push(this.myr.transfer(id.id)); } this.els.push(this.myr.transfer(id)); - } + /** + * Remove MYR entity from the Group + * + * @param {(Group|string)} id Instance of Group or ID of MYR entity + */ remove = (id) => { if (id instanceof Group) { id = id.id; @@ -24,10 +40,25 @@ class Group { this.myr.els.push(el); } + /** + * Retrieve specific MYR entity in the Group + * + * @param {string} outerElId - ID of the entity to retrieve + * @returns {object} MYR object if found, null other wise + */ getEl = (outerElId) => { + if (outerElId.entity) { + outerElId = outerElId.id; + } return this.els[outerElId]; } + /** + * Retrieve the index of specific MYR entity in the Group + * + * @param {string} outerElId - ID of the object to retrieve + * @returns {number} - Index of the array if found, null otherwise. + */ getIndex = (outerElId) => { for (let i in this.els) { if (this.els[i].id === outerElId) { @@ -37,6 +68,13 @@ class Group { return null; } + /** + * Sets the x, y, and z position of the Group + * + * @param {number} x New x position + * @param {number} y New y position + * @param {number} z New z position + */ setPosition = (x = 0, y = 1, z = 0) => { let ent = this.myr.getEl(this.id); ent.position = { @@ -45,6 +83,13 @@ class Group { this.myr.els[this.id] = ent; } + /** + * Sets the x, y, and z scale of the Group + * + * @param {number} x New x scale + * @param {number} y New y scale + * @param {number} z New z scale + */ setScale = (x = 1, y = 1, z = 1) => { let ent = this.myr.getEl(this.id); ent.scale = { @@ -53,6 +98,13 @@ class Group { this.myr.els[this.id] = ent; } + /** + * Sets the x, y, and z rotation of the Group + * + * @param {number} x New x rotation + * @param {number} y New y rotation + * @param {number} z New z rotation + */ setRotation = (x = 0, y = 0, z = 0) => { let ent = this.myr.getEl(this.id); ent.rotation = { @@ -61,13 +113,16 @@ class Group { this.myr.els[this.id] = ent; } + /** + * Return an object with elements of the Group + * @returns {object} Flag indicates it's a Group and elements + */ entObj = () => { return { group: true, els: this.els }; } - } export default Group; From a8eebbe5a7207052e8dec77149eaac4179b1fd30 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 28 May 2021 18:38:25 -0400 Subject: [PATCH 02/67] Add missing description and clean the myr/Myr.js --- src/myr/Myr.js | 486 +++++++++++++++++++++++++++---------------------- 1 file changed, 270 insertions(+), 216 deletions(-) diff --git a/src/myr/Myr.js b/src/myr/Myr.js index 8b6daa47..88dca1cc 100644 --- a/src/myr/Myr.js +++ b/src/myr/Myr.js @@ -5,6 +5,10 @@ import CANNON from "cannon"; import TexturePack from "../components/structural/Textures.js"; class Myr { + /** + * Instantiate MYR class + * @param {object} baseEls list of the entities restore to the new MYR + */ constructor(baseEls) { this.counter = 0; this.baseEls = baseEls; @@ -189,6 +193,9 @@ class Myr { }; } + /** + * Reset the transformation properties of the cursor to the default + */ resetTransformationCursor = () => { this.cursor = { ...this.cursor, @@ -213,6 +220,9 @@ class Myr { }; }; + /** + * Reset the animation properties of the cursor to the default + */ resetAnimationCursor = () => { this.cursor = { ...this.cursor, @@ -226,6 +236,9 @@ class Myr { }; }; + /** + * Reset the light properties of the cursor to the default + */ resetLightCursor = () => { this.cursor.light = { intensity: 1.0, @@ -237,6 +250,9 @@ class Myr { }; }; + /** + * Generate unique id that is assigned to each entity + */ genNewId = () => { return this.counter++; }; @@ -475,55 +491,6 @@ class Myr { return { x: this.cursor.rotation.x, y: this.cursor.rotation.y, z: this.cursor.rotation.z }; } - setCursorAttribute = (key = "", value = "") => { - if (typeof (key) !== "string" || key === "") { - console.error("Error: Invalid key"); - return this.cursor; - } - switch (key.toLowerCase()) { - case "color": - this.setColor(value); - break; - case "texture": - this.setTexture(value); - break; - case "position": - this.setPosition(value.x, value.y, value.z); - break; - case "scale": - this.setScale(value.x, value.y, value.z); - break; - case "rotation": - this.setRotation(value.x, value.y, value.z); - break; - case "radius": - this.setRadius(value); - break; - case "philength": - this.setPhiLength(value); - break; - case "loop": - this.setLoop(value); - break; - case "duration": - this.setDuration(value); - break; - case "magnitude": - this.setMagnitude(value); - break; - case "transparency": - this.setTransparency(value); - break; - default: - this.cursor[key] = value; - } - return this.cursor; - } - - getCursorAttribute = (key = "") => { - return this.cursor[key]; - } - /** * Applies a given x rotation to the cursor * @@ -646,6 +613,13 @@ class Myr { return this.cursor.color; } + /** + * Sets the texture of the cursor. Defaults is empty string. + * + * @param {string} texture Specifying the texture. This can be either texture exist in our sever or valid url to the texture + * @param {number} w Number of times to repeat the texture horizontally + * @param {number} h Number of times to repeat the texture vertically + */ setTexture = (texture = "", w = 1, h = 1) => { let textures = TexturePack(); let textureTitle = [...textures.TexturePack.map(obj => obj.title)]; @@ -668,11 +642,22 @@ class Myr { return this.cursor.texture; } + /** + * Sets whether to enable to color the texture or not + * + * @param {boolean} i Enable or disable texture coloring + */ setTextureColoring = (i) => { this.cursor.textureColoring = Boolean(i); return this.cursor.textureColoring; }; + /** + * Sets the existing cursor as well as creates a new custom cursor attributes to apply to entity + * + * @param {string} key Name of the attribute + * @param {any} value Values apply to attribute + */ setCursorAttribute = (key = "", value = "") => { if (typeof (key) !== "string" || key === "") { console.error("Error: Invalid key"); @@ -712,6 +697,12 @@ class Myr { return this.cursor; } + /** + * Get the any values of the exisitng cursor attribute + * + * @param {string} key Name of the cursor attribute + * @returns Value of the cursor attribute if it exists + */ getCursorAttribute = (key = "") => { return this.cursor[key]; } @@ -720,7 +711,7 @@ class Myr { * Returns a random valid color. * * @param {array} colors An array of colors to choose from. If left - * empty then all colors are drawn from + * empty then random hexadecimal color are chosen. */ getRandomColor = (colors = null) => { let color; @@ -749,8 +740,8 @@ class Myr { /** * Allows the entity to be dropped * - * @param {number} outerElId !!!DESCRIPTION NEEDED!!! - * @param {number} mass !!!DESCRIPTION NEEDED!!! + * @param {string} outerElId Id of the entity to apply the physics + * @param {number} mass Set how heavy the entity is. */ makeDroppable = (outerElId, mass = 2) => { let el = this.getEl(outerElId); @@ -762,7 +753,7 @@ class Myr { /** * Disallows the entity to be dropped * - * @param {number} outerElId !!!DESCRIPTION NEEDED!!! + * @param {string} outerElId Id of the entity to remove the properties */ makeUnDroppable = (outerElId) => { let el = this.getEl(outerElId); @@ -776,8 +767,8 @@ class Myr { /** * Allows the entity to be pushed * - * @param {number} outerElId !!!DESCRIPTION NEEDED!!! - * @param {number} mass !!!DESCRIPTION NEEDED!!! + * @param {string} outerElId Id of the entity to apply the physics + * @param {number} mass Set how heavy the entity is. */ makePushable = (outerElId, mass = 2) => { let el = this.getEl(outerElId); @@ -790,21 +781,7 @@ class Myr { /** * Disallows the entity to be pushed * - * @param {number} outerElId !!!DESCRIPTION NEEDED!!! - */ - makeUnPushable = (outerElId) => { - let el = this.getEl(outerElId); - if (el["force-pushable"]) { - el["dynamic-body"] = null; - el["force-pushable"] = "false"; - } - return outerElId; - } - - /** - * Disallows the entity to be pushed - * - * @param {number} outerElId !!!DESCRIPTION NEEDED!!! + * @param {string} outerElId Id of the entity to remove the properties */ makeUnPushable = (outerElId) => { let el = this.getEl(outerElId); @@ -835,7 +812,7 @@ class Myr { /** * Render an Aframe box with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ box = (params) => { let base = { @@ -853,7 +830,7 @@ class Myr { /** * Render an Aframe circle with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ circle = (params) => { let base = { @@ -870,7 +847,7 @@ class Myr { /** * Render an Aframe cone with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ cone = (params) => { let base = { @@ -887,7 +864,7 @@ class Myr { /** * Render an Aframe cylinder with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ cylinder = (params) => { let base = { @@ -905,7 +882,7 @@ class Myr { /** * Render an Aframe dodecahedron with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ dodecahedron = (params) => { let base = { @@ -922,7 +899,7 @@ class Myr { /** * Render an Aframe icosahedron with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ icosahedron = (params) => { let base = { @@ -939,7 +916,7 @@ class Myr { /** * Render an Aframe octahedron with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ octahedron = (params) => { let base = { @@ -956,7 +933,8 @@ class Myr { /** * Render an Aframe line with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {string} path String of positions that represents the path in following format: "x1 y1 z1, x2 y2 z2,...,xn yn zn" + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ line = (path, params) => { let base = { @@ -975,7 +953,7 @@ class Myr { /** * Render an Aframe plane with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ plane = (params) => { let base = { @@ -992,7 +970,7 @@ class Myr { /** * Render an Aframe polyhedron with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ polyhedron = (params) => { let base = { @@ -1009,7 +987,7 @@ class Myr { /** * Render an Aframe ring with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ ring = (params) => { let base = { @@ -1026,7 +1004,7 @@ class Myr { /** * Render an Aframe sphere with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ sphere = (params) => { let base = { @@ -1043,7 +1021,7 @@ class Myr { /** * Render an Aframe tetrahedron with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ tetrahedron = (params) => { let base = { @@ -1063,6 +1041,9 @@ class Myr { * This is a bit tricky. We need to pass text so we can decide how to render it. * This throws a warning since text is not part of the entity system. * Instead we pass it and then pull it off again if we see it. + * + * @param {string} text Text to display + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ text = (text, params) => { if (typeof text !== "string") { @@ -1089,7 +1070,7 @@ class Myr { /** * Render an Aframe torus with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ torus = (params) => { let base = { @@ -1106,7 +1087,7 @@ class Myr { /** * Render an Aframe torusknot with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ torusknot = (params) => { let base = { @@ -1125,7 +1106,7 @@ class Myr { /** * Render an Aframe triangle with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ triangle = (params) => { let base = { @@ -1142,7 +1123,8 @@ class Myr { /** * Render an Aframe tube with current Myr settings * - * @param {*} params !!!DESCRIPTION NEEDED!!! + * @param {string} path String of positions that represents the path in following format: "x1 y1 z1, x2 y2 z2,...,xn yn zn" + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib */ tube = (path, params) => { let base = { @@ -1158,6 +1140,11 @@ class Myr { return this.mergeProps(base, params); } + /** + * Render an Ambient light with current cursor light settings + * + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib + */ ambientLight = (params) => { let base = { id: "lgt" + this.genNewId(), @@ -1177,6 +1164,11 @@ class Myr { return this.mergeProps(base, params); } + /** + * Render a Directional light with current cursor light settings + * + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib + */ directionalLight = (params) => { let base = { id: "lgt" + this.genNewId(), @@ -1196,6 +1188,11 @@ class Myr { return this.mergeProps(base, params); } + /** + * Render a Spot light with current cursor light settings + * + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib + */ spotLight = (params) => { let base = { id: "lgt" + this.genNewId(), @@ -1220,6 +1217,11 @@ class Myr { return this.mergeProps(base, params); } + /** + * Render an point light with current cursor light settings + * + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib + */ pointLight = (params) => { let base = { id: "lgt" + this.genNewId(), @@ -1242,7 +1244,12 @@ class Myr { return this.mergeProps(base, params); } - //secondColor == groundColor + /** + * Render an Hemisphere light with current cursor light settings + * + * @param {string} secondColor Secondary color for the hemisphere light + * @param {object} params Parameters that can overwrite the cursor attrib or add custom attrib + */ hemisphereLight = (secondColor="red",params) => { let base = { id: "lgt" + this.genNewId(), @@ -1263,7 +1270,11 @@ class Myr { return this.mergeProps(base, params); } - //beamAngle == angle + /** + * Set the extent of the spotlight + * + * @param {number} beamAngle Angle in degree + */ setBeamAngle=(beamAngle = 60)=>{ if(typeof beamAngle === "number"){ this.cursor.light.beamAngle = beamAngle; @@ -1272,6 +1283,12 @@ class Myr { } } + + /** + * Set the decay of the light + * + * @param {number} decay Rate of light decay + */ setDecay = (decay = 0.0) =>{ if(typeof decay === "number"){ this.cursor.light.decay = decay; @@ -1280,6 +1297,11 @@ class Myr { } } + /** + * Set the distance of the light dims as it travels + * + * @param {number} distance Length which light dims + */ setDistance = (distance=0.0) =>{ if(typeof distance === "number"){ this.cursor.light.distance = distance; @@ -1287,6 +1309,12 @@ class Myr { console.error("must pass a numeric for setDistance"); } } + + /** + * Set the intensity of the light + * + * @param {number} intensity Number range from 0 to 10+ + */ setIntensity = (intensity = 1.0) =>{ if(typeof intensity === "number"){ this.cursor.light.intensity = intensity; @@ -1295,7 +1323,11 @@ class Myr { } } - //diffusion == penumbra + /** + * Set the diffusion(penumbra) around the edge of the light + * + * @param {number} diffusion Number range from 0 to 1 + */ setDiffusion = (diffusion = 0.0) => { if(typeof diffusion === "number"){ this.cursor.light.diffusion = diffusion; @@ -1304,6 +1336,13 @@ class Myr { } } + /** + * Set the position of where the lights are facing towards + * + * @param {number} x X Position + * @param {number} y Y Position + * @param {number} z Z Position + */ setLightTarget = (x = 0, y = 0, z = 0) => { if(typeof x === "number" && typeof y === "number" && typeof z === "number"){ this.cursor.light.target = { @@ -1352,9 +1391,9 @@ class Myr { * Apply a spin animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ spin = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.spin; @@ -1377,9 +1416,9 @@ class Myr { * Apply a yoyo animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ yoyo = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1399,11 +1438,11 @@ class Myr { /** * Apply a sideToSide animation to the Aframe element which is passed as arg - * + * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ sideToSide = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1426,9 +1465,9 @@ class Myr { * Apply a goUp animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ goUp = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1450,9 +1489,9 @@ class Myr { * Apply a goDown animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ goDown = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1474,9 +1513,9 @@ class Myr { * Apply a goLeft animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ goLeft = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1498,9 +1537,9 @@ class Myr { * Apply a goRight animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ goRight = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1522,9 +1561,9 @@ class Myr { * Apply a goTowards animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ goTowards = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1546,9 +1585,9 @@ class Myr { * Apply a goAway animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ goAway = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1570,9 +1609,9 @@ class Myr { * Apply a grow animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ grow = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1619,9 +1658,9 @@ class Myr { * Apply a shrink animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ shrink = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1670,9 +1709,9 @@ class Myr { * Apply a fadeOut animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ fadeOut = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.fadeOut; @@ -1710,9 +1749,9 @@ class Myr { * Apply a fadeIn animation to the Aframe element which is passed as arg * * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last */ fadeIn = (outerElId, magnitude = null, loop = null, duration = null) => { magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.general; @@ -1746,30 +1785,12 @@ class Myr { return outerElId; } - colourNameToHex=(colour)=> - { - let colours = {"aliceblue":"#f0f8ff","antiquewhite":"#faebd7","aqua":"#00ffff","aquamarine":"#7fffd4","azure":"#f0ffff", - "beige":"#f5f5dc","bisque":"#ffe4c4","black":"#000000","blanchedalmond":"#ffebcd","blue":"#0000ff","blueviolet":"#8a2be2","brown":"#a52a2a","burlywood":"#deb887", - "cadetblue":"#5f9ea0","chartreuse":"#7fff00","chocolate":"#d2691e","coral":"#ff7f50","cornflowerblue":"#6495ed","cornsilk":"#fff8dc","crimson":"#dc143c","cyan":"#00ffff", - "darkblue":"#00008b","darkcyan":"#008b8b","darkgoldenrod":"#b8860b","darkgray":"#a9a9a9","darkgreen":"#006400","darkkhaki":"#bdb76b","darkmagenta":"#8b008b","darkolivegreen":"#556b2f", - "darkorange":"#ff8c00","darkorchid":"#9932cc","darkred":"#8b0000","darksalmon":"#e9967a","darkseagreen":"#8fbc8f","darkslateblue":"#483d8b","darkslategray":"#2f4f4f","darkturquoise":"#00ced1", - "darkviolet":"#9400d3","deeppink":"#ff1493","deepskyblue":"#00bfff","dimgray":"#696969","dodgerblue":"#1e90ff", - "firebrick":"#b22222","floralwhite":"#fffaf0","forestgreen":"#228b22","fuchsia":"#ff00ff","gainsboro":"#dcdcdc","ghostwhite":"#f8f8ff","gold":"#ffd700","goldenrod":"#daa520","gray":"#808080","green":"#008000","greenyellow":"#adff2f", - "honeydew":"#f0fff0","hotpink":"#ff69b4","indianred ":"#cd5c5c","indigo":"#4b0082","ivory":"#fffff0","khaki":"#f0e68c", - "lavender":"#e6e6fa","lavenderblush":"#fff0f5","lawngreen":"#7cfc00","lemonchiffon":"#fffacd","lightblue":"#add8e6","lightcoral":"#f08080","lightcyan":"#e0ffff","lightgoldenrodyellow":"#fafad2", - "lightgrey":"#d3d3d3","lightgreen":"#90ee90","lightpink":"#ffb6c1","lightsalmon":"#ffa07a","lightseagreen":"#20b2aa","lightskyblue":"#87cefa","lightslategray":"#778899","lightsteelblue":"#b0c4de", - "lightyellow":"#ffffe0","lime":"#00ff00","limegreen":"#32cd32","linen":"#faf0e6","magenta":"#ff00ff","maroon":"#800000","mediumaquamarine":"#66cdaa","mediumblue":"#0000cd","mediumorchid":"#ba55d3","mediumpurple":"#9370d8","mediumseagreen":"#3cb371","mediumslateblue":"#7b68ee", - "mediumspringgreen":"#00fa9a","mediumturquoise":"#48d1cc","mediumvioletred":"#c71585","midnightblue":"#191970","mintcream":"#f5fffa","mistyrose":"#ffe4e1","moccasin":"#ffe4b5","navajowhite":"#ffdead","navy":"#000080", - "oldlace":"#fdf5e6","olive":"#808000","olivedrab":"#6b8e23","orange":"#ffa500","orangered":"#ff4500","orchid":"#da70d6", - "palegoldenrod":"#eee8aa","palegreen":"#98fb98","paleturquoise":"#afeeee","palevioletred":"#d87093","papayawhip":"#ffefd5","peachpuff":"#ffdab9","peru":"#cd853f","pink":"#ffc0cb","plum":"#dda0dd","powderblue":"#b0e0e6","purple":"#800080", - "rebeccapurple":"#663399","red":"#ff0000","rosybrown":"#bc8f8f","royalblue":"#4169e1","saddlebrown":"#8b4513","salmon":"#fa8072","sandybrown":"#f4a460","seagreen":"#2e8b57","seashell":"#fff5ee","sienna":"#a0522d","silver":"#c0c0c0","skyblue":"#87ceeb","slateblue":"#6a5acd","slategray":"#708090","snow":"#fffafa","springgreen":"#00ff7f","steelblue":"#4682b4", - "tan":"#d2b48c","teal":"#008080","thistle":"#d8bfd8","tomato":"#ff6347","turquoise":"#40e0d0","violet":"#ee82ee","wheat":"#f5deb3","white":"#ffffff","whitesmoke":"#f5f5f5","yellow":"#ffff00","yellowgreen":"#9acd32"}; - - if (typeof colours[colour.toLowerCase()] !== "undefined"){ - return colours[colour.toLowerCase()]; - } - return false; - } + /** + * Apply a colorShift animation toe the Aframe element + * + * @param {string} outerElId target element id + * @param {string} color Color the light shift it to + */ colorShift = (outerElId, color) => { let el = this.getEl(outerElId); //if the element is light @@ -1826,6 +1847,37 @@ class Myr { return outerElId; } + /** + * Change the html color code to the hexadecimal + * + * @param {string} colour HTML color code + * + * @returns {string} Hexadecimal representation of the color, return false if color not found. + */ + colourNameToHex=(colour)=> + { + const colours = {"aliceblue":"#f0f8ff","antiquewhite":"#faebd7","aqua":"#00ffff","aquamarine":"#7fffd4","azure":"#f0ffff", + "beige":"#f5f5dc","bisque":"#ffe4c4","black":"#000000","blanchedalmond":"#ffebcd","blue":"#0000ff","blueviolet":"#8a2be2","brown":"#a52a2a","burlywood":"#deb887", + "cadetblue":"#5f9ea0","chartreuse":"#7fff00","chocolate":"#d2691e","coral":"#ff7f50","cornflowerblue":"#6495ed","cornsilk":"#fff8dc","crimson":"#dc143c","cyan":"#00ffff", + "darkblue":"#00008b","darkcyan":"#008b8b","darkgoldenrod":"#b8860b","darkgray":"#a9a9a9","darkgreen":"#006400","darkkhaki":"#bdb76b","darkmagenta":"#8b008b","darkolivegreen":"#556b2f", + "darkorange":"#ff8c00","darkorchid":"#9932cc","darkred":"#8b0000","darksalmon":"#e9967a","darkseagreen":"#8fbc8f","darkslateblue":"#483d8b","darkslategray":"#2f4f4f","darkturquoise":"#00ced1", + "darkviolet":"#9400d3","deeppink":"#ff1493","deepskyblue":"#00bfff","dimgray":"#696969","dodgerblue":"#1e90ff", + "firebrick":"#b22222","floralwhite":"#fffaf0","forestgreen":"#228b22","fuchsia":"#ff00ff","gainsboro":"#dcdcdc","ghostwhite":"#f8f8ff","gold":"#ffd700","goldenrod":"#daa520","gray":"#808080","green":"#008000","greenyellow":"#adff2f", + "honeydew":"#f0fff0","hotpink":"#ff69b4","indianred ":"#cd5c5c","indigo":"#4b0082","ivory":"#fffff0","khaki":"#f0e68c", + "lavender":"#e6e6fa","lavenderblush":"#fff0f5","lawngreen":"#7cfc00","lemonchiffon":"#fffacd","lightblue":"#add8e6","lightcoral":"#f08080","lightcyan":"#e0ffff","lightgoldenrodyellow":"#fafad2", + "lightgrey":"#d3d3d3","lightgreen":"#90ee90","lightpink":"#ffb6c1","lightsalmon":"#ffa07a","lightseagreen":"#20b2aa","lightskyblue":"#87cefa","lightslategray":"#778899","lightsteelblue":"#b0c4de", + "lightyellow":"#ffffe0","lime":"#00ff00","limegreen":"#32cd32","linen":"#faf0e6","magenta":"#ff00ff","maroon":"#800000","mediumaquamarine":"#66cdaa","mediumblue":"#0000cd","mediumorchid":"#ba55d3","mediumpurple":"#9370d8","mediumseagreen":"#3cb371","mediumslateblue":"#7b68ee", + "mediumspringgreen":"#00fa9a","mediumturquoise":"#48d1cc","mediumvioletred":"#c71585","midnightblue":"#191970","mintcream":"#f5fffa","mistyrose":"#ffe4e1","moccasin":"#ffe4b5","navajowhite":"#ffdead","navy":"#000080", + "oldlace":"#fdf5e6","olive":"#808000","olivedrab":"#6b8e23","orange":"#ffa500","orangered":"#ff4500","orchid":"#da70d6", + "palegoldenrod":"#eee8aa","palegreen":"#98fb98","paleturquoise":"#afeeee","palevioletred":"#d87093","papayawhip":"#ffefd5","peachpuff":"#ffdab9","peru":"#cd853f","pink":"#ffc0cb","plum":"#dda0dd","powderblue":"#b0e0e6","purple":"#800080", + "rebeccapurple":"#663399","red":"#ff0000","rosybrown":"#bc8f8f","royalblue":"#4169e1","saddlebrown":"#8b4513","salmon":"#fa8072","sandybrown":"#f4a460","seagreen":"#2e8b57","seashell":"#fff5ee","sienna":"#a0522d","silver":"#c0c0c0","skyblue":"#87ceeb","slateblue":"#6a5acd","slategray":"#708090","snow":"#fffafa","springgreen":"#00ff7f","steelblue":"#4682b4", + "tan":"#d2b48c","teal":"#008080","thistle":"#d8bfd8","tomato":"#ff6347","turquoise":"#40e0d0","violet":"#ee82ee","wheat":"#f5deb3","white":"#ffffff","whitesmoke":"#f5f5f5","yellow":"#ffff00","yellowgreen":"#9acd32"}; + + if (typeof colours[colour.toLowerCase()] !== "undefined"){ + return colours[colour.toLowerCase()]; + } + return false; + } /********************* GETTERS *********************/ /** @@ -1949,26 +2001,6 @@ class Myr { return this.cursor.magnitude.general; }; - - - // MODELS - addCModel = () => { - let asset = { - id: "c-obj", - src: "/img/c.obj" - }; - let el = { - "obj-model": "obj: #c-obj", - mtl: "c-mtl", - position: this.cursor.position, - scale: this.cursor.scale, - rotation: this.cursor.rotation - }; - this.els.push(el); - this.assets.push(asset); - return el; - } - /** * Gets the element associated with the given element ID * @@ -1981,40 +2013,6 @@ class Myr { return this.els[outerElId]; } - /** - * Interface for setting an object's parameters in the DOM - * the idea is the setup an event listener as an almost DOM ready listener. - * - * @param {string} outerElId target element ID - * @param {string} type what param to change - * @param {*} newParam changes - */ - change = (outerElId, type, newParam) => { - document.addEventListener("myr-view-rendered", () => { - try { - let el = document.querySelector("#" + outerElId); - el.setAttribute(type, newParam); - } catch (error) { - return Error("change() failed execution" + - "Ensure you are passing the proper id to the method" + - `Error msg: ${error}`); - } - }); - } - - syncChange = (outerElId, type, newParam) => { - try { - let el = document.querySelector("#" + outerElId); - el.setAttribute(type, newParam); - } catch (error) { - let err = Error("syncChange() failed execution\n" + - "Ensure you are passing the proper id to the method" + - `Error msg: ${error}`); - console.error(err); - return err; - } - } - /** * This creates an entity w shape of object and merges with supplied params * @@ -2031,10 +2029,6 @@ class Myr { return id; } - sleep = (ms) => { - return new Promise(resolve => setTimeout(resolve, ms)); - } - /** * Return a Entity that can be used to group elements together */ @@ -2051,9 +2045,9 @@ class Myr { } /** - * Transfer the object from MYR to the Entity + * Transfer the object from MYR to the Entity. Used to add entity to the group * - * @param {number} id !!!DESCRIPTION NEEDED!!! + * @param {string} id Entity id to remove from list and return */ transfer = (id) => { let retVal = this.els[id]; @@ -2061,20 +2055,80 @@ class Myr { return retVal; } + /* + * Functions that are not in reference or used in anywhere + */ + + sleep = (ms) => { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + // MODELS + addCModel = () => { + let asset = { + id: "c-obj", + src: "/img/c.obj" + }; + let el = { + "obj-model": "obj: #c-obj", + mtl: "c-mtl", + position: this.cursor.position, + scale: this.cursor.scale, + rotation: this.cursor.rotation + }; + this.els.push(el); + this.assets.push(asset); + return el; + } + HALT = () => { // console.log(this); // console.log("Halted"); } + /** + * Interface for setting an object's parameters in the DOM + * the idea is the setup an event listener as an almost DOM ready listener. + * + * @param {string} outerElId target element ID + * @param {string} type what param to change + * @param {*} newParam changes + */ + change = (outerElId, type, newParam) => { + document.addEventListener("myr-view-rendered", () => { + try { + let el = document.querySelector("#" + outerElId); + el.setAttribute(type, newParam); + } catch (error) { + return Error("change() failed execution" + + "Ensure you are passing the proper id to the method" + + `Error msg: ${error}`); + } + }); + } + + syncChange = (outerElId, type, newParam) => { + try { + let el = document.querySelector("#" + outerElId); + el.setAttribute(type, newParam); + } catch (error) { + let err = Error("syncChange() failed execution\n" + + "Ensure you are passing the proper id to the method" + + `Error msg: ${error}`); + console.error(err); + return err; + } + } + infiniteLoopDetector = (function () { let map = {}; - + // define an InfiniteLoopError class function InfiniteLoopError(msg) { Error.call(this, msg); this.type = "InfiniteLoopError"; } - + function infiniteLoopDetector(id) { if (id in map) { if (Date.now() - map[id] > 200) { From 317bea08d4a54267618be55311c42c2f82a25687 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 28 May 2021 20:31:27 -0400 Subject: [PATCH 03/67] Added missing documentation for authAction.js --- src/actions/authActions.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/actions/authActions.js b/src/actions/authActions.js index a77bb285..4828d7b2 100644 --- a/src/actions/authActions.js +++ b/src/actions/authActions.js @@ -5,7 +5,7 @@ import * as types from "../constants/ActionTypes"; * * @param {obj} user User data from the firebase auth obj * - * @returns reducer action obj with type: LOGIN and user obj + * @returns {object} reducer action obj with type: LOGIN and user obj */ export function login(user) { return { type: types.LOGIN, user }; @@ -14,12 +14,19 @@ export function login(user) { /** * Sends a signal to the reducer to logout the current user * - * @returns reducer action obj with type: LOGOUT + * @returns {object} reducer action obj with type: LOGOUT */ export function logout() { return { type: types.LOGOUT }; } +/** + * Sends a signal to the reduce to refresh the token + * + * @param {object} token + * + * @returns {object} reducer action object with type: REFRESH_TOKEN and token obj + */ export function refreshToken(token) { return { type: types.REFRESH_TOKEN, token }; } From b138381bdacc30e052b1546c8bbca43156757999 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 28 May 2021 20:31:52 -0400 Subject: [PATCH 04/67] Added missing documentation for collectionAction.js --- src/actions/collectionActions.js | 51 +++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/actions/collectionActions.js b/src/actions/collectionActions.js index 1b91b3b4..6fc127f9 100644 --- a/src/actions/collectionActions.js +++ b/src/actions/collectionActions.js @@ -2,12 +2,19 @@ import * as types from "../constants/ActionTypes"; export const collectRef = "/apiv1/collections"; -export function asyncCollections(id) { + +/** + * Fetch the list of the user collection asynchronously + * Use when user login or added a new collection + * + * @param {*} uid A JWT token to authenticate with the backend + */ +export function asyncCollections(uid) { // fetch user's collections return (dispatch) => { - if (id) { + if (uid) { let userCollections = []; - fetch(collectRef, {headers: {"x-access-token": id}}).then((data) => { + fetch(collectRef, {headers: {"x-access-token": uid}}).then((data) => { data.json().then((data) => { data.forEach((doc) => { userCollections.push(doc); @@ -19,10 +26,24 @@ export function asyncCollections(id) { }; } +/** + * Sends a signal to the reducer to sync the user collections + * + * @param {object} payload List of user collections + * + * @returns {object} reducer action obj with type SYNC_CLASSES with payload + */ export function syncCollections(payload) { return { type: types.SYNC_CLASSES, payload: payload }; } +/** + * + * Fetch the specific collection specify by user + * @param {string} collectionID Collection id + * @param {*} uid A JWT token to authenticate with the backend + * @returns reducer action obj from syncCollection if collection successfully retrieve the data. void otherwise. + */ export function asyncCollection(collectionID, uid) { // fetch projects in collection return (dispatch) => { @@ -62,27 +83,43 @@ export function asyncCollection(collectionID, uid) { }; } +/** + * Sends a signal to the reducer to load the retrieved collection + * + * @param {object} payload Data of retrieved collection + * @returns {object} redicer action obj with type: SYNC_CLASS and payload + */ export function syncCollection(payload) { return { type: types.SYNC_CLASS, payload: payload }; } -export function deleteCollection(id, name = null, uid) { +/** + * Sends a signal to the reducer to delete the specific collection of user + * + * @param {string} collectionID Collection ID + * @param {string} name Name of the collection if exists + * @param {*} uid A JWT token to authenticate with the backend + * @returns reducer obj with + */ +export function deleteCollection(collectionID, name = null, uid) { return (dispatch) => { - name = (name ? name : id); + name = (name ? name : collectionID); if (window.confirm(`Are you sure you want to delete collection "${name}"?`)) { // Delete Document - fetch(`${collectRef}/collectionID/${name}`, {method: "DELETE", headers: { "x-access-token": uid}}).then((resp) => { + fetch(`${collectRef}/collectionID/${collectionID}`, {method: "DELETE", headers: { "x-access-token": uid}}).then((resp) => { if(resp.status !== 204) { console.error(`Error deleting collection ${name}: ${resp.statusText}`); return; } - dispatch({ type: types.DELETE_CLASS, id: id }); + dispatch({ type: types.DELETE_CLASS, id: collectionID }); }); } }; } + /** + * Creates a new collection * * @param {string} name The name of the collection to be created * @param {*} uid A JWT token to authenticate with the backend From 8a79dd7b9b00e0a31bdfdcb9d0c86baf86c92d19 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Sat, 29 May 2021 19:35:22 -0400 Subject: [PATCH 05/67] Added documentation for all actions functions. --- src/actions/authActions.js | 2 +- src/actions/collectionActions.js | 7 +- src/actions/courseActions.js | 78 +++++++++----- src/actions/editorActions.js | 13 ++- src/actions/projectActions.js | 36 ++++++- src/actions/referenceExampleActions.js | 11 +- src/actions/sceneActions.js | 143 ++++++++++++++++++++++--- 7 files changed, 237 insertions(+), 53 deletions(-) diff --git a/src/actions/authActions.js b/src/actions/authActions.js index 4828d7b2..e11c65ae 100644 --- a/src/actions/authActions.js +++ b/src/actions/authActions.js @@ -21,7 +21,7 @@ export function logout() { } /** - * Sends a signal to the reduce to refresh the token + * Sends a signal to the reducer to refresh the token * * @param {object} token * diff --git a/src/actions/collectionActions.js b/src/actions/collectionActions.js index 6fc127f9..c74ccedb 100644 --- a/src/actions/collectionActions.js +++ b/src/actions/collectionActions.js @@ -38,11 +38,10 @@ export function syncCollections(payload) { } /** - * * Fetch the specific collection specify by user + * * @param {string} collectionID Collection id * @param {*} uid A JWT token to authenticate with the backend - * @returns reducer action obj from syncCollection if collection successfully retrieve the data. void otherwise. */ export function asyncCollection(collectionID, uid) { // fetch projects in collection @@ -87,7 +86,8 @@ export function asyncCollection(collectionID, uid) { * Sends a signal to the reducer to load the retrieved collection * * @param {object} payload Data of retrieved collection - * @returns {object} redicer action obj with type: SYNC_CLASS and payload + * + * @returns {object} reducer action obj with type: SYNC_CLASS and payload */ export function syncCollection(payload) { return { type: types.SYNC_CLASS, payload: payload }; @@ -99,7 +99,6 @@ export function syncCollection(payload) { * @param {string} collectionID Collection ID * @param {string} name Name of the collection if exists * @param {*} uid A JWT token to authenticate with the backend - * @returns reducer obj with */ export function deleteCollection(collectionID, name = null, uid) { return (dispatch) => { diff --git a/src/actions/courseActions.js b/src/actions/courseActions.js index c52f4eb4..85a22773 100644 --- a/src/actions/courseActions.js +++ b/src/actions/courseActions.js @@ -6,7 +6,7 @@ import * as sceneActions from "./sceneActions"; const courseRef = "/apiv1/courses/"; const header = { headers: { "content-type": "application/json" } }; -let noLessons = { +const noLessons = { name: "", id: -1, prompt: "There are no lessons in this course", @@ -19,9 +19,12 @@ const problem = { code: "" }; -/** +/* * Course Actions */ +/** + * Fetch all the courses available + */ export function fetchCourses() { return (dispatch) => { fetch(courseRef, header) @@ -42,10 +45,22 @@ export function fetchCourses() { }; } +/** + * Sends a signal to the reducer to synchronize the courses + * + * @param {*} payload List of courses retrieved + * + * @returns reducer action object with type: SYNC_COURSE and payload + */ export function syncCourses(payload) { return { type: types.SYNC_COURSES, payload: payload }; } +/** + * Fetch specific course + * + * @param {string} courseId id of the course getting + */ export function fetchCourse(courseId) { return (dispatch) => { fetch(courseRef + courseId, header) @@ -84,16 +99,23 @@ export function fetchCourse(courseId) { }; } +/** + * Sends signal to the reducer to load the course retrieved + * @param {*} payload Data of course retrieved + * + * @returns {object} reducer action obj with type: LOAD_COURSE and payload + */ export function loadCourse(course) { - return { - type: types.LOAD_COURSE, - payload: course - }; + return { type: types.LOAD_COURSE, payload: course }; } -/** +/* * Lesson Actions */ +/** + * Fetch the lesson that is supplied by the parameter. + * @param {*} json Lesson data + */ export function fetchLesson(json) { return (dispatch) => { dispatch(loadLesson(json)); @@ -106,10 +128,21 @@ export function fetchLesson(json) { } /** - * Frontend disables option if out of bounds + * Sends signal to the reducer to load a new lesson supplied by parameter + * + * @param {object} lesson Lesson data + * @returns reducer action obj with type: LOAD_LESSON and payload: lesson + */ +export function loadLesson(lesson) { + return { type: types.LOAD_LESSON, payload: lesson }; +} + +/** + * Increment the lesson index and load the next lesson. + * Frontend disables option if out of bounds * - * @param {*} currentIndex !!!DESCRIPTION NEEDED!!! - * @param {*} next !!!DESCRIPTION NEEDED!!! + * @param {number} currentIndex current index of the course + * @param {object} next Object of lesson to be load next */ export function nextLesson(currentIndex, next) { return (dispatch) => { @@ -119,10 +152,11 @@ export function nextLesson(currentIndex, next) { } /** - * Frontend disables option if out of bounds + * Decrement the lesson index and load the previous lesson. + * Frontend disables option if out of bounds * - * @param {*} currentIndex !!!DESCRIPTION NEEDED!!! - * @param {*} prev !!!DESCRIPTION NEEDED!!! + * @param {number} currentIndex current index of the course + * @param {object} prev Object of lesson to be load previous */ export function previousLesson(currentIndex, prev) { return (dispatch) => { @@ -131,18 +165,14 @@ export function previousLesson(currentIndex, prev) { }; } +/** + * Sends signal to the reducer to update the current index of the Course + * + * @param {number} newIndex New index to be set + * @returns {object} reducer action obj with type: SET_INDEX and payload: newIndex + */ export function setCurrentIndex(newIndex) { - return { - type: types.SET_INDEX, - payload: newIndex - }; -} - -export function loadLesson(lesson) { - return { - type: types.LOAD_LESSON, - payload: lesson - }; + return { type: types.SET_INDEX, payload: newIndex }; } export default { diff --git a/src/actions/editorActions.js b/src/actions/editorActions.js index fd0842fb..bcfaba6f 100644 --- a/src/actions/editorActions.js +++ b/src/actions/editorActions.js @@ -8,7 +8,8 @@ const sceneRef = "/apiv1/scenes"; * Sends a signal to the reducer to render the scene * * @param {string} text Text from the Ace Editor component - * + * @param {*} uid A JWT token to authenticate with the backend + * * @returns reducer action obj with action type and text */ export function render(text, uid) { @@ -19,6 +20,7 @@ export function render(text, uid) { * Sends a signal to the reducer to refresh with the given text * * @param {string} text Text from the Ace Editor component + * @param {*} uid A JWT token to authenticate with the backend * * @returns reducer action obj with action type and text */ @@ -36,8 +38,11 @@ export function recover() { } /** - * This does an async fetch to Firebase to grab the scene, then + * This does an async fetch to backend to grab the scene, then * dispatches the necessary functions to update the state. + * + * @param {string} id scene id + * @param {*} uid A JWT token to authenticate with the backend */ export function fetchScene(id, uid = "anon") { return (dispatch) => { // Return a func that dispatches events after async @@ -89,11 +94,13 @@ export function fetchScene(id, uid = "anon") { * * @returns reducer action obj with action type */ - export function updateSavedText(savedText){ return {type: types.EDITOR_UPDATE_SAVEDTEXT, savedText}; } +/** + * Unused function + */ export function addPassword(payload) { return { type: types.ADD_PW, payload }; } diff --git a/src/actions/projectActions.js b/src/actions/projectActions.js index 5c2a2e16..a0592947 100644 --- a/src/actions/projectActions.js +++ b/src/actions/projectActions.js @@ -3,11 +3,16 @@ import * as types from "../constants/ActionTypes"; const sceneRef = "/apiv1/scenes"; const previewRef = "/apiv1/preview/id"; -export function asyncUserProj(id) { +/** + * Retrieved the list of user scenes + * + * @param {*} uid A JWT token to authenticate with the backend + */ +export function asyncUserProj(uid) { // fetch user's project return (dispatch) => { - if (id) { - fetch(`${sceneRef}/`, {headers: {"x-access-token": id}}).then((response) =>{ + if (uid) { + fetch(`${sceneRef}/`, {headers: {"x-access-token": uid}}).then((response) =>{ if(response.status === 200){ response.json().then((json) =>{ json.forEach(element => { @@ -21,10 +26,21 @@ export function asyncUserProj(id) { }; } + +/** + * Sends signal to the reducer to sync the user project + * + * @param {*} payload list of user projects + * + * @returns reducer action obj with type: SYNC_USER_PROJ wiht payload + */ export function syncUserProj(payload) { return { type: types.SYNC_USER_PROJ, payload: payload }; } +/** + * Fetch a eample scenes from the backend + */ export const asyncExampleProj = () => { // fetch example projects return (dispatch) => { @@ -41,10 +57,24 @@ export const asyncExampleProj = () => { }; }; + +/** + * Sends signal to the reducer to sync the example project + * @param {*} payload List of the example project + * + * @returns reducer action obj with type: SYNC_EXAMP_PROJ with payload + */ export function syncExampleProj(payload) { return { type: types.SYNC_EXAMP_PROJ, payload: payload }; } +/** + * Delete the specify user project + * + * @param {*} uid A JWT token to authenticate with the backend + * @param {string} id Scene id to be deleted + * @param {string} name Name of the scene + */ export function deleteProj(uid, id, name) { return (dispatch) => { if (window.confirm(`Are you sure you want to delete ${name}?`)) { diff --git a/src/actions/referenceExampleActions.js b/src/actions/referenceExampleActions.js index a6a3cb37..29da2623 100644 --- a/src/actions/referenceExampleActions.js +++ b/src/actions/referenceExampleActions.js @@ -25,9 +25,10 @@ const notFound = { }; /** - * Lesson Actions + * Fetch specific example scene from backend. + * On success, load and render the example scene * - * @param {*} funcName !!!DESCRIPTION NEEDED!!! + * @param {string} funcName Name of the example scene to retrieve */ export function fetchReferenceExample(funcName) { return (dispatch) => { @@ -60,6 +61,12 @@ export function fetchReferenceExample(funcName) { }; } +/** + * Sends a signal to the reducer to load the retrieved scene + * + * @param {object} refEx object of data of example scene + * @returns reducer action obj with type: LOAD_REF_EX with payload:refEx + */ export function loadReferenceExample(refEx) { return { type: types.LOAD_REF_EX, diff --git a/src/actions/sceneActions.js b/src/actions/sceneActions.js index 4dae10c5..2fd899a4 100644 --- a/src/actions/sceneActions.js +++ b/src/actions/sceneActions.js @@ -22,76 +22,187 @@ export function loadScene(data) { return { type: types.LOAD_SCENE, data }; } +/** + * Sends a signal to the reducer to toggle the coordinate floor + * + * @returns {object} reducer action obj with type: TOGGLE_COORD_SKY + */ export function toggleCoordSky() { return { type: types.TOGGLE_COORD_SKY }; } + +/** + * Sends a signal to the reducer to toggle the default light + * + * @returns {object} reducer action obj with type: TOGGLE_DEFAULT_LIGHT + */ export function toggleDefaultLight() { return { type: types.TOGGLE_DEFAULT_LIGHT }; } + +/** + * Sends a signal to the reducer to toggle the floor + * + * @returns {object} reducer action obj with type: TOGGLE_FLOOR + */ +export function toggleFloor() { + return { type: types.TOGGLE_FLOOR }; +} + +/** + * Sends a signal to the reducer to toggle for light to cast shadow + * + * @returns {object} reducer action obj with type: TOGGLE_CAST_SHADOW + */ export function toggleCastShadow() { return { type: types.TOGGLE_CAST_SHADOW }; } +/** + * Sends a signal to the reducer to toggle for light to show light indicator + * + * @returns {object} reducer action obj with type: TOGGLE_LIGHT_INDICATOR + */ export function toggleLightIndicator(){ return {type: types.TOGGLE_LIGHT_INDICATOR}; } +/** + * Sends a signal to the reducer to change the sky color + * + * @param {string} color Color to be change to + * + * @returns {object} reducer action obj with type: CHANGE_SKY_COLOR with color; + */ export function changeSkyColor(color) { return { type: types.CHANGE_SKY_COLOR, color }; } +/** + * Sends a signal to the reducer to change the sky color + * + * @param {string} color Color to be change to + * + * @returns {object} reducer action obj with type: CHANGE_FLOOR_COLOR with color; + */ export function changeFloorColor(color) { return { type: types.CHANGE_FLOOR_COLOR, color }; } -export function changeCamMode(config) { - return { type: types.CHANGE_CAM_MODE, config }; -} - +/** + * Sends a signal to the reducer to change the position of the camera + * + * @param {number} x X Position + * @param {number} y Y Position + * @param {number} z Z Position + * + * @returns {object} reducer action obj with type: SET_CAMERA with x,y,z position + */ export function setCamera(x, y, z) { return { type: types.SET_CAMERA, x, y, z }; } -export function changePerspective() { - return { type: types.CHANGE_PERSPECTIVE }; -} - +/** + * Sends a signal to the reducer to toggle to be view only(hide the editor) or not + * + * @returns {object} reducer action obj with type: CHANGE_VIEW + */ export function changeView() { return { type: types.CHANGE_VIEW }; } -export function toggleFloor() { - return { type: types.TOGGLE_FLOOR }; -} - +/** + * Sends a signal to the reducer to load the settings sends by the + * + * @returns {object} reducer action obj with type: + */ export function loadSettings(payload) { return { type: types.LOAD_SETTINGS, payload }; } -export function changeSettings(payload) { - return { type: types.CHANGE_SETTINGS, payload }; -} - +/** + * Sends a signal to the reducer to reset the settings to default + * + * @returns {object} reducer action obj with type: RESET_SETTINGS + */ export function resetSettings() { return { type: types.RESET_SETTINGS }; } +/** + * Sends a signal to the reducer to add the scene to the collection + * + * @param {string} payload id of collection to add scene to + * + * @returns {object} reducer action obj with type: ADD_CLASSROOM with payload + */ export function addCollectionID(payload) { return { type: types.ADD_CLASSROOM, payload }; } +/** + * Sends a signal to the reducer to add the scene to the collection + * + * @param {string} payload id of collection to remove scene to + * + * @returns {object} reducer action obj with type: REMOVE_CLASSROOM with payload + */ export function removeCollectionID(payload) { return { type: types.REMOVE_CLASSROOM, payload}; } +/** + * Sends a signal to the reducer to cahnge the description of the scene + * + * @param {string} payload description of the + * + * @returns {object} reducer action obj with type: SET_DESC with payload + */ export function setDesc(payload) { return { type: types.SET_DESC, payload }; } +/** + * Sends a signal to the reducer to change both name and description + * + * @returns {object} reducer action obj with type: + */ export function setNameDesc(payload) { return { type: types.SET_NAME_DESC, payload }; } +/* + * Unused functions + */ +/** + * Sends a signal to the reducer to change the settings + * + * @returns {object} reducer action obj with type: CHANGE_SETTINGS with payload + */ +export function changeSettings(payload) { + return { type: types.CHANGE_SETTINGS, payload }; +} + +/** + * Sends a signal to the reducer to change the mode of the camera + * + * @param {*} config New mode to change + * + * @returns {object} reducer action obj with type: CHANGE_CAM_MODE with config + */ +export function changeCamMode(config) { + return { type: types.CHANGE_CAM_MODE, config }; +} + +/** + * Sends a signal to the reducer to change the perspective + * + * @returns {object} reducer action obj with type: CHANGE_PERSPECTIVE + */ +export function changePerspective() { + return { type: types.CHANGE_PERSPECTIVE }; +} + export default { nameScene, loadScene, From 44c3ca5982b15e9cbb6262935f1791bd40177061 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Sat, 29 May 2021 21:18:43 -0400 Subject: [PATCH 06/67] Added documentation for the reducers --- src/constants/ActionTypes.js | 6 ++- src/reducers/collections.js | 6 +++ src/reducers/course.js | 7 +++ src/reducers/editor.js | 15 ++++-- src/reducers/project.js | 6 +++ src/reducers/referenceExample.js | 5 ++ src/reducers/scene.js | 80 ++++++++++++++++++++------------ src/reducers/user.js | 6 +++ 8 files changed, 94 insertions(+), 37 deletions(-) diff --git a/src/constants/ActionTypes.js b/src/constants/ActionTypes.js index b087dc8c..1f7a84dd 100644 --- a/src/constants/ActionTypes.js +++ b/src/constants/ActionTypes.js @@ -14,14 +14,16 @@ export const EDITOR_CHANGE = "EDITOR_CHANGE"; export const EDITOR_UPDATE_SAVEDTEXT = "EDITOR_UPDATE_SAVEDTEXT"; export const ADD_PW = "ADD_PW"; export const SAVE_START = "SAVE_START"; +//unused constant export const SAVE_FIN = "SAVE_FIN"; export const REQ_RELOAD = "REQ_RELOAD"; -export const ASYNC_USER_PROJ = "ASYNC_USER_PROJ"; export const SYNC_USER_PROJ = "SYNC_USER_PROJ"; -export const ASYNC_EXAMP_PROJ = "ASYNC_EXAMP_PROJ"; export const SYNC_EXAMP_PROJ = "SYNC_EXAMP_PROJ"; export const DELETE_PROJ = "DELETE_PROJ"; +//unused constant +export const ASYNC_USER_PROJ = "ASYNC_USER_PROJ"; +export const ASYNC_EXAMP_PROJ = "ASYNC_EXAMP_PROJ"; export const NAME_SCENE = "NAME_SCENE"; export const NEW_SCENE = "NEW_SCENE"; diff --git a/src/reducers/collections.js b/src/reducers/collections.js index ea674afb..1cdbfef8 100644 --- a/src/reducers/collections.js +++ b/src/reducers/collections.js @@ -5,18 +5,24 @@ const initial_state = { collection: [] }; +/** + * Collection Reducer + */ export default function classes(state = initial_state, action) { switch (action.type) { + //Update list of collections case types.SYNC_CLASSES: return { ...state, collections: action.payload }; + //Load a collection case types.SYNC_CLASS: return { ...state, collection: action.payload }; + //Delete the collection from list case types.DELETE_CLASS: let userClasses = []; userClasses = state.collections.filter(x => { diff --git a/src/reducers/course.js b/src/reducers/course.js index 2da85a6f..8f86bafa 100644 --- a/src/reducers/course.js +++ b/src/reducers/course.js @@ -12,19 +12,25 @@ const initial_state = { } }; +/** + * Course Reducer + */ export default function course(state = initial_state, action) { let payload; switch (action.type) { + //Update list of courses case types.SYNC_COURSES: return { ...state, courses: action.payload }; + //Load a course case types.LOAD_COURSE: return { ...state, course: action.payload }; + //Load a lesson case types.LOAD_LESSON: payload = action.payload; return { @@ -36,6 +42,7 @@ export default function course(state = initial_state, action) { code: payload.code } }; + //Set the index for the current lesson (Where the lesson is) case types.SET_INDEX: return { ...state, diff --git a/src/reducers/editor.js b/src/reducers/editor.js index 692f1bdd..b24896fa 100644 --- a/src/reducers/editor.js +++ b/src/reducers/editor.js @@ -25,13 +25,13 @@ let snapshots = [ ]; -let m = new Myr(); +const m = new Myr(); m.init(); // window.m = m; // Use this to attach it to the window for debugging /** * ESLint doesn't like this but it is better than eval - * @param {*} text !!!DESCRIPTION NEEDED!!! + * @param {string} text MYR code supplied from editor */ function noEvalEvaluation(text) { // eslint-disable-next-line @@ -41,8 +41,13 @@ function noEvalEvaluation(text) { return func; } + +/** + * Editor Reducer + */ export default function editor(state = initial_state, action) { switch (action.type) { + //Handles the evaluation of the MYR code in editor case types.EDITOR_RENDER: m.reset(); @@ -85,7 +90,7 @@ export default function editor(state = initial_state, action) { assets: m.assets || [], message }; - + //Update the text editor case types.EDITOR_REFRESH: m.reset(); return { @@ -93,7 +98,7 @@ export default function editor(state = initial_state, action) { text: action.text, savedText: state.savedText, }; - + //Recover the code case types.EDITOR_RECOVER: // Start at last snap let stableIndex = snapshots.length - 1; @@ -104,7 +109,7 @@ export default function editor(state = initial_state, action) { // Call editor function again with new params return editor({ ...state }, { type: types.EDITOR_RENDER, text: snapshots[stableIndex].text }); - + //Update save text. savedText used to check whether user made changes to the scene case types.EDITOR_UPDATE_SAVEDTEXT: return { ...state, diff --git a/src/reducers/project.js b/src/reducers/project.js index 44bc2307..deebe99b 100644 --- a/src/reducers/project.js +++ b/src/reducers/project.js @@ -5,18 +5,24 @@ const initial_state = { exampleProjs: [] }; +/** + * Project Reducers + */ export default function project(state = initial_state, action) { switch (action.type) { + //Update the list of user projects case types.SYNC_USER_PROJ: return { ...state, userProjs: action.payload }; + //Update the list of example projects case types.SYNC_EXAMP_PROJ: return { ...state, exampleProjs: action.payload }; + //Delete a specific user project case types.DELETE_PROJ: let projs = []; projs = state.userProjs.filter(x => { diff --git a/src/reducers/referenceExample.js b/src/reducers/referenceExample.js index 26fe8126..4ad9d85a 100644 --- a/src/reducers/referenceExample.js +++ b/src/reducers/referenceExample.js @@ -10,8 +10,13 @@ const initial_state = { code: "//Loading" }; + +/** + * Reference Example reducer + */ export default function referenceExample(state = initial_state, action) { switch (action.type) { + //Load specific example scene supplied case types.LOAD_REF_EX: return { ...state, diff --git a/src/reducers/scene.js b/src/reducers/scene.js index 9cc8cfd7..34291a5e 100644 --- a/src/reducers/scene.js +++ b/src/reducers/scene.js @@ -24,7 +24,9 @@ const initial_state = { }; - +/** + * Scene Reducers + */ export default function scene(state = initial_state, action) { if (state.settings.name) { delete state.settings.name; @@ -33,15 +35,18 @@ export default function scene(state = initial_state, action) { delete state.settings.id; } switch (action.type) { + //Update the name of the scene case types.NAME_SCENE: return { ...state, name: action.name }; + //Load a new scene case types.LOAD_SCENE: return { ...action.data }; + //Toggle the grid case types.TOGGLE_COORD_SKY: return { ...state, @@ -50,6 +55,7 @@ export default function scene(state = initial_state, action) { showCoordHelper: !state.settings.showCoordHelper } }; + //Update the position of the camera case types.SET_CAMERA: let camPos = `${action.x || 0} ${action.y + (Math.random() / 10) || 1.6} ${action.z || 0}`; return { @@ -59,6 +65,7 @@ export default function scene(state = initial_state, action) { cameraPosition: camPos } }; + //Toggle the viewOnly mode case types.CHANGE_VIEW: return { ...state, @@ -67,6 +74,7 @@ export default function scene(state = initial_state, action) { viewOnly: !state.settings.viewOnly } }; + //Update the color of sky case types.CHANGE_SKY_COLOR: return { ...state, @@ -75,6 +83,7 @@ export default function scene(state = initial_state, action) { skyColor: action.color } }; + //Update the color of floor case types.CHANGE_FLOOR_COLOR: return { ...state, @@ -83,6 +92,7 @@ export default function scene(state = initial_state, action) { floorColor: action.color } }; + //Toggle the floor case types.TOGGLE_FLOOR: return { ...state, @@ -91,78 +101,88 @@ export default function scene(state = initial_state, action) { showFloor: !state.settings.showFloor } }; - case types.ADD_CLASSROOM: + //Toggle the default light + case types.TOGGLE_DEFAULT_LIGHT: return { ...state, settings: { ...state.settings, - collectionID: action.payload + defaultLight: !state.settings.defaultLight } }; - case types.REMOVE_CLASSROOM: + //Toggle the cast of shadow + case types.TOGGLE_CAST_SHADOW: return { ...state, settings: { ...state.settings, - collectionID: null + castShadow: !state.settings.castShadow } }; - case types.LOAD_SETTINGS: + //Toggle the light indicator + case types.TOGGLE_LIGHT_INDICATOR: + return{ + ...state, + settings:{ + ...state.settings, + lightIndicator: !state.settings.lightIndicator + } + }; + //Add the scene to the collection + case types.ADD_CLASSROOM: return { ...state, settings: { ...state.settings, - ...action.payload + collectionID: action.payload } }; + //Remove the scene from the collection + case types.REMOVE_CLASSROOM: + return { + ...state, + settings: { + ...state.settings, + collectionID: null + } + }; + //Set the description of the scene case types.SET_DESC: return { ...state, desc: action.payload }; + //Set the name and the description of the scene case types.SET_NAME_DESC: return { ...state, name: action.payload.name, desc: action.payload.desc }; - case types.CHANGE_SETTINGS: - const { param, val } = action.payload; + //Load the scene settings + case types.LOAD_SETTINGS: return { ...state, settings: { ...state.settings, - [param]: val + ...action.payload } }; - case types.RESET_SETTINGS: - return { - ...state, - settings: DEF_SETTINGS - }; - case types.TOGGLE_DEFAULT_LIGHT: + //Update the specific scene settings + case types.CHANGE_SETTINGS: + const { param, val } = action.payload; return { ...state, settings: { ...state.settings, - defaultLight: !state.settings.defaultLight + [param]: val } }; - case types.TOGGLE_CAST_SHADOW: + //Reset the settings to the default + case types.RESET_SETTINGS: return { ...state, - settings: { - ...state.settings, - castShadow: !state.settings.castShadow - } - }; - case types.TOGGLE_LIGHT_INDICATOR: - return{ - ...state, - settings:{ - ...state.settings, - lightIndicator: !state.settings.lightIndicator - } + settings: DEF_SETTINGS }; default: return state; diff --git a/src/reducers/user.js b/src/reducers/user.js index 0125f486..3f10b511 100644 --- a/src/reducers/user.js +++ b/src/reducers/user.js @@ -4,16 +4,22 @@ const initial_state = { user: null, }; +/** + * User Reducers + */ export default function user(state = initial_state, action) { switch (action.type) { + //Save user data to state case types.LOGIN: return { user: action.user }; + //Remove user data from state case types.LOGOUT: return { user: null }; + //Assign new token to the uid case types.REFRESH_TOKEN: return { user: { From edf798db7be7374dbb2d85e28477b45bdee49ba3 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Tue, 1 Jun 2021 09:53:06 -0400 Subject: [PATCH 07/67] Added couple more documentation for reducers --- src/reducers/editor.js | 5 +++-- src/reducers/index.js | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/reducers/editor.js b/src/reducers/editor.js index b24896fa..1fafc3b6 100644 --- a/src/reducers/editor.js +++ b/src/reducers/editor.js @@ -30,7 +30,8 @@ m.init(); // window.m = m; // Use this to attach it to the window for debugging /** - * ESLint doesn't like this but it is better than eval + * Conver the MYR code supplied from the editor to a function so it can be executed + * ESLint doesn't like this but it is better than eval * @param {string} text MYR code supplied from editor */ function noEvalEvaluation(text) { @@ -109,7 +110,7 @@ export default function editor(state = initial_state, action) { // Call editor function again with new params return editor({ ...state }, { type: types.EDITOR_RENDER, text: snapshots[stableIndex].text }); - //Update save text. savedText used to check whether user made changes to the scene + //Update save text. savedText use to check whether user made changes to the scene case types.EDITOR_UPDATE_SAVEDTEXT: return { ...state, diff --git a/src/reducers/index.js b/src/reducers/index.js index d453347a..fdc895c6 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -10,6 +10,9 @@ import referenceExample from "./referenceExample"; import thunk from "redux-thunk"; +/** + * @summary This combines all the reducers into a single reducer so it can pass it into store + */ const reducer = combineReducers({ editor, user, @@ -20,8 +23,15 @@ const reducer = combineReducers({ referenceExample }); +/** + * @summary Add third parties library along with the redux compose so it can use with other middleware and enhancers + * Redux devtools extension shows history of the changes to the redux store overtime when debugging. + */ const composeEnhancers = (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true, traceLimit: 25 })) || compose; +/** + * @summary Create a store with the combined reducers and enhancers + */ const store = createStore( reducer, composeEnhancers(applyMiddleware(thunk)) From 96a7118adc2d9007ff002f63890dffa2fb644b9b Mon Sep 17 00:00:00 2001 From: jlu18 Date: Tue, 1 Jun 2021 22:17:42 -0400 Subject: [PATCH 08/67] Added documentation for utils and remove a unnecessasry components --- src/components/structural/View.js | 6 ++-- src/utils/AFramePhysics.js | 56 ++++++------------------------- src/utils/AframeRegIndicator.js | 26 ++++++++++---- src/utils/WASDPlusControls.js | 9 +++++ src/utils/browserType.js | 3 ++ 5 files changed, 45 insertions(+), 55 deletions(-) diff --git a/src/components/structural/View.js b/src/components/structural/View.js index f14ea02b..cac52968 100644 --- a/src/components/structural/View.js +++ b/src/components/structural/View.js @@ -281,9 +281,9 @@ class View extends Component { if (this.props.sceneConfig.settings.showCoordHelper) { return ( - - - + + + { let key; for (key in keys) { return false; } return true; }; + +/** + * @summary Add space and shift controls to the movement + */ AFRAME.registerComponent("wasd-plus-controls", { schema: { acceleration: {type: "number", default : 150}, diff --git a/src/utils/browserType.js b/src/utils/browserType.js index 802d76f2..8bf6421e 100644 --- a/src/utils/browserType.js +++ b/src/utils/browserType.js @@ -1,5 +1,8 @@ import AFRAME from "aframe"; +/** + * @summary Returns type of the device user is using to browse MYR + */ export const browserType = () => { const device = AFRAME.utils.device; From bcf4f2eb244414ea61a6fac13bbdf187b957933f Mon Sep 17 00:00:00 2001 From: jlu18 Date: Wed, 2 Jun 2021 15:32:14 -0400 Subject: [PATCH 09/67] Clean and add documentation for reference, textureReference and tour.js --- src/myr/reference.js | 157 ++++++++++++++++-------------------- src/myr/textureReference.js | 133 +----------------------------- src/myr/tour.js | 4 + 3 files changed, 79 insertions(+), 215 deletions(-) diff --git a/src/myr/reference.js b/src/myr/reference.js index 712703ff..659cb1d2 100644 --- a/src/myr/reference.js +++ b/src/myr/reference.js @@ -5,6 +5,9 @@ import { withStyles } from "@material-ui/core"; +/** + * Custom styles that inject to the cue cards + */ const HtmlTooltip = withStyles(theme => ({ tooltip: { maxWidth: 300, @@ -15,10 +18,16 @@ const HtmlTooltip = withStyles(theme => ({ }, }))(Tooltip); +/** + * Open texture reference page + */ const handleTextureOpen = () => { window.open(window.origin + "/textureReference"); }; +/** + * Return a react elements contain a cue-card for String data type + */ export const stringText = (text) => { return ( { ); }; + +/** + * Return a react elements contain a cue-card for Number data type + */ export const numberText = (text) => { return ( { ); }; + +/** + * Return a react elements contain a cue-card for Boolean data type + */ export const boolText = (text) => { return ( { ); }; +/** + * Return a react elements contain a cue-card for Array data type + */ export const arrayText = (text) => { return ( { ); }; +/** + * Return a react elements contain a cue-card for dynamic data type + */ export const dataText = (text) => { return ( { ); }; -let geometry = [ +/** + * List of geometry reference + */ +const geometry = [ { name: "box", parameters: [], @@ -172,11 +198,6 @@ let geometry = [ description: The octahedron function makes a polyhedron with eight equilateral triangular faces using the current cursor attributes. This function returns an {stringText("elementID")}., example: "octahedron" }, - // This is out temporarily until better fleshed out - //{ - // name: 'line()', - // description: Renders a line using current internal cursor properties. Returns an element id. - //}, { name: "plane", parameters: [], @@ -231,26 +252,34 @@ let geometry = [ description: The triangle function makes flat 2D triangle using the current cursor attributes. This function returns an {stringText("elementID")}., example: "triangle" }, + // This is out temporarily until better fleshed out //{ - // name: tube(), - // description: Renders a tube using current internal cursor properties. Returns an element id., - // example: 'tube' + // name: 'line()', + // description: Renders a line using current internal cursor properties. Returns an element id. //}, - //should this be documented? // { - // name: 'light()', - // description: Renders a light using current internal MYR properties. Returns an element id. + // name: tube(), + // parameters:[], + // description: Renders a tube using current internal cursor properties. Returns an element id., + // example: "tube" // }, - ]; -let transformations = [ +/** + * List of transformation reference + */ +const transformations = [ { name: "resetCursor", parameters: [], description: The resetCursor function resets the properties of the cursor to their defaults. This includes cursor attributes pertaining to Transformations and Animations., example: "resetCursor" }, + { + name: "resetTransformationCursor", + parameters: [], + description: The resetTransformationCursor function resets the transformation properties of the cursor to their defaults., + }, { name: "setColor", parameters: [{ type: "string", name: "color" }], @@ -481,15 +510,13 @@ let transformations = [ name: "getCursorAttribute", parameters: [{ type: "string", name: "key" }], description: The getCursorAttribute function allows the user to get a cursor attributes set by the setCursorAttribute function or by any other cursor setter. - }, - { - name: "resetTransformationCursor", - parameters: [], - description: The resetTransformationCursor function resets the transformation properties of the cursor to their defaults., - }, + } ]; -let animations = [ +/** + * List of animation reference + */ +const animations = [ { name: "setLoop", parameters: [{ type: "bool", name: "loop" }], @@ -523,6 +550,11 @@ let animations = [ parameters: [], description: The getMagnitude function returns the current magnitude attribute of the cursor. The magnitude can be changed by the setMagnitude function. }, + { + name: "resetAnimationCursor", + parameters: [], + description: The resetAnimationCursor function resets the properties of the cursor that contains animation properties to their defaults., + }, { name: "spin", parameters: [{ type: "string", name: "elementID" }], @@ -606,66 +638,18 @@ let animations = [ parameters: [{ type: "string", name: "elementID" }, { type: "string", name: "color" }], description: The colorShift function shifts the element from its original color to the given color. All colors valid for setColor are applicable., example: "colorShift" - }, + } +]; + +/** + * List of light reference + */ +const lights = [ { - name: "resetAnimationCursor", + name: "resetLightCursor", parameters: [], - description: The resetAnimationCursor function resets the properties of the cursor that contains animation properties to their defaults., - }, - // { - // name: spin(element, magnitude, loop, duration), - // description: Spins the element around the y axis magnitude degrees. - // }, - // { - // name: yoyo(element, magnitude, loop, duration), - // description: Bounces the element magnitude units in a positive direction on the y axis for duration milliseconds. - // }, - // { - // name: sideToSide(element, magnitude, loop, duration), - // description: Shifts the element magnitude units in a negative direction on the x axis and back to the original coordinate over duration milliseconds. - // }, - // { - // name: goUp(element, magnitude, loop, duration), - // description: Translates the element magnitude units in a positive direction on the y axis over duration milliseconds. - // }, - // { - // name: goDown(element, magnitude, loop, duration), - // description: Translates the element magnitude units in a negative direction on the y axis over duration milliseconds. - // }, - // { - // name: goRight(element, magnitude, loop, duration), - // description: Translates the element magnitude units in a positive direction on the x axis over duration milliseconds. - // }, - // { - // name: goLeft(element, magnitude, loop, duration), - // description: Translates the element magnitude units in a negative direction on the x axis over duration milliseconds. - // }, - // { - // name: goTowards(element, magnitude, loop, duration), - // description: Translates the element magnitude units in a positive direction on the z axis over duration milliseconds. - // }, - // { - // name: goAway(element, magnitude, loop, duration), - // description: Translates the element magnitude units in a negative direction on the z axis over duration milliseconds. - // }, - // { - // name: grow(element, magnitude, loop, duration), - // description: Scales the element by a magnitude multiplier over duration milliseconds. - // }, - // { - // name: shrink(element, magnitude, loop, duration), - // description: Scales the element by a 1/magnitude multiplier over duration milliseconds. - // }, - // { - // name: fadeOut(element, magnitude, loop, duration), - // description: Modifies transparency from 1 to magnitude [0,1) over duration milliseconds. - // }, - // { - // name: fadeIn(element, magnitude, loop, duration), - // description: Modifies transparency from 0 to magnitude (0,1] over duration milliseconds. - // }, -]; -let lights = [ + description: The resetLightCursor function resets the properties of the cursor that contains light properties to their defaults. + }, { name: "ambientLight", parameters: [], @@ -720,15 +704,13 @@ let lights = [ name: "setLightTarget", parameters: [{type:"number",name:"x"},{type:"number",name:"y"},{type:"number",name:"z"}], description: The setLightTarget function sets the point where the light should be pointed to. The default values are x:0, y:0, z:0. - }, - { - name: "resetLightCursor", - parameters: [], - description: The resetLightCursor function resets the properties of the cursor that contains light properties to their defaults. - }, + } ]; -let groups = [ +/** + * List of group reference + */ +const groups = [ { name: let myGroup = group, parameters: [], @@ -768,6 +750,9 @@ let groups = [ ]; +/** + * Combine lists of refence to single object + */ const reference = { geometry: geometry, transformations: transformations, diff --git a/src/myr/textureReference.js b/src/myr/textureReference.js index 44399eb4..3668fb84 100644 --- a/src/myr/textureReference.js +++ b/src/myr/textureReference.js @@ -1,131 +1,7 @@ -import React from "react"; -import { - Tooltip, - Typography, - withStyles -} from "@material-ui/core"; - -const HtmlTooltip = withStyles(theme => ({ - tooltip: { - maxWidth: 300, - fontSize: theme.typography.pxToRem(14), - "& b": { - fontWeight: "inherit", - }, - }, -}))(Tooltip); - -export const stringText = (text) => { - return ( - - String -

- In computer science a string is any finite sequence of characters - (i.e., letters, numerals, symbols and punctuation marks).
-

- {text === "elementID" && -

An elementID is a special type of string returned by geometries and groups.

} - - } - > - - {text} - -
); -}; -export const numberText = (text) => { - return ( - - Number -

- A number is any real number, or an expression that evaluates to a real number - (e.g., -2, 3.14, 1/3). -

- - } - > - - {text} - -
); -}; -export const boolText = (text) => { - return ( - - Bool -

- In computer science, the bool data type has one of two possible Boolean values: true or false. -

- - } - > - - {text} - -
); -}; - -export const arrayText = (text) => { - return ( - - Array -

- In computer science, an array is a data structure that consists of a number of indexable elements. -

-

- This code sets the color of the cursor to blue: -

-

- let colors = ["blue", "green", "red"];
- setColor(colors[0]);
- box();
-

- - } - > - - {text} - -
); -}; - -export const dataText = (text) => { - return ( - - Data -

- Data can be of any valid JS datatype. This includes a strings, numbers, booleans, and objects among other datatypes.
-

- - } - > - - {text} - -
); -}; - -let texture = [ +/** + * List of geometry reference + */ +const texture = [ { name: "bricks", image: "bricks", @@ -219,7 +95,6 @@ let texture = [ ]; - const textureReference = { texture: texture, }; diff --git a/src/myr/tour.js b/src/myr/tour.js index 9add7ad4..45f80d05 100644 --- a/src/myr/tour.js +++ b/src/myr/tour.js @@ -1,3 +1,7 @@ +/** + * Selector: Where to position the tour card. + * Content : Content to display + */ export const TourSteps = [ { selector: "#ace-editor", From 716411084a491ee80f246abf82d4499b8b4b5145 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Tue, 8 Jun 2021 11:57:30 -0400 Subject: [PATCH 10/67] Added documentation for component/structural/header/ files --- src/components/structural/Footer.js | 3 + src/components/structural/header/Banner.js | 27 ++++ src/components/structural/header/Header.js | 56 ++++++- src/components/structural/header/MyrTour.js | 15 ++ .../structural/header/ProjectView.js | 82 ++++++++-- .../structural/header/SceneConfigMenu.js | 144 ++++++++++++++---- 6 files changed, 282 insertions(+), 45 deletions(-) diff --git a/src/components/structural/Footer.js b/src/components/structural/Footer.js index 876b75dd..e6eaeee3 100644 --- a/src/components/structural/Footer.js +++ b/src/components/structural/Footer.js @@ -1,5 +1,8 @@ import React, { Component } from "react"; +/** + * React component class for the footer includes link to about page, privacy policy, TOS, etc. + */ class Footer extends Component { render() { return ( diff --git a/src/components/structural/header/Banner.js b/src/components/structural/header/Banner.js index 49672106..bfc454b8 100644 --- a/src/components/structural/header/Banner.js +++ b/src/components/structural/header/Banner.js @@ -15,6 +15,9 @@ const redirectedNotif = { const localStorageKey = "seenMsgs"; +/** + * React compoonent class for displaying message on top of MYR (ie. New version release, using old firebase url, etc.) + */ class Banner extends Component { constructor(props){ super(props); @@ -33,6 +36,11 @@ class Banner extends Component { this.setState({mobile: ev.matches}); }); + /** + * Fetch the notificiation from the backend + * If the response is redirected link from firebase, + * push the new link without redirected param + */ fetch(this.props.endpoint).then(resp => { resp.json().then(json => { let arr = []; @@ -52,6 +60,9 @@ class Banner extends Component { }); } + /** + * Handle when banner is close + */ closeButtonClick = () => { //Prevent notification redirects from being pushed to the ignore array if(this.state.currentMessage._id !== -1){ @@ -63,6 +74,7 @@ class Banner extends Component { ); } + //Show the next banner if exists, close it otherwise. if(this.state.messageIndex + 1 >= this.state.messages.length){ this.setState({isOpen: false}); }else{ @@ -73,6 +85,9 @@ class Banner extends Component { } } + /** + * @returns Elements of buttons depends on device + */ renderButtons = () => { const style = { closeButton: { @@ -126,6 +141,9 @@ class Banner extends Component { ); } + /** + * @returns Elements to display messages + */ renderMessage = () => { const style = { title: { @@ -175,6 +193,9 @@ class Banner extends Component { ); } + /** + * @returns Elements to display if user is accessing from desktop + */ renderDesktop = () => { return ( @@ -184,6 +205,9 @@ class Banner extends Component { ); } + /** + * @returns Elements to display if user is accessing from mobile + */ renderMobile = () => { return ( <> @@ -197,6 +221,9 @@ class Banner extends Component { ); } + /** + * Create Banner + */ render = () => { return (this.state.isOpen && this.state.currentMessage ?
{ const sceneSettings = this.props.scene.settings; @@ -177,6 +182,11 @@ class Header extends Component { sceneSettings.skyColor, sceneSettings.viewOnly]; }; + /** + * Compare two arrays of setting and determine whether is the settings are equal or not + * @param {array} newSettings Settings to compare + * @returns {boolean} If settings are equal or not + */ settingsEqual = (newSettings) =>{ for(let i = 0; i < newSettings.length; ++i){ if(newSettings[i] !== this.state.savedSettings[i]){ @@ -213,6 +223,11 @@ class Header extends Component { window.gtag("config", "UA-122925714-1", {"user_id": this.props.user.googleId}); } + /** + * Google auth token object has a expiration time that needed to be refresh after certain time period + * This function set the timeout and will refresh the token after it reach the time + * @param {number} time The time when the token will expired + */ setRefreshTime = (time) => { const oneMinute = 60*1000; let expiryTime = Math.max( @@ -222,6 +237,9 @@ class Header extends Component { setTimeout(this.refreshToken, expiryTime); } + /** + * Refresh token when the time expires, update the token, and set the refresh time again + */ refreshToken = () => { this.state.googleUser.reloadAuthResponse().then((authResponse) => { this.props.logging.refreshToken(authResponse.id_token); @@ -361,6 +379,10 @@ class Header extends Component { return projectId; } + /** + * @return Return a elements with spinner like effects if the spinnerOpen is true + * Use for when saving or loading a scene + */ spinner = () => { if (this.state.spinnerOpen) { return ( @@ -503,36 +525,60 @@ class Header extends Component { this.setState({ projectTab: "a" }); }; + /** + * toggles the load welcome menu + */ handleWelcomeToggle = () => { this.setState({ welcomeOpen: !this.state.welcomeOpen }); }; + /** + * toggles the load courses drawer + */ handleCoursesToggle = () => { this.setState({ coursesOpen: !this.state.coursesOpen }); }; + /** + * toggles the load tour + */ handleTourToggle = () => { this.setState({ tourOpen: !this.state.tourOpen }); }; + /** + * toggles the load collection drawer + */ handleCollectionToggle = () => { this.setState({ collectionOpen: !this.state.collectionOpen }); }; + /** + * close the collection drawer + */ handleCollectionClose = () => { this.setState({ collectionOpen: false }); }; + /** + * toggles the load reference drawer + */ handleReferenceToggle = () => { this.setState({ referenceOpen: !this.state.referenceOpen }); }; + /** + * Handles when collection is deleted + */ handleCollectionDelete = (collectionID) => { if(this.props.scene.settings.collectionID === collectionID) { this.props.sceneActions.removeCollectionID(this.props.scene); } } + /** + * Return a collection component + */ loadCollection = () => { return ( { this.setState({ snackOpen: false }); } + /** + * Display the snackbar that displays the message from render + */ renderSnackBar = () => { return ( { if (this.state.viewOnlyOnOpen) { this.props.changeView(); @@ -19,6 +25,9 @@ class MyrTour extends Component { this.props.handleTourToggle(); } + /** + * Create tour + */ render() { let isDisabled = this.props.layoutType === layoutTypes.REFERENCE; return ( @@ -55,6 +64,9 @@ class MyrTour extends Component { } } +/** + * Wrap each line of string with div + */ const formatLineBreaks = (string) => { if (typeof string !== "string") { return string; @@ -72,6 +84,9 @@ const formatLineBreaks = (string) => { } }; +/** + * Formats all the strings of tours into an elements + */ const formatSteps = (steps) => { return steps.map( (step) => { step.content = formatLineBreaks(step.content); diff --git a/src/components/structural/header/ProjectView.js b/src/components/structural/header/ProjectView.js index af7b110c..280e4b02 100644 --- a/src/components/structural/header/ProjectView.js +++ b/src/components/structural/header/ProjectView.js @@ -19,6 +19,7 @@ import { import { withStyles } from "@material-ui/core/styles"; import "../../../css/ProjectView.css"; + function getOuterModalStyle() { const top = 50; const left = 50; @@ -88,6 +89,10 @@ const exitBtnStyle = { top: 0, right: 0, }; + +/** + * Create component with show + */ class Project extends React.Component { constructor(props) { super(props); @@ -96,41 +101,64 @@ class Project extends React.Component { showImg: false, anchorEl: null, qrCodeOpen: false, - pwProtectOpen: false, shareOpen: false, infoOpen: false, email: "", - pw: "", sendTo: [], value: this.props.tab, + //pwProtectOpen: false, + //pw: "", }; this.emailRef = React.createRef(); } + /** + * Handles when user click on the project + * @param {*} event + */ handleClick = event => { this.setState({ anchorEl: event.currentTarget, projectId: event.currentTarget.id }); }; + /** + * Handles when user clicks on the info in the user project + * @param {*} event + */ handleInfoUserClick = event => { this.setState({ projectId: event.currentTarget.id, isUserProj: true }); this.handleInfoToggle(); }; + /** + * Handles when user clicks on the info in the example project + * @param {*} event + */ handleInfoExampleClick = event => { this.setState({ projectId: event.currentTarget.id, isUserProj: false }); this.handleInfoToggle(); }; + /** + * Handles when the projectview is closed + * @param {*} event + */ handleClose = () => { this.setState({ anchorEl: null }); }; + /** + * Handles when the text change in the textfield + * @param {string} name Place where it saved in state + */ handleTextChange = name => event => { this.setState({ [name]: event.target.value, }); }; + /** + * Handles when the user add the new email address to send + */ handleAddEmail = () => { let arr = [].concat(this.state.sendTo); arr.push(this.state.email); @@ -138,21 +166,31 @@ class Project extends React.Component { this.setState({ sendTo: arr, email: "" }); } + /** + * Handles toggle the project info + */ handleInfoToggle = () => { this.setState({ infoOpen: !this.state.infoOpen }); } + /** + * Handles toggle the qrcode menu + */ handleQrToggle = () => { this.setState({ qrCodeOpen: !this.state.qrCodeOpen }); } - handlePwToggle = () => { - this.setState({ pwProtectOpen: !this.state.pwProtectOpen }); - } - + /** + * Handles toggle the share menu + */ handleShrToggle = () => { this.setState({ shareOpen: !this.state.shareOpen, sendTo: [] }); } + + // handlePwToggle = () => { + // this.setState({ pwProtectOpen: !this.state.pwProtectOpen }); + // } + //handleProjectToggle = () => { // this.setState({ projectsOpen: !this.state.projectsOpen }); // this.setState({ value: "a" }); @@ -200,6 +238,9 @@ class Project extends React.Component { //
// ); + /** + * @returns Email field where user enters addresses they want to share it with + */ shareOptions = () => (
Enter one or more email addresses
@@ -231,6 +272,9 @@ class Project extends React.Component {
); + /** + * @returns Returns the info of the project if it exists + */ infoOpen = () => { let projectId = this.state.projectId; let project; @@ -262,6 +306,9 @@ class Project extends React.Component { ); }; + /** + * @returns QR Code of the link to the project + */ qrCodeOpen = () => { return (
@@ -270,7 +317,13 @@ class Project extends React.Component {
); }; - + + /** + * Helper for creating the project card + * @param {object} proj Porject info + * @param {boolean} canDelete whehter project can be deleted + * @returns Elements of the project card + */ helper = (proj, canDelete) => { if (proj) { let id = proj._id; @@ -331,6 +384,9 @@ class Project extends React.Component { } } + /** + * @returns Create a share menu for QR Code and email + */ sceneMenu = () => ( ); + /** + * Handles the switch between user and example project tab + * @param {*} event + * @param {string} value New tab string + */ handleChange = (event, value) => { this.setState({ value }); }; + /** + * Create project view + */ render() { const { classes } = this.props; let previewToggle = { @@ -503,7 +567,7 @@ class Project extends React.Component { - - + */} diff --git a/src/components/structural/header/SceneConfigMenu.js b/src/components/structural/header/SceneConfigMenu.js index 936d7425..cdbd6a4d 100644 --- a/src/components/structural/header/SceneConfigMenu.js +++ b/src/components/structural/header/SceneConfigMenu.js @@ -121,16 +121,23 @@ class ConfigModal extends Component { this.setState({ open: false, displaySkyColorPicker: false, displayFloorColorPicker: false }); }; - handleClick = event => { - this.setState({ anchorEl: event.currentTarget, projectId: event.currentTarget.id }); - }; + // handleClick = event => { + // this.setState({ anchorEl: event.currentTarget, projectId: event.currentTarget.id }); + // }; + /** + * Handles when the text change in the textfield. Use in mail share and collection + * @param {string} name Place where it saved in state + */ handleTextChange = name => event => { this.setState({ [name]: event.target.value, }); }; + /** + * Handles when the user add the new email address to send + */ handleAddEmail = () => { let arr = [].concat(this.state.sendTo); arr.push(this.state.email); @@ -138,40 +145,49 @@ class ConfigModal extends Component { this.setState({ sendTo: arr, email: "" }); }; + /** + * Handles toggle the qrcode menu + */ handleQrToggle = () => { this.setState({ qrCodeOpen: !this.state.qrCodeOpen }); }; - - handlePwToggle = () => { - this.setState({ pwProtectOpen: !this.state.pwProtectOpen }); - }; - + + /** + * Handles toggle the share menu + */ handleShrToggle = () => { this.setState({ shareOpen: !this.state.shareOpen, sendTo: [] }); }; - pwProtect = () => ( -
-
Please enter a PW.
- - -

- Legal disclaimer: This will only slow down people from accessing your work. MYR is not sutiable for sensitive information. -

-
- ); + // handlePwToggle = () => { + // this.setState({ pwProtectOpen: !this.state.pwProtectOpen }); + // }; + + // pwProtect = () => ( + //
+ //
Please enter a PW.
+ // + // + //

+ // Legal disclaimer: This will only slow down people from accessing your work. MYR is not sutiable for sensitive information. + //

+ //
+ // ); + /** + * @returns Email field where user enters addresses they want to share it with + */ shareOptions = () => (
Enter one or more email addresses
@@ -201,6 +217,9 @@ class ConfigModal extends Component {
); + /** + * @returns QR Code of the link to the project + */ qrCodeOpen = () => { return (
@@ -217,34 +236,54 @@ class ConfigModal extends Component { this.props.sceneActions.toggleCoordSky(); }; + /** + * Update the state and dispatch an action to change the skycolor + * @param {object} color object contains "hex" key + */ handleSkyChangeComplete = (color) => { this.setState({ skyColor: color.hex }); this.props.sceneActions.changeSkyColor(color.hex); }; + /** + * Update the state and dispatch an action to change the floorcolor + * @param {object} color object contains "hex" key + */ handleFloorChangeComplete = (color) => { this.setState({ floorColor: color.hex }); this.props.sceneActions.changeFloorColor(color.hex); }; + /** + * Toggle the color picker for skyColor + */ handleSkyColorClick = () => { this.setState({ displaySkyColorPicker: !this.state.displaySkyColorPicker }); }; + /** + * Toggle the color picker for floorColor + */ handleFloorColorClick = () => { this.setState({ displayFloorColorPicker: !this.state.displayFloorColorPicker }); }; + /** + * Close the color picker for skyColor + */ handleSkyColorClose = () => { this.setState({ displaySkyColorPicker: false }); }; + /** + * Close the color picker for floorColor + */ handleFloorColorClose = () => { this.setState({ displayFloorColorPicker: false }); }; /** - * Toggles whether the editor is showing + * Return button for toggles whether the editor is showing */ viewToggle = () => { let style = this.props.scene.settings.viewOnly ? btnStyle.off : btnStyle.on; @@ -268,7 +307,9 @@ class ConfigModal extends Component { ); }; - // Toggles the grid on and off + /** + * Return button for toggles the grid on and off + */ gridToggle = () => { let style = this.props.scene.settings.showCoordHelper ? btnStyle.on : btnStyle.off; style = { ...btnStyle.base, ...style }; @@ -288,6 +329,10 @@ class ConfigModal extends Component { ); }; + + /** + * Return button for toggles the default light on and off + */ defaultLightToggle = () =>{ let style = this.props.scene.settings.defaultLight ? btnStyle.on : btnStyle.off; style = { ...btnStyle.base, ...style }; @@ -308,6 +353,10 @@ class ConfigModal extends Component { ); } + + /** + * Return button for toggles the shadow on and off + */ castShadowToggle = () => { let style = this.props.scene.settings.castShadow ? btnStyle.on : btnStyle.off; style = { ...btnStyle.base, ...style }; @@ -328,6 +377,10 @@ class ConfigModal extends Component { ); } + + /** + * Return button for toggles the light indicator on and off + */ lightIndicatorToggle = () => { let style = this.props.scene.settings.lightIndicator ? btnStyle.on : btnStyle.off; style = { ...btnStyle.base, ...style }; @@ -350,7 +403,7 @@ class ConfigModal extends Component { } /** - * Toggles the floor on and off + * Return button for toggles the floor on and off */ floorToggle = () => { let style = this.props.scene.settings.showFloor ? btnStyle.on : btnStyle.off; @@ -372,6 +425,9 @@ class ConfigModal extends Component { ); }; + /** + * Return button for toggles addCollection menu + */ addCollectionToggle = () => { return ( { this.setState({ addClassOpen: !this.state.addClassOpen, collectionError: "" }); }; + + /** + * Returns button for shows collection info + */ classInfoToggle = () => { return ( (
Please enter your collection name.
@@ -446,6 +512,9 @@ class ConfigModal extends Component { ); }; + /** + * Returns button for open color picker for skyColor + */ changeSkyColor = () => { return ( { return ( { this.setState({ value }); }; + /** + * Create sceneConfig menu + */ render() { const { classes } = this.props; let isDisabled = this.props.layoutType === layoutTypes.REFERENCE; From ab3e5eed0e98a763f860e29b358679815c0e9dd4 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 9 Jul 2021 16:57:35 -0400 Subject: [PATCH 11/67] Removed unused password protection feature --- src/actions/editorActions.js | 8 -- .../structural/header/ProjectView.js | 74 ------------------- .../structural/header/SceneConfigMenu.js | 47 ------------ src/constants/ActionTypes.js | 1 - 4 files changed, 130 deletions(-) diff --git a/src/actions/editorActions.js b/src/actions/editorActions.js index bcfaba6f..107bc37c 100644 --- a/src/actions/editorActions.js +++ b/src/actions/editorActions.js @@ -98,18 +98,10 @@ export function updateSavedText(savedText){ return {type: types.EDITOR_UPDATE_SAVEDTEXT, savedText}; } -/** - * Unused function - */ -export function addPassword(payload) { - return { type: types.ADD_PW, payload }; -} - export default { render, refresh, recover, fetchScene, - addPassword, updateSavedText, }; \ No newline at end of file diff --git a/src/components/structural/header/ProjectView.js b/src/components/structural/header/ProjectView.js index 280e4b02..0b444b94 100644 --- a/src/components/structural/header/ProjectView.js +++ b/src/components/structural/header/ProjectView.js @@ -106,8 +106,6 @@ class Project extends React.Component { email: "", sendTo: [], value: this.props.tab, - //pwProtectOpen: false, - //pw: "", }; this.emailRef = React.createRef(); } @@ -187,57 +185,6 @@ class Project extends React.Component { this.setState({ shareOpen: !this.state.shareOpen, sendTo: [] }); } - // handlePwToggle = () => { - // this.setState({ pwProtectOpen: !this.state.pwProtectOpen }); - // } - - //handleProjectToggle = () => { - // this.setState({ projectsOpen: !this.state.projectsOpen }); - // this.setState({ value: "a" }); - //}; - - // pwProtect = () => ( - //
- //
Please enter a PW.
- // - // - //

- // Legal disclaimer: This will only slow down people from accessing your work. MYR is not sutiable for sensitive information. - //

- //
- // ); - - // pwProtect = () => ( - //
- //
Please enter a PW.
- // - // - //

- // Legal disclaimer: This will only slow down people from accessing your work. MYR is not sutiable for sensitive information. - //

- //
- // ); - /** * @returns Email field where user enters addresses they want to share it with */ @@ -407,13 +354,6 @@ class Project extends React.Component { - {/* { this.handleClose(); this.handlePwToggle(); }}> - - lock - - - */}
); @@ -567,20 +507,6 @@ class Project extends React.Component { - {/* -
- this.handlePwToggle()} > - clear - - -
-
*/} diff --git a/src/components/structural/header/SceneConfigMenu.js b/src/components/structural/header/SceneConfigMenu.js index cdbd6a4d..05b54727 100644 --- a/src/components/structural/header/SceneConfigMenu.js +++ b/src/components/structural/header/SceneConfigMenu.js @@ -92,7 +92,6 @@ class ConfigModal extends Component { anchorEl: null, displayFloorColorPicker: false, qrCodeOpen: false, - pwProtectOpen: false, shareOpen: false, addClassOpen: false, defaultLight: true, @@ -159,32 +158,6 @@ class ConfigModal extends Component { this.setState({ shareOpen: !this.state.shareOpen, sendTo: [] }); }; - // handlePwToggle = () => { - // this.setState({ pwProtectOpen: !this.state.pwProtectOpen }); - // }; - - // pwProtect = () => ( - //
- //
Please enter a PW.
- // - // - //

- // Legal disclaimer: This will only slow down people from accessing your work. MYR is not sutiable for sensitive information. - //

- //
- // ); - /** * @returns Email field where user enters addresses they want to share it with */ @@ -671,12 +644,6 @@ class ConfigModal extends Component { send Send To - {/* { this.handlePwToggle(); }} > - lock - Add PW - */}
Collection Control
{this.props.displayCollectionConfig ? @@ -730,20 +697,6 @@ class ConfigModal extends Component { - -
- this.handlePwToggle()} > - clear - - -
-
Date: Tue, 13 Jul 2021 12:08:00 -0400 Subject: [PATCH 12/67] Added doc for Editor.js and autoCompleter.js --- src/components/editor/Editor.js | 16 ++++++++++++++++ src/components/editor/customCompleter.js | 17 ++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/components/editor/Editor.js b/src/components/editor/Editor.js index 3107eadd..68956dce 100644 --- a/src/components/editor/Editor.js +++ b/src/components/editor/Editor.js @@ -12,6 +12,12 @@ import "brace/ext/searchbox"; */ class Editor extends Component { + /** + * Called when the Edtior is unmounting (Being removed from the DOM) + * + * Editor will unmount when MYR enters ViewOnly mode, and we want to render + * whatever the code that's in the editor. + */ componentWillUnmount() { // Updates state in reducer before closing editor const text = window.ace.edit("ace-editor").getSession().getValue(); @@ -21,6 +27,12 @@ class Editor extends Component { this.props.render(text); } + /** + * Called when the Editor is mounted (component has been rendererd to the DOM) + * + * It sets custom completer of MYR API to editor, + * and add listener to check whether user have unsaved changes. + */ componentDidMount() { try { // eslint-disable-next-line @@ -46,6 +58,10 @@ class Editor extends Component { }); } + /** + * Called when the editor is loaded. + * It sets options to set the maximum error editor accepts and set the EMCAScript version to 6 + */ onLoad() { window.ace.edit("ace-editor").session.$worker.send("setOptions", [{ "maxerr": 1000, diff --git a/src/components/editor/customCompleter.js b/src/components/editor/customCompleter.js index 438ad20f..02dd0e69 100644 --- a/src/components/editor/customCompleter.js +++ b/src/components/editor/customCompleter.js @@ -1,9 +1,12 @@ import myrReference from "../../myr/reference.js"; import myrTextures from "../structural/Textures.js"; +/** + * Creates customCompleter for all MYR references and keywords for JS, color code, and assets + */ export const customCompleter = { getCompletions: function (editor, session, pos, prefix, callback) { - let BasicAutocompleteKeyWords = [ + const BasicAutocompleteKeyWords = [ "const", "yield", "import", @@ -35,20 +38,20 @@ export const customCompleter = { "static" ]; - let texture = myrTextures(); - let Texture = [...texture.TexturePack.map(obj => obj.title), + const texture = myrTextures(); + const Texture = [...texture.TexturePack.map(obj => obj.title), "group()" ]; - let reference = myrReference(); - let keyWords = [...reference.geometry.map(obj => obj.name + "()"), + const reference = myrReference(); + const MYRKeyWords = [...reference.geometry.map(obj => obj.name + "()"), ...reference.transformations.map(obj => obj.name + "()"), ...reference.animations.map(obj => obj.name + "()"), ...reference.lights.map(obj=>obj.name+"()"), "group()" ]; - let Colors = [ + const Colors = [ "aliceblue", "antiquewhite", "aqua", @@ -208,7 +211,7 @@ export const customCompleter = { }; })); - callback(null, keyWords.map(function (word) { + callback(null, MYRKeyWords.map(function (word) { return { caption: word, value: word, From 0f042d3b4154b118c7018c6723477656c945dc47 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Tue, 13 Jul 2021 12:47:44 -0400 Subject: [PATCH 13/67] Added doc for keyboardshortcut.js --- src/components/editor/KeyboardShortcut.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/components/editor/KeyboardShortcut.js b/src/components/editor/KeyboardShortcut.js index cea5bccf..53c367cb 100644 --- a/src/components/editor/KeyboardShortcut.js +++ b/src/components/editor/KeyboardShortcut.js @@ -69,6 +69,9 @@ const scene = [ }, ]; +/** + * React components create the button with KeyboardShortcut window + */ class KeyboardShortcut extends React.Component { constructor(props){ super(props); @@ -78,6 +81,11 @@ class KeyboardShortcut extends React.Component { }; } + /** + * Helper function to convert the shrotcuts to an equivalent DOM elements + * + * @param {array} data + */ shortcutHelper = (data) => { let shortcuts = []; data.shortcut.forEach((key,i)=>{ @@ -89,18 +97,31 @@ class KeyboardShortcut extends React.Component { return (

{shortcuts} {data.description}

); }; + /** + * Update the state when the button is clicked + * + * @param {object} event target to anchor the window + */ handleClick = (event) =>{ this.setState({ open: true, anchorEl: event.target}); }; + /** + * Update the state when the window is closed + * + * @param {object} event target to anchor the window + */ handleClose = () => { this.setState({ open: false, anchorEl: null}); }; + /** + * Creates the keyboard shortcut in the DOM + */ render(){ return(
From 599beccc5d10a40baa16515e7c4d3fa95afd5b94 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Wed, 14 Jul 2021 07:09:08 -0400 Subject: [PATCH 14/67] Add doc at collection.js, rename some old function name, and fix deleteCollection sending wrong collectionID --- src/actions/collectionActions.js | 2 +- src/components/collection/Collection.js | 68 ++++++++++++++++++++----- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/actions/collectionActions.js b/src/actions/collectionActions.js index c74ccedb..9ea26786 100644 --- a/src/actions/collectionActions.js +++ b/src/actions/collectionActions.js @@ -106,7 +106,7 @@ export function deleteCollection(collectionID, name = null, uid) { if (window.confirm(`Are you sure you want to delete collection "${name}"?`)) { // Delete Document - fetch(`${collectRef}/collectionID/${collectionID}`, {method: "DELETE", headers: { "x-access-token": uid}}).then((resp) => { + fetch(`${collectRef}/collectionID/${name}`, {method: "DELETE", headers: { "x-access-token": uid}}).then((resp) => { if(resp.status !== 204) { console.error(`Error deleting collection ${name}: ${resp.statusText}`); return; diff --git a/src/components/collection/Collection.js b/src/components/collection/Collection.js index 6b845615..a7644cb1 100644 --- a/src/components/collection/Collection.js +++ b/src/components/collection/Collection.js @@ -30,7 +30,7 @@ function getModalStyle() { /** * CSS for modal * - * @param {*} theme !!!DESCRIPTION NEEDED!!! + * @param {import("@material-ui/core").Theme} theme Will use default theme if not provided */ const modelStyles = theme => ({ paper: { @@ -71,6 +71,9 @@ const btnStyle = { } }; +/** + * React Component for Create Collection Modal to Navigate different options for collection + */ class CollectionModal extends Component { constructor(props) { super(props); @@ -82,10 +85,18 @@ class CollectionModal extends Component { }; } + /** + * Move to selected collection page when selected + * @param {object} selectedCollection passed the data of selected collection + */ handleChange = (selectedCollection) => { window.location.assign(window.origin + "/collection/" + selectedCollection.value); } + /** + * Handle when user deleted the selected collection + * @param {object} selectedCollection passed the data of selected collection + */ handleDelete = (selectedCollection) => { let needsToRedirect = (this.props.openCollection === selectedCollection.label); this.props.collectionActions.deleteCollection(selectedCollection.value, selectedCollection.label, this.props.user.uid); @@ -96,29 +107,49 @@ class CollectionModal extends Component { this.props.deleteCallback(selectedCollection.label); } + /** + * Update the state with the collection name user enter in the field + * @param {string} name name of the state to be change + * @param {object} event Event interface when the onChnage event was dispatched + */ handleTextChange = name => event => { this.setState({ [name]: event.target.value, }); }; - handleAddClassToggle = () => { + /** + * Toggle the addOpen state, whether to open "add collection" option + */ + handleAddCollectionToggle = () => { this.setState({ addOpen: !this.state.addOpen }); } - handleOpenClassToggle = () => { + /** + * Toggle the openOpen state, whether to open "open collection" option + */ + handleOpenCollectionToggle = () => { this.setState({ openOpen: !this.state.openOpen }); } - handleDeleteClassToggle = () => { + /** + * Toggle the deleteOpen state, whether to open "delete collection" option + */ + handleDeleteCollectionToggle = () => { this.setState({ deleteOpen: !this.state.deleteOpen }); } + /** + * Close the collection modal and all options + */ handleCloseAll = () => { this.setState({ addOpen: false, openOpen: false, deleteOpen: false }); this.props.handleCollectionClose(); } + /** + * Returns DOM element for modal to select collections + */ selectCollection = () => { const userCollections = this.props.collections.collections; let optionItems = []; @@ -139,6 +170,9 @@ class CollectionModal extends Component { ); } + /** + * Returns DOM element for modal to delete collections + */ deleteCollection = () => { const userCollections = this.props.collections.collections; let optionItems = []; @@ -159,10 +193,13 @@ class CollectionModal extends Component { ); } + /** + * Add new collection to the backend if possible + */ handleSubmit = () => { if (!this.props.user) { window.alert("You must be signed in to create a collection."); - this.handleAddClassToggle(); + this.handleAddCollectionToggle(); } else { let name = this.state.newcollectionID.toLowerCase(); @@ -190,6 +227,9 @@ class CollectionModal extends Component { } } + /** + * Returns DOM element for modal to add collections + */ addClass = () => (
Please enter a new collection name.
@@ -231,13 +271,13 @@ class CollectionModal extends Component {
{ this.handleOpenClassToggle(); }} > + onClick={() => { this.handleOpenCollectionToggle(); }} > storage Open a Collection { this.handleDeleteClassToggle(); }} > + onClick={() => { this.handleDeleteCollectionToggle(); }} > delete Delete a Collection @@ -245,7 +285,7 @@ class CollectionModal extends Component {
{ this.handleAddClassToggle(); }} > + onClick={() => { this.handleAddCollectionToggle(); }} > add_circle Create a Collection @@ -263,11 +303,11 @@ class CollectionModal extends Component { aria-labelledby="simple-modal-title" aria-describedby="simple-modal-description" open={this.state.addOpen} - onClose={this.handleAddClassToggle} > + onClose={this.handleAddCollectionToggle} >
this.handleAddClassToggle()} > + onClick={() => this.handleAddCollectionToggle()} > clear @@ -277,11 +317,11 @@ class CollectionModal extends Component { aria-labelledby="simple-modal-title" aria-describedby="simple-modal-description" open={this.state.openOpen} - onClose={this.handleOpenClassToggle} > + onClose={this.handleOpenCollectionToggle} >
this.handleOpenClassToggle()} > + onClick={() => this.handleOpenCollectionToggle()} > clear @@ -291,11 +331,11 @@ class CollectionModal extends Component { aria-labelledby="simple-modal-title" aria-describedby="simple-modal-description" open={this.state.deleteOpen} - onClose={this.handleDeleteClassToggle} > + onClose={this.handleDeleteCollectionToggle} >
this.handleDeleteClassToggle()} > + onClick={() => this.handleDeleteCollectionToggle()} > clear From fa11f709cb9199d40b8eb760d5712d4ada2882b6 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Wed, 14 Jul 2021 07:58:17 -0400 Subject: [PATCH 15/67] Added doc for selectproject.js and removed a redundant code --- src/components/collection/SelectProject.js | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/components/collection/SelectProject.js b/src/components/collection/SelectProject.js index eb641c87..52e0d43d 100644 --- a/src/components/collection/SelectProject.js +++ b/src/components/collection/SelectProject.js @@ -23,21 +23,23 @@ const selectStyle = { ...base, zIndex: "999" }), - }; +/** + * React component for selecting list of projects from collection + */ class SelectProject extends PureComponent { + + /** + * Fetch the selected scene when the project is selected from the collection + * @param {Event} projectID ID of the project to be fetch + */ handleChange = (projectID) => { // show warning if there's unsaved change if(this.hasEditorChanged()){ - if((window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!"))){ - if (this.props.user && this.props.user.uid) { - this.props.editorActions.fetchScene(projectID.value, this.props.uid); - } else { - this.props.editorActions.fetchScene(projectID.value); - } + if(!window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!")){ + return; } - return; } if (this.props.user && this.props.user.uid) { @@ -47,6 +49,10 @@ class SelectProject extends PureComponent { } } + /** + * Returns wheter the text in the editor match with the savedText + * @returns {boolean} true if savedText is different from text in editor, false otherwise. + */ hasEditorChanged = () => { let text; try { @@ -62,6 +68,9 @@ class SelectProject extends PureComponent { return true; } + /** + * @returns Returns DOM Elements of drop down list of projects + */ renderSelect = () => { let collection = this.props.collection; const placeholder = "Select a project"; @@ -78,6 +87,9 @@ class SelectProject extends PureComponent { ); } + /** + * @returns DOM elements of drop down list of collection + */ render() { return (
From 25f743e2bbd308fae989201491e5e79c8d645976 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Wed, 14 Jul 2021 09:15:13 -0400 Subject: [PATCH 16/67] Added doc for course.js and remove a redundant code --- src/components/collection/SelectProject.js | 2 +- src/components/courses/Course.js | 37 +++++++++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/components/collection/SelectProject.js b/src/components/collection/SelectProject.js index 52e0d43d..e20d43c9 100644 --- a/src/components/collection/SelectProject.js +++ b/src/components/collection/SelectProject.js @@ -88,7 +88,7 @@ class SelectProject extends PureComponent { } /** - * @returns DOM elements of drop down list of collection + * @returns Render DOM elements of drop down list of collection */ render() { return ( diff --git a/src/components/courses/Course.js b/src/components/courses/Course.js index 4f3278d3..ebd9b29a 100644 --- a/src/components/courses/Course.js +++ b/src/components/courses/Course.js @@ -6,31 +6,38 @@ import { Tooltip } from "@material-ui/core"; +/** + * React component for navigating the course lessons and displaying lesson name and description + */ class Lesson extends Component { + /** + * Load next lesson. Give a warning if there's any changes in the editor + */ nextLesson = () => { const currentIndex = this.props.courses.currentIndex; const lessons = this.props.course.lessons; - if(this.hasEditorChanged()){ - if (window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!")) { - this.props.courseActions.nextLesson(currentIndex, lessons[currentIndex + 1]); - } - }else{ - this.props.courseActions.nextLesson(currentIndex, lessons[currentIndex + 1]); + if(this.hasEditorChanged() && !window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!")){ + return; } + this.props.courseActions.nextLesson(currentIndex, lessons[currentIndex + 1]); } + /** + * Load previous lesson. Give a warning if there's any changes in the editor + */ lastLesson = () => { const currentIndex = this.props.courses.currentIndex; const lessons = this.props.course.lessons; - if(this.hasEditorChanged()){ - if (window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!")) { - this.props.courseActions.previousLesson(currentIndex, lessons[currentIndex - 1]); - } - }else{ - this.props.courseActions.previousLesson(currentIndex, lessons[currentIndex - 1]); + if(this.hasEditorChanged() && !window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!")){ + return; } + this.props.courseActions.previousLesson(currentIndex, lessons[currentIndex - 1]); } + /** + * Returns wheter the text in the editor match with the savedText + * @returns {boolean} true if savedText is different from text in editor, false otherwise. + */ hasEditorChanged = () => { let text; try { @@ -47,6 +54,9 @@ class Lesson extends Component { return true; } + /** + * @returns DOM Elements of button that go to previous or + */ renderBtns = () => { const { course, courses } = this.props; let nextValid = courses && courses.currentIndex !== null && course && course.lessons; @@ -84,6 +94,9 @@ class Lesson extends Component { ); } + /** + * @returns Render DOM elements of course lessons + */ render() { return (
From 385bd29d75ffd8012f5bb9c3be271c47769182ed Mon Sep 17 00:00:00 2001 From: jlu18 Date: Wed, 14 Jul 2021 09:33:41 -0400 Subject: [PATCH 17/67] Added doc for courseelect.js and removed unnecessary constructor --- src/components/courses/CourseSelect.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/courses/CourseSelect.js b/src/components/courses/CourseSelect.js index e969a27e..b9c47eb3 100644 --- a/src/components/courses/CourseSelect.js +++ b/src/components/courses/CourseSelect.js @@ -31,8 +31,8 @@ function getModalStyle() { /** * CSS for modal - * - * @param {*} theme !!!DESCRIPTION NEEDED!!! + * + * @param {import("@material-ui/core").Theme} theme Will use default theme if not provided */ const modelStyles = theme => ({ paper: { @@ -48,14 +48,15 @@ const modelStyles = theme => ({ } }); +/** + * React component for creating modal listing courses + */ class CourseSelectModal extends Component { - constructor(props) { - super(props); - this.state = { - // open: false - }; - } - + /** + * Helper function to create card for a course modal. + * @param {object} course Object with course info + * @returns {HTMLElement} Card element of course + */ helper = (course) => { if (course) { let id = course._id; @@ -89,6 +90,7 @@ class CourseSelectModal extends Component { /** * Render all of the elements + * @returns {HTMLElement} Course modal with the list of course cards */ render() { const { classes } = this.props; From bafaac807ab04970767acfdda3fff38a770349dd Mon Sep 17 00:00:00 2001 From: jlu18 Date: Wed, 14 Jul 2021 12:54:13 -0400 Subject: [PATCH 18/67] Removed duplicate in modelReference --- src/myr/modelReference.js | 133 ++---------------------------------- src/myr/textureReference.js | 2 +- 2 files changed, 5 insertions(+), 130 deletions(-) diff --git a/src/myr/modelReference.js b/src/myr/modelReference.js index 40e89427..2e92fb3d 100644 --- a/src/myr/modelReference.js +++ b/src/myr/modelReference.js @@ -1,131 +1,7 @@ -import React from "react"; -import { - Tooltip, - Typography, - withStyles -} from "@material-ui/core"; - -const HtmlTooltip = withStyles(theme => ({ - tooltip: { - maxWidth: 300, - fontSize: theme.typography.pxToRem(14), - "& b": { - fontWeight: "inherit", - }, - }, -}))(Tooltip); - -export const stringText = (text) => { - return ( - - String -

- In computer science a string is any finite sequence of characters - (i.e., letters, numerals, symbols and punctuation marks).
-

- {text === "elementID" && -

An elementID is a special type of string returned by geometries and groups.

} - - } - > - - {text} - -
); -}; -export const numberText = (text) => { - return ( - - Number -

- A number is any real number, or an expression that evaluates to a real number - (e.g., -2, 3.14, 1/3). -

- - } - > - - {text} - -
); -}; -export const boolText = (text) => { - return ( - - Bool -

- In computer science, the bool data type has one of two possible Boolean values: true or false. -

- - } - > - - {text} - -
); -}; - -export const arrayText = (text) => { - return ( - - Array -

- In computer science, an array is a data structure that consists of a number of indexable elements. -

-

- This code sets the color of the cursor to blue: -

-

- let colors = ["blue", "green", "red"];
- setColor(colors[0]);
- box();
-

- - } - > - - {text} - -
); -}; - -export const dataText = (text) => { - return ( - - Data -

- Data can be of any valid JS datatype. This includes a strings, numbers, booleans, and objects among other datatypes.
-

- - } - > - - {text} - -
); -}; - -let model = [ +/** + * List of model reference + */ +const model = [ { name: "sword", model: "sword", @@ -163,7 +39,6 @@ let model = [ }, ]; - const modelReference = { model: model, }; diff --git a/src/myr/textureReference.js b/src/myr/textureReference.js index 775f6f18..6e684f7b 100644 --- a/src/myr/textureReference.js +++ b/src/myr/textureReference.js @@ -1,5 +1,5 @@ /** - * List of geometry reference + * List of texture reference */ const texture = [ { From 14762664c350801047c9633e7d36bf5a65116553 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Wed, 14 Jul 2021 13:10:47 -0400 Subject: [PATCH 19/67] Added doc for files in component/layout directory --- src/components/layouts/Collection.js | 5 +++++ src/components/layouts/Guided.js | 5 +++++ src/components/layouts/Ide.js | 5 +++++ src/components/layouts/ModelReference.js | 5 +++++ src/components/layouts/Reference.js | 5 +++++ src/components/layouts/ReferenceExample.js | 5 +++++ src/components/layouts/TextureReference.js | 5 +++++ 7 files changed, 35 insertions(+) diff --git a/src/components/layouts/Collection.js b/src/components/layouts/Collection.js index ca84d4e7..da5fcddd 100644 --- a/src/components/layouts/Collection.js +++ b/src/components/layouts/Collection.js @@ -7,6 +7,11 @@ import SelectProject from "../collection/SelectProject.js"; import * as layoutTypes from "../../constants/LayoutTypes.js"; +/** + * Create a layout for collection page. + * @param {object} param0 List of props that will be use in components + * @returns {HTMLElement} Layout of the collection page + */ export const Collection = ({ editor, editorActions, user, authActions, scene, sceneActions, projectActions, courseActions, projects, courses, match, collectionActions, collections }) => (
(
(
(
(
(
(
Date: Wed, 14 Jul 2021 15:37:55 -0400 Subject: [PATCH 20/67] Removed HALT and addCModel from Myr.js --- src/myr/Myr.js | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/myr/Myr.js b/src/myr/Myr.js index fbb8dcfe..d9832a26 100644 --- a/src/myr/Myr.js +++ b/src/myr/Myr.js @@ -2104,34 +2104,10 @@ class Myr { /* * Functions that are not in reference or used in anywhere */ - sleep = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); } - // MODELS - addCModel = () => { - let asset = { - id: "c-obj", - src: "/img/c.obj" - }; - let el = { - "obj-model": "obj: #c-obj", - mtl: "c-mtl", - position: this.cursor.position, - scale: this.cursor.scale, - rotation: this.cursor.rotation - }; - this.els.push(el); - this.assets.push(asset); - return el; - } - - HALT = () => { - // console.log(this); - // console.log("Halted"); - } - /** * Interface for setting an object's parameters in the DOM * the idea is the setup an event listener as an almost DOM ready listener. From a09942f1f0f3553276d5d8f6204fd0c6c57d40a9 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 16 Jul 2021 14:44:44 -0400 Subject: [PATCH 21/67] Added doc for View.js --- src/components/structural/View.js | 102 +++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 10 deletions(-) diff --git a/src/components/structural/View.js b/src/components/structural/View.js index 8bb820b7..dc07f39e 100644 --- a/src/components/structural/View.js +++ b/src/components/structural/View.js @@ -18,10 +18,21 @@ class View extends Component { welcomeOpen: true }; } + /** + * The timer ID set to check if the welcome screen is open + * It will use it to cancel the timer once the welcome screen is close + */ intervalID = 0; - componentDidMount() { - // Don't show editor if welcome screen is open + /** + * Called when the MYR Scene is mounted (component has been rendererd to the DOM) + * + * It check if the user's first time visiting, then it will set up a interval to see if the welcome screen is closed for every 1000ms + * It also add a event listener to + * stop key press of movement (arrow key and space) to scroll the page + * hide or show "interface" (editor) depends on when user enter or exit the VR(fullscreen) mode. + */ + componentDidMount() { if (!this.getCookie("hasVisited")) { this.intervalID = setInterval(this.checkForWelcomeScreen, 1000); } @@ -45,7 +56,10 @@ class View extends Component { } /** - * This fires off an event when the system is fully rendered. + * Called when MYR Scene is rendererd (DOM elements is changed/updated) + * + * If the welcome screen is closed, it fires an event for "myr-view-rendererd" which added in + * change() & push() in Myr.js but these are unused functions that are not documented in reference. */ componentDidUpdate() { if (!this.state.welcomeOpen) { @@ -54,14 +68,24 @@ class View extends Component { // Dispatch/Trigger/Fire the event document.dispatchEvent(event); - } - + } } + /** + * Called when the MYR Scene is unmounting (Being removed from the DOM) + * + * It will check if the timerID for checking welcome screen is set, + * If so it will clear/stop the timer from checking. + */ componentWillUnmount() { if (this.intervalID !== 0) { clearInterval(this.intervalID); } } + /** + * On every interval (1000ms) it check whether the cookie hasVisited is set to true + * If so, set state "welcomeOpen" to false (so it will render the scene) + * and stop the timer. + */ checkForWelcomeScreen = () => { if (this.getCookie("hasVisited")) { this.setState({ welcomeOpen: false }); @@ -70,6 +94,11 @@ class View extends Component { } } + /** + * Get value of cookie + * @param {string} cookieName name of cookie + * @returns {string} value of cookie if it exist, return empty string otherwise + */ getCookie = (cookieName) => { let name = cookieName + "="; let decodedCookie = decodeURIComponent(document.cookie); @@ -87,9 +116,10 @@ class View extends Component { } /** - * This renders json to aframe entities + * A helper function that converts MYR objects into a corresponded A-Frame DOM elements * - * @param {*} ent + * @param {object} ent MYR object + * @returns {HTMLElement} A-Frame entities */ helper = (ent) => { if (ent) { @@ -142,9 +172,13 @@ class View extends Component { return ; } } - //return elements that contains necessary configuration for light indicator based on light's type and properties + /** + * Helper fuctions that returns A-Frame elements that contains necessary configuration for light indicator based on light's type and properties + * + * @param {object} ent Myr object + * @returns A-Frame entities of light indicator + */ lightIndicatorHelper =(ent)=>{ - //this is a position for passing in to indicatorroation to determine the rotation of the light that use position as vector. let position =`position:${ent.position.x || 0} ${ent.position.y || 0} ${ent.position.z || 0};`; if(ent.light.target){ @@ -169,7 +203,13 @@ class View extends Component { default: } } - //return string that contains necessary configuration for shadow based on light's type + + /** + * Helper function that returns configuration for shadow based on light's type + * + * @param {object} light light properties + * @returns {string} string of aframe configuration of shadow that will attach to the light attribute + */ lightShadowHelper = (light) =>{ let newState = ""; //ambient and hemisphere light doesn't cast shadow @@ -188,12 +228,23 @@ class View extends Component { return newState; } + /** + * Help convert asset(model,image,etc) datas to A-Frame entitiy + * + * @param {object} asset + * @returns {HTMLElement} a-asset-item of the object + */ assetsHelper = (asset) => { return ( ); } + /** + * It creates 2 different A-Frame camera. As for now, it will always be basicMoveCam. + * + * @returns {HTMLElement} Camera elements + */ createCam = () => { switch (this.props.sceneConfig.settings.camConfig) { case 0: @@ -205,6 +256,14 @@ class View extends Component { } } + /** + * Check point cam is a mode where there's a checkpoints in the scene where user can select them to teleport to that position + * to move around the scene compare to the regular movement. + * + * Check point is currently not implemented in MYR to be an usable feature. + * + * @returns {HTMLElement} Camera elements contains checkpoint control + */ checkpointCam = () => { return ( @@ -220,6 +279,18 @@ class View extends Component { ); } + + /** + * It returns camera basic with different movement control depends on the browser type + * Mobile: + * default movement controls with flying enabled + * VR: + * default movement controls with flying disabled + * Desktop: + * custom wasd-plus-control with controllable movement speed + * + * @returns {HTMLElement} A-Frame camera elements with basic movement + */ basicMoveCam = () => { switch(browserType()) { case "mobile": @@ -276,6 +347,8 @@ class View extends Component { /** * Produces the grid on the ground and the coordinate lines + * + * @returns {HTMLElements} A-Frame entitiy containing grid, tube for axies and text to label those axes */ coordinateHelper = () => { if (this.props.sceneConfig.settings.showCoordHelper) { @@ -311,6 +384,10 @@ class View extends Component { } } + /** + * Display the floor if the showFloor setting is true + * @returns 80x80 plane with showFloor color or null if the showFloor is false + */ makeFloor = () => { if (this.props.sceneConfig.settings.showFloor) { return ( @@ -330,6 +407,11 @@ class View extends Component { } } + /** + * Main part for Rendering MYR Scene! + * + * @returns {HTMLElement} A-Frame scene containing all the settings and MYR objects + */ render = () => { /* eslint-disable */ return ( From 5ac85eeef8ab880bf2350bc6c972b67818c5a6a3 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 16 Jul 2021 15:15:17 -0400 Subject: [PATCH 22/67] Moved un-referenced/unused function to bottom of code in Myr.js. And removed test suite for addCModel --- src/myr/Myr.js | 130 +++++++++++++++++++++++++++--------------- src/tests/Myr.test.js | 7 --- 2 files changed, 84 insertions(+), 53 deletions(-) diff --git a/src/myr/Myr.js b/src/myr/Myr.js index d9832a26..33ffbdda 100644 --- a/src/myr/Myr.js +++ b/src/myr/Myr.js @@ -731,11 +731,6 @@ class Myr { return color; } - drop = (outerElId) => { - this.getEl(outerElId)["dynamic-body"] = "shape: box; mass: 5"; - return outerElId; - } - /** * Allows the entity to be dropped * @@ -791,23 +786,6 @@ class Myr { return outerElId; } - push = (outerElId, x, y, z) => { - // Add an event listener - document.addEventListener("myr-view-rendered", () => { - let el = document.querySelector("#" + outerElId); - if (!el) { - return; - } - el.addEventListener("body-loaded", () => { - el.body.applyImpulse( - /* impulse */ new CANNON.Vec3(x, y, z), - /* world position */ new CANNON.Vec3().copy(el.object3D.position) - ); - }); - }); - return outerElId; - } - /** * Render an Aframe box with current Myr settings * @@ -1409,30 +1387,6 @@ class Myr { /********************* ANIMATIONS *********************/ - /** - * Animate the Aframe element which is passed as arg - * - * @param {number} outerElId target element ID - * @param {number} magnitude !!!DESCRIPTION NEEDED!!! - * @param {*} loop !!!DESCRIPTION NEEDED!!! - * @param {*} duration !!!DESCRIPTION NEEDED!!! - */ - animate = (outerElId, magnitude = null, loop = null, duration = null) => { - magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.spin; - loop = loop !== null ? loop : this.cursor.loop; - duration = duration !== null ? duration : this.cursor.duration; - let el = this.getEl(outerElId); - let anim = ` - property: rotation; - dir: alternate; - to: ${el.rotation.x} ${el.rotation.y + magnitude} ${el.rotation.z}; - dur: ${duration}; - loop: ${Boolean(loop)}; - `; - el.animation = anim; - return outerElId; - }; - /** * Apply a spin animation to the Aframe element which is passed as arg * @@ -2104,17 +2058,89 @@ class Myr { /* * Functions that are not in reference or used in anywhere */ + /** + * Animate the Aframe element which is passed as arg, its same as spin but without linear easing + * + * @param {number} outerElId target element ID + * @param {number} magnitude Magnitude of the animation + * @param {boolean} loop Whether to loop the animation + * @param {number} duration How long the animation last + */ + animate = (outerElId, magnitude = null, loop = null, duration = null) => { + magnitude = magnitude !== null ? magnitude : this.cursor.magnitude.spin; + loop = loop !== null ? loop : this.cursor.loop; + duration = duration !== null ? duration : this.cursor.duration; + let el = this.getEl(outerElId); + let anim = ` + property: rotation; + dir: alternate; + to: ${el.rotation.x} ${el.rotation.y + magnitude} ${el.rotation.z}; + dur: ${duration}; + loop: ${Boolean(loop)}; + `; + el.animation = anim; + return outerElId; + }; + + /** + * It looks like a promise that sleep for certain ms and user can set further action after the time out. + * I don't know the original purpose but I imagine it was something like this. + * ex. + * sleep(5000).then(()=>{ + * console.log("box!"); + * box(); + * }); + * But this will not render box on the scene because it adds the box to the list after Scene is renderered + * + * @param {number} ms how long to sleep in ms + * @returns + */ sleep = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); } + /** + * Looks like temporary function similar to makePushable that apply force the pass object to x,y,z direction + * Not working. + */ + push = (outerElId, x, y, z) => { + // Add an event listener + document.addEventListener("myr-view-rendered", () => { + let el = document.querySelector("#" + outerElId); + if (!el) { + return; + } + el.addEventListener("body-loaded", () => { + el.body.applyImpulse( + /* impulse */ new CANNON.Vec3(x, y, z), + /* world position */ new CANNON.Vec3().copy(el.object3D.position) + ); + }); + }); + return outerElId; + } + + /** + * Looks like a temporary function that just apply physics with constant mass + * + * @param {string} outerElId + * @returns {string} outerElId + */ + drop = (outerElId) => { + this.getEl(outerElId)["dynamic-body"] = "shape: box; mass: 5"; + return outerElId; + } + /** * Interface for setting an object's parameters in the DOM * the idea is the setup an event listener as an almost DOM ready listener. + * + * Ex. change(box(),"material","color:green;"); * * @param {string} outerElId target element ID * @param {string} type what param to change * @param {*} newParam changes + * @returns {Error} Return error if query fail to retrieve the passed Id */ change = (outerElId, type, newParam) => { document.addEventListener("myr-view-rendered", () => { @@ -2129,6 +2155,15 @@ class Myr { }); } + /** + * Interface for setting an object's parameters in the DOM w/o the event listener dispatching the events + * It's not working/I don't know how this work" + * + * @param {string} outerElId target element ID + * @param {string} type what param to change + * @param {*} newParam changes + * @returns {Error} Return error if query fail to retrieve the passed Id + */ syncChange = (outerElId, type, newParam) => { try { let el = document.querySelector("#" + outerElId); @@ -2142,6 +2177,9 @@ class Myr { } } + /** + * Infinite loop detector that's not use in anywhere + */ infiniteLoopDetector = (function () { let map = {}; diff --git a/src/tests/Myr.test.js b/src/tests/Myr.test.js index 030f075d..30e74d42 100644 --- a/src/tests/Myr.test.js +++ b/src/tests/Myr.test.js @@ -734,13 +734,6 @@ describe("Component Animations", () => { }); describe("Other Myr functionality", () => { - it("should add a model", () => { - myr.reset(); - myr.assets = []; - myr.addCModel(); - expect(myr.assets).toContainEqual({ id: "c-obj", src: "/img/c.obj" }); - }); - it("should drop", () => { myr.reset(); let el = myr.box({ material: "color: blue;", position: { x: 1, y: 1, z: 1 } }); From 21d2f1a8a6b369d3e3b4e67d4fda2634751b948f Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 16 Jul 2021 15:19:11 -0400 Subject: [PATCH 23/67] Added doc for Model and Texture.js --- src/components/structural/Models.js | 3 +++ src/components/structural/Textures.js | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/structural/Models.js b/src/components/structural/Models.js index ec66a713..86b2a0c4 100644 --- a/src/components/structural/Models.js +++ b/src/components/structural/Models.js @@ -1,3 +1,6 @@ +/** + * Map of textures' name and url and img url for retrieval + */ let ModelPack = new Map(); // Models that have been cleared for us to host ModelPack.set("sword", {model: "/models/sword.glb", image: "/img/models/sword.png"}); diff --git a/src/components/structural/Textures.js b/src/components/structural/Textures.js index be39c962..6e43dc44 100644 --- a/src/components/structural/Textures.js +++ b/src/components/structural/Textures.js @@ -1,4 +1,7 @@ -let TexturePack = [ +/** + * List of textures' name and url for retrieval + */ +const TexturePack = [ {title:"bricks",url:"/img/textures/bricks.jpg"}, {title:"bark",url:"/img/textures/bark.jpg"}, {title:"checkerboard",url:"/img/textures/checkerboard.jpg"}, From 4f9d7278d4e650f6e52b3595af10e4ca6f19f453 Mon Sep 17 00:00:00 2001 From: jlu18 Date: Fri, 16 Jul 2021 16:01:10 -0400 Subject: [PATCH 24/67] Added doc for welcome screen and scene.js --- src/components/structural/WelcomeScene.js | 10 ++++ src/components/structural/WelcomeScreen.js | 56 ++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/components/structural/WelcomeScene.js b/src/components/structural/WelcomeScene.js index 5b76ad15..2a8072be 100644 --- a/src/components/structural/WelcomeScene.js +++ b/src/components/structural/WelcomeScene.js @@ -1,7 +1,14 @@ import React, { Component } from "react"; import { browserType } from "../../utils/browserType"; +/** + * Welcome Scene component returns static aframe scene to embed in welcome screen + */ class WelcomeScene extends Component { + /** + * Create basicMoveCam + * Refer to basicMoveCam in View.js for more detail description + */ createCam = () => { switch(browserType()) { case "mobile": @@ -52,6 +59,9 @@ class WelcomeScene extends Component { } } + /** + * @returns aframe scene that same as dropsies scene from example project + */ render() { return ( diff --git a/src/components/structural/WelcomeScreen.js b/src/components/structural/WelcomeScreen.js index f61bab08..1dca3fad 100644 --- a/src/components/structural/WelcomeScreen.js +++ b/src/components/structural/WelcomeScreen.js @@ -15,6 +15,9 @@ import CourseSelect from "../courses/CourseSelect.js"; import { withStyles } from "@material-ui/core/styles"; import "../../css/WelcomeScreen.css"; +/** + * @returns {object} Center the Welcome Screen + */ function getOuterModalStyle() { const top = 50; const left = 50; @@ -65,6 +68,10 @@ const exitBtnStyle = { top: 0, right: 0, }; + +/** + * Welcome Component returns a modal of welcome screen that shows up when user first enter MYR + */ class Welcome extends React.Component { constructor(props) { super(props); @@ -75,12 +82,23 @@ class Welcome extends React.Component { }; } + /** + * Called when the Welcome Screen is mounted (component has been rendererd to the DOM) + * + * Header.js has a state to control whether to show welcome screen or not. By default it's false. + * So if user hasn't visisted the MYR, toggle the state to true. + */ componentDidMount() { if (!this.getCookie("hasVisited")) { this.props.handleWelcomeToggle(); } } + /** + * Get value of cookie + * @param {string} cookieName name of cookie + * @returns {string} value of cookie if it exist, return empty string otherwise + */ getCookie = (cookieName) => { let name = cookieName + "="; let decodedCookie = decodeURIComponent(document.cookie); @@ -97,6 +115,11 @@ class Welcome extends React.Component { return ""; } + /** + * If the user is first visiting the MYR, set "hasVisisted" to true + * and set the expiration date to current date + 24 hrs + * So it will re-appear after 24 hrs + */ setCookie = () => { if (!this.getCookie("hasVisited")) { let date = new Date(); @@ -107,16 +130,26 @@ class Welcome extends React.Component { } } + /** + * Handler for when the welcome screen is close either by close button or clicking outside of modal + */ handleClose = () => { this.setCookie(); this.props.handleWelcomeToggle(); }; + /** + * Handler for when user click "never again" button + * It sets a long expiration date so it will "never" expireds + */ neverAgainCookie = () => { document.cookie = "hasVisited=true; expires=Thu, 31 Dec 2099 12:00:00 UTC;"; this.handleClose(); } + /** + * @returns {*} Button with don't show again option + */ neverAgain = () => { return (