Variable 'post' was used to hold the current post and the post where the poll appeared, which can be different when polls are quoted.
132 lines
3.4 KiB
JavaScript
132 lines
3.4 KiB
JavaScript
import EmberObject from "@ember/object";
|
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
|
import WidgetGlue from "discourse/widgets/glue";
|
|
import { getRegister } from "discourse-common/lib/get-owner";
|
|
import { observes } from "discourse-common/utils/decorators";
|
|
|
|
function initializePolls(api) {
|
|
const register = getRegister(api);
|
|
|
|
api.modifyClass("controller:topic", {
|
|
subscribe() {
|
|
this._super(...arguments);
|
|
this.messageBus.subscribe("/polls/" + this.get("model.id"), msg => {
|
|
const post = this.get("model.postStream").findLoadedPost(msg.post_id);
|
|
if (post) {
|
|
post.set("polls", msg.polls);
|
|
}
|
|
});
|
|
},
|
|
unsubscribe() {
|
|
this.messageBus.unsubscribe("/polls/*");
|
|
this._super(...arguments);
|
|
}
|
|
});
|
|
|
|
let _glued = [];
|
|
let _interval = null;
|
|
|
|
function rerender() {
|
|
_glued.forEach(g => g.queueRerender());
|
|
}
|
|
|
|
api.modifyClass("model:post", {
|
|
_polls: null,
|
|
pollsObject: null,
|
|
|
|
// we need a proper ember object so it is bindable
|
|
@observes("polls")
|
|
pollsChanged() {
|
|
const polls = this.polls;
|
|
if (polls) {
|
|
this._polls = this._polls || {};
|
|
polls.forEach(p => {
|
|
const existing = this._polls[p.name];
|
|
if (existing) {
|
|
this._polls[p.name].setProperties(p);
|
|
} else {
|
|
this._polls[p.name] = EmberObject.create(p);
|
|
}
|
|
});
|
|
this.set("pollsObject", this._polls);
|
|
rerender();
|
|
}
|
|
}
|
|
});
|
|
|
|
function attachPolls($elem, helper) {
|
|
const $polls = $(".poll", $elem);
|
|
if (!$polls.length || !helper) {
|
|
return;
|
|
}
|
|
|
|
const post = helper.getModel();
|
|
api.preventCloak(post.id);
|
|
post.pollsChanged();
|
|
|
|
const polls = post.pollsObject || {};
|
|
const votes = post.polls_votes || {};
|
|
|
|
_interval = _interval || setInterval(rerender, 30000);
|
|
|
|
$polls.each((idx, pollElem) => {
|
|
const $poll = $(pollElem);
|
|
const pollName = $poll.data("poll-name");
|
|
let poll = polls[pollName];
|
|
let pollPost = post;
|
|
let vote = votes[pollName] || [];
|
|
|
|
const quotedId = $poll.parent(".expanded-quote").data("post-id");
|
|
if (quotedId && post.quoted[quotedId]) {
|
|
pollPost = post.quoted[quotedId];
|
|
pollPost = EmberObject.create(pollPost);
|
|
poll = EmberObject.create(
|
|
pollPost.polls.find(p => p.name === pollName)
|
|
);
|
|
vote = pollPost.polls_votes || {};
|
|
vote = vote[pollName] || [];
|
|
}
|
|
|
|
if (poll) {
|
|
const attrs = {
|
|
id: `${pollName}-${pollPost.id}`,
|
|
post: pollPost,
|
|
poll,
|
|
vote,
|
|
groupableUserFields: (
|
|
api.container.lookup("site-settings:main")
|
|
.poll_groupable_user_fields || ""
|
|
)
|
|
.split("|")
|
|
.filter(Boolean)
|
|
};
|
|
const glue = new WidgetGlue("discourse-poll", register, attrs);
|
|
glue.appendTo(pollElem);
|
|
_glued.push(glue);
|
|
}
|
|
});
|
|
}
|
|
|
|
function cleanUpPolls() {
|
|
if (_interval) {
|
|
clearInterval(_interval);
|
|
_interval = null;
|
|
}
|
|
|
|
_glued.forEach(g => g.cleanUp());
|
|
_glued = [];
|
|
}
|
|
|
|
api.includePostAttributes("polls", "polls_votes");
|
|
api.decorateCooked(attachPolls, { onlyStream: true, id: "discourse-poll" });
|
|
api.cleanupStream(cleanUpPolls);
|
|
}
|
|
|
|
export default {
|
|
name: "extend-for-poll",
|
|
|
|
initialize() {
|
|
withPluginApi("0.8.7", initializePolls);
|
|
}
|
|
};
|