mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
Add poll widget.
This commit is contained in:
@@ -171,6 +171,7 @@
|
|||||||
"unread_ops": false,
|
"unread_ops": false,
|
||||||
"upload": false,
|
"upload": false,
|
||||||
"user_events": false,
|
"user_events": false,
|
||||||
|
"voting_widget": false,
|
||||||
"widgetize": false,
|
"widgetize": false,
|
||||||
"submessage": false,
|
"submessage": false,
|
||||||
"Plotly": false,
|
"Plotly": false,
|
||||||
|
|||||||
168
static/js/voting_widget.js
Normal file
168
static/js/voting_widget.js
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
var voting_widget = (function () {
|
||||||
|
|
||||||
|
var exports = {};
|
||||||
|
|
||||||
|
var poll_data_holder = function () {
|
||||||
|
// This object just holds data for a poll, although it
|
||||||
|
// works closely with the widget's concept of how data
|
||||||
|
// should be represented for rendering, plus how the
|
||||||
|
// server sends us data.
|
||||||
|
var self = {};
|
||||||
|
|
||||||
|
var me = people.my_current_user_id();
|
||||||
|
var key_to_comment = {};
|
||||||
|
var my_idx = 1;
|
||||||
|
|
||||||
|
self.get_widget_data = function () {
|
||||||
|
var comments = [];
|
||||||
|
|
||||||
|
_.each(key_to_comment, function (obj, key) {
|
||||||
|
var voters = _.keys(obj.votes);
|
||||||
|
|
||||||
|
comments.push({
|
||||||
|
comment: obj.comment,
|
||||||
|
names: people.safe_full_names(voters),
|
||||||
|
count: voters.length,
|
||||||
|
key: key,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var widget_data = {
|
||||||
|
comments: comments,
|
||||||
|
};
|
||||||
|
|
||||||
|
return widget_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.handle = {
|
||||||
|
new_comment: {
|
||||||
|
outbound: function (comment) {
|
||||||
|
var event = {
|
||||||
|
type: 'new_comment',
|
||||||
|
idx: my_idx,
|
||||||
|
comment: comment,
|
||||||
|
};
|
||||||
|
|
||||||
|
my_idx += 1;
|
||||||
|
|
||||||
|
return event;
|
||||||
|
},
|
||||||
|
|
||||||
|
inbound: function (sender_id, data) {
|
||||||
|
var idx = data.idx;
|
||||||
|
var key = sender_id + ',' + idx;
|
||||||
|
var comment = data.comment;
|
||||||
|
var votes = {};
|
||||||
|
|
||||||
|
votes[sender_id] = 1;
|
||||||
|
|
||||||
|
key_to_comment[key] = {
|
||||||
|
comment: comment,
|
||||||
|
user_id: sender_id,
|
||||||
|
votes: votes,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (my_idx <= idx) {
|
||||||
|
my_idx = idx + 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
vote: {
|
||||||
|
outbound: function (key) {
|
||||||
|
var vote = 1;
|
||||||
|
|
||||||
|
// toggle
|
||||||
|
if (key_to_comment[key].votes[me]) {
|
||||||
|
vote = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var event = {
|
||||||
|
type: 'vote',
|
||||||
|
key: key,
|
||||||
|
vote: vote,
|
||||||
|
};
|
||||||
|
|
||||||
|
return event;
|
||||||
|
},
|
||||||
|
|
||||||
|
inbound: function (sender_id, data) {
|
||||||
|
var key = data.key;
|
||||||
|
var vote = data.vote;
|
||||||
|
|
||||||
|
var votes = key_to_comment[key].votes;
|
||||||
|
|
||||||
|
if (vote === 1) {
|
||||||
|
votes[sender_id] = 1;
|
||||||
|
} else {
|
||||||
|
delete votes[sender_id];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
self.handle_event = function (sender_id, data) {
|
||||||
|
var type = data.type;
|
||||||
|
if (self.handle[type]) {
|
||||||
|
self.handle[type].inbound(sender_id, data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.activate = function (opts) {
|
||||||
|
var self = {};
|
||||||
|
|
||||||
|
var elem = opts.elem;
|
||||||
|
var callback = opts.callback;
|
||||||
|
|
||||||
|
var poll_data = poll_data_holder();
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
var html = templates.render('poll-widget');
|
||||||
|
elem.html(html);
|
||||||
|
|
||||||
|
elem.find("button.poll-comment").on('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
var comment = elem.find("input.poll-comment").val();
|
||||||
|
|
||||||
|
var data = poll_data.handle.new_comment.outbound(comment);
|
||||||
|
callback(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function render_results() {
|
||||||
|
var widget_data = poll_data.get_widget_data();
|
||||||
|
var html = templates.render('poll-widget-results', widget_data);
|
||||||
|
elem.find('ul.poll-widget').html(html);
|
||||||
|
|
||||||
|
elem.find("button.poll-vote").on('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
var key = $(e.target).attr('data-key');
|
||||||
|
|
||||||
|
var data = poll_data.handle.vote.outbound(key);
|
||||||
|
callback(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.handle_events = function (events) {
|
||||||
|
_.each(events, function (event) {
|
||||||
|
poll_data.handle_event(event.sender_id, event.data);
|
||||||
|
});
|
||||||
|
render_results();
|
||||||
|
};
|
||||||
|
|
||||||
|
render();
|
||||||
|
render_results();
|
||||||
|
|
||||||
|
return self;
|
||||||
|
};
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
|
||||||
|
}());
|
||||||
|
if (typeof module !== 'undefined') {
|
||||||
|
module.exports = voting_widget;
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ var exports = {};
|
|||||||
|
|
||||||
var widgets = {};
|
var widgets = {};
|
||||||
|
|
||||||
|
widgets.poll = voting_widget;
|
||||||
|
|
||||||
exports.activate = function (in_opts) {
|
exports.activate = function (in_opts) {
|
||||||
var widget_type = in_opts.widget_type;
|
var widget_type = in_opts.widget_type;
|
||||||
var extra_data = in_opts.extra_data;
|
var extra_data = in_opts.extra_data;
|
||||||
|
|||||||
11
static/templates/widgets/poll-widget-results.handlebars
Normal file
11
static/templates/widgets/poll-widget-results.handlebars
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{{#each comments}}
|
||||||
|
<li>
|
||||||
|
<button class="poll-vote" data-key="{{ key }}">
|
||||||
|
{{ count }}
|
||||||
|
</button>
|
||||||
|
{{ comment }}
|
||||||
|
{{#if names}}
|
||||||
|
({{ names }})
|
||||||
|
{{/if}}
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
8
static/templates/widgets/poll-widget.handlebars
Normal file
8
static/templates/widgets/poll-widget.handlebars
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<b>Poll widget</b>
|
||||||
|
<br />
|
||||||
|
<h6>add idea</h6>
|
||||||
|
<input type="text" class="poll-comment" />
|
||||||
|
<button class="poll-comment">submit</button>
|
||||||
|
<br />
|
||||||
|
<ul class="poll-widget">
|
||||||
|
</ul>
|
||||||
@@ -947,6 +947,7 @@ JS_SPECS = {
|
|||||||
'js/top_left_corner.js',
|
'js/top_left_corner.js',
|
||||||
'js/stream_list.js',
|
'js/stream_list.js',
|
||||||
'js/filter.js',
|
'js/filter.js',
|
||||||
|
'js/voting_widget.js',
|
||||||
'js/widgetize.js',
|
'js/widgetize.js',
|
||||||
'js/submessage.js',
|
'js/submessage.js',
|
||||||
'js/fetch_status.js',
|
'js/fetch_status.js',
|
||||||
|
|||||||
Reference in New Issue
Block a user