Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Consistent file uploads #4699

Merged
merged 3 commits into from
Feb 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 37 additions & 52 deletions js/src/modals/CreateAccount/NewImport/newImport.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,22 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import { FloatingActionButton } from 'material-ui';
import { observer } from 'mobx-react';
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { FormattedMessage } from 'react-intl';

import { Form, Input } from '~/ui';
import { AttachFileIcon } from '~/ui/Icons';
import { Form, FileSelect, Input } from '~/ui';

import styles from '../createAccount.css';

const STYLE_HIDDEN = { display: 'none' };

@observer
export default class NewImport extends Component {
static propTypes = {
store: PropTypes.object.isRequired
}

render () {
const { name, nameError, password, passwordHint, walletFile, walletFileError } = this.props.store;
const { name, nameError, password, passwordHint } = this.props.store;

return (
<Form>
Expand Down Expand Up @@ -93,58 +88,48 @@ export default class NewImport extends Component {
/>
</div>
</div>
<div>
<Input
disabled
error={ walletFileError }
hint={
<FormattedMessage
id='createAccount.newImport.file.hint'
defaultMessage='the wallet file for import'
/>
}
label={
<FormattedMessage
id='createAccount.newImport.file.label'
defaultMessage='wallet file'
/>
}
value={ walletFile }
/>
<div className={ styles.upload }>
<FloatingActionButton
mini
onTouchTap={ this.openFileDialog }
>
<AttachFileIcon />
</FloatingActionButton>
<input
onChange={ this.onFileChange }
ref='fileUpload'
style={ STYLE_HIDDEN }
type='file'
/>
</div>
</div>
{ this.renderFileSelector() }
</Form>
);
}

onFileChange = (event) => {
const { store } = this.props;

if (event.target.files.length) {
const reader = new FileReader();

reader.onload = (event) => store.setWalletJson(event.target.result);
reader.readAsText(event.target.files[0]);
}
renderFileSelector () {
const { walletFile, walletFileError } = this.props.store;

store.setWalletFile(event.target.value);
return walletFile
? (
<Input
disabled
error={ walletFileError }
hint={
<FormattedMessage
id='createAccount.newImport.file.hint'
defaultMessage='the wallet file for import'
/>
}
label={
<FormattedMessage
id='createAccount.newImport.file.label'
defaultMessage='wallet file'
/>
}
value={ walletFile }
/>
)
: (
<FileSelect
className={ styles.fileImport }
error={ walletFileError }
onSelect={ this.onFileSelect }
/>
);
}

openFileDialog = () => {
ReactDOM.findDOMNode(this.refs.fileUpload).click();
onFileSelect = (fileName, fileContent) => {
const { store } = this.props;

store.setWalletFile(fileName);
store.setWalletJson(fileContent);
}

onEditName = (event, name) => {
Expand Down
16 changes: 5 additions & 11 deletions js/src/modals/CreateAccount/createAccount.css
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,6 @@
width: 10% !important;
}

.upload {
text-align: right;
float: right;
margin-left: -100%;
margin-top: 28px;
}

.upload>div {
margin-right: 0.5em;
}

.checkbox {
margin-top: 2em;
}
Expand All @@ -131,6 +120,11 @@
}
}

.fileImport {
height: 9em;
margin-top: 1em;
}

.summary {
line-height: 1.618em;
padding: 0 4em 1.5em 4em;
Expand Down
3 changes: 3 additions & 0 deletions js/src/modals/CreateAccount/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,11 @@ export default class Store {
this.phrase = '';
this.name = '';
this.nameError = null;
this.rawKey = '';
this.rawKeyError = null;
this.walletFile = '';
this.walletFileError = null;
this.walletJson = '';
});
}

Expand Down
11 changes: 11 additions & 0 deletions js/src/modals/CreateAccount/store.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,24 @@ describe('modals/CreateAccount/Store', () => {

describe('@action', () => {
describe('clearErrors', () => {
beforeEach(() => {
store.setName('');
store.setPassword('123');
store.setRawKey('test');
store.setWalletFile('test');
store.setWalletJson('test');
});

it('clears all errors', () => {
store.clearErrors();

expect(store.nameError).to.be.null;
expect(store.passwordRepeatError).to.be.null;
expect(store.rawKey).to.equal('');
expect(store.rawKeyError).to.be.null;
expect(store.walletFile).to.equal('');
expect(store.walletFileError).to.be.null;
expect(store.walletJson).to.equal('');
});
});

Expand Down
24 changes: 0 additions & 24 deletions js/src/ui/Actionbar/Import/import.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,6 @@
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/

.importZone {
width: 100%;
height: 200px;
border-width: 2px;
border-color: #666;
border-style: dashed;
border-radius: 10px;

background-color: rgba(50, 50, 50, 0.2);

display: flex;
align-items: center;
justify-content: center;
font-size: 1.2em;

transition: all 0.5s ease;

&:hover {
cursor: pointer;
border-radius: 0;
background-color: rgba(50, 50, 50, 0.5);
}
}

.desc {
margin-top: 0;
color: #ccc;
Expand Down
64 changes: 19 additions & 45 deletions js/src/ui/Actionbar/Import/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import React, { Component, PropTypes } from 'react';
import Dropzone from 'react-dropzone';
import { FormattedMessage } from 'react-intl';

import { nodeOrStringProptype } from '~/util/proptypes';

import Button from '../../Button';
import FileSelect from '../../Form/FileSelect';
import { CancelIcon, DoneIcon, FileUploadIcon } from '../../Icons';
import Portal from '../../Portal';

Expand Down Expand Up @@ -184,25 +184,8 @@ export default class ActionbarImport extends Component {
return this.renderValidation();
}

return this.renderFileSelect();
}

renderFileSelect () {
return (
<div>
<Dropzone
onDrop={ this.onDrop }
multiple={ false }
className={ styles.importZone }
>
<div>
<FormattedMessage
id='ui.actiobar.import.dropzone'
defaultMessage='Drop a file here, or click to select a file to upload.'
/>
</div>
</Dropzone>
</div>
<FileSelect onSelect={ this.onFileSelect } />
);
}

Expand All @@ -224,39 +207,30 @@ export default class ActionbarImport extends Component {
);
}

onDrop = (files) => {
onFileSelect = (file, content) => {
const { renderValidation } = this.props;

const file = files[0];
const reader = new FileReader();

reader.onload = (e) => {
const content = e.target.result;

if (typeof renderValidation !== 'function') {
this.props.onConfirm(content);
return this.onCloseModal();
}

const validationBody = renderValidation(content);
if (typeof renderValidation !== 'function') {
this.props.onConfirm(content);
return this.onCloseModal();
}

if (validationBody && validationBody.error) {
return this.setState({
step: 1,
error: true,
errorText: validationBody.error
});
}
const validationBody = renderValidation(content);

this.setState({
if (validationBody && validationBody.error) {
return this.setState({
step: 1,
validate: true,
validationBody,
content
error: true,
errorText: validationBody.error
});
};
}

reader.readAsText(file);
this.setState({
step: 1,
validate: true,
validationBody,
content
});
}

onConfirm = () => {
Expand Down
52 changes: 52 additions & 0 deletions js/src/ui/Form/FileSelect/fileSelect.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
/* This file is part of Parity.
/*
/* Parity is free software: you can redistribute it and/or modify
/* it under the terms of the GNU General Public License as published by
/* the Free Software Foundation, either version 3 of the License, or
/* (at your option) any later version.
/*
/* Parity is distributed in the hope that it will be useful,
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/* GNU General Public License for more details.
/*
/* You should have received a copy of the GNU General Public License
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/

$backgroundNormal: rgba(0, 0, 0, 0.2);
$backgroundNormalHover: rgba(0, 0, 0, 0.5);
$backgroundError: rgba(255, 0, 0, 0.1);
$backgroundErrorHover: rgba(255, 0, 0, 0.2);

.dropzone {
align-items: center;
background: $backgroundNormal;
border: 2px dashed #666;
border-radius: 0.5em;
display: flex;
justify-content: center;
font-size: 1.2em;
height: 12em;
transition: all 0.5s ease;
width: 100%;

&:hover {
background: $backgroundNormalHover;
border-radius: 0;
cursor: pointer;
}

&.error {
background: $backgroundError;

&:hover {
background: $backgroundErrorHover;
}
}

.label {
color: #aaa;
}
}
Loading