FIX: Poll requires logged in user to log in again

FIX: Open/Closing the poll wasn't updating the UI
REFACTOR: ES6 FTW
This commit is contained in:
Régis Hanol 2015-03-03 16:17:07 +01:00
parent 9698447e89
commit 4714a562d9
7 changed files with 100 additions and 106 deletions

View File

@ -4,42 +4,44 @@ export default DiscourseController.extend({
poll: null, poll: null,
showResults: Em.computed.oneWay('poll.closed'), showResults: Em.computed.oneWay('poll.closed'),
disableRadio: Em.computed.any('poll.closed', 'loading'), disableRadio: Em.computed.any('poll.closed', 'loading'),
showToggleClosePoll: function() { showToggleClosePoll: Em.computed.alias('poll.post.topic.details.can_edit'),
return this.get('poll.post.topic.details.can_edit');
}.property('poll.post.topic.details.can_edit'),
actions: { actions: {
selectOption: function(option) { selectOption(option) {
if (this.get('disableRadio')) { if (this.get('disableRadio')) {
return; return;
} }
if (!this.get('currentUser.id')) { if (!this.get('postController.currentUser.id')) {
this.get('postController').send('showLogin'); this.get('postController').send('showLogin');
return; return;
} }
this.set('loading', true); this.set('loading', true);
const self = this;
this.get('poll').saveVote(option).then(function() { this.get('poll').saveVote(option).then(function() {
this.set('loading', false); self.setProperties({ loading: false, showResults: true});
this.set('showResults', true); });
}.bind(this));
}, },
toggleShowResults: function() { toggleShowResults() {
this.set('showResults', !this.get('showResults')); this.toggleProperty('showResults');
}, },
toggleClosePoll: function() { toggleClosePoll() {
const self = this;
this.set('loading', true); this.set('loading', true);
return Discourse.ajax("/poll/toggle_close", {
type: "PUT", return Discourse.ajax('/poll/toggle_close', {
data: {post_id: this.get('poll.post.id')} type: 'PUT',
}).then(function(topicJson) { data: { post_id: this.get('poll.post.id') }
this.set('poll.post.topic.title', topicJson.basic_topic.title); }).then(function(result) {
this.set('poll.post.topic.fancy_title', topicJson.basic_topic.title); self.set('poll.post.topic.title', result.basic_topic.title);
this.set('loading', false); self.set('poll.post.topic.fancy_title', result.basic_topic.title);
}.bind(this)); self.set('loading', false);
});
} }
} }
}); });

View File

@ -1,12 +1,12 @@
<table> <table>
{{#each po in poll.options}} {{#each po in poll.options}}
<tr {{bind-attr class=po.checked:active}} {{action "selectOption" po.option}}> <tr {{bind-attr class="po.checked:active"}} {{action "selectOption" po.option}}>
<td class="radio"> <td class="radio">
<input type="radio" name="poll" {{bind-attr checked=po.checked disabled=controller.disableRadio}}> <input type="radio" name="poll" {{bind-attr checked="po.checked" disabled="disableRadio"}}>
</td> </td>
<td class="option"> <td class="option">
<div class="option">{{{po.option}}}</div> <div class="option">{{{po.option}}}</div>
{{#if controller.showResults}} {{#if showResults}}
<div class="result">{{i18n 'poll.voteCount' count=po.votes}}</div> <div class="result">{{i18n 'poll.voteCount' count=po.votes}}</div>
{{/if}} {{/if}}
</td> </td>
@ -15,27 +15,23 @@
</table> </table>
<div class='row'> <div class='row'>
<button {{action "toggleShowResults"}} class="btn btn-small show-results"> <button {{action "toggleShowResults"}} class="btn btn-small show-results">
{{#if showResults}} {{#if showResults}}
<i class="fa fa-eye-slash"></i> {{fa-icon "eye-slash"}} {{i18n 'poll.results.hide'}}
{{i18n 'poll.results.hide'}}
{{else}}
<i class="fa fa-eye"></i>
{{i18n 'poll.results.show'}}
{{/if}}
</button>
{{#if showToggleClosePoll}}
<button {{action "toggleClosePoll"}} class="btn btn-small toggle-poll">
{{#if poll.closed}}
<i class="fa fa-unlock-alt"></i>
{{i18n 'poll.open_poll'}}
{{else}} {{else}}
<i class="fa fa-lock"></i> {{fa-icon "eye"}} {{i18n 'poll.results.show'}}
{{i18n 'poll.close_poll'}}
{{/if}} {{/if}}
</button> </button>
{{/if}}
{{#if showToggleClosePoll}}
<button {{action "toggleClosePoll"}} class="btn btn-small toggle-poll">
{{#if poll.closed}}
{{fa-icon "unlock-alt"}} {{i18n 'poll.open_poll'}}
{{else}}
{{fa-icon "lock"}} {{i18n 'poll.close_poll'}}
{{/if}}
</button>
{{/if}}
</div> </div>
{{loading-spinner condition=loading}} {{loading-spinner condition=loading}}

View File

@ -1,65 +1,17 @@
import Poll from "discourse/plugins/poll/models/poll";
import PollView from "discourse/plugins/poll/views/poll";
import PollController from "discourse/plugins/poll/controllers/poll"; import PollController from "discourse/plugins/poll/controllers/poll";
import PostView from "discourse/views/post"; import PostView from "discourse/views/post";
var Poll = Discourse.Model.extend({
post: null,
options: [],
closed: false,
postObserver: function() {
this.updateFromJson(this.get('post.poll_details'));
}.observes('post.poll_details'),
fetchNewPostDetails: Discourse.debounce(function() {
var self = this;
Discourse.debounce(function() {
self.get('post.topic.postStream').triggerChangedPost(self.get('post.id'), self.get('post.topic.updated_at'));
}, 500);
}).observes('post.topic.title'),
updateFromJson: function(json) {
var selectedOption = json["selected"];
var options = [];
Object.keys(json["options"]).forEach(function(option) {
options.push(Ember.Object.create({
option: option,
votes: json["options"][option],
checked: (option === selectedOption)
}));
});
this.set('options', options);
this.set('closed', json.closed);
},
saveVote: function(option) {
this.get('options').forEach(function(opt) {
opt.set('checked', opt.get('option') === option);
});
return Discourse.ajax("/poll", {
type: "PUT",
data: {post_id: this.get('post.id'), option: option}
}).then(function(newJSON) {
this.updateFromJson(newJSON);
}.bind(this));
}
});
var PollView = Ember.View.extend({
templateName: "poll",
classNames: ['poll-ui'],
});
function initializePollView(self) { function initializePollView(self) {
var post = self.get('post'); const post = self.get('post'),
var pollDetails = post.get('poll_details'); pollDetails = post.get('poll_details');
var poll = Poll.create({post: post}); let poll = Poll.create({ post: post });
poll.updateFromJson(pollDetails); poll.updateFromJson(pollDetails);
var pollController = PollController.create({ const pollController = PollController.create({
poll: poll, poll: poll,
showResults: pollDetails["selected"], showResults: pollDetails["selected"],
postController: self.get('controller') postController: self.get('controller')
@ -74,29 +26,25 @@ export default {
initialize: function() { initialize: function() {
PostView.reopen({ PostView.reopen({
createPollUI: function($post) { createPollUI: function($post) {
var post = this.get('post'); if (!this.get('post').get('poll_details')) {
if (!post.get('poll_details')) {
return; return;
} }
var view = initializePollView(this); let view = initializePollView(this),
var pollContainer = $post.find(".poll-ui:first"); pollContainer = $post.find(".poll-ui:first");
if (pollContainer.length === 0) { if (pollContainer.length === 0) {
pollContainer = $post.find("ul:first"); pollContainer = $post.find("ul:first");
} }
var $div = $('<div>'); let $div = $('<div>');
pollContainer.replaceWith($div); pollContainer.replaceWith($div);
view.constructor.renderer.appendTo(view, $div[0]); view.constructor.renderer.appendTo(view, $div[0]);
this.set('pollView', view); this.set('pollView', view);
}.on('postViewInserted'), }.on('postViewInserted'),
clearPollView: function() { clearPollView: function() {
if (this.get('pollView')) { if (this.get('pollView')) { this.get('pollView').destroy(); }
this.get('pollView').destroy();
}
}.on('willClearRender') }.on('willClearRender')
}); });
} }

View File

@ -0,0 +1,42 @@
export default Discourse.Model.extend({
post: null,
options: [],
closed: false,
postObserver: function() {
this.updateFromJson(this.get('post.poll_details'));
}.observes('post.poll_details'),
fetchNewPostDetails: Discourse.debounce(function() {
this.get('post.topic.postStream').triggerChangedPost(this.get('post.id'), this.get('post.topic.updated_at'));
}, 250).observes('post.topic.title'),
updateFromJson(json) {
const selectedOption = json["selected"];
let options = [];
Object.keys(json["options"]).forEach(function(option) {
options.push(Ember.Object.create({
option: option,
votes: json["options"][option],
checked: option === selectedOption
}));
});
this.setProperties({ options: options, closed: json.closed });
},
saveVote(option) {
this.get('options').forEach(function(opt) {
opt.set('checked', opt.get('option') === option);
});
const self = this;
return Discourse.ajax("/poll", {
type: "PUT",
data: { post_id: this.get('post.id'), option: option }
}).then(function(newJSON) {
self.updateFromJson(newJSON);
});
}
});

View File

@ -4,6 +4,6 @@ Discourse.Dialect.inlineBetween({
rawContents: true, rawContents: true,
emitter: function(contents) { emitter: function(contents) {
var list = Discourse.Dialect.cook(contents, {}); var list = Discourse.Dialect.cook(contents, {});
return ['div', {class: 'poll-ui'}, list]; return ['div', { class: 'poll-ui' }, list];
} }
}); });

View File

@ -0,0 +1,4 @@
export default Ember.View.extend({
templateName: "poll",
classNames: ['poll-ui'],
});

View File

@ -145,7 +145,9 @@ after_initialize do
end end
# Poll UI. # Poll UI.
register_asset "javascripts/models/poll.js.es6"
register_asset "javascripts/controllers/poll.js.es6" register_asset "javascripts/controllers/poll.js.es6"
register_asset "javascripts/views/poll.js.es6"
register_asset "javascripts/discourse/templates/poll.hbs" register_asset "javascripts/discourse/templates/poll.hbs"
register_asset "javascripts/initializers/poll.js.es6" register_asset "javascripts/initializers/poll.js.es6"
register_asset "javascripts/poll_bbcode.js", :server_side register_asset "javascripts/poll_bbcode.js", :server_side