mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	shared: Move PollData into shared.
This commit is contained in:
		
				
					committed by
					
						
						Steve Howell
					
				
			
			
				
	
			
			
			
						parent
						
							42f328fec6
						
					
				
				
					commit
					da0c616b69
				
			@@ -8,6 +8,8 @@ const {run_test} = require("../zjsunit/test");
 | 
			
		||||
const blueslip = require("../zjsunit/zblueslip");
 | 
			
		||||
const $ = require("../zjsunit/zjquery");
 | 
			
		||||
 | 
			
		||||
const {PollData} = zrequire("../../static/shared/js/poll_data");
 | 
			
		||||
 | 
			
		||||
mock_cjs("jquery", $);
 | 
			
		||||
 | 
			
		||||
const poll_widget = zrequire("poll_widget");
 | 
			
		||||
@@ -32,7 +34,7 @@ run_test("PollData my question", () => {
 | 
			
		||||
    const is_my_poll = true;
 | 
			
		||||
    const question = "Favorite color?";
 | 
			
		||||
 | 
			
		||||
    const data_holder = new poll_widget.PollData({
 | 
			
		||||
    const data_holder = new PollData({
 | 
			
		||||
        current_user_id: me.user_id,
 | 
			
		||||
        is_my_poll,
 | 
			
		||||
        question,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,193 +1,12 @@
 | 
			
		||||
import $ from "jquery";
 | 
			
		||||
 | 
			
		||||
import {PollData} from "../shared/js/poll_data";
 | 
			
		||||
import render_widgets_poll_widget from "../templates/widgets/poll_widget.hbs";
 | 
			
		||||
import render_widgets_poll_widget_results from "../templates/widgets/poll_widget_results.hbs";
 | 
			
		||||
 | 
			
		||||
import * as blueslip from "./blueslip";
 | 
			
		||||
import * as people from "./people";
 | 
			
		||||
 | 
			
		||||
export class PollData {
 | 
			
		||||
    // 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.
 | 
			
		||||
 | 
			
		||||
    key_to_option = new Map();
 | 
			
		||||
    my_idx = 1;
 | 
			
		||||
 | 
			
		||||
    constructor({
 | 
			
		||||
        current_user_id,
 | 
			
		||||
        is_my_poll,
 | 
			
		||||
        question,
 | 
			
		||||
        options,
 | 
			
		||||
        comma_separated_names,
 | 
			
		||||
        report_error_function,
 | 
			
		||||
    }) {
 | 
			
		||||
        this.me = current_user_id;
 | 
			
		||||
        this.is_my_poll = is_my_poll;
 | 
			
		||||
        this.poll_question = question;
 | 
			
		||||
        this.input_mode = is_my_poll; // for now
 | 
			
		||||
        this.comma_separated_names = comma_separated_names;
 | 
			
		||||
        this.report_error_function = report_error_function;
 | 
			
		||||
 | 
			
		||||
        if (question) {
 | 
			
		||||
            this.set_question(question);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const [i, option] of options.entries()) {
 | 
			
		||||
            this.handle.new_option.inbound("canned", {
 | 
			
		||||
                idx: i,
 | 
			
		||||
                option,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_question(new_question) {
 | 
			
		||||
        this.input_mode = false;
 | 
			
		||||
        this.poll_question = new_question;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_question() {
 | 
			
		||||
        return this.poll_question;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_input_mode() {
 | 
			
		||||
        this.input_mode = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear_input_mode() {
 | 
			
		||||
        this.input_mode = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_input_mode() {
 | 
			
		||||
        return this.input_mode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_widget_data() {
 | 
			
		||||
        const options = [];
 | 
			
		||||
 | 
			
		||||
        for (const [key, obj] of this.key_to_option) {
 | 
			
		||||
            const voters = Array.from(obj.votes.keys());
 | 
			
		||||
            const current_user_vote = voters.includes(this.me);
 | 
			
		||||
 | 
			
		||||
            options.push({
 | 
			
		||||
                option: obj.option,
 | 
			
		||||
                names: this.comma_separated_names(voters),
 | 
			
		||||
                count: voters.length,
 | 
			
		||||
                key,
 | 
			
		||||
                current_user_vote,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const widget_data = {
 | 
			
		||||
            options,
 | 
			
		||||
            question: this.poll_question,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return widget_data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    handle = {
 | 
			
		||||
        new_option: {
 | 
			
		||||
            outbound: (option) => {
 | 
			
		||||
                const event = {
 | 
			
		||||
                    type: "new_option",
 | 
			
		||||
                    idx: this.my_idx,
 | 
			
		||||
                    option,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                this.my_idx += 1;
 | 
			
		||||
 | 
			
		||||
                return event;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            inbound: (sender_id, data) => {
 | 
			
		||||
                const idx = data.idx;
 | 
			
		||||
                const key = sender_id + "," + idx;
 | 
			
		||||
                const option = data.option;
 | 
			
		||||
                const votes = new Map();
 | 
			
		||||
 | 
			
		||||
                this.key_to_option.set(key, {
 | 
			
		||||
                    option,
 | 
			
		||||
                    user_id: sender_id,
 | 
			
		||||
                    votes,
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                if (this.my_idx <= idx) {
 | 
			
		||||
                    this.my_idx = idx + 1;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        question: {
 | 
			
		||||
            outbound: (question) => {
 | 
			
		||||
                const event = {
 | 
			
		||||
                    type: "question",
 | 
			
		||||
                    question,
 | 
			
		||||
                };
 | 
			
		||||
                if (this.is_my_poll) {
 | 
			
		||||
                    return event;
 | 
			
		||||
                }
 | 
			
		||||
                return undefined;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            inbound: (sender_id, data) => {
 | 
			
		||||
                this.set_question(data.question);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        vote: {
 | 
			
		||||
            outbound: (key) => {
 | 
			
		||||
                let vote = 1;
 | 
			
		||||
 | 
			
		||||
                // toggle
 | 
			
		||||
                if (this.key_to_option.get(key).votes.get(this.me)) {
 | 
			
		||||
                    vote = -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const event = {
 | 
			
		||||
                    type: "vote",
 | 
			
		||||
                    key,
 | 
			
		||||
                    vote,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                return event;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            inbound: (sender_id, data) => {
 | 
			
		||||
                const key = data.key;
 | 
			
		||||
                const vote = data.vote;
 | 
			
		||||
                const option = this.key_to_option.get(key);
 | 
			
		||||
 | 
			
		||||
                if (option === undefined) {
 | 
			
		||||
                    this.report_error_function("unknown key for poll: " + key);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const votes = option.votes;
 | 
			
		||||
 | 
			
		||||
                if (vote === 1) {
 | 
			
		||||
                    votes.set(sender_id, 1);
 | 
			
		||||
                } else {
 | 
			
		||||
                    votes.delete(sender_id);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    handle_event(sender_id, data) {
 | 
			
		||||
        const type = data.type;
 | 
			
		||||
        if (this.handle[type]) {
 | 
			
		||||
            this.handle[type].inbound(sender_id, data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // function to check whether option already exists
 | 
			
		||||
    is_option_present(data, latest_option) {
 | 
			
		||||
        return data.some((el) => el.option === latest_option);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function activate({
 | 
			
		||||
    elem,
 | 
			
		||||
    callback,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										181
									
								
								static/shared/js/poll_data.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								static/shared/js/poll_data.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,181 @@
 | 
			
		||||
export class PollData {
 | 
			
		||||
    // 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.
 | 
			
		||||
 | 
			
		||||
    key_to_option = new Map();
 | 
			
		||||
    my_idx = 1;
 | 
			
		||||
 | 
			
		||||
    constructor({
 | 
			
		||||
        current_user_id,
 | 
			
		||||
        is_my_poll,
 | 
			
		||||
        question,
 | 
			
		||||
        options,
 | 
			
		||||
        comma_separated_names,
 | 
			
		||||
        report_error_function,
 | 
			
		||||
    }) {
 | 
			
		||||
        this.me = current_user_id;
 | 
			
		||||
        this.is_my_poll = is_my_poll;
 | 
			
		||||
        this.poll_question = question;
 | 
			
		||||
        this.input_mode = is_my_poll; // for now
 | 
			
		||||
        this.comma_separated_names = comma_separated_names;
 | 
			
		||||
        this.report_error_function = report_error_function;
 | 
			
		||||
 | 
			
		||||
        if (question) {
 | 
			
		||||
            this.set_question(question);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const [i, option] of options.entries()) {
 | 
			
		||||
            this.handle.new_option.inbound("canned", {
 | 
			
		||||
                idx: i,
 | 
			
		||||
                option,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_question(new_question) {
 | 
			
		||||
        this.input_mode = false;
 | 
			
		||||
        this.poll_question = new_question;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_question() {
 | 
			
		||||
        return this.poll_question;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_input_mode() {
 | 
			
		||||
        this.input_mode = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear_input_mode() {
 | 
			
		||||
        this.input_mode = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_input_mode() {
 | 
			
		||||
        return this.input_mode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_widget_data() {
 | 
			
		||||
        const options = [];
 | 
			
		||||
 | 
			
		||||
        for (const [key, obj] of this.key_to_option) {
 | 
			
		||||
            const voters = Array.from(obj.votes.keys());
 | 
			
		||||
            const current_user_vote = voters.includes(this.me);
 | 
			
		||||
 | 
			
		||||
            options.push({
 | 
			
		||||
                option: obj.option,
 | 
			
		||||
                names: this.comma_separated_names(voters),
 | 
			
		||||
                count: voters.length,
 | 
			
		||||
                key,
 | 
			
		||||
                current_user_vote,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const widget_data = {
 | 
			
		||||
            options,
 | 
			
		||||
            question: this.poll_question,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return widget_data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    handle = {
 | 
			
		||||
        new_option: {
 | 
			
		||||
            outbound: (option) => {
 | 
			
		||||
                const event = {
 | 
			
		||||
                    type: "new_option",
 | 
			
		||||
                    idx: this.my_idx,
 | 
			
		||||
                    option,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                this.my_idx += 1;
 | 
			
		||||
 | 
			
		||||
                return event;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            inbound: (sender_id, data) => {
 | 
			
		||||
                const idx = data.idx;
 | 
			
		||||
                const key = sender_id + "," + idx;
 | 
			
		||||
                const option = data.option;
 | 
			
		||||
                const votes = new Map();
 | 
			
		||||
 | 
			
		||||
                this.key_to_option.set(key, {
 | 
			
		||||
                    option,
 | 
			
		||||
                    user_id: sender_id,
 | 
			
		||||
                    votes,
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                if (this.my_idx <= idx) {
 | 
			
		||||
                    this.my_idx = idx + 1;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        question: {
 | 
			
		||||
            outbound: (question) => {
 | 
			
		||||
                const event = {
 | 
			
		||||
                    type: "question",
 | 
			
		||||
                    question,
 | 
			
		||||
                };
 | 
			
		||||
                if (this.is_my_poll) {
 | 
			
		||||
                    return event;
 | 
			
		||||
                }
 | 
			
		||||
                return undefined;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            inbound: (sender_id, data) => {
 | 
			
		||||
                this.set_question(data.question);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        vote: {
 | 
			
		||||
            outbound: (key) => {
 | 
			
		||||
                let vote = 1;
 | 
			
		||||
 | 
			
		||||
                // toggle
 | 
			
		||||
                if (this.key_to_option.get(key).votes.get(this.me)) {
 | 
			
		||||
                    vote = -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const event = {
 | 
			
		||||
                    type: "vote",
 | 
			
		||||
                    key,
 | 
			
		||||
                    vote,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                return event;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            inbound: (sender_id, data) => {
 | 
			
		||||
                const key = data.key;
 | 
			
		||||
                const vote = data.vote;
 | 
			
		||||
                const option = this.key_to_option.get(key);
 | 
			
		||||
 | 
			
		||||
                if (option === undefined) {
 | 
			
		||||
                    this.report_error_function("unknown key for poll: " + key);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const votes = option.votes;
 | 
			
		||||
 | 
			
		||||
                if (vote === 1) {
 | 
			
		||||
                    votes.set(sender_id, 1);
 | 
			
		||||
                } else {
 | 
			
		||||
                    votes.delete(sender_id);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    handle_event(sender_id, data) {
 | 
			
		||||
        const type = data.type;
 | 
			
		||||
        if (this.handle[type]) {
 | 
			
		||||
            this.handle[type].inbound(sender_id, data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // function to check whether option already exists
 | 
			
		||||
    is_option_present(data, latest_option) {
 | 
			
		||||
        return data.some((el) => el.option === latest_option);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -167,6 +167,7 @@ EXEMPT_FILES = {
 | 
			
		||||
    "static/js/zform.js",
 | 
			
		||||
    "static/js/zulip.js",
 | 
			
		||||
    "static/js/zulip_test.js",
 | 
			
		||||
    "static/shared/js/poll_data.js",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
from tools.lib.test_script import add_provision_check_override_param, assert_provisioning_status_ok
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user