diff --git a/app/controllers/index.js b/app/controllers/index.js index 764a620..6e60243 100644 --- a/app/controllers/index.js +++ b/app/controllers/index.js @@ -6,15 +6,6 @@ import injectService from 'ember-service/inject'; export default Controller.extend({ kredits: injectService(), - init() { - this._super(...arguments); - let contract = this.get('kredits.kredits').Operator.contract; - contract.onproposalvoted = this._handleProposalVoted.bind(this); - contract.onproposalcreated = this._handleProposalCreated.bind(this); - contract.onproposalexecuted = this._handleProposalExecuted.bind(this); - // TODO: transfer on the token contract - }, - contributors: alias('kredits.contributors'), contributorsWithKredits: filter('contributors', function(contributor) { return contributor.get('balance') !== 0; @@ -29,54 +20,6 @@ export default Controller.extend({ proposalsClosedSorted: sort('proposalsClosed', 'proposalsSorting'), proposalsOpenSorted: sort('proposalsOpen', 'proposalsSorting'), - _handleProposalCreated(proposalId) { - // TODO: check if proposalId is already a string - let proposal = this.get('proposals') - .findBy('id', proposalId.toString()); - if (proposal) { - Ember.Logger.debug('[index] proposal exists, not adding from event'); - return; - } - - proposal = this.get('kredits.kredits').Operator.getById(proposalId); - this.get('proposals').pushObject(proposal); - }, - - _handleProposalExecuted(proposalId, contributorId, amount) { - let proposal = this.get('proposals') - .findBy('id', proposalId); - - if (proposal.get('isExecuted')) { - Ember.Logger.debug('[index] proposal already executed, not adding from event'); - return; - } - - proposal.setProperties({ - 'executed': true, - }); - - this.get('contributors') - .findBy('id', contributorId) - .incrementProperty('balance', amount); - }, - - _handleProposalVoted(proposalId, voter, totalVotes) { - this.get('proposals') - .findBy('id', proposalId) - .setProperties({ 'votesCount': totalVotes }); - }, - - _handleTransfer(from, to, value) { - value = value.toNumber(); - this.get('contributors') - .findBy('address', from) - .decrementProperty('balance', value); - this.get('contributors') - .findBy('address', to) - .incrementProperty('balance', value); - }, - - actions: { confirmProposal(proposalId) { this.get('kredits').vote(proposalId).then(transaction => { diff --git a/app/lib/kredits/contracts/base.js b/app/lib/kredits/contracts/base.js index a7a35aa..c54ca22 100644 --- a/app/lib/kredits/contracts/base.js +++ b/app/lib/kredits/contracts/base.js @@ -7,4 +7,11 @@ export default class Base { return this.contract.functions; } + on(type, callback) { + let eventMethod = `on${type.toLowerCase()}`; + // Don't use this.contract.events here. Seems to be a bug in ethers.js + this.contract[eventMethod] = callback; + + return this; + } } diff --git a/app/services/kredits.js b/app/services/kredits.js index cc25378..5100470 100644 --- a/app/services/kredits.js +++ b/app/services/kredits.js @@ -88,6 +88,22 @@ export default Service.extend({ }).then(({ contributors, proposals }) => { this.set('contributors', contributors); this.set('proposals', proposals); + }).then(() => { + this.get('kredits').Operator + .on('ProposalCreated', (proposalId) => { + this.handleProposalCreated(proposalId); + }) + .on('ProposalVoted', (proposalId, voter, totalVotes) => { + this.handleProposalVoted(proposalId, totalVotes); + }) + .on('ProposalExecuted', (proposalId, contributorId, amount) => { + this.handleProposalExecuted(proposalId, contributorId, amount); + }); + + this.get('kredits').Token + .on('Transfer', (from, to, value) => { + this.handleTransfer(from, to, value); + }); }); }, @@ -169,5 +185,60 @@ export default Service.extend({ return this.get('kredits').Contributor.getById(id); } }); - }) + }), + + findProposalById(proposalId) { + return this.get('proposals').findBy('id', proposalId.toString()); + }, + + // Contract events + handleProposalCreated(proposalId) { + let proposal = this.findProposalById(proposalId); + + if (proposal) { + debug('[events] proposal exists, not adding from event'); + return; + } + + this.get('kredits').Operator.getById(proposalId) + .then((proposal) => { + this.get('proposals').pushObject(proposal); + }); + }, + + // TODO: We may want to reload that proposal to show the voter as voted + handleProposalVoted(proposalId, totalVotes) { + let proposal = this.findProposalById(proposalId); + + if (proposal) { + proposal.set('votesCount', totalVotes); + } + }, + + handleProposalExecuted(proposalId, contributorId, amount) { + let proposal = this.findProposalById(proposalId); + + if (proposal.get('isExecuted')) { + debug('[events] proposal already executed, not adding from event'); + return; + } + + proposal.set('executed', true); + + this.get('contributors') + .findBy('id', contributorId.toString()) + .incrementProperty('balance', amount); + }, + + handleTransfer(from, to, value) { + value = value.toNumber(); + + this.get('contributors') + .findBy('address', from) + .decrementProperty('balance', value); + + this.get('contributors') + .findBy('address', to) + .incrementProperty('balance', value); + }, }); diff --git a/tests/unit/controllers/index-test.js b/tests/unit/controllers/index-test.js index 827d256..bbc749f 100644 --- a/tests/unit/controllers/index-test.js +++ b/tests/unit/controllers/index-test.js @@ -23,12 +23,7 @@ let addFixtures = function(controller) { }; test('doesn\'t contain people with 0 balance', function(assert) { - // This is a bit strange... we do not want the controller to call the init function defined in the controller that - // initializes the event handlers on the contracts. Main reason is that we do not have proper contracts in test mode. - // this seems to work. but probably kills some controller stuff, which is fine in this test - let controller = this.subject({ - init: function() { } - }); + let controller = this.subject(); addFixtures(controller); let contributorsSorted = controller.get('contributorsSorted');