From 16c4b12cfdc1209f12340f83af6884ba6715e306 Mon Sep 17 00:00:00 2001
From: krashanoff
Date: Wed, 21 Oct 2020 16:33:41 -0700
Subject: [PATCH 1/7] Third time's the charm, baby.
---
.../Sketches/components/ConfirmDeleteModal.js | 8 +++-
.../Sketches/components/CreateSketchModal.js | 32 +++++--------
.../Sketches/components/EditSketchModal.js | 40 ++++++++--------
.../TextEditor/components/TextEditor.js | 13 ++---
src/lib/fetch.js | 48 ++++++++++++-------
5 files changed, 71 insertions(+), 70 deletions(-)
diff --git a/src/components/Sketches/components/ConfirmDeleteModal.js b/src/components/Sketches/components/ConfirmDeleteModal.js
index 29870508..73d05f3f 100644
--- a/src/components/Sketches/components/ConfirmDeleteModal.js
+++ b/src/components/Sketches/components/ConfirmDeleteModal.js
@@ -20,13 +20,17 @@ class ConfirmDeleteModal extends React.Component {
fetch
.deleteSketch(data)
.then((res) => {
- return res.json();
+ return {
+ ok: res.ok,
+ data: res.ok ? res.json() : "",
+ error: !res.ok ? res.text() : "",
+ };
})
.then((json) => {
if (!json.ok) {
this.setState({
spinner: false,
- error: json.error || "Failed to create sketch, please try again later",
+ error: json.error || "Failed to delete sketch, please try again later",
});
return;
}
diff --git a/src/components/Sketches/components/CreateSketchModal.js b/src/components/Sketches/components/CreateSketchModal.js
index defc34c4..9f1cd01a 100644
--- a/src/components/Sketches/components/CreateSketchModal.js
+++ b/src/components/Sketches/components/CreateSketchModal.js
@@ -1,6 +1,6 @@
import React from "react";
import DropdownButton from "./DropdownButton";
-import ImageSelector from "../../common/ImageSelector"
+import ImageSelector from "../../common/ImageSelector";
import {
SketchThumbnailArray,
LanguageDropdownValues,
@@ -46,7 +46,7 @@ class CreateSketchModal extends React.Component {
});
};
- setNext = val => {
+ setNext = (val) => {
this.setState({
next: val,
error: "",
@@ -111,7 +111,7 @@ class CreateSketchModal extends React.Component {
return false;
};
- onFirstSubmit = e => {
+ onFirstSubmit = (e) => {
e.preventDefault();
if (this.badNameInput() || this.badLanguageInput()) {
return;
@@ -119,7 +119,7 @@ class CreateSketchModal extends React.Component {
this.setNext(true);
};
- onSecondSubmit = async e => {
+ onSecondSubmit = async (e) => {
e.preventDefault();
if (this.badThumbnailInput()) return;
@@ -135,23 +135,15 @@ class CreateSketchModal extends React.Component {
try {
fetch
.createSketch(data)
- .then(res => {
- return res.json();
- })
- .then(json => {
- if (!json.ok) {
- this.setState({
- disableSubmit: false,
- error: json.error || "Failed to create sketch, please try again later",
- });
- return;
- }
- this.props.addProgram(json.data.key, json.data.programData || {});
- this.props.setMostRecentProgram(json.data.key);
+ .then((res) => res.json())
+ .then((json) => {
+ const { uid, ...programData } = json;
+ this.props.addProgram(uid, programData || {});
+ this.props.setMostRecentProgram(uid);
this.setState({ redirect: true });
this.closeModal();
})
- .catch(err => {
+ .catch((err) => {
this.setState({
disableSubmit: false,
error: "Failed to create sketch, please try again later",
@@ -245,7 +237,7 @@ class CreateSketchModal extends React.Component {
this.setState({ name: e.target.value })}
+ onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
id="sketch-name"
/>
@@ -259,7 +251,7 @@ class CreateSketchModal extends React.Component {
this.setState({ language: lang })}
+ onSelect={(lang) => this.setState({ language: lang })}
displayValue={this.state.language.display || LanguageDropdownDefault.display}
/>
diff --git a/src/components/Sketches/components/EditSketchModal.js b/src/components/Sketches/components/EditSketchModal.js
index 749aa91e..2777928e 100644
--- a/src/components/Sketches/components/EditSketchModal.js
+++ b/src/components/Sketches/components/EditSketchModal.js
@@ -80,7 +80,7 @@ class EditSketchModal extends React.Component {
return false;
};
- handleSubmitEdit = async e => {
+ handleSubmitEdit = async (e) => {
e.preventDefault();
if (this.badNameInput() || this.badLanguageInput()) {
@@ -109,29 +109,27 @@ class EditSketchModal extends React.Component {
try {
fetch
.updatePrograms(this.props.uid, updateData)
- .then(res => {
- return res.json();
- })
- .then(json => {
- if (!json.ok) {
+ .then((res) => {
+ if (res.ok) {
+ if (this.state.newLanguage !== -1) {
+ this.props.setProgramLanguage(this.props.sketchKey, this.state.newLanguage.value);
+ }
+ if (this.state.newName !== -1) {
+ this.props.setProgramName(this.props.sketchKey, this.state.newName);
+ }
+ if (this.state.newThumbnail !== -1) {
+ this.props.setProgramThumbnail(this.props.sketchKey, this.state.newThumbnail);
+ }
+ this.closeModal();
+ } else {
this.setState({
disableSubmit: false,
- error: json.error || "Failed to edit sketch, please try again later",
+ error: res.text() || "Failed to edit sketch, please try again later",
});
return;
}
- if (this.state.newLanguage !== -1) {
- this.props.setProgramLanguage(this.props.sketchKey, this.state.newLanguage.value);
- }
- if (this.state.newName !== -1) {
- this.props.setProgramName(this.props.sketchKey, this.state.newName);
- }
- if (this.state.newThumbnail !== -1) {
- this.props.setProgramThumbnail(this.props.sketchKey, this.state.newThumbnail);
- }
- this.closeModal();
})
- .catch(err => {
+ .catch((err) => {
this.setState({
disableSubmit: false,
error: "Failed to edit sketch, please try again later",
@@ -176,7 +174,7 @@ class EditSketchModal extends React.Component {
this.setState({ newName: e.target.value })}
+ onChange={(e) => this.setState({ newName: e.target.value })}
value={this.state.newName !== -1 ? this.state.newName : this.props.sketchName}
id="sketch-name"
/>
@@ -190,7 +188,7 @@ class EditSketchModal extends React.Component {
this.setState({ newLanguage: lang })}
+ onSelect={(lang) => this.setState({ newLanguage: lang })}
displayValue={
this.state.newLanguage !== -1
? this.state.newLanguage.display
@@ -289,7 +287,7 @@ class EditSketchModal extends React.Component {
/>
);
return (
- {
- return res.json();
- })
+ .then((res) => res.json())
.then((json) => {
- if (!json.ok) {
- this.setState({
- error: json.error || "Failed to create sketch, please try again later",
- });
- return;
- }
+ const { uid, ...programData } = json;
this.setState({ forking: false, forked: true });
- this.props.addProgram(json.data.key, json.data.programData || {});
+ this.props.addProgram(uid, programData || {});
})
.catch((err) => {
this.setState({
diff --git a/src/lib/fetch.js b/src/lib/fetch.js
index 3d9b3e62..11c8fe9d 100644
--- a/src/lib/fetch.js
+++ b/src/lib/fetch.js
@@ -16,7 +16,7 @@ import constants from "../constants";
*/
export const getUserData = async (uid = "", includePrograms = false) => {
const getUserDataEndpoint = (uid = "", includePrograms = false) =>
- `${constants.SERVER_URL}/getUserData/${uid}${includePrograms ? "?programs=true" : ""}`;
+ `${constants.SERVER_URL}/user/get?uid=${uid}${includePrograms ? "&programs=true" : ""}`;
const options = {
method: "get",
@@ -24,12 +24,18 @@ export const getUserData = async (uid = "", includePrograms = false) => {
};
try {
- let result = await fetch(getUserDataEndpoint(uid, includePrograms), options);
- let { ok, data, error } = await result.json();
-
+ const result = await fetch(getUserDataEndpoint(uid, includePrograms), options);
+ let ok = await result.ok;
+ if (!ok) {
+ await createUser(uid);
+ return getUserData(uid, includePrograms);
+ }
+ let data = ok ? await result.json() : {};
+ let error = !ok ? await result.text() : "";
return { ok, data, error };
} catch (err) {
- return { ok: "false", error: "SERVER ERROR: Unable to get user data from server", err: err };
+ await createUser(uid);
+ return getUserData(uid, includePrograms);
}
};
@@ -48,7 +54,7 @@ const makeServerRequest = (data, endpoint, method = "post") => {
},
};
- if (method === "post" || method === "put") {
+ if (method !== "get") {
let body = "";
// if the passed-in data object has at least 1 key, set the body to the stringified data object
try {
@@ -72,8 +78,13 @@ const makeServerRequest = (data, endpoint, method = "post") => {
*/
export const updatePrograms = (uid = "", programs) => {
- const endpoint = `updatePrograms/${uid}`;
- return makeServerRequest(programs, endpoint, "put");
+ const endpoint = `program/update`;
+ return makeServerRequest({ uid, programs }, endpoint, "put");
+};
+
+export const createUser = (uid) => {
+ console.log("creating user");
+ return makeServerRequest({ uid }, "user/create", "post");
};
/**
@@ -83,8 +94,8 @@ export const updatePrograms = (uid = "", programs) => {
*/
export const updateUserData = (uid = "", userData) => {
- const endpoint = `updateUserData/${uid}`;
- return makeServerRequest(userData, endpoint);
+ const endpoint = `user/update`;
+ return makeServerRequest({ uid, ...userData }, endpoint, "put");
};
/**
@@ -92,8 +103,9 @@ export const updateUserData = (uid = "", userData) => {
* @param {Object} data required data to create program - might eventually become enumerated
*/
-export const createSketch = data => {
- return makeServerRequest(data, "createProgram");
+export const createSketch = (data) => {
+ const { uid, ...rest } = data;
+ return makeServerRequest({ uid, program: rest }, "program/create");
};
/**
@@ -101,8 +113,9 @@ export const createSketch = data => {
* @param {Object} data required data to delete program (uid, docID, name)
*/
-export const deleteSketch = data => {
- return makeServerRequest(data, "deleteProgram");
+export const deleteSketch = (data) => {
+ const { uid, name } = data;
+ return makeServerRequest({ uid, pid: name }, "program/delete", "delete");
};
/**
@@ -110,9 +123,10 @@ export const deleteSketch = data => {
* @param {string} docID the key for the requested program in the top-level programs object
*/
-export const getSketch = async docID => {
- const endpoint = `getProgram/${docID}`;
+export const getSketch = async (docID) => {
+ const endpoint = `program/get?pid=${docID}`;
let result = await makeServerRequest({}, endpoint, "get");
- let { ok, sketch } = await result.json();
+ let ok = await result.ok;
+ let sketch = await result.json();
return { ok, sketch };
};
From 9ed19122e2b9d433a193dce9d2809f21710cb3c5 Mon Sep 17 00:00:00 2001
From: krashanoff
Date: Wed, 21 Oct 2020 16:53:10 -0700
Subject: [PATCH 2/7] New URL, fix response handling by deleteProgram.
---
.../Sketches/components/ConfirmDeleteModal.js | 11 ++---------
src/constants/index.js | 4 ++--
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/src/components/Sketches/components/ConfirmDeleteModal.js b/src/components/Sketches/components/ConfirmDeleteModal.js
index 73d05f3f..66997de8 100644
--- a/src/components/Sketches/components/ConfirmDeleteModal.js
+++ b/src/components/Sketches/components/ConfirmDeleteModal.js
@@ -20,17 +20,10 @@ class ConfirmDeleteModal extends React.Component {
fetch
.deleteSketch(data)
.then((res) => {
- return {
- ok: res.ok,
- data: res.ok ? res.json() : "",
- error: !res.ok ? res.text() : "",
- };
- })
- .then((json) => {
- if (!json.ok) {
+ if (!res.ok) {
this.setState({
spinner: false,
- error: json.error || "Failed to delete sketch, please try again later",
+ error: res.text() || "Failed to delete sketch, please try again later",
});
return;
}
diff --git a/src/constants/index.js b/src/constants/index.js
index 24de4654..a712807e 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -51,10 +51,10 @@ const ROUTER_BASE_NAME = "/";
var SERVER_URL = "http://localhost:8081";
if (process && process.env) {
if (process.env.REACT_APP_SERVER_TYPE === "staging") {
- SERVER_URL = "https://teach-la-staging-backend.herokuapp.com";
+ SERVER_URL = "https://tla-backend-staging.herokuapp.com";
}
if (process.env.REACT_APP_SERVER_TYPE === "prod") {
- SERVER_URL = "https://teach-la-backend.herokuapp.com";
+ SERVER_URL = "https://tla-backend-prod.herokuapp.com";
}
}
From 6bd7d78afd4fdff5ce9312b773699dd90874f046 Mon Sep 17 00:00:00 2001
From: Timothy Poon
Date: Thu, 29 Oct 2020 16:42:05 -0700
Subject: [PATCH 3/7] Add react to supported languages
---
src/components/Output/Output.js | 14 +++--
src/components/Output/Processing.js | 43 ++------------
src/components/Output/React.js | 57 +++++++++++++++++++
src/components/Output/constants/index.js | 36 ++++++++++++
src/components/Sketches/constants/index.js | 11 ++--
src/components/Sketches/index.js | 14 +++--
.../TextEditor/components/TextEditor.js | 1 +
src/components/common/DropdownButton.js | 28 +++++----
src/constants/index.js | 6 +-
src/util/languages/CodeDownloader.js | 22 ++++---
10 files changed, 160 insertions(+), 72 deletions(-)
create mode 100644 src/components/Output/React.js
create mode 100644 src/components/Output/constants/index.js
diff --git a/src/components/Output/Output.js b/src/components/Output/Output.js
index acc3913e..063461b7 100644
--- a/src/components/Output/Output.js
+++ b/src/components/Output/Output.js
@@ -1,9 +1,10 @@
import React from "react";
-import { PYTHON, HTML, PROCESSING } from "../../constants";
+import { PYTHON, HTML, PROCESSING, REACT } from "../../constants";
import { OUTPUT_ONLY } from "../../constants";
import EditorRadio from "../TextEditor/components/EditorRadio.js";
import CreateProcessingDoc from "../Output/Processing";
import CreatePythonDoc from "../Output/Python";
+import CreateReactDoc from "../Output/React";
import { Button } from "reactstrap";
import ViewportAwareButton from "../common/ViewportAwareButton.js";
import OpenPanelButtonContainer from "../common/containers/OpenPanelButtonContainer.js";
@@ -56,7 +57,7 @@ class Output extends React.Component {
renderOpenPanelButton = () => this.props.viewMode === OUTPUT_ONLY && ;
- renderIframe = getSrcDoc => {
+ renderIframe = (getSrcDoc) => {
//check if getsrcdoc is a function
if (!getSrcDoc && {}.toString.call(getSrcDoc) === "[object Function]") {
console.log("Null src doc function found");
@@ -72,7 +73,7 @@ class Output extends React.Component {
srcDoc={getSrcDoc()}
src=""
title="output-iframe"
- onLoad={e => {
+ onLoad={(e) => {
// console.log(e);
}}
/>
@@ -99,6 +100,9 @@ class Output extends React.Component {
case PROCESSING:
srcDocFunc = () => CreateProcessingDoc(runResult, showConsole);
break;
+ case REACT:
+ srcDocFunc = () => CreateReactDoc(runResult, showConsole);
+ break;
case PYTHON:
runResult = btoa(runResult);
srcDocFunc = () => CreatePythonDoc(runResult, showConsole);
@@ -123,7 +127,7 @@ class Output extends React.Component {
);
toggleConsole = () => {
- this.setState(prevState => {
+ this.setState((prevState) => {
return { showConsole: !prevState.showConsole };
});
};
@@ -159,7 +163,7 @@ class Output extends React.Component {
);
runCode = () => {
- this.setState(prevState => ({
+ this.setState((prevState) => ({
run: prevState.run + 1,
}));
};
diff --git a/src/components/Output/Processing.js b/src/components/Output/Processing.js
index 90857b4d..bef42238 100644
--- a/src/components/Output/Processing.js
+++ b/src/components/Output/Processing.js
@@ -1,41 +1,6 @@
-const getProcessingSrcDocLoggingScript = () => `
-
- `;
-
-const getUserScript = code => `
+const getUserScript = (code) => `
@@ -48,7 +13,7 @@ const getProcessingSrcDocBody = (code, showConsole) => `
? ``
: ``
}
- ${getProcessingSrcDocLoggingScript()}
+ ${getJsSrcDocLoggingScript()}
${getUserScript(code)}
+ ${
+ showConsole
+ ? ``
+ : ``
+ }
+ ${getJsSrcDocLoggingScript()}
+ ${getUserScript(code)}
+
+
`;
@@ -81,6 +46,6 @@ const getProcessingSrcDocHead = () => `
`;
-export default function(code, showConsole) {
+export default function (code, showConsole) {
return ` ${getProcessingSrcDocHead()} ${getProcessingSrcDocBody(code, showConsole)}`;
}
diff --git a/src/components/Output/React.js b/src/components/Output/React.js
new file mode 100644
index 00000000..f1f233e1
--- /dev/null
+++ b/src/components/Output/React.js
@@ -0,0 +1,57 @@
+import { getJsSrcDocLoggingScript } from "./constants";
+
+const getReactSrcDocHead = () => `
+
+
+
+
+
+
+
+
+ `;
+
+const getUserScript = (code) => `
+
+`;
+
+const getReactSrcDocBody = (code, showConsole) => `
+
+ `;
+
+export default function (code, showConsole) {
+ return ` ${getReactSrcDocHead()} ${getReactSrcDocBody(code, showConsole)}`;
+}
diff --git a/src/components/Output/constants/index.js b/src/components/Output/constants/index.js
new file mode 100644
index 00000000..59342ec7
--- /dev/null
+++ b/src/components/Output/constants/index.js
@@ -0,0 +1,36 @@
+export const getJsSrcDocLoggingScript = () => `
+
+`;
diff --git a/src/components/Sketches/constants/index.js b/src/components/Sketches/constants/index.js
index daa261b8..fa5ef576 100644
--- a/src/components/Sketches/constants/index.js
+++ b/src/components/Sketches/constants/index.js
@@ -1,3 +1,5 @@
+const { PYTHON, HTML, PROCESSING, REACT } = require("../../../constants");
+
const SketchThumbnailArray = [
"Ant",
"Badger",
@@ -60,12 +62,13 @@ const SketchThumbnailArray = [
];
const LanguageDropdownValues = [
- { display: "Python", value: "python" },
- { display: "Processing", value: "processing" },
- { display: "HTML", value: "html" },
+ { display: "Python", value: PYTHON },
+ { display: "Processing", value: PROCESSING },
+ { display: "React", value: REACT },
+ { display: "HTML", value: HTML },
];
-const LanguageDropdownDefault = { display: "Python", value: "python" };
+const LanguageDropdownDefault = { display: "Python", value: PYTHON };
module.exports = {
SketchThumbnailArray,
diff --git a/src/components/Sketches/index.js b/src/components/Sketches/index.js
index 7715fa02..f1d23336 100644
--- a/src/components/Sketches/index.js
+++ b/src/components/Sketches/index.js
@@ -5,6 +5,7 @@ import CreateSketchModalContainer from "./containers/CreateSketchModalContainer"
import EditSketchModalContainer from "./containers/EditSketchModalContainer";
import OpenPanelButtonContainer from "../common/containers/OpenPanelButtonContainer";
import { SketchThumbnailArray } from "./constants";
+import { PYTHON, PROCESSING, REACT, HTML } from "../../constants";
import CodeDownloader from "../../util/languages/CodeDownloader";
import "styles/Sketches.scss";
@@ -13,8 +14,7 @@ import { Button } from "reactstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCogs } from "@fortawesome/free-solid-svg-icons";
import { faFile } from "@fortawesome/free-solid-svg-icons";
-import { faPython } from "@fortawesome/free-brands-svg-icons";
-import { faHtml5 } from "@fortawesome/free-brands-svg-icons";
+import { faPython, faHtml5, faReact } from "@fortawesome/free-brands-svg-icons";
const ROW_PADDING = 100;
const SKETCH_WIDTH = 220;
@@ -109,15 +109,19 @@ class Sketches extends React.Component {
let faLanguage;
let languageDisplay; // not a great way to do this!
switch (language) {
- case "python":
+ case PYTHON:
faLanguage = faPython;
languageDisplay = "Python";
break;
- case "processing":
+ case PROCESSING:
faLanguage = faCogs;
languageDisplay = "Processing";
break;
- case "html":
+ case REACT:
+ faLanguage = faReact;
+ languageDisplay = "React";
+ break;
+ case HTML:
default:
faLanguage = faHtml5;
languageDisplay = "HTML";
diff --git a/src/components/TextEditor/components/TextEditor.js b/src/components/TextEditor/components/TextEditor.js
index 60662cc5..35c06a64 100644
--- a/src/components/TextEditor/components/TextEditor.js
+++ b/src/components/TextEditor/components/TextEditor.js
@@ -24,6 +24,7 @@ if (typeof window !== "undefined" && typeof window.navigator !== "undefined") {
require("codemirror/mode/javascript/javascript.js");
require("codemirror/mode/htmlmixed/htmlmixed.js");
require("codemirror/mode/python/python.js");
+ require("codemirror/mode/jsx/jsx.js");
require("codemirror/mode/clike/clike.js");
}
/**----------Props--------
diff --git a/src/components/common/DropdownButton.js b/src/components/common/DropdownButton.js
index f640e4fd..537b6a0a 100644
--- a/src/components/common/DropdownButton.js
+++ b/src/components/common/DropdownButton.js
@@ -1,8 +1,8 @@
import React from "react";
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from "reactstrap";
import { faCogs } from "@fortawesome/free-solid-svg-icons";
-import { faPython } from "@fortawesome/free-brands-svg-icons";
-import { faHtml5 } from "@fortawesome/free-brands-svg-icons";
+import { faPython, faHtml5, faReact } from "@fortawesome/free-brands-svg-icons";
+import { PYTHON, PROCESSING, REACT, HTML } from "../../constants";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
/**--------Props---------------
@@ -25,11 +25,11 @@ export default class DropdownButton extends React.Component {
//==============React Lifecycle Functions===================//
componentDidMount() {}
- toggleHandler = prevVal => {
+ toggleHandler = (prevVal) => {
this.setState({ dropdownOpen: !prevVal });
};
- selectLanguage = program => {
+ selectLanguage = (program) => {
let result = true;
if (this.props.dirty) {
result = window.confirm("Are you sure you want to change programs? You have unsaved changes");
@@ -42,16 +42,19 @@ export default class DropdownButton extends React.Component {
renderDropdownItems = () => {
//map each program string in the array to a dropdown item
- return this.props.dropdownItems.map(program => {
+ return this.props.dropdownItems.map((program) => {
let faLanguage;
switch (program.language) {
- case "python":
+ case PYTHON:
faLanguage = faPython;
break;
- case "processing":
+ case PROCESSING:
faLanguage = faCogs;
break;
- case "html":
+ case REACT:
+ faLanguage = faReact;
+ break;
+ case HTML:
default:
faLanguage = faHtml5;
}
@@ -72,13 +75,16 @@ export default class DropdownButton extends React.Component {
let faLanguage;
switch (this.props.currentLanguage) {
- case "python":
+ case PYTHON:
faLanguage = faPython;
break;
- case "processing":
+ case PROCESSING:
faLanguage = faCogs;
break;
- case "html":
+ case REACT:
+ faLanguage = faReact;
+ break;
+ case HTML:
default:
faLanguage = faHtml5;
}
diff --git a/src/constants/index.js b/src/constants/index.js
index a712807e..58ffeaf9 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -4,8 +4,9 @@ const PYTHON = "python";
const JAVASCRIPT = "javascript";
const HTML = "html";
const PROCESSING = "processing";
+const REACT = "react";
-const SUPPORTED_LANGUAGES = [PYTHON, JAVASCRIPT, HTML, PROCESSING];
+const SUPPORTED_LANGUAGES = [PYTHON, JAVASCRIPT, HTML, PROCESSING, REACT];
//used for syntax highlighting in editor
let CODEMIRROR_CONVERSIONS = {};
@@ -21,6 +22,8 @@ SUPPORTED_LANGUAGES.forEach((lang) => {
return (CODEMIRROR_CONVERSIONS[lang] = "htmlmixed");
case PROCESSING:
return (CODEMIRROR_CONVERSIONS[lang] = "javascript");
+ case REACT:
+ return (CODEMIRROR_CONVERSIONS[lang] = "jsx");
default:
console.error("SUPPORTED LANGUAGE WITH NO MODE");
}
@@ -76,6 +79,7 @@ module.exports = {
JAVASCRIPT,
HTML,
PROCESSING,
+ REACT,
// photo names
PHOTO_NAMES,
diff --git a/src/util/languages/CodeDownloader.js b/src/util/languages/CodeDownloader.js
index 75afe25e..027df363 100644
--- a/src/util/languages/CodeDownloader.js
+++ b/src/util/languages/CodeDownloader.js
@@ -1,14 +1,17 @@
import ProcessingConstructor from "../../components/Output/Processing";
+import ReactConstructor from "../../components/Output/React";
+import { PYTHON, REACT, HTML, PROCESSING } from "../../constants";
export default class CodeDownloader {
static download = (name, language, code) => {
let extension = ".";
switch (language) {
- case "python":
+ case PYTHON:
extension += "py";
break;
- case "processing": // this is because we construct the processing result as an HTML file. jank.
- case "html":
+ case PROCESSING: // this is because we construct the processing result as an HTML file. jank.
+ case REACT: // same here
+ case HTML:
extension += "html";
break;
default:
@@ -17,10 +20,15 @@ export default class CodeDownloader {
// taken from this: https://stackoverflow.com/questions/44656610/download-a-string-as-txt-file-in-react
const element = document.createElement("a");
let file;
- if (language === "processing") {
- file = new Blob([ProcessingConstructor(code, true)], { type: "text/plain" });
- } else {
- file = new Blob([code], { type: "text/plain" });
+ switch (language) {
+ case PROCESSING:
+ file = new Blob([ProcessingConstructor(code, true)], { type: "text/plain" });
+ break;
+ case REACT:
+ file = new Blob([ReactConstructor(code, true)], { type: "text/plain" });
+ break;
+ default:
+ file = new Blob([code], { type: "text/plain" });
}
element.href = URL.createObjectURL(file);
element.download = name + extension;
From 3d48d4251ae520979068feef9f9185c2bc14fb34 Mon Sep 17 00:00:00 2001
From: Timothy Poon
Date: Thu, 29 Oct 2020 17:33:21 -0700
Subject: [PATCH 4/7] undo unintentional code style changes
---
src/components/Output/Output.js | 8 ++++----
src/components/Output/Processing.js | 2 +-
src/components/Output/React.js | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/components/Output/Output.js b/src/components/Output/Output.js
index 063461b7..402f7a35 100644
--- a/src/components/Output/Output.js
+++ b/src/components/Output/Output.js
@@ -57,7 +57,7 @@ class Output extends React.Component {
renderOpenPanelButton = () => this.props.viewMode === OUTPUT_ONLY && ;
- renderIframe = (getSrcDoc) => {
+ renderIframe = getSrcDoc => {
//check if getsrcdoc is a function
if (!getSrcDoc && {}.toString.call(getSrcDoc) === "[object Function]") {
console.log("Null src doc function found");
@@ -73,7 +73,7 @@ class Output extends React.Component {
srcDoc={getSrcDoc()}
src=""
title="output-iframe"
- onLoad={(e) => {
+ onLoad={e => {
// console.log(e);
}}
/>
@@ -127,7 +127,7 @@ class Output extends React.Component {
);
toggleConsole = () => {
- this.setState((prevState) => {
+ this.setState(prevState => {
return { showConsole: !prevState.showConsole };
});
};
@@ -163,7 +163,7 @@ class Output extends React.Component {
);
runCode = () => {
- this.setState((prevState) => ({
+ this.setState(prevState => ({
run: prevState.run + 1,
}));
};
diff --git a/src/components/Output/Processing.js b/src/components/Output/Processing.js
index bef42238..3d8628da 100644
--- a/src/components/Output/Processing.js
+++ b/src/components/Output/Processing.js
@@ -1,6 +1,6 @@
import { getJsSrcDocLoggingScript } from "./constants";
-const getUserScript = (code) => `
+const getUserScript = code => `
diff --git a/src/components/Output/React.js b/src/components/Output/React.js
index f1f233e1..6c73f66e 100644
--- a/src/components/Output/React.js
+++ b/src/components/Output/React.js
@@ -29,7 +29,7 @@ const getReactSrcDocHead = () => `
`;
-const getUserScript = (code) => `
+const getUserScript = code => `