Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Register as delegate - Closes #354 #543

Merged
merged 13 commits into from
Aug 11, 2017
3 changes: 3 additions & 0 deletions src/components/header/header.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@
.menu {
right: -16px !important;
}
.hidden {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.hidden is not used.

display: none;
}
9 changes: 8 additions & 1 deletion src/components/header/headerElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import logo from '../../assets/images/LISK-nano.png';
import styles from './header.css';
import VerifyMessage from '../signVerify/verifyMessage';
import SignMessage from '../signVerify/signMessage';
import RegisterDelegate from '../registerDelegate';
import Send from '../send';
import PrivateWrapper from '../privateWrapper';

Expand All @@ -20,7 +21,13 @@ const HeaderElement = props => (
theme={styles}
>
<MenuItem caption="Register second passphrase" />
<MenuItem caption="Register as delegate" />
<MenuItem caption="Register as delegate"
className={(props.account.isDelegate) ? styles.hidden : ''}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the PR is in progress, but I just noticed this one thing. IMO more elegant way to conditionally hide an element in react is the ternary operator - {shouldShow ? <Element /> : null }.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a small component with no reprinting effect, there's no difference. I'll change anyways.

onClick={() => props.setActiveDialog({
title: 'Register as delegate',
childComponent: RegisterDelegate,
})}
/>
<MenuItem caption="Sign message"
className='sign-message'
onClick={() => props.setActiveDialog({
Expand Down
4 changes: 3 additions & 1 deletion src/components/header/headerElement.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ describe('HeaderElement', () => {
beforeEach(() => {
const mockInputProps = {
setActiveDialog: () => { },
account: {},
};
propsMock = sinon.mock(mockInputProps);
wrapper = shallow(<HeaderElement setActiveDialog={mockInputProps.setActiveDialog} />);
wrapper = shallow(<HeaderElement account={mockInputProps.account}
setActiveDialog={mockInputProps.setActiveDialog} />);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be simplified to wrapper = shallow(<HeaderElement { ...mockInputProps }/>);

});

afterEach(() => {
Expand Down
2 changes: 2 additions & 0 deletions src/components/login/loginFormComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ class LoginFormComponent extends React.Component {
getAccount(this.props.peers.data, accountInfo.address).then((result) => {
onAccountUpdated(result);
getDelegate(this.props.peers.data, accountInfo.publicKey).then((data) => {
console.log('success');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this console.log

onAccountUpdated({ delegate: data.delegate, isDelegate: true });
}).catch(() => {
console.log('error');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this console.log

onAccountUpdated({ delegate: {}, isDelegate: false });
});
// redirect to main/transactions
Expand Down
2 changes: 1 addition & 1 deletion src/components/passphrase/passphraseGenerator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import chai, { expect } from 'chai';
import { spy } from 'sinon';
import sinonChai from 'sinon-chai';
import { mount, shallow } from 'enzyme';
import { shallow } from 'enzyme';
import PassphraseGenerator from './passphraseGenerator';

chai.use(sinonChai);
Expand Down
22 changes: 22 additions & 0 deletions src/components/registerDelegate/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { connect } from 'react-redux';
import RegisterDelegate from './registerDelegate';
import { accountUpdated } from '../../actions/account';
import { successAlertDialogDisplayed, errorAlertDialogDisplayed } from '../../actions/dialog';

const mapStateToProps = state => ({
account: state.account,
peers: state.peers,
});

const mapDispatchToProps = dispatch => ({
onAccountUpdated: data => dispatch(accountUpdated(data)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot find where is this used.

showSuccessAlert: data => dispatch(successAlertDialogDisplayed(data)),
showErrorAlert: data => dispatch(errorAlertDialogDisplayed(data)),
});

const RegisterDelegateConnected = connect(
mapStateToProps,
mapDispatchToProps,
)(RegisterDelegate);

export default RegisterDelegateConnected;
75 changes: 75 additions & 0 deletions src/components/registerDelegate/registerDelegate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react';
import grid from 'flexboxgrid/dist/flexboxgrid.css';
import Input from 'react-toolbox/lib/input';
import Button from 'react-toolbox/lib/button';
import InfoParagraph from '../infoParagraph';
import { registerDelegate } from '../../utils/api/delegate';

class RegisterDelegate extends React.Component {
constructor() {
super();

this.state = {
title: 'register as delegate',
name: '',
nameError: '',
};
}

changeHandler(name, value) {
this.setState({ [name]: value });
}

register(username, secondSecret) {
registerDelegate(this.props.peers.data, username,
this.props.account.passphrase, secondSecret)
.then(() => {
this.props.showSuccessAlert({
text: `Delegate registration was successfully submitted with username: "${this.state.name}". It can take several seconds before it is processed.`,
});
})
.catch((error) => {
if (error && error.message === 'Username already exists') {
this.setState({ nameError: error.message });
} else {
this.props.showErrorAlert({
text: error && error.message ? `${error.message}.` : 'An error occurred while registering as delegate.',
});
}
});
}

render() {
// notify use about insufficient balance
return (
<div>
<Input label='Delegate name' required={true}
autoFocus={true}
onChange={this.changeHandler.bind(this, 'name')}
error={this.state.nameError}
value={this.state.name} />
{
this.props.account.secondSecret &&
<Input label='Second secret' required={true}
value={this.state.secondSecret} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Input won't set this.state.secondSecret without onChange

}
<hr/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hr is not visible due to display:none from passphrase.css. passphrase.css needs to be fixed.

<InfoParagraph>
Becoming a delegate requires registration. You may choose your own
delegate name, which can be used to promote your delegate. Only the
top 101 delegates are eligible to forge. All fees are shared equally
between the top 101 delegates.
</InfoParagraph>
<section className={`${grid.row} ${grid['between-xs']}`}>
<Button label='Cancel' className='cancel-button' onClick={this.props.closeDialog} />
<Button label='Register'
primary={true} raised={true}
disabled={!this.state.name}
onClick={this.register.bind(this, this.state.name, this.state.secondSecret)}/>
</section>
</div>
);
}
}

export default RegisterDelegate;
2 changes: 1 addition & 1 deletion src/components/voting/votingHeader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('VotingHeader', () => {

it('click on i.material-icons should clear vlaue of search input', () => {
wrapper.instance().search('query', '555');
wrapper.find('i.material-icons').simulate('click')
wrapper.find('i.material-icons').simulate('click');
expect(wrapper.state('query')).to.be.equal('');
});
});
6 changes: 1 addition & 5 deletions src/utils/passphrase.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import chai, { expect } from 'chai';
import { spy } from 'sinon';
import sinonChai from 'sinon-chai';
import { expect } from 'chai';
import { generateSeed, generatePassphrase } from './passphrase';

if (global._bitcore) delete global._bitcore;
const mnemonic = require('bitcore-mnemonic');

chai.use(sinonChai);

const randoms = [
0.35125316992864564, 0.6836880327771695, 0.05720201294124072, 0.7136064360838184,
0.7655709865481362, 0.9670469669099078, 0.6699998930954159, 0.4377283727720742,
Expand Down