mirror of https://github.com/zulip/zulip.git
notifications: Split out message_notifications module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
e48771993b
commit
db20fd12e0
|
@ -133,6 +133,7 @@ EXEMPT_FILES = make_set(
|
|||
"web/src/message_list_view.js",
|
||||
"web/src/message_lists.js",
|
||||
"web/src/message_live_update.js",
|
||||
"web/src/message_notifications.js",
|
||||
"web/src/message_scroll.js",
|
||||
"web/src/message_scroll_state.ts",
|
||||
"web/src/message_util.js",
|
||||
|
|
|
@ -13,6 +13,7 @@ import * as message_edit from "./message_edit";
|
|||
import * as message_edit_history from "./message_edit_history";
|
||||
import * as message_helper from "./message_helper";
|
||||
import * as message_lists from "./message_lists";
|
||||
import * as message_notifications from "./message_notifications";
|
||||
import * as message_store from "./message_store";
|
||||
import * as message_util from "./message_util";
|
||||
import * as narrow from "./narrow";
|
||||
|
@ -161,7 +162,7 @@ export function insert_new_messages(messages, sent_by_this_client) {
|
|||
}
|
||||
|
||||
unread_ops.process_visible();
|
||||
notifications.received_messages(messages);
|
||||
message_notifications.received_messages(messages);
|
||||
stream_list.update_streams_sidebar();
|
||||
pm_list.update_private_messages();
|
||||
recent_view_ui.process_messages(messages);
|
||||
|
@ -482,7 +483,7 @@ export function update_messages(events) {
|
|||
anchor_message.last_edit_timestamp = event.edit_timestamp;
|
||||
}
|
||||
|
||||
notifications.received_messages([anchor_message]);
|
||||
message_notifications.received_messages([anchor_message]);
|
||||
alert_words.process_message(anchor_message);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,404 @@
|
|||
import $ from "jquery";
|
||||
|
||||
import * as alert_words from "./alert_words";
|
||||
import * as blueslip from "./blueslip";
|
||||
import {$t} from "./i18n";
|
||||
import * as message_parser from "./message_parser";
|
||||
import * as narrow from "./narrow";
|
||||
import * as notifications from "./notifications";
|
||||
import * as people from "./people";
|
||||
import * as spoilers from "./spoilers";
|
||||
import * as stream_data from "./stream_data";
|
||||
import * as ui_util from "./ui_util";
|
||||
import * as unread from "./unread";
|
||||
import {user_settings} from "./user_settings";
|
||||
import * as user_topics from "./user_topics";
|
||||
|
||||
function get_notification_content(message) {
|
||||
let content;
|
||||
// Convert the content to plain text, replacing emoji with their alt text
|
||||
const $content = $("<div>").html(message.content);
|
||||
ui_util.replace_emoji_with_text($content);
|
||||
spoilers.hide_spoilers_in_notification($content);
|
||||
|
||||
if (
|
||||
$content.text().trim() === "" &&
|
||||
(message_parser.message_has_image(message) ||
|
||||
message_parser.message_has_attachment(message))
|
||||
) {
|
||||
content = $t({defaultMessage: "(attached file)"});
|
||||
} else {
|
||||
content = $content.text();
|
||||
}
|
||||
|
||||
if (message.is_me_message) {
|
||||
content = message.sender_full_name + content.slice(3);
|
||||
}
|
||||
|
||||
if (
|
||||
(message.type === "private" || message.type === "test-notification") &&
|
||||
!user_settings.pm_content_in_desktop_notifications
|
||||
) {
|
||||
content = "New direct message from " + message.sender_full_name;
|
||||
}
|
||||
|
||||
if (content.length > 150) {
|
||||
let i;
|
||||
// Truncate content at a word boundary
|
||||
for (i = 150; i > 0; i -= 1) {
|
||||
if (content[i] === " ") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
content = content.slice(0, i);
|
||||
content += " [...]";
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
function debug_notification_source_value(message) {
|
||||
let notification_source;
|
||||
|
||||
if (message.type === "private" || message.type === "test-notification") {
|
||||
notification_source = "pm";
|
||||
} else if (message.mentioned) {
|
||||
notification_source = "mention";
|
||||
} else if (message.alerted) {
|
||||
notification_source = "alert";
|
||||
} else {
|
||||
notification_source = "stream";
|
||||
}
|
||||
|
||||
blueslip.debug("Desktop notification from source " + notification_source);
|
||||
}
|
||||
|
||||
function get_notification_key(message) {
|
||||
let key;
|
||||
|
||||
if (message.type === "private" || message.type === "test-notification") {
|
||||
key = message.display_reply_to;
|
||||
} else {
|
||||
const stream_name = stream_data.get_stream_name_from_id(message.stream_id);
|
||||
key = message.sender_full_name + " to " + stream_name + " > " + message.topic;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
function remove_sender_from_list_of_recipients(message) {
|
||||
return `, ${message.display_reply_to}, `
|
||||
.replace(`, ${message.sender_full_name}, `, ", ")
|
||||
.slice(", ".length, -", ".length);
|
||||
}
|
||||
|
||||
function get_notification_title(message, content, msg_count) {
|
||||
let title = message.sender_full_name;
|
||||
let other_recipients;
|
||||
|
||||
if (msg_count > 1) {
|
||||
title = msg_count + " messages from " + title;
|
||||
}
|
||||
|
||||
switch (message.type) {
|
||||
case "test-notification":
|
||||
other_recipients = remove_sender_from_list_of_recipients(message);
|
||||
break;
|
||||
case "private":
|
||||
other_recipients = remove_sender_from_list_of_recipients(message);
|
||||
if (message.display_recipient.length > 2) {
|
||||
// If the message has too many recipients to list them all...
|
||||
if (content.length + title.length + other_recipients.length > 230) {
|
||||
// Then count how many people are in the conversation and summarize
|
||||
// by saying the conversation is with "you and [number] other people"
|
||||
other_recipients =
|
||||
other_recipients.replaceAll(/[^,]/g, "").length + " other people";
|
||||
}
|
||||
|
||||
title += " (to you and " + other_recipients + ")";
|
||||
} else {
|
||||
title += " (to you)";
|
||||
}
|
||||
break;
|
||||
case "stream": {
|
||||
const stream_name = stream_data.get_stream_name_from_id(message.stream_id);
|
||||
title += " (to " + stream_name + " > " + message.topic + ")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
export function process_notification(notification) {
|
||||
const message = notification.message;
|
||||
const content = get_notification_content(message);
|
||||
const key = get_notification_key(message);
|
||||
let notification_object;
|
||||
let msg_count = 1;
|
||||
|
||||
debug_notification_source_value(message);
|
||||
|
||||
if (notifications.notice_memory.has(key)) {
|
||||
msg_count = notifications.notice_memory.get(key).msg_count + 1;
|
||||
notification_object = notifications.notice_memory.get(key).obj;
|
||||
notification_object.close();
|
||||
}
|
||||
|
||||
const title = get_notification_title(message, content, msg_count);
|
||||
|
||||
if (notification.desktop_notify) {
|
||||
const icon_url = people.small_avatar_url(message);
|
||||
notification_object = new notifications.NotificationAPI(title, {
|
||||
icon: icon_url,
|
||||
body: content,
|
||||
tag: message.id,
|
||||
});
|
||||
notifications.notice_memory.set(key, {
|
||||
obj: notification_object,
|
||||
msg_count,
|
||||
message_id: message.id,
|
||||
});
|
||||
|
||||
if (typeof notification_object.addEventListener === "function") {
|
||||
// Sadly, some third-party Electron apps like Franz/Ferdi
|
||||
// misimplement the Notification API not inheriting from
|
||||
// EventTarget. This results in addEventListener being
|
||||
// unavailable for them.
|
||||
notification_object.addEventListener("click", () => {
|
||||
notification_object.close();
|
||||
if (message.type !== "test-notification") {
|
||||
narrow.by_topic(message.id, {trigger: "notification"});
|
||||
}
|
||||
window.focus();
|
||||
});
|
||||
notification_object.addEventListener("close", () => {
|
||||
notifications.notice_memory.delete(key);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function message_is_notifiable(message) {
|
||||
// Independent of the user's notification settings, are there
|
||||
// properties of the message that unconditionally mean we
|
||||
// shouldn't notify about it.
|
||||
|
||||
if (message.sent_by_me) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a message is edited multiple times, we want to err on the side of
|
||||
// not spamming notifications.
|
||||
if (message.notification_sent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// @-<username> mentions take precedence over muted-ness. Note
|
||||
// that @all mentions are still suppressed by muting.
|
||||
if (message.mentioned_me_directly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Messages to followed topics take precedence over muted-ness.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Messages to unmuted topics in muted streams may generate desktop notifications.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
stream_data.is_muted(message.stream_id) &&
|
||||
!user_topics.is_topic_unmuted(message.stream_id, message.topic)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (message.type === "stream" && user_topics.is_topic_muted(message.stream_id, message.topic)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything else is on the table; next filter based on notification
|
||||
// settings.
|
||||
return true;
|
||||
}
|
||||
|
||||
export function should_send_desktop_notification(message) {
|
||||
// Always notify for testing notifications.
|
||||
if (message.type === "test-notification") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// For streams, send if desktop notifications are enabled for all
|
||||
// message on this stream.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
stream_data.receives_notifications(message.stream_id, "desktop_notifications")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_followed_topic_desktop_notifications determines whether we pop up
|
||||
// a notification for messages in followed topics.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_desktop_notifications
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_desktop_notifications determines whether we pop up a
|
||||
// notification for direct messages, mentions, and/or alerts.
|
||||
if (!user_settings.enable_desktop_notifications) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// And then we need to check if the message is a direct message,
|
||||
// mention, wildcard mention with wildcard_mentions_notify, or alert.
|
||||
if (message.type === "private") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (alert_words.notifies(message)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.mentioned_me_directly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The following blocks for 'wildcard mentions' and 'Followed topic wildcard mentions'
|
||||
// should be placed below (as they are right now) the 'user_settings.enable_desktop_notifications'
|
||||
// block because the global, stream-specific, and followed topic wildcard mention
|
||||
// settings are wrappers around the personal-mention setting.
|
||||
// wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
stream_data.receives_notifications(message.stream_id, "wildcard_mentions_notify")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Followed topic wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_wildcard_mentions_notify
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function should_send_audible_notification(message) {
|
||||
// If `None` is selected as the notification sound, never send
|
||||
// audible notifications regardless of other configuration.
|
||||
if (user_settings.notification_sound === "none") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For streams, ding if sounds are enabled for all messages on
|
||||
// this stream.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
stream_data.receives_notifications(message.stream_id, "audible_notifications")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_followed_topic_audible_notifications determines whether we ding
|
||||
// for messages in followed topics.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_audible_notifications
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_sounds determines whether we ding for direct messages,
|
||||
// mentions, and/or alerts.
|
||||
if (!user_settings.enable_sounds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// And then we need to check if the message is a direct message,
|
||||
// mention, wildcard mention with wildcard_mentions_notify, or alert.
|
||||
if (message.type === "private" || message.type === "test-notification") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (alert_words.notifies(message)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.mentioned_me_directly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The following blocks for 'wildcard mentions' and 'Followed topic wildcard mentions'
|
||||
// should be placed below (as they are right now) the 'user_settings.enable_sounds'
|
||||
// block because the global, stream-specific, and followed topic wildcard mention
|
||||
// settings are wrappers around the personal-mention setting.
|
||||
// wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
stream_data.receives_notifications(message.stream_id, "wildcard_mentions_notify")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Followed topic wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_wildcard_mentions_notify
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function received_messages(messages) {
|
||||
for (const message of messages) {
|
||||
if (!message_is_notifiable(message)) {
|
||||
continue;
|
||||
}
|
||||
if (!unread.message_unread(message)) {
|
||||
// The message is already read; Zulip is currently in focus.
|
||||
continue;
|
||||
}
|
||||
|
||||
message.notification_sent = true;
|
||||
|
||||
if (should_send_desktop_notification(message)) {
|
||||
process_notification({
|
||||
message,
|
||||
desktop_notify: notifications.granted_desktop_notifications_permission(),
|
||||
});
|
||||
}
|
||||
if (should_send_audible_notification(message)) {
|
||||
ui_util.play_audio($("#user-notification-sound-audio")[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function send_test_notification(content) {
|
||||
received_messages([
|
||||
{
|
||||
id: Math.random(),
|
||||
type: "test-notification",
|
||||
sender_email: "notification-bot@zulip.com",
|
||||
sender_full_name: "Notification Bot",
|
||||
display_reply_to: "Notification Bot",
|
||||
content,
|
||||
unread: true,
|
||||
},
|
||||
]);
|
||||
}
|
|
@ -3,26 +3,21 @@ import $ from "jquery";
|
|||
import render_message_sent_banner from "../templates/compose_banner/message_sent_banner.hbs";
|
||||
import render_unmute_topic_banner from "../templates/compose_banner/unmute_topic_banner.hbs";
|
||||
|
||||
import * as alert_words from "./alert_words";
|
||||
import * as blueslip from "./blueslip";
|
||||
import * as compose_banner from "./compose_banner";
|
||||
import * as hash_util from "./hash_util";
|
||||
import {$t} from "./i18n";
|
||||
import * as message_lists from "./message_lists";
|
||||
import * as message_parser from "./message_parser";
|
||||
import * as narrow from "./narrow";
|
||||
import * as narrow_state from "./narrow_state";
|
||||
import * as people from "./people";
|
||||
import * as spoilers from "./spoilers";
|
||||
import * as stream_data from "./stream_data";
|
||||
import * as ui_util from "./ui_util";
|
||||
import * as unread from "./unread";
|
||||
import {user_settings} from "./user_settings";
|
||||
import * as user_topics from "./user_topics";
|
||||
|
||||
const notice_memory = new Map();
|
||||
export const notice_memory = new Map();
|
||||
|
||||
let NotificationAPI;
|
||||
export let NotificationAPI;
|
||||
|
||||
export function set_notification_api(n) {
|
||||
NotificationAPI = n;
|
||||
|
@ -140,171 +135,6 @@ export function notify_above_composebox(
|
|||
compose_banner.append_compose_banner_to_banner_list($notification, $("#compose_banners"));
|
||||
}
|
||||
|
||||
function get_notification_content(message) {
|
||||
let content;
|
||||
// Convert the content to plain text, replacing emoji with their alt text
|
||||
const $content = $("<div>").html(message.content);
|
||||
ui_util.replace_emoji_with_text($content);
|
||||
spoilers.hide_spoilers_in_notification($content);
|
||||
|
||||
if (
|
||||
$content.text().trim() === "" &&
|
||||
(message_parser.message_has_image(message) ||
|
||||
message_parser.message_has_attachment(message))
|
||||
) {
|
||||
content = $t({defaultMessage: "(attached file)"});
|
||||
} else {
|
||||
content = $content.text();
|
||||
}
|
||||
|
||||
if (message.is_me_message) {
|
||||
content = message.sender_full_name + content.slice(3);
|
||||
}
|
||||
|
||||
if (
|
||||
(message.type === "private" || message.type === "test-notification") &&
|
||||
!user_settings.pm_content_in_desktop_notifications
|
||||
) {
|
||||
content = "New direct message from " + message.sender_full_name;
|
||||
}
|
||||
|
||||
if (content.length > 150) {
|
||||
let i;
|
||||
// Truncate content at a word boundary
|
||||
for (i = 150; i > 0; i -= 1) {
|
||||
if (content[i] === " ") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
content = content.slice(0, i);
|
||||
content += " [...]";
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
function debug_notification_source_value(message) {
|
||||
let notification_source;
|
||||
|
||||
if (message.type === "private" || message.type === "test-notification") {
|
||||
notification_source = "pm";
|
||||
} else if (message.mentioned) {
|
||||
notification_source = "mention";
|
||||
} else if (message.alerted) {
|
||||
notification_source = "alert";
|
||||
} else {
|
||||
notification_source = "stream";
|
||||
}
|
||||
|
||||
blueslip.debug("Desktop notification from source " + notification_source);
|
||||
}
|
||||
|
||||
function get_notification_key(message) {
|
||||
let key;
|
||||
|
||||
if (message.type === "private" || message.type === "test-notification") {
|
||||
key = message.display_reply_to;
|
||||
} else {
|
||||
const stream_name = stream_data.get_stream_name_from_id(message.stream_id);
|
||||
key = message.sender_full_name + " to " + stream_name + " > " + message.topic;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
function remove_sender_from_list_of_recipients(message) {
|
||||
return `, ${message.display_reply_to}, `
|
||||
.replace(`, ${message.sender_full_name}, `, ", ")
|
||||
.slice(", ".length, -", ".length);
|
||||
}
|
||||
|
||||
function get_notification_title(message, content, msg_count) {
|
||||
let title = message.sender_full_name;
|
||||
let other_recipients;
|
||||
|
||||
if (msg_count > 1) {
|
||||
title = msg_count + " messages from " + title;
|
||||
}
|
||||
|
||||
switch (message.type) {
|
||||
case "test-notification":
|
||||
other_recipients = remove_sender_from_list_of_recipients(message);
|
||||
break;
|
||||
case "private":
|
||||
other_recipients = remove_sender_from_list_of_recipients(message);
|
||||
if (message.display_recipient.length > 2) {
|
||||
// If the message has too many recipients to list them all...
|
||||
if (content.length + title.length + other_recipients.length > 230) {
|
||||
// Then count how many people are in the conversation and summarize
|
||||
// by saying the conversation is with "you and [number] other people"
|
||||
other_recipients =
|
||||
other_recipients.replaceAll(/[^,]/g, "").length + " other people";
|
||||
}
|
||||
|
||||
title += " (to you and " + other_recipients + ")";
|
||||
} else {
|
||||
title += " (to you)";
|
||||
}
|
||||
break;
|
||||
case "stream": {
|
||||
const stream_name = stream_data.get_stream_name_from_id(message.stream_id);
|
||||
title += " (to " + stream_name + " > " + message.topic + ")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
export function process_notification(notification) {
|
||||
const message = notification.message;
|
||||
const content = get_notification_content(message);
|
||||
const key = get_notification_key(message);
|
||||
let notification_object;
|
||||
let msg_count = 1;
|
||||
|
||||
debug_notification_source_value(message);
|
||||
|
||||
if (notice_memory.has(key)) {
|
||||
msg_count = notice_memory.get(key).msg_count + 1;
|
||||
notification_object = notice_memory.get(key).obj;
|
||||
notification_object.close();
|
||||
}
|
||||
|
||||
const title = get_notification_title(message, content, msg_count);
|
||||
|
||||
if (notification.desktop_notify) {
|
||||
const icon_url = people.small_avatar_url(message);
|
||||
notification_object = new NotificationAPI(title, {
|
||||
icon: icon_url,
|
||||
body: content,
|
||||
tag: message.id,
|
||||
});
|
||||
notice_memory.set(key, {
|
||||
obj: notification_object,
|
||||
msg_count,
|
||||
message_id: message.id,
|
||||
});
|
||||
|
||||
if (typeof notification_object.addEventListener === "function") {
|
||||
// Sadly, some third-party Electron apps like Franz/Ferdi
|
||||
// misimplement the Notification API not inheriting from
|
||||
// EventTarget. This results in addEventListener being
|
||||
// unavailable for them.
|
||||
notification_object.addEventListener("click", () => {
|
||||
notification_object.close();
|
||||
if (message.type !== "test-notification") {
|
||||
narrow.by_topic(message.id, {trigger: "notification"});
|
||||
}
|
||||
window.focus();
|
||||
});
|
||||
notification_object.addEventListener("close", () => {
|
||||
notice_memory.delete(key);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function close_notification(message) {
|
||||
for (const [key, notice_mem_entry] of notice_memory) {
|
||||
if (notice_mem_entry.message_id === message.id) {
|
||||
|
@ -314,192 +144,6 @@ export function close_notification(message) {
|
|||
}
|
||||
}
|
||||
|
||||
export function message_is_notifiable(message) {
|
||||
// Independent of the user's notification settings, are there
|
||||
// properties of the message that unconditionally mean we
|
||||
// shouldn't notify about it.
|
||||
|
||||
if (message.sent_by_me) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a message is edited multiple times, we want to err on the side of
|
||||
// not spamming notifications.
|
||||
if (message.notification_sent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// @-<username> mentions take precedence over muted-ness. Note
|
||||
// that @all mentions are still suppressed by muting.
|
||||
if (message.mentioned_me_directly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Messages to followed topics take precedence over muted-ness.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Messages to unmuted topics in muted streams may generate desktop notifications.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
stream_data.is_muted(message.stream_id) &&
|
||||
!user_topics.is_topic_unmuted(message.stream_id, message.topic)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (message.type === "stream" && user_topics.is_topic_muted(message.stream_id, message.topic)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything else is on the table; next filter based on notification
|
||||
// settings.
|
||||
return true;
|
||||
}
|
||||
|
||||
export function should_send_desktop_notification(message) {
|
||||
// Always notify for testing notifications.
|
||||
if (message.type === "test-notification") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// For streams, send if desktop notifications are enabled for all
|
||||
// message on this stream.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
stream_data.receives_notifications(message.stream_id, "desktop_notifications")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_followed_topic_desktop_notifications determines whether we pop up
|
||||
// a notification for messages in followed topics.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_desktop_notifications
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_desktop_notifications determines whether we pop up a
|
||||
// notification for direct messages, mentions, and/or alerts.
|
||||
if (!user_settings.enable_desktop_notifications) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// And then we need to check if the message is a direct message,
|
||||
// mention, wildcard mention with wildcard_mentions_notify, or alert.
|
||||
if (message.type === "private") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (alert_words.notifies(message)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.mentioned_me_directly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The following blocks for 'wildcard mentions' and 'Followed topic wildcard mentions'
|
||||
// should be placed below (as they are right now) the 'user_settings.enable_desktop_notifications'
|
||||
// block because the global, stream-specific, and followed topic wildcard mention
|
||||
// settings are wrappers around the personal-mention setting.
|
||||
// wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
stream_data.receives_notifications(message.stream_id, "wildcard_mentions_notify")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Followed topic wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_wildcard_mentions_notify
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function should_send_audible_notification(message) {
|
||||
// If `None` is selected as the notification sound, never send
|
||||
// audible notifications regardless of other configuration.
|
||||
if (user_settings.notification_sound === "none") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For streams, ding if sounds are enabled for all messages on
|
||||
// this stream.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
stream_data.receives_notifications(message.stream_id, "audible_notifications")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_followed_topic_audible_notifications determines whether we ding
|
||||
// for messages in followed topics.
|
||||
if (
|
||||
message.type === "stream" &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_audible_notifications
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable_sounds determines whether we ding for direct messages,
|
||||
// mentions, and/or alerts.
|
||||
if (!user_settings.enable_sounds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// And then we need to check if the message is a direct message,
|
||||
// mention, wildcard mention with wildcard_mentions_notify, or alert.
|
||||
if (message.type === "private" || message.type === "test-notification") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (alert_words.notifies(message)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.mentioned_me_directly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The following blocks for 'wildcard mentions' and 'Followed topic wildcard mentions'
|
||||
// should be placed below (as they are right now) the 'user_settings.enable_sounds'
|
||||
// block because the global, stream-specific, and followed topic wildcard mention
|
||||
// settings are wrappers around the personal-mention setting.
|
||||
// wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
stream_data.receives_notifications(message.stream_id, "wildcard_mentions_notify")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Followed topic wildcard mentions
|
||||
if (
|
||||
message.mentioned &&
|
||||
user_topics.is_topic_followed(message.stream_id, message.topic) &&
|
||||
user_settings.enable_followed_topic_wildcard_mentions_notify
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function granted_desktop_notifications_permission() {
|
||||
return NotificationAPI && NotificationAPI.permission === "granted";
|
||||
}
|
||||
|
@ -510,44 +154,6 @@ export function request_desktop_notifications_permission() {
|
|||
}
|
||||
}
|
||||
|
||||
export function received_messages(messages) {
|
||||
for (const message of messages) {
|
||||
if (!message_is_notifiable(message)) {
|
||||
continue;
|
||||
}
|
||||
if (!unread.message_unread(message)) {
|
||||
// The message is already read; Zulip is currently in focus.
|
||||
continue;
|
||||
}
|
||||
|
||||
message.notification_sent = true;
|
||||
|
||||
if (should_send_desktop_notification(message)) {
|
||||
process_notification({
|
||||
message,
|
||||
desktop_notify: granted_desktop_notifications_permission(),
|
||||
});
|
||||
}
|
||||
if (should_send_audible_notification(message)) {
|
||||
ui_util.play_audio($("#user-notification-sound-audio")[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function send_test_notification(content) {
|
||||
received_messages([
|
||||
{
|
||||
id: Math.random(),
|
||||
type: "test-notification",
|
||||
sender_email: "notification-bot@zulip.com",
|
||||
sender_full_name: "Notification Bot",
|
||||
display_reply_to: "Notification Bot",
|
||||
content,
|
||||
unread: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
// Note that this returns values that are not HTML-escaped, for use in
|
||||
// Handlebars templates that will do further escaping.
|
||||
function get_message_header(message) {
|
||||
|
@ -736,13 +342,13 @@ export function reify_message_id(opts) {
|
|||
}
|
||||
}
|
||||
|
||||
function register_click_handlers({on_click_scroll_to_selected}) {
|
||||
export function register_click_handlers({on_click_scroll_to_selected}) {
|
||||
$("#compose_banners").on(
|
||||
"click",
|
||||
".narrow_to_recipient .above_compose_banner_action_link",
|
||||
(e) => {
|
||||
const message_id = $(e.currentTarget).data("message-id");
|
||||
narrow.by_topic(message_id, {trigger: "compose_notification"});
|
||||
narrow.by_topic(message_id, {trigger: "notification"});
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as blueslip from "./blueslip";
|
|||
import * as channel from "./channel";
|
||||
import * as confirm_dialog from "./confirm_dialog";
|
||||
import {$t, $t_html} from "./i18n";
|
||||
import * as notifications from "./notifications";
|
||||
import * as message_notifications from "./message_notifications";
|
||||
import {page_params} from "./page_params";
|
||||
import * as settings_config from "./settings_config";
|
||||
import * as settings_org from "./settings_org";
|
||||
|
@ -280,7 +280,7 @@ export function set_up(settings_panel) {
|
|||
// intentionally don't let organization administrators set
|
||||
// organization-level defaults.
|
||||
$container.find(".send_test_notification").on("click", () => {
|
||||
notifications.send_test_notification(
|
||||
message_notifications.send_test_notification(
|
||||
$t({defaultMessage: "This is what a Zulip notification looks like."}),
|
||||
);
|
||||
});
|
||||
|
|
|
@ -22,8 +22,8 @@ const {run_test} = require("./lib/test");
|
|||
// replace them with {}.
|
||||
const huddle_data = mock_esm("../src/huddle_data");
|
||||
const message_lists = mock_esm("../src/message_lists");
|
||||
const message_notifications = mock_esm("../src/message_notifications");
|
||||
const message_util = mock_esm("../src/message_util");
|
||||
const notifications = mock_esm("../src/notifications");
|
||||
const pm_list = mock_esm("../src/pm_list");
|
||||
const recent_view_data = mock_esm("../src/recent_view_data");
|
||||
const stream_list = mock_esm("../src/stream_list");
|
||||
|
@ -99,9 +99,9 @@ run_test("insert_message", ({override}) => {
|
|||
assert.equal(message_store.get(new_message.id), undefined);
|
||||
|
||||
helper.redirect(huddle_data, "process_loaded_messages");
|
||||
helper.redirect(message_notifications, "received_messages");
|
||||
helper.redirect(message_util, "add_new_messages_data");
|
||||
helper.redirect(message_util, "add_new_messages");
|
||||
helper.redirect(notifications, "received_messages");
|
||||
helper.redirect(recent_view_data, "process_message");
|
||||
helper.redirect(stream_list, "update_streams_sidebar");
|
||||
helper.redirect(unread_ops, "process_visible");
|
||||
|
@ -122,7 +122,7 @@ run_test("insert_message", ({override}) => {
|
|||
[message_util, "add_new_messages"],
|
||||
[unread_ui, "update_unread_counts"],
|
||||
[unread_ops, "process_visible"],
|
||||
[notifications, "received_messages"],
|
||||
[message_notifications, "received_messages"],
|
||||
[stream_list, "update_streams_sidebar"],
|
||||
[recent_view_data, "process_message"],
|
||||
]);
|
||||
|
|
|
@ -9,7 +9,7 @@ const {page_params} = require("./lib/zpage_params");
|
|||
|
||||
const message_edit = mock_esm("../src/message_edit");
|
||||
const message_lists = mock_esm("../src/message_lists");
|
||||
const notifications = mock_esm("../src/notifications");
|
||||
const message_notifications = mock_esm("../src/message_notifications");
|
||||
const pm_list = mock_esm("../src/pm_list");
|
||||
const stream_list = mock_esm("../src/stream_list");
|
||||
const unread_ui = mock_esm("../src/unread_ui");
|
||||
|
@ -99,7 +99,7 @@ run_test("update_messages", () => {
|
|||
|
||||
const side_effects = [
|
||||
[message_edit, "end_message_edit"],
|
||||
[notifications, "received_messages"],
|
||||
[message_notifications, "received_messages"],
|
||||
[unread_ui, "update_unread_counts"],
|
||||
[stream_list, "update_streams_sidebar"],
|
||||
[pm_list, "update_private_messages"],
|
||||
|
|
|
@ -13,6 +13,7 @@ const user_topics = zrequire("user_topics");
|
|||
const stream_data = zrequire("stream_data");
|
||||
|
||||
const notifications = zrequire("notifications");
|
||||
const message_notifications = zrequire("message_notifications");
|
||||
|
||||
// Not muted streams
|
||||
const general = {
|
||||
|
@ -82,10 +83,10 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "whatever",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
// Not notifiable because it was sent by the current user
|
||||
assert.equal(notifications.message_is_notifiable(message), false);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), false);
|
||||
|
||||
// Case 2: If the user has already been sent a notification about this message,
|
||||
// DO NOT notify the user
|
||||
|
@ -103,9 +104,9 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "whatever",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), false);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), false);
|
||||
|
||||
// Case 3: If a message mentions the user directly,
|
||||
// DO notify the user
|
||||
|
@ -121,9 +122,9 @@ test("message_is_notifiable", () => {
|
|||
stream_id: muted.stream_id,
|
||||
topic: "topic_three",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// Case 4: If the message has been sent to a followed topic,
|
||||
// DO visually and audibly notify the user if 'enable_followed_topic_desktop_notifications'
|
||||
|
@ -140,17 +141,17 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "followed topic",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// But not if 'enable_followed_topic_desktop_notifications'
|
||||
// and 'enable_followed_topic_audible_notifications' are disabled.
|
||||
user_settings.enable_followed_topic_desktop_notifications = false;
|
||||
user_settings.enable_followed_topic_audible_notifications = false;
|
||||
assert.equal(notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// Reset state
|
||||
user_settings.enable_followed_topic_desktop_notifications = true;
|
||||
|
@ -168,9 +169,9 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "vanilla",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// Case 6:
|
||||
// Wildcard mention should trigger notification in unmuted topic
|
||||
|
@ -186,21 +187,21 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "vanilla",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// But not if it's disabled
|
||||
user_settings.wildcard_mentions_notify = false;
|
||||
assert.equal(notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// And the stream-level setting overrides the global setting
|
||||
general.wildcard_mentions_notify = true;
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// Reset state
|
||||
user_settings.wildcard_mentions_notify = true;
|
||||
|
@ -220,9 +221,9 @@ test("message_is_notifiable", () => {
|
|||
stream_id: muted.stream_id,
|
||||
topic: "whatever",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), false);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), false);
|
||||
|
||||
// Case 8: If a message is in a muted stream
|
||||
// and does mention the user DIRECTLY,
|
||||
|
@ -238,9 +239,9 @@ test("message_is_notifiable", () => {
|
|||
stream_id: muted.stream_id,
|
||||
topic: "whatever",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// Case 9: If a message is in a muted topic
|
||||
// and does not mention the user DIRECTLY (i.e. wildcard mention),
|
||||
|
@ -256,9 +257,9 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "muted topic",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), false);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), false);
|
||||
|
||||
// Case 10:
|
||||
// Wildcard mentions in a followed topic with 'wildcard_mentions_notify',
|
||||
|
@ -280,15 +281,15 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "followed topic",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), true);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// But not if 'enable_followed_topic_wildcard_mentions_notify' is disabled
|
||||
user_settings.enable_followed_topic_wildcard_mentions_notify = false;
|
||||
assert.equal(notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// Reset state
|
||||
user_settings.wildcard_mentions_notify = true;
|
||||
|
@ -310,9 +311,9 @@ test("message_is_notifiable", () => {
|
|||
topic: "whatever",
|
||||
};
|
||||
user_settings.notification_sound = "none";
|
||||
assert.equal(notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), true);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
|
||||
// Reset state
|
||||
user_settings.notification_sound = "ding";
|
||||
|
@ -332,9 +333,9 @@ test("message_is_notifiable", () => {
|
|||
stream_id: general.stream_id,
|
||||
topic: "whatever",
|
||||
};
|
||||
assert.equal(notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(notifications.message_is_notifiable(message), true);
|
||||
assert.equal(message_notifications.should_send_desktop_notification(message), false);
|
||||
assert.equal(message_notifications.should_send_audible_notification(message), false);
|
||||
assert.equal(message_notifications.message_is_notifiable(message), true);
|
||||
});
|
||||
|
||||
test("basic_notifications", () => {
|
||||
|
@ -393,7 +394,7 @@ test("basic_notifications", () => {
|
|||
};
|
||||
|
||||
// Send notification.
|
||||
notifications.process_notification({message: message_1, desktop_notify: true});
|
||||
message_notifications.process_notification({message: message_1, desktop_notify: true});
|
||||
n = notifications.get_notifications();
|
||||
assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
|
||||
assert.equal(n.size, 1);
|
||||
|
@ -408,7 +409,7 @@ test("basic_notifications", () => {
|
|||
|
||||
// Send notification.
|
||||
message_1.id = 1001;
|
||||
notifications.process_notification({message: message_1, desktop_notify: true});
|
||||
message_notifications.process_notification({message: message_1, desktop_notify: true});
|
||||
n = notifications.get_notifications();
|
||||
assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
|
||||
assert.equal(n.size, 1);
|
||||
|
@ -416,14 +417,14 @@ test("basic_notifications", () => {
|
|||
|
||||
// Process same message again. Notification count shouldn't increase.
|
||||
message_1.id = 1002;
|
||||
notifications.process_notification({message: message_1, desktop_notify: true});
|
||||
message_notifications.process_notification({message: message_1, desktop_notify: true});
|
||||
n = notifications.get_notifications();
|
||||
assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
|
||||
assert.equal(n.size, 1);
|
||||
assert.equal(last_shown_message_id, message_1.id);
|
||||
|
||||
// Send another message. Notification count should increase.
|
||||
notifications.process_notification({message: message_2, desktop_notify: true});
|
||||
message_notifications.process_notification({message: message_2, desktop_notify: true});
|
||||
n = notifications.get_notifications();
|
||||
assert.equal(n.has("Gus Fring to general > lunch"), true);
|
||||
assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
|
||||
|
|
Loading…
Reference in New Issue