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

Commit

Permalink
Merge pull request #146 from LiskHQ/138_vote-list-too-high
Browse files Browse the repository at this point in the history
Vote list too high - Fixes #138
  • Loading branch information
karmacoma authored Apr 27, 2017
2 parents 61a9eed + f951313 commit 4c09077
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 81 deletions.
19 changes: 9 additions & 10 deletions src/app/components/delegates/delegates.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ app.component('delegates', {
passphrase: '<',
},
controller: class delegates {
constructor($scope, $peers, $mdDialog, $mdMedia, $mdToast, $timeout) {
constructor($scope, delegateService, $mdDialog, $mdMedia, $mdToast, $timeout) {
this.$scope = $scope;
this.$peers = $peers;
this.delegateService = delegateService;
this.$mdDialog = $mdDialog;
this.$mdMedia = $mdMedia;
this.$mdToast = $mdToast;
Expand Down Expand Up @@ -43,7 +43,7 @@ app.component('delegates', {
updateAll() {
this.delegates = [];
this.delegatesDisplayedCount = 20;
this.$peers.listAccountDelegates({
this.delegateService.listAccountDelegates({
address: this.account.address,
}).then((data) => {
this.votedList = data.delegates || [];
Expand All @@ -56,7 +56,7 @@ app.component('delegates', {

loadDelegates(offset, search, replace) {
this.loading = true;
this.$peers.listDelegates({
this.delegateService.listDelegates({
offset,
limit: '100',
q: search,
Expand Down Expand Up @@ -142,9 +142,8 @@ app.component('delegates', {

checkPendingVotes() {
this.$timeout(() => {
this.$peers.listAccountDelegates({
address: this.account.address,
}).then((data) => {
this.delegateService.listAccountDelegates(this.account,
).then((data) => {
this.votedList = data.delegates || [];
this.votedDict = {};
(this.votedList).forEach((delegate) => {
Expand Down Expand Up @@ -217,8 +216,8 @@ app.component('delegates', {
this._selectDelegate(delegate, list);
} else {
this.pendingRequests++;
this.$peers.getDelegate({ username,
}).then((data) => {
this.delegateService.getDelegate(username,
).then((data) => {
this._selectDelegate(data.delegate, list);
}).catch(() => {
this.invalidUsernames.push(username);
Expand Down Expand Up @@ -255,7 +254,7 @@ app.component('delegates', {
}
},
template:
'<md-dialog>' +
'<md-dialog flex="80">' +
'<vote account="account" passphrase="passphrase" ' +
'vote-list="voteList" unvote-list="unvoteList">' +
'</vote>' +
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/delegates/delegates.pug
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ div.offline-hide
i.material-icons list
span Input Names
md-menu.pull-right.right-action-buttons
md-button.pull-right(ng-click='$mdOpenMenu()', ng-disabled='$ctrl.votedList.length == 0')
md-button.pull-right(ng-click='$mdOpenMenu()')
i.material-icons visibility
span My votes ({{$ctrl.votedList.length}})
md-menu-content(width='4')
Expand Down
22 changes: 17 additions & 5 deletions src/app/components/delegates/vote.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,32 @@ app.component('vote', {
unvoteList: '=',
},
controller: class vote {
constructor($scope, $mdDialog, $mdToast, $peers) {
constructor($scope, $mdDialog, $mdToast, delegateService) {
this.$mdDialog = $mdDialog;
this.$mdToast = $mdToast;
this.$peers = $peers;
this.delegateService = delegateService;

this.votedDict = {};
this.votedList = [];

this.delegateService.listAccountDelegates({
address: this.account.address,
}).then((data) => {
this.votedList = data.delegates || [];
this.votedList.forEach((delegate) => {
this.votedDict[delegate.username] = delegate;
});
});
}

vote() {
this.votingInProgress = true;
this.$peers.sendRequestPromise('accounts/delegates', {
this.delegateService.vote({
secret: this.passphrase,
publicKey: this.account.publicKey,
secondSecret: this.secondPassphrase,
delegates: this.voteList.map(delegate => `+${delegate.publicKey}`).concat(
this.unvoteList.map(delegate => `-${delegate.publicKey}`)),
voteList: this.voteList,
unvoteList: this.unvoteList,
}).then(() => {
this.$mdDialog.hide(this.voteList, this.unvoteList);
const toast = this.$mdToast.simple();
Expand Down
25 changes: 0 additions & 25 deletions src/app/components/delegates/vote.less
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,4 @@
float: right;
}

.remove-button {
float: right;
position: absolute;
right: 4px;
top: 4px;

.material-icons {
vertical-align: inherit;
}
}

.vote-list-item {
margin: 0 -24px;
}
.vote-list-item .md-list-item-inner {
padding: 0 8px;
}

.vote-list-item:hover {
cursor: pointer;

.remove-button {
color: #c62828;
}
}
}
28 changes: 12 additions & 16 deletions src/app/components/delegates/vote.pug
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ div.dialog-vote(aria-label='Vote for delegates')
h2 Vote for delegates
md-dialog-content
.md-dialog-content
div(ng-if='$ctrl.voteList.length')
h4 Add vote to:
md-list
md-list-item.vote-list-item(ng-repeat='delegate in $ctrl.voteList', ng-click='$ctrl.removeVote($ctrl.voteList, $index)')
div
span {{delegate.username}}
md-button.md-icon-button.remove-button(ng-click='$ctrl.removeVote($ctrl.voteList, $index)')
i.material-icons close
div
h4 Add vote to
md-chips(ng-model='$ctrl.voteList', md-require-match='true', md-max-chips='33', md-autocomplete-snap)
md-chip-template {{$chip.username}}
md-autocomplete(flex, required, md-input-minlength='2', md-no-cache='false', md-selected-item='$ctrl.selectedVoteDelegate', md-search-text='$ctrl.voteSearchText', md-items='delegate in $ctrl.delegateService.voteAutocomplete($ctrl.voteSearchText, $ctrl.votedDict)', md-item-text='delegate.username', md-require-match, placeholder='Search by username')
span(md-highlight-text='$ctrl.voteSearchText') {{delegate.username}}
md-divider(ng-if='$ctrl.voteList.length && $ctrl.unvoteList.length')
div(ng-if='$ctrl.unvoteList.length')
h4 Remove vote from:
md-list
md-list-item.vote-list-item(ng-repeat='delegate in $ctrl.unvoteList', ng-click='$ctrl.removeVote($ctrl.unvoteList, $index)')
div
span {{delegate.username}}
md-button.md-icon-button.remove-button(ng-click='$ctrl.removeVote($ctrl.unvoteList, $index)')
i.material-icons close
div
h4 Remove vote from
md-chips(ng-model='$ctrl.unvoteList', md-require-match='true', md-max-chips='33')
md-chip-template {{$chip.username}}
md-autocomplete(flex, required, md-input-minlength='2', md-no-cache='false', md-selected-item='$ctrl.selectedUnvoteDelegate', md-search-text='$ctrl.unvoteSearchText', md-items='delegate in $ctrl.delegateService.unvoteAutocomplete($ctrl.unvoteSearchText, $ctrl.votedList)', md-item-text='delegate.username', md-require-match, placeholder='Search by username')
span(md-highlight-text='$ctrl.unvoteSearchText') {{delegate.username}}
p.pull-right Fee: 1 LSK
md-divider
div(layout='row')
Expand Down
1 change: 1 addition & 0 deletions src/app/lisk-nano.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ import './services/success';
import './services/error';
import './services/passphrase';
import './services/sign-verify';
import './services/delegateService';

import './filters/lsk';
35 changes: 35 additions & 0 deletions src/app/services/delegateService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
app.factory('delegateService', $peers => ({
listAccountDelegates(options) {
return $peers.sendRequestPromise('accounts/delegates', options);
},

listDelegates(options) {
return $peers.sendRequestPromise(`delegates/${options.q ? 'search' : ''}`, options);
},

getDelegate(options) {
return $peers.sendRequestPromise('delegates/get', options);
},

vote(options) {
return $peers.sendRequestPromise('accounts/delegates', {
secret: options.secret,
publicKey: options.publicKey,
secondSecret: options.secondSecret,
delegates: options.voteList.map(delegate => `+${delegate.publicKey}`).concat(
options.unvoteList.map(delegate => `-${delegate.publicKey}`),
),
});
},

voteAutocomplete(username, votedDict) {
return this.listDelegates({ q: username }).then(
response => response.delegates.filter(d => !votedDict[d.username]),
);
},

unvoteAutocomplete(username, votedList) {
return votedList.filter(delegate => delegate.username.indexOf(username) !== -1);
},
}));

12 changes: 0 additions & 12 deletions src/app/services/peers/peers.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,6 @@ app.factory('$peers', ($timeout, $cookies, $location, $q) => {
return deferred.promise;
}

listAccountDelegates(urlParams) {
return this.sendRequestPromise('accounts/delegates', urlParams);
}

listDelegates(urlParams) {
return this.sendRequestPromise(`delegates/${urlParams.q ? 'search' : ''}`, urlParams);
}

getDelegate(urlParams) {
return this.sendRequestPromise('delegates/get', urlParams);
}

listTransactions(address, limit, offset) {
return this.sendRequestPromise('transactions', {
senderId: address,
Expand Down
10 changes: 5 additions & 5 deletions src/test/components/delegates/delegates.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,10 @@ describe('delegates component controller', () => {
});

describe('parseVoteListFromInput(list)', () => {
let peersMock;
let delegateServiceMock;

beforeEach(() => {
peersMock = sinon.mock(controller.$peers);
delegateServiceMock = sinon.mock(controller.delegateService);
});

it('parses this.usernameInput to list of delegates and opens vote dialog if all delegates were immediately resolved', () => {
Expand All @@ -257,7 +257,7 @@ describe('delegates component controller', () => {
it('parses this.usernameInput to list of delegates and opens vote dialog if all delegates were resolved immediately or from server', () => {
const username = 'not_fetched_yet';
const deffered = $q.defer();
peersMock.expects('sendRequestPromise').withArgs('delegates/get', { username }).returns(deffered.promise);
delegateServiceMock.expects('getDelegate').withArgs(username).returns(deffered.promise);
const spy = sinon.spy(controller, 'openVoteDialog');
controller.usernameInput = `${username}\ngenesis_42\ngenesis_46`;

Expand All @@ -276,7 +276,7 @@ describe('delegates component controller', () => {
it('parses this.usernameInput to list of delegates and opens vote dialog if any delegates were resolved', () => {
const username = 'invalid_name';
const deffered = $q.defer();
peersMock.expects('sendRequestPromise').withArgs('delegates/get', { username }).returns(deffered.promise);
delegateServiceMock.expects('getDelegate').withArgs(username).returns(deffered.promise);
const spy = sinon.spy(controller, 'openVoteDialog');
controller.usernameInput = `${username}\ngenesis_42\ngenesis_46`;

Expand All @@ -290,7 +290,7 @@ describe('delegates component controller', () => {
it('parses this.usernameInput to list of delegates and shows error toast if no delegates were resolved', () => {
const username = 'invalid_name';
const deffered = $q.defer();
peersMock.expects('sendRequestPromise').withArgs('delegates/get', { username }).returns(deffered.promise);
delegateServiceMock.expects('getDelegate').withArgs(username).returns(deffered.promise);
const toastSpy = sinon.spy(controller.$mdToast, 'show');
const dialogSpy = sinon.spy(controller, 'openVoteDialog');
controller.usernameInput = username;
Expand Down
15 changes: 8 additions & 7 deletions src/test/components/delegates/vote.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,20 @@ describe('Vote component controller', () => {
let $scope;
let controller;
let $componentController;
let peersMock;
let $peers;
let delegateServiceMock;
let delegateService;
let $q;

beforeEach(inject((_$componentController_, _$rootScope_, _$peers_, _$q_) => {
beforeEach(inject((_$componentController_, _$rootScope_, _delegateService_, _$q_) => {
$componentController = _$componentController_;
$rootScope = _$rootScope_;
$peers = _$peers_;
delegateService = _delegateService_;
$q = _$q_;
}));

beforeEach(() => {
peersMock = sinon.mock($peers);
delegateServiceMock = sinon.mock(delegateService);
delegateServiceMock.expects('listAccountDelegates').returns($q.defer().promise);

$scope = $rootScope.$new();
controller = $componentController('vote', $scope, {
Expand Down Expand Up @@ -100,14 +101,14 @@ describe('Vote component controller', () => {

beforeEach(() => {
deffered = $q.defer();
peersMock.expects('sendRequestPromise').withArgs('accounts/delegates').returns(deffered.promise);
delegateServiceMock.expects('vote').returns(deffered.promise);
mdToastMock = sinon.mock(controller.$mdToast);
mdToastMock.expects('show');
});

afterEach(() => {
mdToastMock.verify();
peersMock.verify();
delegateServiceMock.verify();
});

it('shows an error $mdToast if request fails', () => {
Expand Down
Loading

0 comments on commit 4c09077

Please sign in to comment.