message_notifications: Convert module to typescript.

This commit is contained in:
evykassirer 2024-09-23 15:21:45 -07:00 committed by Tim Abbott
parent 6c390551de
commit 471d042a11
6 changed files with 65 additions and 27 deletions

View File

@ -151,7 +151,7 @@ EXEMPT_FILES = make_set(
"web/src/message_list_view.ts", "web/src/message_list_view.ts",
"web/src/message_lists.ts", "web/src/message_lists.ts",
"web/src/message_live_update.ts", "web/src/message_live_update.ts",
"web/src/message_notifications.js", "web/src/message_notifications.ts",
"web/src/message_scroll.js", "web/src/message_scroll.js",
"web/src/message_scroll_state.ts", "web/src/message_scroll_state.ts",
"web/src/message_util.ts", "web/src/message_util.ts",

View File

@ -21,7 +21,7 @@ export function set_notification_api(n: typeof NotificationAPI): void {
NotificationAPI = n; NotificationAPI = n;
} }
class ElectronBridgeNotification extends EventTarget { export class ElectronBridgeNotification extends EventTarget {
title: string; title: string;
dir: NotificationDirection; dir: NotificationDirection;
lang: string; lang: string;

View File

@ -3,8 +3,10 @@ import $ from "jquery";
import * as alert_words from "./alert_words"; import * as alert_words from "./alert_words";
import * as blueslip from "./blueslip"; import * as blueslip from "./blueslip";
import * as desktop_notifications from "./desktop_notifications"; import * as desktop_notifications from "./desktop_notifications";
import type {ElectronBridgeNotification} from "./desktop_notifications";
import {$t} from "./i18n"; import {$t} from "./i18n";
import * as message_parser from "./message_parser"; import * as message_parser from "./message_parser";
import type {Message} from "./message_store";
import * as message_view from "./message_view"; import * as message_view from "./message_view";
import * as people from "./people"; import * as people from "./people";
import * as spoilers from "./spoilers"; import * as spoilers from "./spoilers";
@ -14,7 +16,27 @@ import {user_settings} from "./user_settings";
import * as user_topics from "./user_topics"; import * as user_topics from "./user_topics";
import * as util from "./util"; import * as util from "./util";
function get_notification_content(message) { type TestNotificationMessage = {
id: number;
type: "test-notification";
sender_email: string;
sender_full_name: string;
display_reply_to: string;
content: string;
unread: boolean;
notification_sent?: boolean;
// Needed for functions that handle Message
is_me_message?: undefined;
sent_by_me?: undefined;
mentioned_me_directly?: undefined;
};
function small_avatar_url_for_test_notification(message: TestNotificationMessage): string {
// this is a heavily simplified version of people.small_avatar_url
return people.gravatar_url_for_email(message.sender_email);
}
function get_notification_content(message: Message | TestNotificationMessage): string {
let content; let content;
// Convert the content to plain text, replacing emoji with their alt text // Convert the content to plain text, replacing emoji with their alt text
const $content = $("<div>").html(message.content); const $content = $("<div>").html(message.content);
@ -50,7 +72,7 @@ function get_notification_content(message) {
return content; return content;
} }
function debug_notification_source_value(message) { function debug_notification_source_value(message: Message | TestNotificationMessage): void {
let notification_source; let notification_source;
if (message.type === "private" || message.type === "test-notification") { if (message.type === "private" || message.type === "test-notification") {
@ -66,7 +88,7 @@ function debug_notification_source_value(message) {
blueslip.debug("Desktop notification from source " + notification_source); blueslip.debug("Desktop notification from source " + notification_source);
} }
function get_notification_key(message) { function get_notification_key(message: Message | TestNotificationMessage): string {
let key; let key;
if (message.type === "private" || message.type === "test-notification") { if (message.type === "private" || message.type === "test-notification") {
@ -79,13 +101,16 @@ function get_notification_key(message) {
return key; return key;
} }
function remove_sender_from_list_of_recipients(message) { function remove_sender_from_list_of_recipients(message: Message): string {
return `, ${message.display_reply_to}, ` return `, ${message.display_reply_to}, `
.replace(`, ${message.sender_full_name}, `, ", ") .replace(`, ${message.sender_full_name}, `, ", ")
.slice(", ".length, -", ".length); .slice(", ".length, -", ".length);
} }
function get_notification_title(message, msg_count) { function get_notification_title(
message: Message | TestNotificationMessage,
msg_count: number,
): string {
let title_prefix = message.sender_full_name; let title_prefix = message.sender_full_name;
let title_suffix = ""; let title_suffix = "";
let other_recipients; let other_recipients;
@ -139,29 +164,36 @@ function get_notification_title(message, msg_count) {
return title_prefix + title_suffix; return title_prefix + title_suffix;
} }
export function process_notification(notification) { export function process_notification(notification: {
message: Message | TestNotificationMessage;
desktop_notify: boolean;
}): void {
const message = notification.message; const message = notification.message;
const content = get_notification_content(message); const content = get_notification_content(message);
const key = get_notification_key(message); const key = get_notification_key(message);
let notification_object; let notification_object: ElectronBridgeNotification | Notification;
let msg_count = 1; let msg_count = 1;
debug_notification_source_value(message); debug_notification_source_value(message);
if (desktop_notifications.notice_memory.has(key)) { const notice_memory = desktop_notifications.notice_memory.get(key);
msg_count = desktop_notifications.notice_memory.get(key).msg_count + 1; if (notice_memory) {
notification_object = desktop_notifications.notice_memory.get(key).obj; msg_count = notice_memory.msg_count + 1;
notification_object = notice_memory.obj;
notification_object.close(); notification_object.close();
} }
const title = get_notification_title(message, msg_count); const title = get_notification_title(message, msg_count);
if (notification.desktop_notify && desktop_notifications.NotificationAPI !== undefined) { if (notification.desktop_notify && desktop_notifications.NotificationAPI !== undefined) {
const icon_url = people.small_avatar_url(message); const icon_url =
message.type === "test-notification"
? small_avatar_url_for_test_notification(message)
: people.small_avatar_url(message);
notification_object = new desktop_notifications.NotificationAPI(title, { notification_object = new desktop_notifications.NotificationAPI(title, {
icon: icon_url, icon: icon_url,
body: content, body: content,
tag: message.id, tag: message.id.toString(),
}); });
desktop_notifications.notice_memory.set(key, { desktop_notifications.notice_memory.set(key, {
obj: notification_object, obj: notification_object,
@ -188,7 +220,7 @@ export function process_notification(notification) {
} }
} }
export function message_is_notifiable(message) { export function message_is_notifiable(message: Message | TestNotificationMessage): boolean {
// Independent of the user's notification settings, are there // Independent of the user's notification settings, are there
// properties of the message that unconditionally mean we // properties of the message that unconditionally mean we
// shouldn't notify about it. // shouldn't notify about it.
@ -235,7 +267,9 @@ export function message_is_notifiable(message) {
return true; return true;
} }
export function should_send_desktop_notification(message) { export function should_send_desktop_notification(
message: Message | TestNotificationMessage,
): boolean {
// Always notify for testing notifications. // Always notify for testing notifications.
if (message.type === "test-notification") { if (message.type === "test-notification") {
return true; return true;
@ -304,7 +338,9 @@ export function should_send_desktop_notification(message) {
return false; return false;
} }
export function should_send_audible_notification(message) { export function should_send_audible_notification(
message: Message | TestNotificationMessage,
): boolean {
// If `None` is selected as the notification sound, never send // If `None` is selected as the notification sound, never send
// audible notifications regardless of other configuration. // audible notifications regardless of other configuration.
if (user_settings.notification_sound === "none") { if (user_settings.notification_sound === "none") {
@ -374,7 +410,7 @@ export function should_send_audible_notification(message) {
return false; return false;
} }
export function received_messages(messages) { export function received_messages(messages: (Message | TestNotificationMessage)[]): void {
for (const message of messages) { for (const message of messages) {
if (!message_is_notifiable(message)) { if (!message_is_notifiable(message)) {
continue; continue;
@ -393,12 +429,12 @@ export function received_messages(messages) {
}); });
} }
if (should_send_audible_notification(message)) { if (should_send_audible_notification(message)) {
ui_util.play_audio($("#user-notification-sound-audio")[0]); void ui_util.play_audio(util.the($("#user-notification-sound-audio")));
} }
} }
} }
export function send_test_notification(content) { export function send_test_notification(content: string): void {
received_messages([ received_messages([
{ {
id: Math.random(), id: Math.random(),

View File

@ -173,6 +173,8 @@ export type Message = (
status_emoji_info?: UserStatusEmojiInfo | undefined; // Used in `message_body.hbs` status_emoji_info?: UserStatusEmojiInfo | undefined; // Used in `message_body.hbs`
local_edit_timestamp?: number; // Used for edited messages local_edit_timestamp?: number; // Used for edited messages
notification_sent?: boolean; // Used in message_notifications
} & ( } & (
| { | {
type: "private"; type: "private";

View File

@ -800,7 +800,7 @@ export function user_can_direct_message(recipient_ids_string: string): boolean {
return !other_human_recipients_exist; return !other_human_recipients_exist;
} }
function gravatar_url_for_email(email: string): string { export function gravatar_url_for_email(email: string): string {
const hash = md5(email.toLowerCase()); const hash = md5(email.toLowerCase());
return "https://secure.gravatar.com/avatar/" + hash + "?d=identicon"; return "https://secure.gravatar.com/avatar/" + hash + "?d=identicon";
} }

View File

@ -402,14 +402,14 @@ test("basic_notifications", () => {
n = desktop_notifications.get_notifications(); n = desktop_notifications.get_notifications();
assert.equal(n.has("Jesse Pinkman to general > whatever"), true); assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
assert.equal(n.size, 1); assert.equal(n.size, 1);
assert.equal(last_shown_message_id, message_1.id); assert.equal(last_shown_message_id, message_1.id.toString());
// Remove notification. // Remove notification.
desktop_notifications.close_notification(message_1); desktop_notifications.close_notification(message_1);
n = desktop_notifications.get_notifications(); n = desktop_notifications.get_notifications();
assert.equal(n.has("Jesse Pinkman to general > whatever"), false); assert.equal(n.has("Jesse Pinkman to general > whatever"), false);
assert.equal(n.size, 0); assert.equal(n.size, 0);
assert.equal(last_closed_message_id, message_1.id); assert.equal(last_closed_message_id, message_1.id.toString());
// Send notification. // Send notification.
message_1.id = 1001; message_1.id = 1001;
@ -417,7 +417,7 @@ test("basic_notifications", () => {
n = desktop_notifications.get_notifications(); n = desktop_notifications.get_notifications();
assert.equal(n.has("Jesse Pinkman to general > whatever"), true); assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
assert.equal(n.size, 1); assert.equal(n.size, 1);
assert.equal(last_shown_message_id, message_1.id); assert.equal(last_shown_message_id, message_1.id.toString());
// Process same message again. Notification count shouldn't increase. // Process same message again. Notification count shouldn't increase.
message_1.id = 1002; message_1.id = 1002;
@ -425,7 +425,7 @@ test("basic_notifications", () => {
n = desktop_notifications.get_notifications(); n = desktop_notifications.get_notifications();
assert.equal(n.has("Jesse Pinkman to general > whatever"), true); assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
assert.equal(n.size, 1); assert.equal(n.size, 1);
assert.equal(last_shown_message_id, message_1.id); assert.equal(last_shown_message_id, message_1.id.toString());
// Send another message. Notification count should increase. // Send another message. Notification count should increase.
message_notifications.process_notification({message: message_2, desktop_notify: true}); message_notifications.process_notification({message: message_2, desktop_notify: true});
@ -433,7 +433,7 @@ test("basic_notifications", () => {
assert.equal(n.has("Gus Fring to general > lunch"), true); assert.equal(n.has("Gus Fring to general > lunch"), true);
assert.equal(n.has("Jesse Pinkman to general > whatever"), true); assert.equal(n.has("Jesse Pinkman to general > whatever"), true);
assert.equal(n.size, 2); assert.equal(n.size, 2);
assert.equal(last_shown_message_id, message_2.id); assert.equal(last_shown_message_id, message_2.id.toString());
// Remove notifications. // Remove notifications.
desktop_notifications.close_notification(message_1); desktop_notifications.close_notification(message_1);
@ -441,5 +441,5 @@ test("basic_notifications", () => {
n = desktop_notifications.get_notifications(); n = desktop_notifications.get_notifications();
assert.equal(n.has("Jesse Pinkman to general > whatever"), false); assert.equal(n.has("Jesse Pinkman to general > whatever"), false);
assert.equal(n.size, 0); assert.equal(n.size, 0);
assert.equal(last_closed_message_id, message_2.id); assert.equal(last_closed_message_id, message_2.id.toString());
}); });