|
1 | 1 | import React, { Component } from 'react'; |
2 | | -import axios from 'axios'; |
3 | 2 | import Header from '../components/Header'; |
4 | | -import CodeEditor from '../components/CodeEditor'; |
5 | | -import ResultsEditor from '../components/ResultsEditor'; |
6 | | -import { Grid, Button, FormControl, FormControlLabel, Checkbox, Select, MenuItem } from '@material-ui/core'; |
7 | | -import code from '../resources/code'; |
8 | | -import languages from '../resources/languages'; |
| 3 | +import CoderpadWrapper from '../components/CoderpadWrapper'; |
9 | 4 | import './App.css'; |
10 | 5 |
|
11 | | -// Backend servers to execute code. |
12 | | -const EXECUTE_CODE_DEV_POST_URL = 'http://localhost:5000/coderpad/execute' |
13 | | -const EXECUTE_CODE_PROD_POST_URL = 'https://aws.dannyhp.com/coderpad/execute' |
14 | | -const EXECUTE_CODE_POST_URL = EXECUTE_CODE_PROD_POST_URL |
15 | | - |
16 | | -// Backend servers to save code (Pastebin: https://github.com/dannyhp1/pastebin) |
17 | | -const SAVE_CODE_DEV_POST_URL = 'http://localhost:5000/pastebin/save' |
18 | | -const SAVE_CODE_PROD_POST_URL = 'https://aws.dannyhp.com/pastebin/save' |
19 | | -const SAVE_CODE_POST_URL = SAVE_CODE_PROD_POST_URL |
20 | | - |
21 | | -// Default settings on page loadup. |
22 | | -const DEFAULT_LANGUAGE = 'python' |
23 | | -const DEFAULT_AUTOCOMPLETE = false |
24 | | -const DEFAULT_PRACTICE = false |
25 | | - |
26 | | -// Notification messages. |
27 | | -const EXECUTING_CODE_MESSAGE = 'Running your code...' |
28 | | -const EXECUTING_CODE_ERROR = 'Code cannot be executed. Network connection to server cannot be established.\n' |
29 | | - |
30 | 6 | class App extends Component { |
31 | | - constructor(props) { |
32 | | - super(props) |
33 | | - |
34 | | - // Default language set to Java; coderpad now supports C++, Java, and Python. |
35 | | - this.state = this.getInitialState() |
36 | | - } |
37 | | - |
38 | | - getInitialState = () => { |
39 | | - return ({ |
40 | | - language: DEFAULT_LANGUAGE, |
41 | | - source: {'java': code['java'], 'python': code['python'], 'c_cpp': code['c_cpp']}, |
42 | | - results: [ ], |
43 | | - disabled: false, |
44 | | - practice: DEFAULT_PRACTICE, |
45 | | - autocomplete: DEFAULT_AUTOCOMPLETE |
46 | | - }) |
47 | | - } |
48 | | - |
49 | | - /** |
50 | | - * Changes the current source code. |
51 | | - * @param string value The source code as a string. |
52 | | - */ |
53 | | - onChangeCode = (value) => { |
54 | | - let currentSource = this.state.source |
55 | | - currentSource[this.state.language] = value |
56 | | - |
57 | | - this.setState({ |
58 | | - ...this.state, |
59 | | - source: currentSource |
60 | | - }) |
61 | | - } |
62 | | - |
63 | | - /** |
64 | | - * Changes the programming language. |
65 | | - * @param event event The event of switching select box. |
66 | | - */ |
67 | | - onChangeLanguage = (event) => { |
68 | | - this.setState({ |
69 | | - ...this.state, |
70 | | - language: event.target.value |
71 | | - }) |
72 | | - } |
73 | | - |
74 | | - /** |
75 | | - * Enables/disables practice mode. |
76 | | - */ |
77 | | - onChangePractice = () => { |
78 | | - this.setState({ |
79 | | - ...this.state, |
80 | | - practice: !this.state.practice |
81 | | - }) |
82 | | - } |
83 | | - |
84 | | - /** |
85 | | - * Enables/disables autocomplete. |
86 | | - */ |
87 | | - onChangeAutocomplete = () => { |
88 | | - this.setState({ |
89 | | - ...this.state, |
90 | | - autocomplete: !this.state.autocomplete |
91 | | - }) |
92 | | - } |
93 | | - |
94 | | - /** |
95 | | - * Adds code executing message and disables run button. |
96 | | - */ |
97 | | - setRunningStatus = () => { |
98 | | - let currentResults = this.state.results |
99 | | - currentResults.unshift(EXECUTING_CODE_MESSAGE) |
100 | | - |
101 | | - this.setState({ |
102 | | - ...this.state, |
103 | | - results: currentResults, |
104 | | - disabled: true |
105 | | - }) |
106 | | - } |
107 | | - |
108 | | - /** |
109 | | - * Removes code executing message and reenables run button. |
110 | | - */ |
111 | | - setFinishedStatus = () => { |
112 | | - let currentResults = this.state.results |
113 | | - currentResults.shift() |
114 | | - |
115 | | - this.setState({ |
116 | | - ...this.state, |
117 | | - results: currentResults, |
118 | | - disabled: false |
119 | | - }) |
120 | | - } |
121 | | - |
122 | | - /** |
123 | | - * Makes request to backend server and parses code execution results. |
124 | | - */ |
125 | | - executeCode = () => { |
126 | | - this.setRunningStatus() |
127 | | - |
128 | | - axios.post(EXECUTE_CODE_POST_URL, { |
129 | | - language: this.state.language, |
130 | | - code: this.state.source[this.state.language], |
131 | | - }).then(response => { |
132 | | - const build = response['data']['build'] |
133 | | - // const error = response['data']['error'] |
134 | | - const run = response['data']['run'] |
135 | | - |
136 | | - const result = { build: null, message: null } |
137 | | - |
138 | | - if (run !== 'None') { |
139 | | - result['build'] = true |
140 | | - result['message'] = run |
141 | | - } else { |
142 | | - result['build'] = false |
143 | | - result['message'] = build |
144 | | - } |
145 | | - |
146 | | - this.addToLog(result) |
147 | | - }).catch(error => { |
148 | | - this.setFinishedStatus() |
149 | | - |
150 | | - let currentResults = this.state.results |
151 | | - currentResults.unshift(EXECUTING_CODE_ERROR) |
152 | | - |
153 | | - this.setState({ |
154 | | - ...this.state, |
155 | | - results: currentResults |
156 | | - }) |
157 | | - }) |
158 | | - } |
159 | | - |
160 | | - /** |
161 | | - * Clears all of the logs from the current state. |
162 | | - */ |
163 | | - clearLogs = () => { |
164 | | - this.setState({ |
165 | | - ...this.state, |
166 | | - results: [ ] |
167 | | - }) |
168 | | - } |
169 | | - |
170 | | - /** |
171 | | - * Downloads the currently displayed source code to the user's desktop. |
172 | | - */ |
173 | | - downloadCode = () => { |
174 | | - // TODO: Code to download source code. |
175 | | - } |
176 | | - |
177 | | - /** |
178 | | - * Adds the result message to the log. |
179 | | - * @param object result Results of POST request containing build status and running message. |
180 | | - */ |
181 | | - addToLog = (result) => { |
182 | | - // Before processing the new result, we must pop the message 'Running your code...' off and re-enable the button. |
183 | | - this.setFinishedStatus() |
184 | | - |
185 | | - // TODO: Keep only a specific amount of logs. |
186 | | - let currentResults = this.state.results |
187 | | - |
188 | | - if (result['build'] === true) { |
189 | | - currentResults.unshift('[' + languages[this.state.language] + '] Build successfully completed!\nStandard output:\n' + result['message']) |
190 | | - } else { |
191 | | - currentResults.unshift('[' + languages[this.state.language] + '] Build failed!\nBuild errors:\n' + result['message']) |
192 | | - } |
193 | | - |
194 | | - this.setState({ |
195 | | - ...this.state, |
196 | | - results: currentResults |
197 | | - }) |
198 | | - } |
199 | | - |
200 | | - /** |
201 | | - * Compiles the list of logs into a single string. |
202 | | - */ |
203 | | - getLogs = () => { |
204 | | - return this.state.results.join('\n\n') |
205 | | - } |
206 | | - |
207 | 7 | render() { |
208 | 8 | return ( |
209 | 9 | <div className="App"> |
210 | 10 | <Header /> |
211 | | - |
212 | | - <Grid container style={{ marginBottom: '1.5%' }}> |
213 | | - <Grid item xs={6}> |
214 | | - <CodeEditor |
215 | | - autocomplete={this.state.autocomplete} |
216 | | - language={this.state.practice === true ? 'plain_text' : this.state.language} |
217 | | - source={this.state.source[this.state.language]} |
218 | | - onChange={this.onChangeCode} /> |
219 | | - </Grid> |
220 | | - <Grid item xs={6}> |
221 | | - <ResultsEditor logs={this.getLogs()} /> |
222 | | - </Grid> |
223 | | - </Grid> |
224 | | - |
225 | | - <Grid container> |
226 | | - <Grid item xs={6}> |
227 | | - <FormControl style={{ textAlign: 'center', width: '20%', marginLeft: '1.5%', marginRight: '2.5%' }}> |
228 | | - <Select |
229 | | - labelId='select-language-label' |
230 | | - id='select-language' |
231 | | - value={this.state.language} |
232 | | - onChange={this.onChangeLanguage} |
233 | | - style={{ color: '#ffffff' }} |
234 | | - > |
235 | | - <MenuItem value='java'>{languages['java']}</MenuItem> |
236 | | - <MenuItem value='python'>{languages['python']}</MenuItem> |
237 | | - <MenuItem value='c_cpp'>{languages['c_cpp']}</MenuItem> |
238 | | - </Select> |
239 | | - </FormControl> |
240 | | - <FormControlLabel |
241 | | - control={ |
242 | | - <Checkbox |
243 | | - checked={this.state.autocomplete} |
244 | | - onChange={this.onChangeAutocomplete} |
245 | | - value='autocomplete' |
246 | | - style={{ color: '#0269a4' }} |
247 | | - /> |
248 | | - } |
249 | | - label='Code Autocomplete' |
250 | | - style={{ marginRight: '2.5%' }} |
251 | | - /> |
252 | | - <FormControlLabel |
253 | | - control={ |
254 | | - <Checkbox |
255 | | - checked={this.state.practice} |
256 | | - onChange={this.onChangePractice} |
257 | | - value='practice' |
258 | | - style={{ color: '#0269a4' }} |
259 | | - /> |
260 | | - } |
261 | | - label='Practice Mode' |
262 | | - style={{ marginRight: '2.5%' }} |
263 | | - /> |
264 | | - </Grid> |
265 | | - <Grid item xs={6} style={{ textAlign: 'right' }}> |
266 | | - {/* TODO: Add 'Download Code' button to download script to local desktop for users. */} |
267 | | - {/* <Button variant='contained' color='primary' |
268 | | - disabled |
269 | | - onClick={this.downloadCode} |
270 | | - style={{ background: '#0269a4', marginRight: '3.5%' }}> |
271 | | - Download Code |
272 | | - </Button> */} |
273 | | - <Button variant='contained' color='primary' |
274 | | - onClick={this.clearLogs} |
275 | | - style={{ background: '#0269a4', marginRight: '2.5%' }}> |
276 | | - Clear Logs |
277 | | - </Button> |
278 | | - <Button variant='contained' color='primary' |
279 | | - onClick={this.executeCode} |
280 | | - disabled={this.state.disabled} |
281 | | - style={{ background: '#0269a4', marginRight: '1.5%' }}> |
282 | | - {this.state.disabled ? 'Running code...' : 'Run Code'} |
283 | | - </Button> |
284 | | - </Grid> |
285 | | - </Grid> |
| 11 | + <CoderpadWrapper /> |
286 | 12 | </div> |
287 | 13 | ); |
288 | 14 | } |
|
0 commit comments