From e15edc84c2956c67dc32c1ecdb28cfb985eca74a Mon Sep 17 00:00:00 2001 From: Prakhar Pratyush Date: Thu, 30 Oct 2025 23:06:11 +0530 Subject: [PATCH] desktop_notification: Fix error when message deleted while narrowing. Earlier: When a user clicked the desktop notification, but before we finished processing that click, the message deletion got processed. It resulted in an error. This commit fixes the bug by taking the user to the conversation where the now-deleted message had been prior to deletion - narrow to the message's near view. Signed-off-by: Prakhar Pratyush --- web/src/hotkey.ts | 26 ++------------------------ web/src/message_notifications.ts | 5 ++++- web/src/message_view.ts | 30 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/web/src/hotkey.ts b/web/src/hotkey.ts index 9f7f28e2f8..6bdb76b447 100644 --- a/web/src/hotkey.ts +++ b/web/src/hotkey.ts @@ -1473,30 +1473,8 @@ function process_hotkey(e: JQuery.KeyDownEvent, hotkey: Hotkey): boolean { // The following code is essentially equivalent to // `window.location = hashutil.by_conversation_and_time_url(msg)` // but we use `message_view.show` to pass in the `trigger` parameter - switch (msg.type) { - case "private": - message_view.show( - [ - {operator: "dm", operand: msg.reply_to}, - {operator: "near", operand: String(msg.id)}, - ], - {trigger: "hotkey"}, - ); - return true; - case "stream": - message_view.show( - [ - { - operator: "channel", - operand: msg.stream_id.toString(), - }, - {operator: "topic", operand: msg.topic}, - {operator: "near", operand: String(msg.id)}, - ], - {trigger: "hotkey"}, - ); - return true; - } + message_view.narrow_to_message_near(msg, "hotkey"); + return true; } } diff --git a/web/src/message_notifications.ts b/web/src/message_notifications.ts index 7e52b06da8..ec9e0ce2e9 100644 --- a/web/src/message_notifications.ts +++ b/web/src/message_notifications.ts @@ -210,7 +210,10 @@ export function process_notification(notification: { notification_object.addEventListener("click", () => { notification_object.close(); if (message.type !== "test-notification") { - message_view.narrow_by_topic(message.id, {trigger: "notification"}); + // Narrowing to message's near view helps to handle the case + // where a user clicked the notification, but before narrowing + // the message deletion got processed. + message_view.narrow_to_message_near(message, "notification"); } window.focus(); }); diff --git a/web/src/message_view.ts b/web/src/message_view.ts index 164783632a..d6cba82d85 100644 --- a/web/src/message_view.ts +++ b/web/src/message_view.ts @@ -39,6 +39,7 @@ import * as message_lists from "./message_lists.ts"; import * as message_scroll_state from "./message_scroll_state.ts"; import {raw_message_schema} from "./message_store.ts"; import * as message_store from "./message_store.ts"; +import type {Message} from "./message_store.ts"; import * as message_view_header from "./message_view_header.ts"; import * as message_viewport from "./message_viewport.ts"; import * as narrow_banner from "./narrow_banner.ts"; @@ -1534,3 +1535,32 @@ export function rerender_combined_feed(combined_feed_msg_list: MessageList): voi force_rerender: true, }); } + +export function narrow_to_message_near(message: Message, trigger: string): void { + // The following code is essentially equivalent to + // `window.location.href = hashutil.by_conversation_and_time_url(msg)` + // but we use `show` to pass in the `trigger` parameter. + switch (message.type) { + case "private": + show( + [ + {operator: "dm", operand: message.reply_to}, + {operator: "near", operand: String(message.id)}, + ], + {trigger}, + ); + return; + case "stream": + show( + [ + { + operator: "channel", + operand: message.stream_id.toString(), + }, + {operator: "topic", operand: message.topic}, + {operator: "near", operand: String(message.id)}, + ], + {trigger}, + ); + } +}