Skip to content

Commit

Permalink
Merge pull request #202 from engaging-computing/dev
Browse files Browse the repository at this point in the history
Added Reference Examples and UI improvements
  • Loading branch information
jasondkiesling authored Jun 9, 2019
2 parents 1eced12 + c1a10a5 commit 6b17412
Show file tree
Hide file tree
Showing 25 changed files with 698 additions and 182 deletions.
3 changes: 2 additions & 1 deletion src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export { default as EditorActions } from './editorActions';
export { default as ProjectActions } from './projectActions';
export { default as SceneActions } from './sceneActions';
export { default as CourseActions } from './courseActions';
export { default as ClassroomActions } from './classroomActions';
export { default as ClassroomActions } from './classroomActions';
export { default as ReferenceExampleActions } from './referenceExampleActions';
47 changes: 47 additions & 0 deletions src/actions/referenceExampleActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { render } from './editorActions';

import * as types from '../constants/ActionTypes';

const refExRef = '/apiv1/referenceExamples/';
const header = { headers: { 'content-type': 'application/json' } };
const problem = {
name: "Error",
type: "Unknown",
info: "An unknown error occured. Please try refreshing the page",
suggestedCourse: null,
code: ""
};

//Lesson Actions
export function fetchReferenceExample(funcName) {
return (dispatch) => {
fetch(refExRef + funcName, header)
.then(response => {
response.json()
.then(json => {
dispatch(loadReferenceExample(json));
dispatch(render(json.code || ""));
})
.catch(err => {
dispatch(loadReferenceExample(problem));
console.error(err);
});
})
.catch(err => {
dispatch(loadReferenceExample(problem));
console.error(err);
});
};
}

export function loadReferenceExample(refEx) {
return {
type: types.LOAD_REF_EX,
payload: refEx
};
}

export default {
loadReferenceExample,
fetchReferenceExample
};
5 changes: 4 additions & 1 deletion src/components/CourseSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
CardContent,
IconButton,
Icon,
Modal
Modal,
Tooltip
} from "@material-ui/core";

import { withStyles } from "@material-ui/core/styles";
Expand Down Expand Up @@ -122,6 +123,7 @@ class CourseSelectModal extends Component {
const courses = [].concat(this.props.courses);
return (
<div>
<Tooltip title = "Courses">
<IconButton
onClick={this.handleOpen}
id="select-course"
Expand All @@ -133,6 +135,7 @@ class CourseSelectModal extends Component {
}}>
<Icon className="material-icons">school</Icon>
</IconButton >
</Tooltip>
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
Expand Down
9 changes: 9 additions & 0 deletions src/components/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@ import 'brace/theme/github';
import 'brace/ext/language_tools';
import customCompleter from './customCompleter.js'

import 'brace/ext/searchbox';

/**
* @summary - Editor is a React Component that creat the Ace Editor in the DOM.
*
*/

class Editor extends Component {
componentWillUnmount() {
//Updates state in reducer before closing editor
const text = window.ace.edit("ace-editor").getSession().getValue();
this.props.refresh(text, this.props.user ? this.props.user.uid : 'anon');
this.props.render(text);
}

componentDidMount() {
try {
Expand Down
39 changes: 33 additions & 6 deletions src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class Header extends Component {
anchorEl: null,
navAwayModal: false,
needsNewId: false, // this explicitly tells us to make a new id
spinnerOpen: false
spinnerOpen: false,
referenceOpen: false
};
}

Expand All @@ -59,6 +60,9 @@ class Header extends Component {
if (this.props.courseName) {
this.props.courseActions.fetchCourse(this.props.courseName);
}
else if (this.props.refExName) {
this.props.referenceExampleActions.fetchReferenceExample(this.props.refExName);
}
else if (this.props.classroom) {
let userClasses = [];
classes.where('classroomID', '==', this.props.classroom).get().then(snap => {
Expand Down Expand Up @@ -305,6 +309,7 @@ class Header extends Component {
handleRender = () => {
try {
let editor = window.ace.edit("ace-editor");
this.props.actions.refresh(editor.getSession().getValue());
this.props.actions.render(editor.getSession().getValue(), this.props.user ? this.props.user.uid : 'anon');
} catch (error) {
this.props.actions.render(this.props.text, this.props.user ? this.props.user.uid : 'anon');
Expand Down Expand Up @@ -343,8 +348,17 @@ class Header extends Component {
* @summary - When the user clicks save it will upload the information to Firebase
*/
handleSave = () => {
let editor = window.ace.edit("ace-editor");
let text = editor.getSession().getValue();
let editor, text;
if(!this.props.viewOnly) {
//If in editor mode, gets text directly from editor
editor = window.ace.edit("ace-editor");
text = editor.getSession().getValue();
this.props.actions.refresh(text, this.props.user ? this.props.user.uid : 'anon');
} else {
//Otherwise, gets text from state (should be up to date since it is refreshed on editor unmount)
text = this.props.text;
}

if (this.props.user && this.props.user.uid && text) {
this.setState({ spinnerOpen: true });
let ts = Date.now();
Expand All @@ -354,6 +368,7 @@ class Header extends Component {
let img = scene.components.screenshot.getCanvas('perspective').toDataURL('image/jpeg', 0.1);
let path = "images/perspective/" + projectId;
let imgRef = storageRef.child(path);

imgRef.putString(img, 'data_url').then((snapshot) => {
// Put the new document into the scenes collection
scenes.doc(projectId).set({
Expand All @@ -367,7 +382,7 @@ class Header extends Component {
// If we have a new projectId reload page with it
if (this.props.courseName) {
this.setState({ spinnerOpen: false });
window.open(window.origin + '/' + projectId);
//window.open(window.origin + '/' + projectId);
} else if (projectId !== this.props.projectId) {
window.location.href = window.origin + '/' + projectId;
} else {
Expand Down Expand Up @@ -454,6 +469,10 @@ class Header extends Component {
this.setState({ classroomOpen: false });
};

handleReferenceToggle = () => {
this.setState({ referenceOpen: !this.state.referenceOpen });
};

loadDrawer = () => {
return (
<Drawer
Expand Down Expand Up @@ -645,6 +664,8 @@ class Header extends Component {
<Tooltip title="Open" placement="bottom-start">
<IconButton
id="open-btn"
referenceOpen={this.state.referenceOpen}
handleReferenceToggle={this.handleReferenceToggle}
onClick={this.handleLoadToggle}
className="header-btn"
style={style.default}>
Expand All @@ -653,11 +674,17 @@ class Header extends Component {
</Tooltip>
<MyrTour
viewOnly={this.props.scene.settings.viewOnly}
changeView={this.props.sceneActions.changeView}/>
changeView={this.props.sceneActions.changeView}
layoutType={this.props.layoutType}
referenceOpen={this.state.referenceOpen}
handleReferenceToggle={this.handleReferenceToggle}/>
</div>
<div className="col-3 d-flex justify-content-end">
{/* <Classroom classrooms={this.props.classrooms} classroomActions={this.props.classroomActions} user={this.props.user} /> */}
<Reference layoutType={this.props.layoutType} />
<Reference
layoutType={this.props.layoutType}
referenceOpen={this.state.referenceOpen}
handleReferenceToggle={this.handleReferenceToggle} />
<SceneConfigMenu
scene={this.props.scene}
sceneActions={this.props.sceneActions}
Expand Down
48 changes: 30 additions & 18 deletions src/components/MyrTour.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component } from 'react';
import Tour from 'reactour';
import { Button } from '@material-ui/core';
import * as layoutTypes from '../constants/LayoutTypes';

class MyrTour extends Component {
constructor(props) {
Expand All @@ -19,26 +20,37 @@ class MyrTour extends Component {
}

render() {
let isDisabled = this.props.layoutType === layoutTypes.REFERENCE;
return (
<React.Fragment>
<Tour
steps={steps}
maskClassName="mask"
isOpen={this.state.isTourOpen}
onAfterOpen={()=>{
this.setState({ viewOnlyOnOpen: this.props.viewOnly });
if(this.props.viewOnly) {
this.props.changeView();
}
}}
onRequestClose={this.closeTour} />
<Button
style={{ color: "#fff", fontSize: "66%" }}
size="small"
className="d-none d-md-block"
onClick={() => this.setState({ isTourOpen: true })}>
Take the Tour
</ Button>
{!isDisabled ?
<React.Fragment>
<Tour
steps={steps}
maskClassName="mask"
isOpen={this.state.isTourOpen}
onAfterOpen={()=>{
this.setState({ viewOnlyOnOpen: this.props.viewOnly });
if(this.props.viewOnly) {
this.props.changeView();
}
}}
onRequestClose={this.closeTour} />
<Button
style={{ color: "#fff", fontSize: "66%" }}
size="small"
className="d-none d-md-block"
onClick={() => {
this.setState({ isTourOpen: true });
if(this.props.referenceOpen) {
this.props.handleReferenceToggle();
}
}}>
Take the Tour
</ Button>
</React.Fragment>
: null
}
</React.Fragment>
);
}
Expand Down
60 changes: 60 additions & 0 deletions src/components/RefExInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { Component } from 'react';
import {
Button,
Icon
} from '@material-ui/core';

class ReferenceExampleBox extends Component {

suggestedCourse = () => {
const { suggestedCourse, suggestedCourseName } = this.props.referenceExample;
return (
this.props.referenceExample && suggestedCourseName ?
<Button
variant="raised"
onClick={() => window.location.href = window.origin + '/course/' + suggestedCourse}
color="primary"
className="ref-ex-btn">
<Icon className="material-icons">school</Icon>
<div id="suggested-course">
Suggested Course: {suggestedCourseName}
</div>
</Button>
: null
);
}

renderParams = (functionParams) => {
let returnString = "(";
for (let i = 0; i < functionParams.length; i++) {
returnString += functionParams[i];
if (i !== functionParams.length - 1) { returnString += ", "; }
}
return returnString += ")";
// return returnString;
}

renderTitle = () => {
const { functionName, functionParams } = this.props.referenceExample;
return (
<h3>{(this.props.referenceExample && functionName) ?
("Function: " + functionName + this.renderParams(functionParams))
: "Loading..."}
</h3>
);
}

render() {
return (
<div id="ref-ex">
<this.renderTitle />
<h6>{(this.props.referenceExample && this.props.referenceExample.type) ? "Type: " + this.props.referenceExample.type : "Loading..."}</h6>
<p>{(this.props.referenceExample && this.props.referenceExample.info) ? this.props.referenceExample.info : "Loading..."} </p>
<this.suggestedCourse />
</div>
);
}
}


export default ReferenceExampleBox;
Loading

0 comments on commit 6b17412

Please sign in to comment.