Skip to content
This repository was archived by the owner on Jul 31, 2020. It is now read-only.

Commit 941aa69

Browse files
committed
repl + description(side-content)
repl is transferred from cadet-frontend, but still need to sort out the props needed
1 parent ca63408 commit 941aa69

16 files changed

+533
-47
lines changed

output.txt

Whitespace-only changes.

package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"@testing-library/react": "^9.3.2",
1111
"@testing-library/user-event": "^7.1.2",
1212
"@types/jest": "^24.0.0",
13+
"@types/lz-string": "^1.3.33",
1314
"@types/node": "^12.0.0",
1415
"@types/react": "^16.9.23",
1516
"@types/react-dom": "^16.9.5",

src/NavBar/NavBar.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { useContext } from "react";
33
import IconButton from "@material-ui/core/IconButton";
44
import ClearIcon from "@material-ui/icons/Clear";
55
import DehazeIcon from "@material-ui/icons/Dehaze";
6-
import DirectionsRunIcon from "@material-ui/icons/DirectionsRun";
6+
import PlayArrowIcon from "@material-ui/icons/PlayArrow";
77
import { SideBarContext, IAction } from "./SideBarContext";
88
import SourceDropDown from "./SourceDropDown";
99
import "./NavBar.css";
@@ -103,7 +103,7 @@ const NavBar: React.FC = () => {
103103
<div className="spacer2"></div>
104104
<div className="playButton">
105105
<IconButton>
106-
<DirectionsRunIcon
106+
<PlayArrowIcon
107107
style={{
108108
color: "white",
109109
height: "45px"

src/Store.tsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,28 @@ import { createContext } from "react";
44
const defaultSource: string = "Source";
55
const defaultLanguage: string = "Language";
66
const defaultLibaray: string = "Library";
7+
const defaultValue: string = "// Type your program in here\n\n";
78

8-
interface IGlobalState {
9+
export interface IGlobalState {
910
source: string | undefined;
1011
library: string | undefined;
1112
language: string | undefined;
13+
playgroundEditorValue: string | undefined;
1214
}
1315

1416
export interface IGlobalAction {
1517
type: String;
1618
source?: string;
1719
library?: string;
1820
language?: string;
21+
playgroundEditorValue?: string;
1922
}
2023

2124
const initialState: IGlobalState = {
2225
source: defaultSource,
2326
library: defaultLibaray,
24-
language: defaultLanguage
27+
language: defaultLanguage,
28+
playgroundEditorValue: defaultValue
2529
};
2630

2731
export const Store = createContext<IGlobalState | any>(initialState);
@@ -37,7 +41,6 @@ function reducer(
3741
source: action.source
3842
};
3943
case "CHANGE_LIBRARY":
40-
console.log(action.library);
4144
return {
4245
...globalState,
4346
library: action.library
@@ -47,6 +50,12 @@ function reducer(
4750
...globalState,
4851
language: action.language
4952
};
53+
case "UPDATE_EDITOR_VALUE":
54+
console.log(globalState.playgroundEditorValue);
55+
return {
56+
...globalState,
57+
playgroundEditorValue: action.playgroundEditorValue
58+
};
5059
default:
5160
throw new Error();
5261
}

src/Workspace/CanvasOutput.tsx

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as React from "react";
2+
3+
interface IProps {
4+
canvas: HTMLCanvasElement;
5+
}
6+
/**
7+
* Takes the output of the rendered graphics (in a hidden canvas tag under <body>)
8+
* and makes it into a new <canvas> output for viewing.
9+
*/
10+
class CanvasOutput extends React.Component<IProps, {}> {
11+
private $parent: HTMLElement | null;
12+
13+
constructor(props: IProps) {
14+
super(props);
15+
//not sure
16+
this.$parent = props.canvas;
17+
}
18+
19+
public componentDidMount() {
20+
this.$parent!.appendChild(this.props.canvas);
21+
this.props.canvas.hidden = false;
22+
}
23+
24+
public render() {
25+
return <div ref={r => (this.$parent = r)} className="canvas-container" />;
26+
}
27+
}
28+
29+
export default CanvasOutput;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import * as React from "react";
2+
import AutorenewIcon from "@material-ui/icons/Autorenew";
3+
4+
import { LINKS } from "../../utils/constants";
5+
6+
interface IEnvVisualizerState {
7+
loading: boolean;
8+
}
9+
10+
class EnvVisualizer extends React.Component<{}, IEnvVisualizerState> {
11+
private $parent: HTMLElement | null;
12+
13+
constructor(props: any) {
14+
super(props);
15+
this.state = { loading: true };
16+
this.$parent = null;
17+
}
18+
19+
public componentDidMount() {
20+
this.tryToLoad();
21+
}
22+
23+
public render() {
24+
return (
25+
<div ref={r => (this.$parent = r)}>
26+
<p>
27+
The environmental visualizer generates the environmental model diagram
28+
based on breakpoints set in the editor.
29+
<br />
30+
<br />
31+
It is activated by clicking on the gutter of the editor (where all the
32+
line numbers are, on the left) to set a breakpoint, and then running
33+
the program.
34+
<br />
35+
<br />
36+
The environment model diagram follows a notation introduced in{" "}
37+
<a href={LINKS.SOURCE_DOCS_CHAPTER_3_2} target="_blank">
38+
<i>
39+
Structure and Interpretation of Computer Programs, JavaScript
40+
Adaptation, Chapter 3, Section 2
41+
</i>
42+
</a>
43+
.
44+
</p>
45+
{this.state.loading && <AutorenewIcon />}
46+
</div>
47+
);
48+
}
49+
50+
private tryToLoad = () => {
51+
const element = (window as any).EnvVisualizer;
52+
if (this.$parent && element) {
53+
// Env Visualizer has been loaded into the DOM
54+
element.init(this.$parent);
55+
this.setState((state, props) => {
56+
return { loading: false };
57+
});
58+
} else {
59+
// Try again in 1 second
60+
window.setTimeout(this.tryToLoad, 1000);
61+
}
62+
};
63+
}
64+
65+
export default EnvVisualizer;
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import AutorenewIcon from "@material-ui/icons/Autorenew";
2+
import * as React from "react";
3+
// import { createContext } from '../../../utils/slangHelper';
4+
5+
interface IInspectorState {
6+
loading: boolean;
7+
}
8+
9+
class Inspector extends React.Component<{}, IInspectorState> {
10+
private $parent: HTMLElement | null;
11+
12+
constructor(props: any) {
13+
super(props);
14+
this.state = { loading: true };
15+
this.$parent = null;
16+
}
17+
18+
public componentDidMount() {
19+
this.tryToLoad();
20+
}
21+
22+
public render() {
23+
return (
24+
<div ref={r => (this.$parent = r)} className="sa-inspector">
25+
<p>
26+
The inspector generates a list of variable bindings based on
27+
breakpoints set in the editor.
28+
<br />
29+
<br />
30+
It is activated by clicking on the gutter of the editor (where all the
31+
line numbers are, on the left) to set a breakpoint, and then running
32+
the program. Only the first line of a statement can have a breakpoint.
33+
The program halts just before the statement is evaluated.
34+
</p>
35+
{this.state.loading && <AutorenewIcon />}
36+
</div>
37+
);
38+
}
39+
40+
private tryToLoad = () => {
41+
const element = (window as any).Inspector;
42+
if (this.$parent && element) {
43+
// Inspector has been loaded into the DOM
44+
element.init(this.$parent);
45+
this.setState((state, props) => {
46+
return { loading: false };
47+
});
48+
} else {
49+
// Try again in 1 second
50+
window.setTimeout(this.tryToLoad, 1000);
51+
}
52+
};
53+
}
54+
55+
export default Inspector;

src/Workspace/Description/TabContent.tsx

-10
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,8 @@ import { makeStyles, Theme } from "@material-ui/core/styles";
33
import AppBar from "@material-ui/core/AppBar";
44
import Tabs from "@material-ui/core/Tabs";
55
import Tab from "@material-ui/core/Tab";
6-
import PhoneIcon from "@material-ui/icons/Phone";
7-
import FavoriteIcon from "@material-ui/icons/Favorite";
8-
import PersonPinIcon from "@material-ui/icons/PersonPin";
9-
import HelpIcon from "@material-ui/icons/Help";
10-
import ShoppingBasket from "@material-ui/icons/ShoppingBasket";
11-
import ThumbDown from "@material-ui/icons/ThumbDown";
12-
import ThumbUp from "@material-ui/icons/ThumbUp";
136
import Typography from "@material-ui/core/Typography";
147
import Box from "@material-ui/core/Box";
15-
import { LINKS } from "./../../utils/constants";
16-
import Markdown from "./../../utils/Markdown";
17-
import IntroductionTab from "./IntroductionTab";
188

199
interface TabPanelProps {
2010
children?: React.ReactNode;

src/Workspace/Description/index.tsx

+21-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import SettingsEthernetIcon from "@material-ui/icons/SettingsEthernet";
1010
import ListVisualizer from "./ListVisualizer";
1111
import VisibilityIcon from "@material-ui/icons/Visibility";
1212
import SubstVisualizer from "./SubstVisualizer";
13+
import SearchIcon from "@material-ui/icons/Search";
14+
import PublicIcon from "@material-ui/icons/Public";
15+
import EnvVisualizer from "./EnvVisualizer";
16+
import Inspector from "./Inspector";
1317

1418
const useStyles = makeStyles({
1519
root: {
@@ -33,10 +37,20 @@ export default function Description() {
3337
const { globalState, dispatch } = useContext(Store);
3438
let tabButtonArr: JSX.Element[];
3539
let tabContentArr: JSX.Element[];
36-
if (globalState.source == "Source1") {
37-
tabButtonArr = [<ImportContactsIcon />, <SettingsEthernetIcon />];
38-
tabContentArr = [<IntroductionTab />, <ListVisualizer />];
39-
} else {
40+
if (globalState.source == "Source3" || globalState.source == "Source4") {
41+
tabButtonArr = [
42+
<ImportContactsIcon />,
43+
<VisibilityIcon />,
44+
<SearchIcon />,
45+
<PublicIcon />
46+
];
47+
tabContentArr = [
48+
<IntroductionTab />,
49+
<ListVisualizer />,
50+
<Inspector />,
51+
<EnvVisualizer />
52+
];
53+
} else if (globalState.source == "Source2") {
4054
tabButtonArr = [
4155
<ImportContactsIcon />,
4256
<VisibilityIcon />,
@@ -47,6 +61,9 @@ export default function Description() {
4761
<ListVisualizer />,
4862
<SubstVisualizer content={["function", "f(x)"]} />
4963
];
64+
} else {
65+
tabButtonArr = [<ImportContactsIcon />, <SettingsEthernetIcon />];
66+
tabContentArr = [<IntroductionTab />, <ListVisualizer />];
5067
}
5168

5269
return (

src/Workspace/Editor.tsx

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
import React from "react";
1+
import React, { useContext } from "react";
22
import AceEditor from "react-ace";
33

44
import "ace-builds/src-noconflict/mode-javascript"; // replace with mode source in the future
55
import "ace-builds/src-noconflict/theme-tomorrow";
6+
import { IGlobalAction, Store } from "../Store";
67

78
export interface IEditorProps {
89
preloadedProg: string;
910
callBack: (newCode: string) => void;
1011
}
1112

1213
function Editor(props: IEditorProps) {
13-
const [value, setValue] = React.useState(props.preloadedProg);
14-
14+
const { globalState, dispatch } = useContext(Store);
1515
function onChangeMethod(newCode: string) {
16-
props.callBack(newCode);
17-
setValue(newCode);
16+
return dispatch({
17+
type: "UPDATE_EDITOR_VALUE",
18+
playgroundEditorValue: newCode
19+
});
1820
}
1921

2022
return (
@@ -25,10 +27,9 @@ function Editor(props: IEditorProps) {
2527
height="100vh"
2628
width="inherit"
2729
fontSize="17"
28-
value={value}
30+
value={globalState.playgroundEditorValue}
2931
tabSize={4}
3032
onChange={onChangeMethod}
31-
style={{ zIndex: -1 }}
3233
/>
3334
);
3435
}

0 commit comments

Comments
 (0)