WIP Sync contributions

This commit is contained in:
2020-05-29 13:13:21 +02:00
parent eb2c613ac9
commit 63dd5430bc
12 changed files with 129 additions and 32 deletions
@@ -29,7 +29,7 @@
</div> </div>
{{/if}} {{/if}}
<ul class="contribution-list"> <ul class="contribution-list {{if @loading 'loading'}}">
{{#each this.contributionsFiltered as |contribution|}} {{#each this.contributionsFiltered as |contribution|}}
<li role="button" data-contribution-id={{contribution.id}} <li role="button" data-contribution-id={{contribution.id}}
{{action "openContributionDetails" contribution}} {{action "openContributionDetails" contribution}}
+1 -4
View File
@@ -2,12 +2,10 @@ import Component from '@ember/component';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
export default Component.extend({ export default Component.extend({
tagName: '',
router: service(), router: service(),
tagName: 'table',
classNames: 'contributor-list',
selectedContributorId: null, selectedContributorId: null,
actions: { actions: {
@@ -17,5 +15,4 @@ export default Component.extend({
} }
} }
}); });
+25 -21
View File
@@ -1,21 +1,25 @@
<tbody> <table class="contributor-list {{if @loading 'loading'}}">
{{#each @contributorList as |c|}} <thead>
<tr role="button" </thead>
onclick={{action "openContributorDetails" c.contributor}} <tbody>
class="{{if (is-current-user c.contributor) "current-user"}} {{if (eq c.contributor.id @selectedContributorId) "selected"}}"> {{#each @contributorList as |c|}}
<td class="person"> <tr role="button"
<UserAvatar @contributor={{c.contributor}} /> {{c.contributor.name}} onclick={{action "openContributorDetails" c.contributor}}
</td> class="{{if (is-current-user c.contributor) "current-user"}} {{if (eq c.contributor.id @selectedContributorId) "selected"}}">
<td class="kredits"> <td class="person">
<span class="amount"> <UserAvatar @contributor={{c.contributor}} /> {{c.contributor.name}}
{{#if @showUnconfirmedKredits}} </td>
{{c.amountTotal}} <td class="kredits">
{{else}} <span class="amount">
{{c.amountConfirmed}} {{#if @showUnconfirmedKredits}}
{{/if}} {{c.amountTotal}}
</span> {{else}}
<span class="symbol">₭S</span> {{c.amountConfirmed}}
</td> {{/if}}
</tr> </span>
{{/each}} <span class="symbol">₭S</span>
</tbody> </td>
</tr>
{{/each}}
</tbody>
</table>
+4 -2
View File
@@ -25,9 +25,11 @@ export default Route.extend({
}) })
.then(() => { .then(() => {
if (this.kredits.contributorsNeedFetch) { if (this.kredits.contributorsNeedFetch) {
schedule('afterRender', this.kredits, this.kredits.fetchContributors); schedule('afterRender', this.kredits.syncContributors,
this.kredits.syncContributors.perform);
} }
schedule('afterRender', this.kredits, this.kredits.fetchContributions); schedule('afterRender', this.kredits.syncContributions,
this.kredits.syncContributions.perform);
}); });
} }
}); });
+44 -1
View File
@@ -8,6 +8,8 @@ import { alias, notEmpty } from '@ember/object/computed';
import { isEmpty, isPresent } from '@ember/utils'; import { isEmpty, isPresent } from '@ember/utils';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';
import groupBy from 'kredits-web/utils/group-by'; import groupBy from 'kredits-web/utils/group-by';
import processContributorData from 'kredits-web/utils/process-contributor-data'; import processContributorData from 'kredits-web/utils/process-contributor-data';
import processContributionData from 'kredits-web/utils/process-contribution-data'; import processContributionData from 'kredits-web/utils/process-contribution-data';
@@ -240,6 +242,7 @@ export default Service.extend({
const loadedContributor = this.contributors.findBy('id', contributor.id); const loadedContributor = this.contributors.findBy('id', contributor.id);
if (loadedContributor) { this.contributors.removeObject(loadedContributor); } if (loadedContributor) { this.contributors.removeObject(loadedContributor); }
this.contributors.pushObject(contributor); this.contributors.pushObject(contributor);
return contributor;
}, },
async cacheLoadedContributors () { async cacheLoadedContributors () {
@@ -258,6 +261,10 @@ export default Service.extend({
}); });
}, },
syncContributors: task(function * () {
yield this.fetchContributors();
}),
addContribution (attributes) { addContribution (attributes) {
console.debug('[kredits] add contribution', attributes); console.debug('[kredits] add contribution', attributes);
@@ -278,7 +285,7 @@ export default Service.extend({
return this.kredits.Contribution.all(options) return this.kredits.Contribution.all(options)
.then(contributions => { .then(contributions => {
return contributions.map(data => { return contributions.map(data => {
loadContributionFromData(data); const contribution = this.loadContributionFromData(data);
return contribution; return contribution;
}); });
}) })
@@ -298,6 +305,7 @@ export default Service.extend({
const loadedContribution = this.contributions.findBy('id', contribution.id); const loadedContribution = this.contributions.findBy('id', contribution.id);
if (loadedContribution) { this.contributions.removeObject(loadedContribution); } if (loadedContribution) { this.contributions.removeObject(loadedContribution); }
this.contributions.pushObject(contribution); this.contributions.pushObject(contribution);
return contribution;
}, },
async cacheLoadedContributions () { async cacheLoadedContributions () {
@@ -316,6 +324,41 @@ export default Service.extend({
}); });
}, },
syncContributions: task(function * () {
yield this.fetchNewContributions.perform();
yield this.syncUnconfirmedContributions.perform();
}),
fetchNewContributions: task(function * () {
const count = yield this.kredits.Contribution.functions.contributionsCount();
const lastKnownContributionId = Math.max.apply(null, this.contributions.mapBy('id'));
const toFetch = count - lastKnownContributionId;
if (toFetch > 0) {
console.debug(`[kredits] Fetching ${toFetch} new contributions`);
for (let id = lastKnownContributionId; id <= count; id++) {
const data = yield this.kredits.Contribution.getById(id);
const c = this.loadContributionFromData(data);
yield this.browserCache.contributions.setItem(c.id.toString(), c.serialize());
}
} else {
console.debug(`[kredits] No new contributions to fetch`);
}
}),
syncUnconfirmedContributions: task(function * () {
if (this.contributionsUnconfirmed.length > 0) {
console.debug(`[kredits] Syncing unconfirmed contributions`);
for (const c of this.contributionsUnconfirmed) {
const data = yield this.kredits.Contribution.getById(c.id);
const contribution = this.loadContributionFromData(data);
yield this.browserCache.contributions.setItem(c.id.toString(), contribution.serialize());
}
} else {
console.debug(`[kredits] No unconfirmed contributions to sync`);
}
}),
veto (contributionId) { veto (contributionId) {
console.debug('[kredits] veto against', contributionId); console.debug('[kredits] veto against', contributionId);
const contribution = this.contributions.findBy('id', contributionId); const contribution = this.contributions.findBy('id', contributionId);
+17
View File
@@ -0,0 +1,17 @@
@mixin loading-border-top {
&::before {
display: block;
width: 100%;
height: 1px;
content: '';
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 40%, #68d7fb 60%, rgba(255, 255, 255, 0.2));
background-size: 200% 200%;
animation: kitt 2.5s linear infinite;
}
}
@keyframes kitt {
0%{ background-position: 0% 0%}
50%{ background-position: 100% 0%}
100%{ background-position: 0% 0%}
}
+1
View File
@@ -88,6 +88,7 @@ section {
@import "buttons"; @import "buttons";
@import "forms"; @import "forms";
@import "sugar";
@import "components/contribution-list"; @import "components/contribution-list";
@import "components/contribution-details"; @import "components/contribution-details";
@@ -114,4 +114,13 @@ ul.contribution-list {
} }
} }
&.loading {
@include loading-border-top;
li {
&:first-of-type {
border-top: none;
}
}
}
} }
@@ -1,4 +1,5 @@
table.contributor-list { table.contributor-list {
position: relative;
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
@@ -48,4 +49,11 @@ table.contributor-list {
} }
} }
} }
&.loading {
@include loading-border-top;
&::before {
position: absolute;
}
}
} }
+7 -3
View File
@@ -29,7 +29,8 @@
<div class="content"> <div class="content">
<ContributorList @contributorList={{this.kreditsToplist}} <ContributorList @contributorList={{this.kreditsToplist}}
@showUnconfirmedKredits={{this.showUnconfirmedKredits}} @showUnconfirmedKredits={{this.showUnconfirmedKredits}}
@selectedContributorId={{this.selectedContributorId}} /> @selectedContributorId={{this.selectedContributorId}}
@loading={{this.kredits.syncContributors.isRunning}} />
<p class="stats"> <p class="stats">
<span class="number">{{await this.kredits.totalKreditsEarned}}</span> kredits confirmed and issued to <span class="number">{{await this.kredits.totalKreditsEarned}}</span> kredits confirmed and issued to
@@ -58,7 +59,9 @@
{{#if this.contributionsUnconfirmed}} {{#if this.contributionsUnconfirmed}}
<section id="contributions-unconfirmed"> <section id="contributions-unconfirmed">
<header class="with-nav"> <header class="with-nav">
<h2>Latest Contributions</h2> <h2>
Latest Contributions
</h2>
<nav> <nav>
<button type="button" <button type="button"
onclick={{action "toggleQuickFilterUnconfirmed"}} onclick={{action "toggleQuickFilterUnconfirmed"}}
@@ -78,7 +81,8 @@
@vetoContribution={{action "vetoContribution"}} @vetoContribution={{action "vetoContribution"}}
@contractInteractionEnabled={{this.kredits.hasAccounts}} @contractInteractionEnabled={{this.kredits.hasAccounts}}
@selectedContributionId={{this.selectedContributionId}} @selectedContributionId={{this.selectedContributionId}}
@showQuickFilter={{this.showQuickFilterUnconfirmed}} /> @showQuickFilter={{this.showQuickFilterUnconfirmed}}
@loading={{this.kredits.syncContributions.isRunning}}/>
</div> </div>
</section> </section>
{{/if}} {{/if}}
+11
View File
@@ -10259,6 +10259,17 @@
"semver": "^5.4.1" "semver": "^5.4.1"
} }
}, },
"ember-concurrency": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/ember-concurrency/-/ember-concurrency-1.1.7.tgz",
"integrity": "sha512-PtEJvB4wG8e5CEHRC9ILl2BxF6U/xlMOhfCji/x7FxNFB9M230Du86LAy+4/yOozZHyoARVuazABPUj02P+DmQ==",
"dev": true,
"requires": {
"ember-cli-babel": "^7.7.3",
"ember-compatibility-helpers": "^1.2.0",
"ember-maybe-import-regenerator": "^0.1.6"
}
},
"ember-diff-attrs": { "ember-diff-attrs": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/ember-diff-attrs/-/ember-diff-attrs-0.2.2.tgz", "resolved": "https://registry.npmjs.org/ember-diff-attrs/-/ember-diff-attrs-0.2.2.tgz",
+1
View File
@@ -47,6 +47,7 @@
"ember-cli-sass": "^10.0.1", "ember-cli-sass": "^10.0.1",
"ember-cli-sri": "^2.1.1", "ember-cli-sri": "^2.1.1",
"ember-cli-uglify": "^3.0.0", "ember-cli-uglify": "^3.0.0",
"ember-concurrency": "^1.1.7",
"ember-export-application-global": "^2.0.1", "ember-export-application-global": "^2.0.1",
"ember-fetch": "^8.0.1", "ember-fetch": "^8.0.1",
"ember-flatpickr": "^2.16.2", "ember-flatpickr": "^2.16.2",