PERF: Paginate public polls.

This commit is contained in:
Guo Xiang Tan
2016-06-09 21:33:17 +08:00
parent e66c51fd85
commit a36203ff78
15 changed files with 102 additions and 91 deletions

View File

@@ -3,29 +3,14 @@ import User from 'discourse/models/user';
import PollVoters from 'discourse/plugins/poll/components/poll-voters';
export default PollVoters.extend({
@computed("pollsVoters", "poll.options", "showMore", "isExpanded", "numOfVotersToShow")
users(pollsVoters, options, showMore, isExpanded, numOfVotersToShow) {
var users = [];
var voterIds = [];
const shouldLimit = showMore && !isExpanded;
options.forEach(option => {
option.voter_ids.forEach(voterId => {
if (shouldLimit) {
if (!(users.length > numOfVotersToShow - 1)) {
users.push(pollsVoters[voterId]);
}
} else {
users.push(pollsVoters[voterId]);
}
})
});
return users;
@computed("poll.voters", "pollsVoters")
canLoadMore(voters, pollsVoters) {
return pollsVoters.length < voters;
},
@computed("pollsVoters", "numOfVotersToShow")
showMore(pollsVoters, numOfVotersToShow) {
return !(Object.keys(pollsVoters).length < numOfVotersToShow);
@computed("poll.options", "offset")
voterIds(options) {
const ids = [].concat(...(options.map(option => option.voter_ids)));
return this._getIds(ids);
}
});

View File

@@ -2,8 +2,6 @@ import round from "discourse/lib/round";
import computed from 'ember-addons/ember-computed-decorators';
export default Em.Component.extend({
tagName: "span",
@computed("poll.options.@each.{html,votes}")
totalScore() {
return _.reduce(this.get("poll.options"), function(total, o) {

View File

@@ -3,23 +3,13 @@ import User from 'discourse/models/user';
import PollVoters from 'discourse/plugins/poll/components/poll-voters';
export default PollVoters.extend({
@computed("pollsVoters", "option.voter_ids", "showMore", "isExpanded", "numOfVotersToShow")
users(pollsVoters, voterIds, showMore, isExpanded, numOfVotersToShow) {
var users = [];
if (showMore && !isExpanded) {
voterIds = voterIds.slice(0, numOfVotersToShow);
}
voterIds.forEach(voterId => {
users.push(pollsVoters[voterId]);
});
return users;
@computed("option.votes", "pollsVoters")
canLoadMore(voters, pollsVoters) {
return pollsVoters.length < voters;
},
@computed("option.votes", "numOfVotersToShow")
showMore(numOfVotes, numOfVotersToShow) {
return !(numOfVotes < numOfVotersToShow);
@computed("option.voter_ids", "offset")
voterIds(ids) {
return this._getIds(ids);
}
});

View File

@@ -3,11 +3,51 @@ export default Ember.Component.extend({
tagName: 'ul',
classNames: ["poll-voters-list"],
isExpanded: false,
numOfVotersToShow: 20,
numOfVotersToShow: 0,
offset: 0,
loading: false,
pollsVoters: null,
init() {
this._super();
this.set("pollsVoters", []);
},
_fetchUsers() {
this.set("loading", true);
Discourse.ajax("/polls/voters.json", {
type: "get",
data: { user_ids: this.get("voterIds") }
}).then(result => {
if (this.isDestroyed) return;
this.set("pollsVoters", this.get("pollsVoters").concat(result.users));
this.incrementProperty("offset");
this.set("loading", false);
}).catch((error) => {
Ember.logger.log(error);
bootbox.alert(I18n.t('poll.error_while_fetching_voters'));
});
},
_getIds(ids) {
const numOfVotersToShow = this.get("numOfVotersToShow");
const offset = this.get("offset");
return ids.slice(numOfVotersToShow * offset, numOfVotersToShow * (offset + 1));
},
didInsertElement() {
this._super();
Ember.run.schedule("afterRender", () => {
this.set("numOfVotersToShow", Math.round(this.$().width() / 25) * 2);
if (this.get("voterIds").length > 0) this._fetchUsers();
});
},
actions: {
toggleExpand() {
this.toggleProperty("isExpanded");
loadMore() {
this._fetchUsers();
}
}
});

View File

@@ -6,7 +6,6 @@ export default Ember.Controller.extend({
isRandom : Ember.computed.equal("poll.order", "random"),
isClosed: Ember.computed.equal("poll.status", "closed"),
isPublic: Ember.computed.equal("poll.public", "true"),
pollsVoters: Ember.computed.alias("post.polls_voters"),
// shows the results when
// - poll is closed
@@ -152,10 +151,6 @@ export default Ember.Controller.extend({
this.setProperties({ vote: votes, showResults: true });
this.set("model", Em.Object.create(poll));
if (poll.public) {
this.get("pollsVoters")[currentUser.get("id")] = currentUser;
}
}).catch(() => {
bootbox.alert(I18n.t("poll.error_while_casting_votes"));
}).finally(() => {

View File

@@ -1,5 +1,7 @@
{{{averageRating}}}
<div class="poll-results-number-rating">
{{{averageRating}}}
</div>
{{#if poll.public}}
{{poll-results-number-voters poll=poll pollsVoters=pollsVoters}}
{{poll-results-number-voters poll=poll}}
{{/if}}

View File

@@ -11,7 +11,7 @@
</div>
{{#if poll.public}}
{{poll-results-standard-voters option=option pollsVoters=pollsVoters}}
{{poll-results-standard-voters option=option}}
{{/if}}
</li>
{{/each}}

View File

@@ -1,5 +1,5 @@
<div class="poll-voters">
{{#each users as |user|}}
{{#each pollsVoters as |user|}}
<li>
<a data-user-card={{unbound user.username}}>
{{avatar user imageSize="tiny" ignoreTitle="true"}}
@@ -8,12 +8,10 @@
{{/each}}
<div class="poll-voters-toggle-expand">
{{#if showMore}}
{{#if isExpanded}}
<a {{action "toggleExpand"}}>{{fa-icon "chevron-up"}}</a>
{{else}}
<a {{action "toggleExpand"}}>{{fa-icon "chevron-down"}}</a>
{{/if}}
{{#if canLoadMore}}
{{#conditional-loading-spinner condition=loading size="small"}}
<a {{action "loadMore"}}>{{fa-icon "chevron-down"}}</a>
{{/conditional-loading-spinner}}
{{/if}}
</div>
</div>

View File

@@ -2,9 +2,9 @@
<div class="poll-container">
{{#if showingResults}}
{{#if isNumber}}
{{poll-results-number poll=poll pollsVoters=pollsVoters}}
{{poll-results-number poll=poll}}
{{else}}
{{poll-results-standard poll=poll pollsVoters=pollsVoters}}
{{poll-results-standard poll=poll}}
{{/if}}
{{else}}
<ul>

View File

@@ -29,10 +29,6 @@ function initializePolls(api) {
const post = this.get('model.postStream').findLoadedPost(msg.post_id);
if (post) {
post.set('polls', msg.polls);
if (msg.user) {
post.set(`polls_voters.${msg.user.id}`, msg.user);
}
}
});
},
@@ -80,7 +76,6 @@ function initializePolls(api) {
const post = helper.getModel();
api.preventCloak(post.id);
const votes = post.get('polls_votes') || {};
post.set("polls_voters", (post.get("polls_voters") || {}));
post.pollsChanged();