Skip to content

Commit 6e8be4d

Browse files
committed
Fix minor bugs and do frontend code refactoring
1 parent eb89a86 commit 6e8be4d

File tree

16 files changed

+213
-201
lines changed

16 files changed

+213
-201
lines changed

src/frontend/common/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CODE_CPP, CODE_JAVA, CODE_JS } from '/skeletons';
1+
import { CODE_CPP, CODE_JAVA, CODE_JS } from '/files';
22

33
const languages = [{
44
name: 'JavaScript',

src/frontend/common/util.js

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { README_MD } from '/skeletons';
2-
31
const classes = (...arr) => arr.filter(v => v).join(' ');
42

53
const distance = (a, b) => {
@@ -20,28 +18,7 @@ const refineGist = gist => {
2018
content: file.content,
2119
contributors: [{ login, avatar_url }],
2220
}));
23-
return { gistId, title, files, gist };
24-
};
25-
26-
const getFiles = current => {
27-
const { algorithm, scratchPaper } = current;
28-
if (algorithm) return algorithm.files;
29-
if (scratchPaper) return scratchPaper.files;
30-
return [{
31-
name: 'README.md',
32-
content: README_MD,
33-
contributors: [{
34-
login: 'algorithm-visualizer',
35-
avatar_url: 'https://github.com/algorithm-visualizer.png',
36-
}],
37-
}];
38-
};
39-
40-
const getTitleArray = current => {
41-
const { algorithm, scratchPaper } = current;
42-
if (algorithm) return [algorithm.categoryName, algorithm.algorithmName];
43-
if (scratchPaper) return ['Scratch Paper', scratchPaper.title];
44-
return ['Algorithm Visualizer'];
21+
return { login, gistId, title, files };
4522
};
4623

4724
const handleError = function (error) {
@@ -54,7 +31,5 @@ export {
5431
distance,
5532
extension,
5633
refineGist,
57-
getFiles,
58-
getTitleArray,
5934
handleError,
6035
};

src/frontend/components/App/index.jsx

Lines changed: 54 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import {
1919
} from '/components';
2020
import { AlgorithmApi, GitHubApi } from '/apis';
2121
import { actions } from '/reducers';
22-
import { extension, getFiles, getTitleArray, handleError, refineGist } from '/common/util';
22+
import { extension, handleError, refineGist } from '/common/util';
2323
import { exts, languages } from '/common/config';
24-
import { SCRATCH_PAPER_MD } from '/skeletons';
24+
import { SCRATCH_PAPER_MD } from '/files';
2525
import styles from './stylesheet.scss';
2626

2727
loadProgressBar();
@@ -53,7 +53,9 @@ class App extends React.Component {
5353
.then(({ categories }) => this.props.setCategories(categories))
5454
.catch(handleError.bind(this));
5555

56-
window.onbeforeunload = () => this.isGistSaved() ? undefined : 'Changes you made will not be saved.';
56+
this.props.history.block(() => {
57+
if (!this.isSaved()) return 'Are you sure want to discard changes?';
58+
});
5759
}
5860

5961
componentWillUnmount() {
@@ -65,26 +67,12 @@ class App extends React.Component {
6567

6668
componentWillReceiveProps(nextProps) {
6769
const { params } = nextProps.match;
68-
const { algorithm, scratchPaper } = nextProps.current;
69-
70-
const categoryKey = algorithm && algorithm.categoryKey;
71-
const algorithmKey = algorithm && algorithm.algorithmKey;
72-
const gistId = scratchPaper && scratchPaper.gistId;
73-
74-
if (params.categoryKey !== categoryKey ||
75-
params.algorithmKey !== algorithmKey ||
76-
params.gistId !== gistId) {
77-
if (nextProps.location.pathname !== this.props.location.pathname) {
78-
this.loadAlgorithm(params);
79-
} else {
80-
if (categoryKey && algorithmKey) {
81-
this.props.history.push(`/${categoryKey}/${algorithmKey}`);
82-
} else if (gistId) {
83-
this.props.history.push(`/scratch-paper/${gistId}`);
84-
} else {
85-
this.props.history.push('/');
86-
}
87-
}
70+
if (params !== this.props.match.params) {
71+
const { categoryKey, algorithmKey, gistId } = params;
72+
const { algorithm, scratchPaper } = nextProps.current;
73+
if (algorithm && algorithm.categoryKey === categoryKey && algorithm.algorithmKey === algorithmKey) return;
74+
if (scratchPaper && scratchPaper.gistId === gistId) return;
75+
this.loadAlgorithm(params);
8876
}
8977
}
9078

@@ -95,7 +83,6 @@ class App extends React.Component {
9583
.then(user => {
9684
const { login, avatar_url } = user;
9785
this.props.setUser({ login, avatar_url });
98-
Cookies.set('login', login);
9986
})
10087
.then(() => this.loadScratchPapers())
10188
.catch(() => this.signOut());
@@ -106,7 +93,6 @@ class App extends React.Component {
10693
GitHubApi.auth(undefined)
10794
.then(() => {
10895
this.props.setUser(undefined);
109-
Cookies.remove('login');
11096
})
11197
.then(() => this.props.setScratchPapers([]));
11298
}
@@ -134,44 +120,37 @@ class App extends React.Component {
134120
.catch(handleError.bind(this));
135121
}
136122

137-
loadAlgorithm({ categoryKey, algorithmKey, gistId }, forceLoad = false) {
138-
if (!forceLoad && !this.isGistSaved() && !window.confirm('Are you sure want to discard changes?')) return;
139-
123+
loadAlgorithm({ categoryKey, algorithmKey, gistId }) {
140124
const { ext } = this.props.env;
141-
let fetchPromise = null;
142-
if (categoryKey && algorithmKey) {
143-
fetchPromise = AlgorithmApi.getAlgorithm(categoryKey, algorithmKey)
144-
.then(({ algorithm }) => this.props.setAlgorithm(algorithm));
145-
} else if (['new', 'forked'].includes(gistId)) {
146-
gistId = 'new';
147-
const language = languages.find(language => language.ext === ext);
148-
fetchPromise = Promise.resolve(this.props.setScratchPaper({
149-
gistId,
150-
title: 'Untitled',
151-
files: [{
152-
name: 'README.md',
153-
content: SCRATCH_PAPER_MD,
154-
contributors: undefined,
155-
}, {
156-
name: `code.${ext}`,
157-
content: language.skeleton,
158-
contributors: undefined,
159-
}],
160-
}));
161-
} else if (gistId) {
162-
fetchPromise = GitHubApi.getGist(gistId, { timestamp: Date.now() })
163-
.then(refineGist)
164-
.then(this.props.setScratchPaper);
165-
} else {
166-
fetchPromise = Promise.reject(new Error());
167-
}
168-
fetchPromise
125+
const fetch = () => {
126+
if (categoryKey && algorithmKey) {
127+
return AlgorithmApi.getAlgorithm(categoryKey, algorithmKey)
128+
.then(({ algorithm }) => this.props.setAlgorithm(algorithm));
129+
} else if (gistId === 'new') {
130+
const language = languages.find(language => language.ext === ext);
131+
this.props.setScratchPaper({
132+
login: undefined,
133+
gistId,
134+
title: 'Untitled',
135+
files: [SCRATCH_PAPER_MD, language.skeleton],
136+
});
137+
return Promise.resolve();
138+
} else if (gistId) {
139+
return GitHubApi.getGist(gistId, { timestamp: Date.now() })
140+
.then(refineGist)
141+
.then(this.props.setScratchPaper);
142+
} else {
143+
this.props.setHome();
144+
return Promise.resolve();
145+
}
146+
};
147+
fetch()
169148
.catch(error => {
170-
if (error.message) handleError.bind(this)(error);
149+
handleError.bind(this)(error);
171150
this.props.setHome();
172151
})
173152
.finally(() => {
174-
const files = getFiles(this.props.current);
153+
const { files } = this.props.current;
175154
let editorTabIndex = files.findIndex(file => extension(file.name) === ext);
176155
if (!~editorTabIndex) editorTabIndex = files.findIndex(file => exts.includes(extension(file.name)));
177156
if (!~editorTabIndex) editorTabIndex = Math.min(0, files.length - 1);
@@ -185,15 +164,15 @@ class App extends React.Component {
185164
}
186165

187166
handleChangeEditorTabIndex(editorTabIndex) {
188-
const files = getFiles(this.props.current);
167+
const { files } = this.props.current;
189168
if (editorTabIndex === files.length) this.handleAddFile();
190169
this.setState({ editorTabIndex });
191170
this.props.shouldBuild();
192171
}
193172

194173
handleAddFile() {
195174
const { ext } = this.props.env;
196-
const files = getFiles(this.props.current);
175+
const { files } = this.props.current;
197176
let name = `code.${ext}`;
198177
let count = 0;
199178
while (files.some(file => file.name === name)) name = `code-${++count}.${ext}`;
@@ -213,7 +192,7 @@ class App extends React.Component {
213192

214193
handleDeleteFile() {
215194
const { editorTabIndex } = this.state;
216-
const files = getFiles(this.props.current);
195+
const { files } = this.props.current;
217196
this.handleChangeEditorTabIndex(Math.min(editorTabIndex, files.length - 2));
218197
this.props.deleteFile(editorTabIndex);
219198
}
@@ -222,16 +201,17 @@ class App extends React.Component {
222201
this.setState({ navigatorOpened });
223202
}
224203

225-
isGistSaved() {
226-
const { scratchPaper } = this.props.current;
227-
if (!scratchPaper) return true;
228-
const { title, files, lastTitle, lastFiles } = scratchPaper;
229-
const serializeFiles = files => JSON.stringify(files.map(({ name, content }) => ({ name, content })));
230-
return title === lastTitle && serializeFiles(files) === serializeFiles(lastFiles);
204+
isSaved() {
205+
const { titles, files, lastTitles, lastFiles } = this.props.current;
206+
const serialize = (titles, files) => JSON.stringify({
207+
titles,
208+
files: files.map(({ name, content }) => ({ name, content })),
209+
});
210+
return serialize(titles, files) === serialize(lastTitles, lastFiles);
231211
}
232212

233213
getDescription() {
234-
const files = getFiles(this.props.current);
214+
const { files } = this.props.current;
235215
const readmeFile = files.find(file => file.name === 'README.md');
236216
if (!readmeFile) return '';
237217
const groups = /^\s*# .*\n+([^\n]+)/.exec(readmeFile.content);
@@ -241,10 +221,9 @@ class App extends React.Component {
241221
render() {
242222
const { navigatorOpened, workspaceWeights, editorTabIndex } = this.state;
243223

244-
const files = getFiles(this.props.current);
245-
const titleArray = getTitleArray(this.props.current);
246-
const gistSaved = this.isGistSaved();
247-
const title = `${gistSaved ? '' : '(Unsaved) '}${titleArray.join(' - ')}`;
224+
const { files, titles } = this.props.current;
225+
const saved = this.isSaved();
226+
const title = `${saved ? '' : '(Unsaved) '}${titles.join(' - ')}`;
248227
const description = this.getDescription();
249228
const file = files[editorTabIndex];
250229

@@ -265,14 +244,12 @@ class App extends React.Component {
265244
<title>{title}</title>
266245
<meta name="description" content={description} />
267246
</Helmet>
268-
<Header className={styles.header} onClickTitleBar={() => this.toggleNavigatorOpened()}
269-
navigatorOpened={navigatorOpened} loadScratchPapers={() => this.loadScratchPapers()}
270-
loadAlgorithm={this.loadAlgorithm.bind(this)} gistSaved={gistSaved}
271-
file={file} />
247+
<Header className={styles.header} onClickTitleBar={() => this.toggleNavigatorOpened()} saved={saved}
248+
navigatorOpened={navigatorOpened} loadScratchPapers={() => this.loadScratchPapers()} file={file} />
272249
<ResizableContainer className={styles.workspace} horizontal weights={workspaceWeights}
273250
visibles={[navigatorOpened, true, true]}
274251
onChangeWeights={weights => this.handleChangeWorkspaceWeights(weights)}>
275-
<Navigator loadAlgorithm={this.loadAlgorithm.bind(this)} />
252+
<Navigator />
276253
<VisualizationViewer className={styles.visualization_viewer} />
277254
<TabContainer className={styles.editor_tab_container} titles={editorTitles} tabIndex={editorTabIndex}
278255
onChangeTabIndex={tabIndex => this.handleChangeEditorTabIndex(tabIndex)}>

src/frontend/components/CodeEditor/index.jsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import 'brace/mode/markdown';
55
import 'brace/mode/javascript';
66
import 'brace/mode/c_cpp';
77
import 'brace/mode/java';
8-
import 'brace/mode/python';
98
import 'brace/theme/tomorrow_night_eighties';
109
import 'brace/ext/searchbox';
1110
import faTrashAlt from '@fortawesome/fontawesome-free-solid/faTrashAlt';
@@ -17,7 +16,7 @@ import { languages } from '/common/config';
1716
import { Button, Ellipsis } from '/components';
1817
import styles from './stylesheet.scss';
1918

20-
@connect(({ current, env, player }) => ({ current, env, player }), actions, null, { withRef: true })
19+
@connect(({ env, player }) => ({ env, player }), actions, null, { withRef: true })
2120
class CodeEditor extends React.Component {
2221
constructor(props) {
2322
super(props);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy