From 7edbf673e48cf995e81cda3ba9ff339119665f2f Mon Sep 17 00:00:00 2001 From: isakhagg Date: Tue, 9 Nov 2021 16:48:42 +0100 Subject: [PATCH] poll: Handle duplicate poll options. Fixes #20164. --- static/js/poll_widget.js | 22 +++++++++++++++++++++- static/shared/js/poll_data.js | 8 ++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/static/js/poll_widget.js b/static/js/poll_widget.js index 283d6cea4f..0f7b39ae70 100644 --- a/static/js/poll_widget.js +++ b/static/js/poll_widget.js @@ -5,6 +5,7 @@ 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 {$t} from "./i18n"; import * as people from "./people"; export function activate({ @@ -154,11 +155,13 @@ export function activate({ elem.find("button.poll-option").on("click", (e) => { e.stopPropagation(); + check_option_button(); submit_option(); }); - elem.find("input.poll-option").on("keydown", (e) => { + elem.find("input.poll-option").on("keyup", (e) => { e.stopPropagation(); + check_option_button(); if (e.key === "Enter") { submit_option(); @@ -172,6 +175,23 @@ export function activate({ }); } + function check_option_button() { + const poll_option_input = elem.find("input.poll-option"); + const option = poll_option_input.val().trim(); + const options = poll_data.get_widget_data().options; + + if (poll_data.is_option_present(options, option)) { + elem.find("button.poll-option").attr("disabled", true); + elem.find("button.poll-option").attr( + "title", + $t({defaultMessage: "Option already present."}), + ); + } else { + elem.find("button.poll-option").attr("disabled", false); + elem.find("button.poll-option").removeAttr("title"); + } + } + function render_results() { const widget_data = poll_data.get_widget_data(); diff --git a/static/shared/js/poll_data.js b/static/shared/js/poll_data.js index 36c4e13a48..5d9e9e9407 100644 --- a/static/shared/js/poll_data.js +++ b/static/shared/js/poll_data.js @@ -103,6 +103,14 @@ export class PollData { // All message readers may add a new option to the poll. const idx = data.idx; const option = data.option; + const options = this.get_widget_data().options; + + // While the UI doesn't allow adding duplicate options + // to an existing poll, the /poll command syntax to create + // them does not prevent duplicates, so we suppress them here. + if (this.is_option_present(options, option)) { + return; + } if (!Number.isInteger(idx) || idx < 0 || idx > MAX_IDX) { this.report_error_function("poll widget: bad type for inbound option idx");