mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Add poll widget.
This commit is contained in:
		@@ -171,6 +171,7 @@
 | 
			
		||||
        "unread_ops": false,
 | 
			
		||||
        "upload": false,
 | 
			
		||||
        "user_events": false,
 | 
			
		||||
        "voting_widget": false,
 | 
			
		||||
        "widgetize": false,
 | 
			
		||||
        "submessage": 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 = {};
 | 
			
		||||
 | 
			
		||||
widgets.poll = voting_widget;
 | 
			
		||||
 | 
			
		||||
exports.activate = function (in_opts) {
 | 
			
		||||
    var widget_type = in_opts.widget_type;
 | 
			
		||||
    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/stream_list.js',
 | 
			
		||||
            'js/filter.js',
 | 
			
		||||
            'js/voting_widget.js',
 | 
			
		||||
            'js/widgetize.js',
 | 
			
		||||
            'js/submessage.js',
 | 
			
		||||
            'js/fetch_status.js',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user