From aeebbbb825bedc36a53c17efcf542146da1aedbf Mon Sep 17 00:00:00 2001 From: Pratik Chanda Date: Fri, 13 Sep 2024 03:47:58 +0530 Subject: [PATCH] tooltips: Defer computing last_edit_timestr until tooltip renders. Earlier, we used to compute last_edit_timestr as data-tippy-content when rendering the whole message feed. This commit changes the behaviour by computing the `last_edit_timestr` when a user hovers over the message_edit_notice. Fixes: zulip#27240. --- web/src/message_list_tooltips.ts | 35 +++++++++++- web/src/message_list_view.ts | 53 +++++-------------- web/templates/edited_notice.hbs | 6 +-- web/templates/message_edit_notice_tooltip.hbs | 6 ++- 4 files changed, 55 insertions(+), 45 deletions(-) diff --git a/web/src/message_list_tooltips.ts b/web/src/message_list_tooltips.ts index 58992b8a4a..6081d3db54 100644 --- a/web/src/message_list_tooltips.ts +++ b/web/src/message_list_tooltips.ts @@ -6,7 +6,9 @@ import render_message_edit_notice_tooltip from "../templates/message_edit_notice import render_message_inline_image_tooltip from "../templates/message_inline_image_tooltip.hbs"; import render_narrow_tooltip from "../templates/narrow_tooltip.hbs"; +import {$t} from "./i18n"; import * as message_lists from "./message_lists"; +import type {Message} from "./message_store"; import * as popover_menus from "./popover_menus"; import * as reactions from "./reactions"; import * as rows from "./rows"; @@ -120,6 +122,30 @@ export function destroy_all_message_list_tooltips(): void { message_list_tippy_instances.clear(); } +function get_last_edit_timestr(message: Message): string { + let last_edit_timestamp; + if (message.local_edit_timestamp !== undefined) { + last_edit_timestamp = message.local_edit_timestamp; + } else { + last_edit_timestamp = message.last_edit_timestamp!; + } + const last_edit_time = new Date(last_edit_timestamp * 1000); + let date = timerender.render_date(last_edit_time).textContent; + // If the date is today or yesterday, we don't want to show the date as capitalized. + // Thus, we need to check if the date string contains a digit or not using regex, + // since any other date except today/yesterday will contain a digit. + if (date && !/\d/.test(date)) { + date = date.toLowerCase(); + } + return $t( + {defaultMessage: "{date} at {time}"}, + { + date, + time: timerender.stringify_time(last_edit_time), + }, + ); +} + export function initialize(): void { message_list_tooltip(".tippy-narrow-tooltip", { delay: LONG_HOVER_DELAY, @@ -338,11 +364,16 @@ export function initialize(): void { }, onShow(instance) { const $elem = $(instance.reference); - const edited_notice_str = $elem.attr("data-tippy-content"); + assert(message_lists.current !== undefined); + const message_id = Number($elem.closest(".message_row").attr("data-message-id")); + const message_container = message_lists.current.view.message_containers.get(message_id); + assert(message_container !== undefined); + const last_edit_timestr = get_last_edit_timestr(message_container.msg); instance.setContent( parse_html( render_message_edit_notice_tooltip({ - edited_notice_str, + message_container, + last_edit_timestr, realm_allow_edit_history: realm.realm_allow_edit_history, }), ), diff --git a/web/src/message_list_view.ts b/web/src/message_list_view.ts index 05da22947b..ee62d2b3bf 100644 --- a/web/src/message_list_view.ts +++ b/web/src/message_list_view.ts @@ -53,7 +53,7 @@ export type MessageContainer = { include_recipient: boolean; include_sender: boolean; is_hidden: boolean; - last_edit_timestr: string | undefined; + last_edit_timestamp: number | undefined; mention_classname: string | undefined; message_edit_notices_in_left_col: boolean; message_edit_notices_alongside_sender: boolean; @@ -161,7 +161,7 @@ function same_recipient(a: MessageContainer | undefined, b: MessageContainer | u function analyze_edit_history( message: Message, - last_edit_timestr: string | undefined, + last_edit_timestamp: number | undefined, ): { edited: boolean; moved: boolean; @@ -212,9 +212,9 @@ function analyze_edit_history( moved = true; } } - } else if (last_edit_timestr !== undefined) { + } else if (last_edit_timestamp !== undefined) { // When the edit_history is disabled for the organization, we do not receive the edit_history - // variable in the message object. In this case, we will check if the last_edit_timestr is + // variable in the message object. In this case, we will check if the last_edit_timestamp is // available or not. Since we don't have the edit_history, we can't determine if the message // was moved or edited. Therefore, we simply mark the messages as edited. edited = true; @@ -597,59 +597,34 @@ export class MessageListView { ); } - _get_msg_timestring(message: Message): string | undefined { + _get_message_edited_vars(message: Message): { + last_edit_timestamp: number | undefined; + moved: boolean; + modified: boolean; + } { let last_edit_timestamp; if (message.local_edit_timestamp !== undefined) { last_edit_timestamp = message.local_edit_timestamp; } else { last_edit_timestamp = message.last_edit_timestamp; } - if (last_edit_timestamp !== undefined) { - const last_edit_time = new Date(last_edit_timestamp * 1000); - let date = timerender.render_date(last_edit_time).textContent; - // If the date is today or yesterday, we don't want to show the date as capitalized. - // Thus, we need to check if the date string contains a digit or not using regex, - // since any other date except today/yesterday will contain a digit. - if (date && !/\d/.test(date)) { - date = date.toLowerCase(); - } - return $t( - {defaultMessage: "{date} at {time}"}, - { - date, - time: timerender.stringify_time(last_edit_time), - }, - ); - } - return undefined; - } + const edit_history_details = analyze_edit_history(message, last_edit_timestamp); - _get_message_edited_vars(message: Message): { - last_edit_timestr: string | undefined; - moved: boolean; - modified: boolean; - } { - const last_edit_timestr = this._get_msg_timestring(message); - const edit_history_details = analyze_edit_history(message, last_edit_timestr); - - if ( - last_edit_timestr === undefined || - !(edit_history_details.moved || edit_history_details.edited) - ) { + if (!last_edit_timestamp || !(edit_history_details.moved || edit_history_details.edited)) { // For messages whose edit history at most includes // resolving topics, we don't display an EDITED/MOVED // notice at all. (The message actions popover will still // display an edit history option, so you can see when it // was marked as resolved if you need to). return { - last_edit_timestr: undefined, + last_edit_timestamp: undefined, moved: false, modified: false, }; } return { - last_edit_timestr, + last_edit_timestamp, moved: edit_history_details.moved && !edit_history_details.edited, modified: true, }; @@ -674,7 +649,7 @@ export class MessageListView { mention_classname: string | undefined; include_sender: boolean; status_message: string | false; - last_edit_timestr: string | undefined; + last_edit_timestamp: number | undefined; moved: boolean; modified: boolean; } { diff --git a/web/templates/edited_notice.hbs b/web/templates/edited_notice.hbs index d7e25e4e19..a4931cfccc 100644 --- a/web/templates/edited_notice.hbs +++ b/web/templates/edited_notice.hbs @@ -1,14 +1,14 @@ {{#if modified}} {{#if msg/local_edit_timestamp}} -
+
{{t "SAVING"}}
{{else if moved}} -
+
{{t "MOVED"}}
{{else}} -
+
{{t "EDITED"}}
{{/if}} diff --git a/web/templates/message_edit_notice_tooltip.hbs b/web/templates/message_edit_notice_tooltip.hbs index 69ff0dd489..9f0f6418ff 100644 --- a/web/templates/message_edit_notice_tooltip.hbs +++ b/web/templates/message_edit_notice_tooltip.hbs @@ -1,7 +1,11 @@
{{t "View edit history"}}
{{#if realm_allow_edit_history}} -
{{edited_notice_str}}
+ {{#if message_container/moved}} +
{{t 'Last moved {last_edit_timestr}.'}}
+ {{else}} +
{{t 'Last edited {last_edit_timestr}.'}}
+ {{/if}} {{/if}}
{{tooltip_hotkey_hints "Shift" "H"}}