nodebb-plugin-poll 3.2.9 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -19
- package/languages/en_GB/poll.json +12 -4
- package/languages/fr/poll.json +46 -38
- package/lib/config.js +13 -29
- package/lib/hooks.js +82 -68
- package/lib/nodebb.js +0 -1
- package/lib/poll.js +242 -121
- package/lib/sockets.js +60 -44
- package/lib/vote.js +29 -16
- package/library.js +27 -25
- package/package.json +4 -4
- package/plugin.json +8 -5
- package/public/js/admin.js +3 -32
- package/public/js/poll/creator.js +230 -170
- package/public/js/poll/main.js +64 -28
- package/public/js/poll/view.js +67 -81
- package/public/scss/style.scss +1 -4
- package/schema.md +24 -0
- package/templates/admin/partials/widgets/poll.tpl +2 -2
- package/templates/admin/plugins/poll.tpl +63 -48
- package/templates/poll/creator.tpl +18 -22
- package/templates/poll/manage.tpl +18 -0
- package/templates/poll/option-input.tpl +6 -0
- package/templates/poll/view/details.tpl +7 -6
- package/templates/poll/view.tpl +14 -9
- package/upgrades/poll-4.0-upgrade.js +128 -0
- package/lib/scheduler.js +0 -52
- package/lib/serializer.js +0 -4
- package/public/js/poll/serializer.js +0 -173
|
@@ -1,203 +1,240 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
(function (Poll) {
|
|
4
|
-
|
|
4
|
+
const Creator = {};
|
|
5
5
|
|
|
6
6
|
function init() {
|
|
7
7
|
$(window).on('action:composer.enhanced', initComposer);
|
|
8
|
+
}
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
function initComposer(ev, { postContainer, postData }) {
|
|
11
|
+
require(['composer', 'composer/formatting'], function (composer, formatting) {
|
|
12
|
+
if (formatting) {
|
|
13
|
+
formatting.addButtonDispatch('poll', function (/* textarea */) {
|
|
14
|
+
onPollButtonClicked(composer);
|
|
15
|
+
});
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
if ($.Redactor) {
|
|
13
|
-
if (data.composerData.isMain && $.Redactor.opts.plugins.indexOf('poll') === -1) {
|
|
14
|
-
$.Redactor.opts.plugins.push('poll');
|
|
15
|
-
} else if (!data.composerData.isMain && $.Redactor.opts.plugins.indexOf('poll') !== -1) {
|
|
16
|
-
$.Redactor.opts.plugins.splice($.Redactor.opts.plugins.indexOf('poll'), 1);
|
|
17
|
-
}
|
|
17
|
+
updateComposerBadgeCount(postContainer, postData.polls ? postData.polls.length : 0);
|
|
18
18
|
}
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
async function onPollButtonClicked(composer) {
|
|
23
|
+
const postData = composer.posts[composer.active];
|
|
24
|
+
if (!postData) {
|
|
25
|
+
return showAlert('error', '[[poll:error.invalid-post]]');
|
|
26
|
+
}
|
|
27
|
+
if (parseInt(postData.cid, 10) === 0) {
|
|
28
|
+
return showAlert('error', '[[error:category-not-selected]]');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const canCreate = await socket.emit('plugins.poll.canCreate', {
|
|
32
|
+
cid: postData.cid,
|
|
33
|
+
pid: postData.pid,
|
|
34
|
+
tid: postData.tid,
|
|
29
35
|
});
|
|
36
|
+
if (!canCreate) {
|
|
37
|
+
return showAlert('error', '[[error:no-privileges]]');
|
|
38
|
+
}
|
|
39
|
+
postData.polls = postData.polls || [];
|
|
40
|
+
await openManageModal({ postData, uuid: composer.active });
|
|
30
41
|
}
|
|
31
42
|
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
43
|
+
async function openManageModal(payload) {
|
|
44
|
+
const bootbox = await app.require('bootbox');
|
|
45
|
+
const { postData, modal, uuid } = payload;
|
|
46
|
+
const html = await app.parseAndTranslate('poll/manage', { post: postData });
|
|
47
|
+
|
|
48
|
+
if (modal) {
|
|
49
|
+
modal.find('.bootbox-body').html(html[0].outerHTML);
|
|
50
|
+
handleSort({ modal, polls: postData.polls });
|
|
51
|
+
} else {
|
|
52
|
+
const modal = bootbox.dialog({
|
|
53
|
+
title: '[[poll:manage-polls]]',
|
|
54
|
+
message: html,
|
|
55
|
+
className: 'poll-manage',
|
|
56
|
+
buttons: {
|
|
57
|
+
add: {
|
|
58
|
+
label: '<i class="fa fa-plus"></i> [[poll:add-poll]]',
|
|
59
|
+
className: 'btn-success',
|
|
60
|
+
callback: () => {
|
|
61
|
+
Creator.show('[[poll:creator_title]]', {
|
|
62
|
+
// temp id, will be replaced in the backend before saving
|
|
63
|
+
// used to identify the poll in the manage modal after creation
|
|
64
|
+
// so we can edit/delete
|
|
65
|
+
pollId: Date.now(),
|
|
66
|
+
maximumVotesPerUser: config.poll.maximumVotesPerUser,
|
|
67
|
+
}, config.poll).then((newPoll) => {
|
|
68
|
+
if (newPoll) {
|
|
69
|
+
postData.polls.push(newPoll);
|
|
70
|
+
}
|
|
71
|
+
openManageModal({ ...payload, modal });
|
|
72
|
+
const postContainer = $(`[component="composer"][data-uuid="${uuid}"]`);
|
|
73
|
+
updateComposerBadgeCount(postContainer, postData.polls.length);
|
|
74
|
+
});
|
|
75
|
+
return false;
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
close: {
|
|
79
|
+
label: '[[global:close]]',
|
|
80
|
+
className: 'btn-primary',
|
|
81
|
+
},
|
|
58
82
|
},
|
|
59
|
-
};
|
|
60
|
-
|
|
83
|
+
});
|
|
84
|
+
handleDelete({ ...payload, modal });
|
|
85
|
+
handleEdit({ ...payload, modal });
|
|
86
|
+
handleSort({ modal, polls: postData.polls });
|
|
87
|
+
}
|
|
61
88
|
}
|
|
62
89
|
|
|
63
|
-
function
|
|
64
|
-
require(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
socket.emit('plugins.poll.canCreate', {
|
|
74
|
-
cid: post.cid,
|
|
75
|
-
pid: post.pid,
|
|
76
|
-
}, function (err, canCreate) {
|
|
77
|
-
if (err) {
|
|
78
|
-
return alerts.error(err);
|
|
90
|
+
async function handleDelete(payload) {
|
|
91
|
+
const bootbox = await app.require('bootbox');
|
|
92
|
+
const { uuid, modal, postData } = payload;
|
|
93
|
+
modal.on('click', 'button[data-action="remove"]', function () {
|
|
94
|
+
const clickedPollId = $(this).attr('data-poll-id');
|
|
95
|
+
bootbox.confirm('[[poll:confirm-remove]]', (ok) => {
|
|
96
|
+
if (!ok) {
|
|
97
|
+
return;
|
|
79
98
|
}
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
const poll = postData?.polls.find(poll => String(poll.pollId) === clickedPollId);
|
|
100
|
+
if (poll) {
|
|
101
|
+
postData.polls = postData.polls.filter(poll => String(poll.pollId) !== clickedPollId);
|
|
102
|
+
openManageModal(payload);
|
|
103
|
+
const postContainer = $(`[component="composer"][data-uuid="${uuid}"]`);
|
|
104
|
+
updateComposerBadgeCount(postContainer, postData.polls.length);
|
|
82
105
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
var poll = {};
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
};
|
|
89
109
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
110
|
+
function handleEdit(payload) {
|
|
111
|
+
const { modal, postData } = payload;
|
|
112
|
+
modal.on('click', 'button[data-action="edit"]', async function () {
|
|
113
|
+
const clickedPollId = $(this).attr('data-poll-id');
|
|
114
|
+
const poll = postData?.polls.find(poll => String(poll.pollId) === clickedPollId);
|
|
115
|
+
if (poll) {
|
|
116
|
+
const editedPoll = await Creator.show(
|
|
117
|
+
'[[poll:edit-a-poll-title]]',
|
|
118
|
+
poll,
|
|
119
|
+
config.poll,
|
|
120
|
+
);
|
|
121
|
+
if (editedPoll) {
|
|
122
|
+
postData.polls = postData.polls.map(
|
|
123
|
+
p => String(p.pollId) === String(editedPoll.pollId) ? editedPoll : p
|
|
124
|
+
);
|
|
125
|
+
openManageModal(payload);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
93
130
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
131
|
+
function handleSort({ modal, polls }) {
|
|
132
|
+
if (Array.isArray(polls) && polls.length > 1) {
|
|
133
|
+
const selectorEl = modal.find('.topic-poll-modal');
|
|
134
|
+
selectorEl.sortable({
|
|
135
|
+
handle: '[component="sort/handle"]',
|
|
136
|
+
axis: 'y',
|
|
137
|
+
zIndex: 9999,
|
|
138
|
+
items: '[component="post/poll/item"]',
|
|
139
|
+
});
|
|
140
|
+
selectorEl.on('sortupdate', function () {
|
|
141
|
+
if (!polls) return;
|
|
142
|
+
const newOrder = [];
|
|
143
|
+
selectorEl.find('[component="post/poll/item"]').each(function () {
|
|
144
|
+
const pollId = $(this).attr('data-poll-id');
|
|
145
|
+
const poll = polls.find(p => String(p.pollId) === pollId);
|
|
146
|
+
if (poll) {
|
|
147
|
+
newOrder.push(poll);
|
|
99
148
|
}
|
|
100
|
-
|
|
101
|
-
Creator.show(poll, config, function (data) {
|
|
102
|
-
// Anything invalid will be discarded by the serializer
|
|
103
|
-
var markup = Poll.serializer.deserialize(data, config);
|
|
104
|
-
|
|
105
|
-
// Remove any existing poll markup
|
|
106
|
-
textarea.value = Poll.serializer.removeMarkup(textarea.value);
|
|
107
|
-
|
|
108
|
-
// Insert the poll markup at the bottom
|
|
109
|
-
if (textarea.value.charAt(textarea.value.length - 1) !== '\n') {
|
|
110
|
-
markup = '\n' + markup;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if ($.Redactor) {
|
|
114
|
-
textarea.redactor(textarea.value + '<p>' + markup + '</p>');
|
|
115
|
-
} else {
|
|
116
|
-
controls.insertIntoTextarea(textarea, markup);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
149
|
});
|
|
150
|
+
// Mutate polls array in place
|
|
151
|
+
polls.length = 0;
|
|
152
|
+
Array.prototype.push.apply(polls, newOrder);
|
|
120
153
|
});
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
Creator.show = function (poll, config, callback) {
|
|
125
|
-
if (poll.hasOwnProperty('info')) {
|
|
126
|
-
return Poll.alertError('Editing not implemented');
|
|
127
154
|
}
|
|
155
|
+
};
|
|
128
156
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
157
|
+
Creator.show = function (modalTitle, poll, config) {
|
|
158
|
+
return new Promise((resolve) => {
|
|
159
|
+
require(['bootbox'], function (bootbox) {
|
|
160
|
+
app.parseAndTranslate('poll/creator', { poll, config }, function (html) {
|
|
161
|
+
const modal = bootbox.dialog({
|
|
162
|
+
title: modalTitle,
|
|
163
|
+
message: html,
|
|
164
|
+
className: 'poll-creator',
|
|
165
|
+
buttons: {
|
|
166
|
+
cancel: {
|
|
167
|
+
label: '[[global:close]]',
|
|
168
|
+
callback: function () {
|
|
169
|
+
resolve(null);
|
|
170
|
+
},
|
|
141
171
|
},
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (obj.settings.end) {
|
|
160
|
-
obj.settings.end = new Date(obj.settings.end).getTime();
|
|
161
|
-
}
|
|
162
|
-
callback(obj);
|
|
163
|
-
return true;
|
|
172
|
+
save: {
|
|
173
|
+
label: '[[modules:bootbox.confirm]]',
|
|
174
|
+
callback: function () {
|
|
175
|
+
clearErrors();
|
|
176
|
+
const form = modal.find('#pollCreator');
|
|
177
|
+
const newPoll = serializeObjectFromForm(form);
|
|
178
|
+
|
|
179
|
+
// Let's be nice and at least show an error if there are no options
|
|
180
|
+
if (newPoll.options.length === 0) {
|
|
181
|
+
error('[[poll:error.no_options]]');
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
resolve(newPoll);
|
|
186
|
+
return true;
|
|
187
|
+
},
|
|
164
188
|
},
|
|
165
189
|
},
|
|
166
|
-
}
|
|
167
|
-
});
|
|
190
|
+
});
|
|
168
191
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
192
|
+
handleOptionSort({ modal });
|
|
193
|
+
|
|
194
|
+
// Add option adder
|
|
195
|
+
modal.find('#pollAddOption')
|
|
196
|
+
.off('click')
|
|
197
|
+
.on('click', async function (e) {
|
|
198
|
+
const el = $(e.currentTarget);
|
|
199
|
+
if (config.maxOptions <= el.prevAll('input').length) {
|
|
200
|
+
clearErrors();
|
|
201
|
+
error(`[[poll:error.max_options, ${config.maxOptions}]]`);
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
const id = Date.now();
|
|
205
|
+
const newOptionInput = await app.parseAndTranslate('poll/option-input', {
|
|
206
|
+
id: id,
|
|
207
|
+
title: '',
|
|
182
208
|
});
|
|
183
|
-
|
|
184
|
-
|
|
209
|
+
const container = modal.find('#poll-options-container');
|
|
210
|
+
container.append(newOptionInput);
|
|
211
|
+
modal.find(`[data-option-id="${id}"] input`).focus();
|
|
212
|
+
});
|
|
185
213
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
214
|
+
modal.find('#poll-options-container').on('click', '[data-action="remove-option"]', function () {
|
|
215
|
+
$(this).parents('[component="post/poll/option/item"]').remove();
|
|
189
216
|
});
|
|
217
|
+
});
|
|
190
218
|
});
|
|
191
219
|
});
|
|
192
220
|
};
|
|
193
221
|
|
|
194
|
-
function
|
|
195
|
-
|
|
222
|
+
function handleOptionSort({ modal }) {
|
|
223
|
+
const selectorEl = modal.find('#poll-options-container');
|
|
224
|
+
selectorEl.sortable({
|
|
225
|
+
handle: '[component="sort/handle"]',
|
|
226
|
+
axis: 'y',
|
|
227
|
+
zIndex: 9999,
|
|
228
|
+
items: '[component="post/poll/option/item"]',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
196
231
|
|
|
232
|
+
async function error(message) {
|
|
233
|
+
const errorBox = $('#pollErrorBox');
|
|
234
|
+
const translator = await app.require('translator');
|
|
235
|
+
const msgTranslated = await translator.translate(message);
|
|
197
236
|
errorBox.removeClass('hidden');
|
|
198
|
-
errorBox.append(
|
|
199
|
-
|
|
200
|
-
return false;
|
|
237
|
+
errorBox.append(msgTranslated + '<br>');
|
|
201
238
|
}
|
|
202
239
|
|
|
203
240
|
function clearErrors() {
|
|
@@ -205,21 +242,44 @@
|
|
|
205
242
|
}
|
|
206
243
|
|
|
207
244
|
function serializeObjectFromForm(form) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
245
|
+
const obj = form.serializeObject();
|
|
246
|
+
obj.options = obj.options || [];
|
|
247
|
+
obj.id = obj.id || [];
|
|
248
|
+
|
|
249
|
+
const options = obj.options.map((opt, index) => ({
|
|
250
|
+
id: obj.id[index],
|
|
251
|
+
title: opt,
|
|
252
|
+
})).filter(option => option.title?.length);
|
|
253
|
+
|
|
254
|
+
const result = {
|
|
255
|
+
pollId: obj.pollId,
|
|
256
|
+
options: options,
|
|
257
|
+
title: obj.title,
|
|
258
|
+
maximumVotesPerUser: obj.maximumVotesPerUser,
|
|
259
|
+
disallowVoteUpdate: obj.disallowVoteUpdate === 'on' ? 1 : 0,
|
|
260
|
+
allowAnonVoting: obj.allowAnonVoting === 'on' ? 1 : 0,
|
|
261
|
+
end: obj.end ? new Date(obj.end).getTime() : 0,
|
|
218
262
|
};
|
|
219
263
|
|
|
220
264
|
return result;
|
|
221
265
|
}
|
|
222
266
|
|
|
267
|
+
function showAlert(type, message) {
|
|
268
|
+
require(['alerts'], function (alerts) {
|
|
269
|
+
alerts[type](message);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function updateComposerBadgeCount(postContainer, count) {
|
|
274
|
+
require(['composer'], (composer) => {
|
|
275
|
+
composer.updateFormattingBtnBadgeCount(
|
|
276
|
+
postContainer,
|
|
277
|
+
'poll',
|
|
278
|
+
count
|
|
279
|
+
);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
223
283
|
Poll.creator = Creator;
|
|
224
284
|
|
|
225
285
|
init();
|
package/public/js/poll/main.js
CHANGED
|
@@ -4,38 +4,65 @@
|
|
|
4
4
|
|
|
5
5
|
window.Poll = {};
|
|
6
6
|
|
|
7
|
-
(function () {
|
|
7
|
+
$(document).ready(function () {
|
|
8
8
|
window.Poll.alertError = function (message) {
|
|
9
9
|
require(['alerts'], function (alerts) {
|
|
10
10
|
alerts.error(message);
|
|
11
11
|
});
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
require('
|
|
14
|
+
require(['hooks'], function (hooks) {
|
|
15
|
+
// add polls to data that is sent to server on composer submit
|
|
16
|
+
hooks.on('filter:composer.submit', function (hookData) {
|
|
17
|
+
hookData.composerData.polls = hookData.postData.polls || [];
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
hooks.on('filter:composer.drafts.save', function (hookData) {
|
|
21
|
+
const { draft, postData } = hookData;
|
|
22
|
+
if (Object.hasOwn(postData, 'polls')) {
|
|
23
|
+
draft.polls = postData.polls || [];
|
|
24
|
+
}
|
|
25
|
+
return hookData;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
hooks.on('filter:composer.drafts.open', function (hookData) {
|
|
29
|
+
const { draft } = hookData;
|
|
30
|
+
if (Object.hasOwn(draft, 'polls')) {
|
|
31
|
+
hookData.composerData.polls = draft.polls || [];
|
|
32
|
+
}
|
|
33
|
+
return hookData;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
hooks.on('filter:composer.topic.push', function (hookData) {
|
|
37
|
+
hookData.pushData.polls = hookData.data.polls || [];
|
|
38
|
+
return hookData;
|
|
39
|
+
});
|
|
40
|
+
hooks.on('filter:composer.reply.push', function (hookData) {
|
|
41
|
+
hookData.pushData.polls = hookData.data.polls || [];
|
|
42
|
+
return hookData;
|
|
43
|
+
});
|
|
44
|
+
});
|
|
15
45
|
|
|
16
46
|
$(window).on('action:topic.loading', function () {
|
|
17
|
-
|
|
18
|
-
getPollByPost(
|
|
19
|
-
}
|
|
47
|
+
ajaxify.data.posts.forEach((post) => {
|
|
48
|
+
getPollByPost(post);
|
|
49
|
+
});
|
|
20
50
|
});
|
|
21
51
|
|
|
22
52
|
$(window).on('action:posts.loaded', function (ev, data) {
|
|
23
53
|
data.posts.forEach((post) => {
|
|
24
|
-
|
|
25
|
-
getPollByPost(post);
|
|
26
|
-
}
|
|
54
|
+
getPollByPost(post);
|
|
27
55
|
});
|
|
28
56
|
});
|
|
29
57
|
|
|
30
58
|
$(window).on('action:posts.edited', function (ev, data) {
|
|
31
|
-
|
|
32
|
-
getPollByPost(data.post);
|
|
33
|
-
}
|
|
59
|
+
getPollByPost(data.post);
|
|
34
60
|
});
|
|
35
61
|
|
|
36
62
|
$(window).on('action:ajaxify.end', function () {
|
|
37
63
|
$('[data-widget-poll-id]').each(function () {
|
|
38
|
-
|
|
64
|
+
const $this = $(this);
|
|
65
|
+
getPolls([$this.attr('data-widget-poll-id')], $this);
|
|
39
66
|
});
|
|
40
67
|
});
|
|
41
68
|
|
|
@@ -44,25 +71,34 @@ window.Poll = {};
|
|
|
44
71
|
});
|
|
45
72
|
|
|
46
73
|
function getPollByPost(post) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
74
|
+
if (!post || !post.hasOwnProperty('pollIds') || !post.pollIds) return;
|
|
75
|
+
let pollIds;
|
|
76
|
+
try {
|
|
77
|
+
pollIds = JSON.parse(post.pollIds || '[]');
|
|
78
|
+
} catch (err) {
|
|
79
|
+
pollIds = [];
|
|
80
|
+
}
|
|
81
|
+
if (pollIds.length) {
|
|
82
|
+
const postEl = $(`[component="post"][data-pid="${post.pid}"]`);
|
|
83
|
+
getPolls(pollIds, postEl.find('[component="post/content"]'));
|
|
50
84
|
}
|
|
51
85
|
}
|
|
52
86
|
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
87
|
+
function getPolls(pollIds, container) {
|
|
88
|
+
const validPollIds = pollIds.map(id => parseInt(id, 10)).filter(id => !isNaN(id));
|
|
89
|
+
socket.emit('plugins.poll.get', { pollIds: validPollIds }, async function (err, pollDataArr) {
|
|
90
|
+
if (err) {
|
|
91
|
+
return Poll.alertError(err.message);
|
|
58
92
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return Poll.alertError(err.message);
|
|
62
|
-
}
|
|
93
|
+
pollDataArr.reverse();
|
|
94
|
+
for (const pollData of pollDataArr) {
|
|
63
95
|
pollData.container = container;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
96
|
+
if (container.attr('data-widget-poll-id')) {
|
|
97
|
+
pollData.isWidget = true;
|
|
98
|
+
}
|
|
99
|
+
// eslint-disable-next-line no-await-in-loop
|
|
100
|
+
await Poll.view.load(pollData);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
67
103
|
}
|
|
68
|
-
}
|
|
104
|
+
});
|