Files
zulip/static/js/alert_words.js
jai2201 5e49ddf4e1 settings: Add sorting feature for list of alert words.
This changes the method of rendering list of alert words in DOM,
earlier it was rendered using 'for' loop over the array of alert_words
which is now changed to render using ListWidget, which gets a array
of objects from get_word_list() in alert_words.js.

The use of ListWidget helps to define a parent_container and $container
in table-body of alert-words-table using which we can now apply sorting over
alert words with the help of handle_sort() function in list_widget.js

Changed the method of adding alert_word_settings_item row in table body
through {{#with}} loop because of rendering through ListWidget, which was done
earlier using for loop over each alert-word in while rendering the list.

this commit also mocks template of render_alert_word_item
while mocking ListWidget.create() function in render_alert_words_ui().
and checks that ListWidget.create() is not called when variable `loaded`
is set as false.

Fixes #21142.
2022-02-25 17:33:11 -08:00

72 lines
2.6 KiB
JavaScript

import _ from "lodash";
import * as people from "./people";
// For simplicity, we use a list for our internal
// data, since that matches what the server sends us.
let my_alert_words = [];
export function set_words(words) {
my_alert_words = words;
}
export function get_word_list() {
// Returns a array of objects
// (with each alert_word as value and 'word' as key to the object.)
const words = [];
for (const word of my_alert_words) {
words.push({word});
}
return words;
}
export function has_alert_word(word) {
return my_alert_words.includes(word);
}
export function process_message(message) {
// Parsing for alert words is expensive, so we rely on the host
// to tell us there any alert words to even look for.
if (!message.alerted) {
return;
}
for (const word of my_alert_words) {
const clean = _.escapeRegExp(word);
const before_punctuation = "\\s|^|>|[\\(\\\".,';\\[]";
const after_punctuation = "(?=\\s)|$|<|[\\)\\\"\\?!:.,';\\]!]";
const regex = new RegExp(`(${before_punctuation})(${clean})(${after_punctuation})`, "ig");
message.content = message.content.replace(
regex,
(match, before, word, after, offset, content) => {
// Logic for ensuring that we don't muck up rendered HTML.
const pre_match = content.slice(0, offset);
// We want to find the position of the `<` and `>` only in the
// match and the string before it. So, don't include the last
// character of match in `check_string`. This covers the corner
// case when there is an alert word just before `<` or `>`.
const check_string = pre_match + match.slice(0, -1);
const in_tag = check_string.lastIndexOf("<") > check_string.lastIndexOf(">");
// Matched word is inside a HTML tag so don't perform any highlighting.
if (in_tag === true) {
return before + word + after;
}
return before + "<span class='alert-word'>" + word + "</span>" + after;
},
);
}
}
export function notifies(message) {
// We exclude ourselves from notifications when we type one of our own
// alert words into a message, just because that can be annoying for
// certain types of workflows where everybody on your team, including
// yourself, sets up an alert word to effectively mention the team.
return !people.is_current_user(message.sender_email) && message.alerted;
}
export const initialize = (params) => {
my_alert_words = params.alert_words;
};