UX: disable 'Hide results' button when poll is closed
This commit is contained in:
parent
e211bf7d0b
commit
cc75890cd4
|
@ -107,21 +107,21 @@ const PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
|
|
||||||
// If it's the same topic as ours, build the URL from the topic object
|
// If it's the same topic as ours, build the URL from the topic object
|
||||||
if (topic && topic.get('id') === topicId) {
|
if (topic && topic.get('id') === topicId) {
|
||||||
navLink = "<a href='" + topic.urlForPostNumber(postNumber) + "' title='" + quoteTitle + "' class='back'></a>";
|
navLink = `<a href='${topic.urlForPostNumber(postNumber)}' title='${quoteTitle}' class='back'></a>`;
|
||||||
} else {
|
} else {
|
||||||
// Made up slug should be replaced with canonical URL
|
// Made up slug should be replaced with canonical URL
|
||||||
navLink = "<a href='" + Discourse.getURL("/t/via-quote/") + topicId + "/" + postNumber + "' title='" + quoteTitle + "' class='quote-other-topic'></a>";
|
navLink = `<a href='${Discourse.getURL("/t/via-quote/") + topicId + "/" + postNumber}' title='${quoteTitle}' class='quote-other-topic'></a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (topic = this.get('controller.content')) {
|
} else if (topic = this.get('controller.content')) {
|
||||||
// assume the same topic
|
// assume the same topic
|
||||||
navLink = "<a href='" + topic.urlForPostNumber(postNumber) + "' title='" + quoteTitle + "' class='back'></a>";
|
navLink = `<a href='${topic.urlForPostNumber(postNumber)}' title='${quoteTitle}' class='back'></a>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only add the expand/contract control if it's not a full post
|
// Only add the expand/contract control if it's not a full post
|
||||||
let expandContract = "";
|
let expandContract = "";
|
||||||
if (!$aside.data('full')) {
|
if (!$aside.data('full')) {
|
||||||
expandContract = "<i class='fa fa-" + desc + "' title='" + I18n.t("post.expand_collapse") + "'></i>";
|
expandContract = `<i class='fa fa-${desc}' title='${I18n.t("post.expand_collapse")}'></i>`;
|
||||||
$('.title', $aside).css('cursor', 'pointer');
|
$('.title', $aside).css('cursor', 'pointer');
|
||||||
}
|
}
|
||||||
$('.quote-controls', $aside).html(expandContract + navLink);
|
$('.quote-controls', $aside).html(expandContract + navLink);
|
||||||
|
@ -129,20 +129,18 @@ const PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
|
|
||||||
_toggleQuote($aside) {
|
_toggleQuote($aside) {
|
||||||
if (this.get('expanding')) { return; }
|
if (this.get('expanding')) { return; }
|
||||||
|
|
||||||
this.set('expanding', true);
|
this.set('expanding', true);
|
||||||
|
|
||||||
$aside.data('expanded', !$aside.data('expanded'));
|
$aside.data('expanded', !$aside.data('expanded'));
|
||||||
|
|
||||||
const self = this,
|
const finished = () => this.set('expanding', false);
|
||||||
finished = function() {
|
|
||||||
self.set('expanding', false);
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($aside.data('expanded')) {
|
if ($aside.data('expanded')) {
|
||||||
this._updateQuoteElements($aside, 'chevron-up');
|
this._updateQuoteElements($aside, 'chevron-up');
|
||||||
// Show expanded quote
|
// Show expanded quote
|
||||||
const $blockQuote = $('blockquote', $aside);
|
const $blockQuote = $('blockquote', $aside);
|
||||||
$aside.data('original-contents',$blockQuote.html());
|
$aside.data('original-contents', $blockQuote.html());
|
||||||
|
|
||||||
const originalText = $blockQuote.text().trim();
|
const originalText = $blockQuote.text().trim();
|
||||||
$blockQuote.html(I18n.t("loading"));
|
$blockQuote.html(I18n.t("loading"));
|
||||||
|
@ -154,7 +152,7 @@ const PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||||
const postId = parseInt($aside.data('post'), 10);
|
const postId = parseInt($aside.data('post'), 10);
|
||||||
topicId = parseInt(topicId, 10);
|
topicId = parseInt(topicId, 10);
|
||||||
|
|
||||||
Discourse.ajax("/posts/by_number/" + topicId + "/" + postId).then(function (result) {
|
Discourse.ajax(`/posts/by_number/${topicId}/${postId}`).then(result => {
|
||||||
const div = $("<div class='expanded-quote'></div>");
|
const div = $("<div class='expanded-quote'></div>");
|
||||||
div.html(result.cooked);
|
div.html(result.cooked);
|
||||||
div.highlight(originalText, {caseSensitive: true, element: 'span', className: 'highlighted'});
|
div.highlight(originalText, {caseSensitive: true, element: 'span', className: 'highlighted'});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
isMultiple: Ember.computed.equal("poll.type", "multiple"),
|
isMultiple: Ember.computed.equal("poll.type", "multiple"),
|
||||||
isNumber: Ember.computed.equal("poll.type", "number"),
|
isNumber: Ember.computed.equal("poll.type", "number"),
|
||||||
|
@ -11,12 +13,10 @@ export default Ember.Controller.extend({
|
||||||
showingResults: Em.computed.or("isClosed", "post.topic.closed", "post.topic.archived", "showResults"),
|
showingResults: Em.computed.or("isClosed", "post.topic.closed", "post.topic.archived", "showResults"),
|
||||||
|
|
||||||
showResultsDisabled: Em.computed.equal("poll.voters", 0),
|
showResultsDisabled: Em.computed.equal("poll.voters", 0),
|
||||||
hideResultsDisabled: Em.computed.alias("isClosed"),
|
hideResultsDisabled: Em.computed.or("isClosed", "post.topic.closed", "post.topic.archived"),
|
||||||
|
|
||||||
poll: function() {
|
|
||||||
const poll = this.get("model"),
|
|
||||||
vote = this.get("vote");
|
|
||||||
|
|
||||||
|
@computed("model", "vote")
|
||||||
|
poll(poll, vote) {
|
||||||
if (poll) {
|
if (poll) {
|
||||||
const options = _.map(poll.get("options"), o => Em.Object.create(o));
|
const options = _.map(poll.get("options"), o => Em.Object.create(o));
|
||||||
|
|
||||||
|
@ -28,44 +28,46 @@ export default Ember.Controller.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
return poll;
|
return poll;
|
||||||
}.property("model"),
|
},
|
||||||
|
|
||||||
selectedOptions: function() {
|
@computed("poll.options.@each.selected")
|
||||||
|
selectedOptions() {
|
||||||
return _.map(this.get("poll.options").filterBy("selected"), o => o.get("id"));
|
return _.map(this.get("poll.options").filterBy("selected"), o => o.get("id"));
|
||||||
}.property("poll.options.@each.selected"),
|
},
|
||||||
|
|
||||||
min: function() {
|
@computed("poll.min")
|
||||||
let min = parseInt(this.get("poll.min"), 10);
|
min(min) {
|
||||||
|
min = parseInt(min, 10);
|
||||||
if (isNaN(min) || min < 1) { min = 1; }
|
if (isNaN(min) || min < 1) { min = 1; }
|
||||||
return min;
|
return min;
|
||||||
}.property("poll.min"),
|
},
|
||||||
|
|
||||||
max: function() {
|
@computed("poll.max", "poll.options.length")
|
||||||
let options = this.get("poll.options.length"),
|
max(max, options) {
|
||||||
max = parseInt(this.get("poll.max"), 10);
|
max = parseInt(max, 10);
|
||||||
if (isNaN(max) || max > options) { max = options; }
|
if (isNaN(max) || max > options) { max = options; }
|
||||||
return max;
|
return max;
|
||||||
}.property("poll.max", "poll.options.length"),
|
},
|
||||||
|
|
||||||
votersText: function() {
|
@computed("poll.voters")
|
||||||
return I18n.t("poll.voters", { count: this.get("poll.voters") });
|
votersText(count) {
|
||||||
}.property("poll.voters"),
|
return I18n.t("poll.voters", { count });
|
||||||
|
},
|
||||||
|
|
||||||
totalVotes: function() {
|
@computed("poll.options.@each.votes")
|
||||||
|
totalVotes() {
|
||||||
return _.reduce(this.get("poll.options"), function(total, o) {
|
return _.reduce(this.get("poll.options"), function(total, o) {
|
||||||
return total + parseInt(o.get("votes"), 10);
|
return total + parseInt(o.get("votes"), 10);
|
||||||
}, 0);
|
}, 0);
|
||||||
}.property("poll.options.@each.votes"),
|
},
|
||||||
|
|
||||||
totalVotesText: function() {
|
@computed("totalVotes")
|
||||||
return I18n.t("poll.total_votes", { count: this.get("totalVotes") });
|
totalVotesText(count) {
|
||||||
}.property("totalVotes"),
|
return I18n.t("poll.total_votes", { count });
|
||||||
|
},
|
||||||
multipleHelpText: function() {
|
|
||||||
const options = this.get("poll.options.length"),
|
|
||||||
min = this.get("min"),
|
|
||||||
max = this.get("max");
|
|
||||||
|
|
||||||
|
@computed("min", "max", "poll.options.length")
|
||||||
|
multipleHelpText(min, max, options) {
|
||||||
if (max > 0) {
|
if (max > 0) {
|
||||||
if (min === max) {
|
if (min === max) {
|
||||||
if (min > 1) {
|
if (min > 1) {
|
||||||
|
@ -73,7 +75,7 @@ export default Ember.Controller.extend({
|
||||||
}
|
}
|
||||||
} else if (min > 1) {
|
} else if (min > 1) {
|
||||||
if (max < options) {
|
if (max < options) {
|
||||||
return I18n.t("poll.multiple.help.between_min_and_max_options", { min: min, max: max });
|
return I18n.t("poll.multiple.help.between_min_and_max_options", { min, max });
|
||||||
} else {
|
} else {
|
||||||
return I18n.t("poll.multiple.help.at_least_min_options", { count: min });
|
return I18n.t("poll.multiple.help.at_least_min_options", { count: min });
|
||||||
}
|
}
|
||||||
|
@ -81,33 +83,31 @@ export default Ember.Controller.extend({
|
||||||
return I18n.t("poll.multiple.help.up_to_max_options", { count: max });
|
return I18n.t("poll.multiple.help.up_to_max_options", { count: max });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.property("min", "max", "poll.options.length"),
|
},
|
||||||
|
|
||||||
canCastVotes: function() {
|
@computed("isClosed", "showResults", "loading", "isMultiple", "selectedOptions.length", "min", "max")
|
||||||
if (this.get("isClosed") || this.get("showingResults") || this.get("loading")) {
|
canCastVotes(isClosed, showResults, loading, isMultiple, selectedOptionCount, min, max) {
|
||||||
|
if (isClosed || showResults || loading) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedOptionCount = this.get("selectedOptions.length");
|
if (isMultiple) {
|
||||||
|
return selectedOptionCount >= min && selectedOptionCount <= max;
|
||||||
if (this.get("isMultiple")) {
|
|
||||||
return selectedOptionCount >= this.get("min") && selectedOptionCount <= this.get("max");
|
|
||||||
} else {
|
} else {
|
||||||
return selectedOptionCount > 0;
|
return selectedOptionCount > 0;
|
||||||
}
|
}
|
||||||
}.property("isClosed", "showingResults", "loading",
|
},
|
||||||
"selectedOptions.length",
|
|
||||||
"isMultiple", "min", "max"),
|
|
||||||
|
|
||||||
castVotesDisabled: Em.computed.not("canCastVotes"),
|
castVotesDisabled: Em.computed.not("canCastVotes"),
|
||||||
|
|
||||||
canToggleStatus: function() {
|
@computed("loading", "post.user_id", "post.topic.closed", "post.topic.archived")
|
||||||
|
canToggleStatus(loading, userId, topicClosed, topicArchived) {
|
||||||
return this.currentUser &&
|
return this.currentUser &&
|
||||||
(this.currentUser.get("id") === this.get("post.user_id") || this.currentUser.get("staff")) &&
|
(this.currentUser.get("id") === userId || this.currentUser.get("staff")) &&
|
||||||
!this.get("loading") &&
|
!loading &&
|
||||||
!this.get("post.topic.closed") &&
|
!topicClosed &&
|
||||||
!this.get("post.topic.archived");
|
!topicArchived;
|
||||||
}.property("loading", "post.user_id", "post.topic.{closed,archived}"),
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
|
@ -130,8 +130,6 @@ export default Ember.Controller.extend({
|
||||||
if (!this.get("canCastVotes")) { return; }
|
if (!this.get("canCastVotes")) { return; }
|
||||||
if (!this.currentUser) { return this.send("showLogin"); }
|
if (!this.currentUser) { return this.send("showLogin"); }
|
||||||
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
this.set("loading", true);
|
this.set("loading", true);
|
||||||
|
|
||||||
Discourse.ajax("/polls/vote", {
|
Discourse.ajax("/polls/vote", {
|
||||||
|
@ -141,13 +139,13 @@ export default Ember.Controller.extend({
|
||||||
poll_name: this.get("poll.name"),
|
poll_name: this.get("poll.name"),
|
||||||
options: this.get("selectedOptions"),
|
options: this.get("selectedOptions"),
|
||||||
}
|
}
|
||||||
}).then(function(results) {
|
}).then(results => {
|
||||||
self.setProperties({ vote: results.vote, showResults: true });
|
this.setProperties({ vote: results.vote, showResults: true });
|
||||||
self.set("model", Em.Object.create(results.poll));
|
this.set("model", Em.Object.create(results.poll));
|
||||||
}).catch(function() {
|
}).catch(() => {
|
||||||
bootbox.alert(I18n.t("poll.error_while_casting_votes"));
|
bootbox.alert(I18n.t("poll.error_while_casting_votes"));
|
||||||
}).finally(function() {
|
}).finally(() => {
|
||||||
self.set("loading", false);
|
this.set("loading", false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -176,11 +174,11 @@ export default Ember.Controller.extend({
|
||||||
poll_name: self.get("poll.name"),
|
poll_name: self.get("poll.name"),
|
||||||
status: self.get("isClosed") ? "open" : "closed",
|
status: self.get("isClosed") ? "open" : "closed",
|
||||||
}
|
}
|
||||||
}).then(function(results) {
|
}).then(results => {
|
||||||
self.set("model", Em.Object.create(results.poll));
|
self.set("model", Em.Object.create(results.poll));
|
||||||
}).catch(function() {
|
}).catch(() => {
|
||||||
bootbox.alert(I18n.t("poll.error_while_toggling_status"));
|
bootbox.alert(I18n.t("poll.error_while_toggling_status"));
|
||||||
}).finally(function() {
|
}).finally(() => {
|
||||||
self.set("loading", false);
|
self.set("loading", false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,9 @@
|
||||||
|
|
||||||
<div class="poll-buttons">
|
<div class="poll-buttons">
|
||||||
{{#if isMultiple}}
|
{{#if isMultiple}}
|
||||||
{{d-button class="cast-votes" title="poll.cast-votes.title" label="poll.cast-votes.label" disabled=castVotesDisabled action="castVotes"}}
|
{{#unless hideResultsDisabled}}
|
||||||
|
{{d-button class="cast-votes" title="poll.cast-votes.title" label="poll.cast-votes.label" disabled=castVotesDisabled action="castVotes"}}
|
||||||
|
{{/unless}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if showingResults}}
|
{{#if showingResults}}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import PostView from "discourse/views/post";
|
import PostView from "discourse/views/post";
|
||||||
|
import { on } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
function createPollView(container, post, poll, vote) {
|
function createPollView(container, post, poll, vote) {
|
||||||
const controller = container.lookup("controller:poll", { singleton: false }),
|
const controller = container.lookup("controller:poll", { singleton: false }),
|
||||||
|
@ -22,12 +23,14 @@ export default {
|
||||||
messageBus.subscribe("/polls", data => {
|
messageBus.subscribe("/polls", data => {
|
||||||
const post = container.lookup("controller:topic").get('model.postStream').findLoadedPost(data.post_id);
|
const post = container.lookup("controller:topic").get('model.postStream').findLoadedPost(data.post_id);
|
||||||
// HACK to trigger the "postViewUpdated" event
|
// HACK to trigger the "postViewUpdated" event
|
||||||
Em.run.next(_ => post.set("cooked", post.get("cooked") + " "));
|
Em.run.next(() => post.set("cooked", post.get("cooked") + " "));
|
||||||
});
|
});
|
||||||
|
|
||||||
// overwrite polls
|
// overwrite polls
|
||||||
PostView.reopen({
|
PostView.reopen({
|
||||||
_createPollViews: function($post) {
|
|
||||||
|
@on("postViewInserted", "postViewUpdated")
|
||||||
|
_createPollViews($post) {
|
||||||
const post = this.get("post"),
|
const post = this.get("post"),
|
||||||
polls = post.get("polls"),
|
polls = post.get("polls"),
|
||||||
votes = post.get("polls_votes") || {};
|
votes = post.get("polls_votes") || {};
|
||||||
|
@ -48,11 +51,11 @@ export default {
|
||||||
pollView = createPollView(container, post, polls[pollName], votes[pollName]);
|
pollView = createPollView(container, post, polls[pollName], votes[pollName]);
|
||||||
|
|
||||||
$poll.replaceWith($div);
|
$poll.replaceWith($div);
|
||||||
Em.run.next(_ => pollView.renderer.replaceIn(pollView, $div[0]));
|
Em.run.next(() => pollView.renderer.replaceIn(pollView, $div[0]));
|
||||||
pollViews[pollName] = pollView;
|
pollViews[pollName] = pollView;
|
||||||
});
|
});
|
||||||
|
|
||||||
messageBus.subscribe("/polls/" + this.get("post.id"), results => {
|
messageBus.subscribe(`/polls/${this.get("post.id")}`, results => {
|
||||||
if (results && results.polls) {
|
if (results && results.polls) {
|
||||||
_.forEach(results.polls, poll => {
|
_.forEach(results.polls, poll => {
|
||||||
if (pollViews[poll.name]) {
|
if (pollViews[poll.name]) {
|
||||||
|
@ -63,15 +66,16 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.set("pollViews", pollViews);
|
this.set("pollViews", pollViews);
|
||||||
}.on("postViewInserted", "postViewUpdated"),
|
},
|
||||||
|
|
||||||
_cleanUpPollViews: function() {
|
@on("willClearRender")
|
||||||
messageBus.unsubscribe("/polls/" + this.get("post.id"));
|
_cleanUpPollViews() {
|
||||||
|
messageBus.unsubscribe(`/polls/${this.get("post.id")}`);
|
||||||
|
|
||||||
if (this.get("pollViews")) {
|
if (this.get("pollViews")) {
|
||||||
_.forEach(this.get("pollViews"), v => v.destroy());
|
_.forEach(this.get("pollViews"), v => v.destroy());
|
||||||
}
|
}
|
||||||
}.on("willClearRender")
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { on } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export default Em.View.extend({
|
export default Em.View.extend({
|
||||||
templateName: "poll",
|
templateName: "poll",
|
||||||
classNames: ["poll"],
|
classNames: ["poll"],
|
||||||
|
@ -9,8 +11,9 @@ export default Em.View.extend({
|
||||||
"data-poll-name": Em.computed.alias("poll.name"),
|
"data-poll-name": Em.computed.alias("poll.name"),
|
||||||
"data-poll-status": Em.computed.alias("poll.status"),
|
"data-poll-status": Em.computed.alias("poll.status"),
|
||||||
|
|
||||||
_fixPollContainerHeight: function() {
|
@on("didInsertElement")
|
||||||
|
_fixPollContainerHeight() {
|
||||||
const pollContainer = this.$(".poll-container");
|
const pollContainer = this.$(".poll-container");
|
||||||
pollContainer.height(pollContainer.height());
|
pollContainer.height(pollContainer.height());
|
||||||
}.on("didInsertElement")
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue