Skip to content

Commit d9ea48a

Browse files
committed
Fixed file upload
1 parent 607e9a3 commit d9ea48a

File tree

5 files changed

+127
-124
lines changed

5 files changed

+127
-124
lines changed

App/containers/CodeContainer.js

Lines changed: 100 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import PropTypes from 'prop-types';
33

44
import {connect} from 'react-redux';
55

6-
import {Form, Grid, Segment, Button, Icon} from 'semantic-ui-react';
6+
import {Form, Grid, Segment, Button, Icon, Tab} from 'semantic-ui-react';
77

8-
import classNames from 'classnames';
98
import Dropzone from 'react-dropzone';
109

1110
import EditorContainer from '../containers/EditorContainer';
@@ -60,15 +59,21 @@ class CodeContainer extends Component {
6059
}
6160

6261
onDrop(files) {
62+
const {onCodeChange} = this.props;
63+
64+
if (!window.File || !window.FileReader) {
65+
alert('Your browser does not support File API');
66+
}
67+
6368
const file = files[0];
6469
const reader = new FileReader();
6570

6671
reader.onload = (event) => {
67-
this.props.onCodeChange(event.target.result);
72+
onCodeChange(event.target.result);
73+
this.onTabClick(TAB_CODE);
6874
};
6975

7076
reader.readAsText(file);
71-
7277
}
7378

7479
toggleEvaluate = () => {
@@ -135,12 +140,9 @@ class CodeContainer extends Component {
135140

136141
done = true;
137142
flush();
138-
139143
}
140144

141-
render() {
142-
const tabIndex = this.state.selectedTabIndex;
143-
145+
buildPanes() {
144146
const {
145147
code,
146148
obfuscatedCode,
@@ -153,87 +155,102 @@ class CodeContainer extends Component {
153155
hasObfuscatedCode,
154156
} = this.props;
155157

156-
return (
157-
<div>
158-
159-
<div className="ui top attached stackable three item menu">
160-
<Title active={tabIndex === TAB_CODE} onClick={() => this.onTabClick(TAB_CODE)}>Copy & Paste
161-
JavaScript Code</Title>
162-
<Title active={tabIndex === TAB_UPLOAD} onClick={() => this.onTabClick(TAB_UPLOAD)}>Upload
163-
JavaScript Files</Title>
164-
<Title active={tabIndex === TAB_RESULTS} onClick={() => this.onTabClick(TAB_RESULTS)}>Output</Title>
165-
</div>
166-
167-
<Pane active={tabIndex === TAB_CODE}>
168-
<EditorContainer onBlur={onCodeChange} value={code}/>
169-
<Segment basic>
170-
<Button
171-
loading={pending}
172-
disabled={pending}
173-
primary
174-
onClick={onObfuscateClick}
175-
>
176-
Obfuscate
177-
</Button>
178-
</Segment>
179-
</Pane>
180-
181-
<Pane active={tabIndex === TAB_UPLOAD}>
182-
<Dropzone onDrop={::this.onDrop} multiple={false} className="DropZone">
183-
<div>Try dropping some files here, or click to select files to upload.</div>
184-
</Dropzone>
185-
</Pane>
186-
187-
<Pane active={tabIndex === TAB_RESULTS}>
188-
<Form>
189-
<Form.TextArea
190-
value={obfuscatedCode}
191-
onFocus={(event) => event.target.select()}
192-
/>
193-
</Form>
194-
195-
<Grid columns={2} relaxed>
196-
<Grid.Column width={13}>
158+
return [
159+
{
160+
menuItem: 'Copy & Paste JavaScript Code',
161+
render: () => (
162+
<Pane>
163+
<EditorContainer onBlur={onCodeChange} value={code}/>
164+
<Segment basic>
165+
<Button
166+
loading={pending}
167+
disabled={pending}
168+
primary
169+
onClick={onObfuscateClick}
170+
>
171+
Obfuscate
172+
</Button>
173+
</Segment>
174+
</Pane>
175+
)
176+
},
177+
{
178+
menuItem: 'Upload JavaScript File',
179+
render: () => (
180+
<Pane>
181+
<Dropzone onDrop={::this.onDrop} multiple={false} className="DropZone">
182+
<div>Try dropping some file here, or click to select file to upload.</div>
183+
</Dropzone>
184+
</Pane>
185+
)
186+
},
187+
{
188+
menuItem: 'Output',
189+
render: () => (
190+
<Pane>
191+
<Form>
192+
<Form.TextArea
193+
value={obfuscatedCode}
194+
onFocus={(event) => event.target.select()}
195+
/>
196+
</Form>
197+
198+
<Grid stackable columns={2} relaxed>
199+
<Grid.Column width={13}>
200+
<Segment basic>
201+
<Button
202+
disabled={!hasObfuscatedCode}
203+
onClick={onDownloadCodeClick}
204+
>
205+
<Icon name='download'/> Download obfuscated code
206+
</Button>
207+
{hasSourceMap &&
208+
<Button
209+
onClick={onDownloadSourceMapClick}
210+
>
211+
<Icon name='download'/> Download source map file
212+
</Button>
213+
}
214+
</Segment>
215+
</Grid.Column>
216+
217+
<Grid.Column width={3}>
218+
<Segment basic>
219+
<Form.Checkbox
220+
label='Evaluate'
221+
checked={this.state.evaluate}
222+
onChange={this.toggleEvaluate}/>
223+
</Segment>
224+
</Grid.Column>
225+
</Grid>
226+
227+
{this.state.evaluate &&
197228
<Segment basic>
198-
<Button
199-
disabled={!hasObfuscatedCode}
200-
onClick={onDownloadCodeClick}
201-
>
202-
<Icon name='download'/> Download obfuscated code
203-
</Button>
204-
{hasSourceMap &&
205-
<Button
206-
onClick={onDownloadSourceMapClick}
207-
>
208-
<Icon name='download'/> Download source map file
209-
</Button>
210-
}
229+
<div className="evaluatedCode">
230+
{this.state.evaluatedResult}
231+
</div>
211232
</Segment>
212-
</Grid.Column>
233+
}
234+
</Pane>
235+
)
236+
}
237+
];
238+
}
213239

214-
<Grid.Column width={3}>
215-
<Segment basic>
216-
<Form.Checkbox
217-
label='Evaluate'
218-
checked={this.state.evaluate}
219-
onChange={this.toggleEvaluate}/>
220-
</Segment>
221-
</Grid.Column>
222-
</Grid>
223-
224-
{this.state.evaluate &&
225-
<Segment basic>
226-
<div className="evaluatedCode">
227-
{this.state.evaluatedResult}
228-
</div>
229-
</Segment>
230-
}
231-
</Pane>
240+
render() {
241+
const tabIndex = this.state.selectedTabIndex;
232242

243+
return (
244+
<div>
245+
<Tab
246+
activeIndex={tabIndex}
247+
menu={{attached: 'top', stackable: true, widths: 'three'}}
248+
panes={this.buildPanes()}
249+
onTabChange={(event, data) => this.onTabClick(data.activeIndex)}
250+
/>
233251
</div>
234252
);
235253
}
236-
237254
}
238255

239256
const mapStateToProps = (state) => {
@@ -248,32 +265,13 @@ export default connect(mapStateToProps)(CodeContainer);
248265

249266

250267
const Pane = (props) => {
251-
const className = classNames('ui bottom attached tab segment'.split(' '), {'active': props.active});
252268
return (
253-
<div className={className}>
269+
<div className="ui bottom attached tab segment active">
254270
{props.children}
255271
</div>
256272
)
257273
};
258274

259275
Pane.propTypes = {
260-
active: PropTypes.bool.isRequired,
261-
children: PropTypes.node.isRequired,
262-
};
263-
264-
265-
const Title = (props) => {
266-
const className = classNames('item', {'active': props.active});
267-
268-
return (
269-
<a className={className} onClick={props.onClick}>
270-
{props.children}
271-
</a>
272-
)
273-
};
274-
275-
Title.propTypes = {
276-
active: PropTypes.bool.isRequired,
277276
children: PropTypes.node.isRequired,
278-
onClick: PropTypes.func.isRequired,
279277
};

App/containers/EditorContainer.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import React, {Component} from 'react';
22
import PropTypes from 'prop-types';
33

4-
import Codemirror from 'react-codemirror';
4+
import {Controlled as CodeMirror} from 'react-codemirror2'
55

66
require('codemirror/mode/javascript/javascript');
77

88
export default class EditorContainer extends Component {
9+
editor = null;
10+
911
constructor(props) {
1012
super(props);
1113

1214
this.state = {
13-
code: props.value,
15+
code: props.value
1416
}
1517
}
1618

@@ -19,26 +21,29 @@ export default class EditorContainer extends Component {
1921
onBlur: PropTypes.func.isRequired,
2022
};
2123

22-
componentDidMount() {
23-
this.refs.editor.getCodeMirror().execCommand('selectAll');
24-
}
25-
2624
componentWillReceiveProps(nextProps) {
2725
this.setState({
2826
code: nextProps.value
2927
});
28+
29+
setTimeout(() => {
30+
this.editor && this.editor.refresh();
31+
}, 1);
3032
}
3133

32-
handleOnChange(newCode) {
34+
handleEditorMount(editor) {
35+
editor.execCommand('selectAll');
36+
this.editor = editor;
37+
}
38+
39+
handleOnChange(editor, data, value) {
3340
this.setState({
34-
code: newCode
41+
code: value
3542
});
3643
}
3744

38-
handleFocusChange(focused) {
39-
if (!focused) {
40-
this.props.onBlur(this.state.code);
41-
}
45+
handleFocusChange(editor) {
46+
this.props.onBlur(editor.getValue());
4247
}
4348

4449
render() {
@@ -49,11 +54,12 @@ export default class EditorContainer extends Component {
4954
};
5055

5156
return (
52-
<Codemirror
53-
ref='editor'
57+
<CodeMirror
58+
editorDidMount={::this.handleEditorMount}
5459
value={this.state.code}
55-
onChange={::this.handleOnChange}
56-
onFocusChange={::this.handleFocusChange}
60+
onBeforeChange={::this.handleOnChange}
61+
onFocus={::this.handleFocusChange}
62+
onBlur={::this.handleFocusChange}
5763
options={options}
5864
/>
5965
);

App/containers/EntryInputContainer.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ export default class EntryInputContainer extends Component {
6767
const Labels = ({entries, onCloseClick}) =>
6868
<div className="ui labels">
6969
{entries.map(entry =>
70-
<span className="ui label" key={entry}>
71-
{entry}
72-
<i onClick={() => onCloseClick(entry)} className="icon close"/>
73-
</span>
70+
<span className="ui label" key={entry}>
71+
{entry}
72+
<i onClick={() => onCloseClick(entry)} className="icon close"/>
73+
</span>
7474
)}
7575
</div>;
7676

App/reducers/code.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const initialState = {
2323
export const code = (state = initialState, action) => {
2424

2525
switch (action.type) {
26-
2726
case types.UPDATE_CODE:
2827
return {
2928
...state,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"javascript-obfuscator": "0.16.0",
2626
"prop-types": "15.6.1",
2727
"react": "16.3.0",
28-
"react-codemirror": "1.0.0",
28+
"react-codemirror2": "5.0.1",
2929
"react-dom": "16.3.0",
3030
"react-dropzone": "4.2.9",
3131
"react-redux": "5.0.7",

0 commit comments

Comments
 (0)