message_overlay: Fix restore tooltips detached with message content.

To avoid restore tooltip of message from being displayed outside
the overlay, we define a boundary, outside which the tooltip
cannot exist. Popper library is smart enough to render the tooltip
correctly by respecting the provided boundary and flipping the
tooltip placement if required.
This commit is contained in:
Aman Agrawal
2025-04-11 13:17:32 +05:30
committed by Tim Abbott
parent b11cbbab01
commit cd439c0232
6 changed files with 37 additions and 2 deletions

View File

@@ -288,6 +288,7 @@ export function launch(): void {
const first_element_id = [...formatted_narrow_drafts, ...formatted_other_drafts][0]?.draft_id;
messages_overlay_ui.set_initial_element(first_element_id, keyboard_handling_context);
setup_event_handlers();
messages_overlay_ui.initialize_restore_overlay_message_tooltip();
}
export function update_bulk_delete_ui(): void {

View File

@@ -1,6 +1,9 @@
import $ from "jquery";
import assert from "minimalistic-assert";
import * as tippy from "tippy.js";
import {LONG_HOVER_DELAY} from "./tippyjs.ts";
import {parse_html} from "./ui_util.ts";
import * as util from "./util.ts";
export type Context = {
@@ -183,3 +186,32 @@ function scroll_to_element($element: JQuery, context: Context): void {
function get_element_by_id(id: string, context: Context): JQuery {
return $(`.overlay-message-row[${CSS.escape(context.id_attribute_name)}='${CSS.escape(id)}']`);
}
export function initialize_restore_overlay_message_tooltip(): void {
tippy.default(".message_content.restore-overlay-message", {
delay: LONG_HOVER_DELAY,
placement: "top",
content(reference) {
const template_id = $(reference).attr("data-tooltip-template-id");
assert(template_id !== undefined);
const $template = $(`#${CSS.escape(template_id)}`);
return parse_html($template.html());
},
popperOptions: {
modifiers: [
{
name: "preventOverflow",
options: {
// Prevent tooltip from overflowing the message list boundary.
// If it overflows, tooltip uses bottom placement.
// If it overflows from both top and bottom, tooltip is placed
// at the top overlapping with message content.
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
boundary: document.querySelector(".overlay-messages-list")!,
altAxis: true,
},
},
],
},
});
}

View File

@@ -146,6 +146,7 @@ export function launch(): void {
const first_element_id = keyboard_handling_context.get_items_ids()[0];
messages_overlay_ui.set_initial_element(first_element_id, keyboard_handling_context);
messages_overlay_ui.initialize_restore_overlay_message_tooltip();
}
export function rerender(): void {

View File

@@ -49,7 +49,7 @@
</div>
</div>
</div>
<div class="message_content rendered_markdown restore-overlay-message tippy-zulip-delayed-tooltip" data-tooltip-template-id="restore-draft-tooltip-template">{{rendered_markdown content}}</div>
<div class="message_content rendered_markdown restore-overlay-message" data-tooltip-template-id="restore-draft-tooltip-template">{{rendered_markdown content}}</div>
</div>
</div>
</div>

View File

@@ -40,7 +40,7 @@
<i class="fa fa-trash-o fa-lg delete-overlay-message tippy-zulip-tooltip" aria-hidden="true" data-tooltip-template-id="delete-scheduled-message-tooltip-template"></i>
</div>
</div>
<div class="message_content rendered_markdown restore-overlay-message tippy-zulip-delayed-tooltip" data-tooltip-template-id="restore-scheduled-message-tooltip-template">{{rendered_markdown rendered_content}}</div>
<div class="message_content rendered_markdown restore-overlay-message" data-tooltip-template-id="restore-scheduled-message-tooltip-template">{{rendered_markdown rendered_content}}</div>
</div>
</div>
</div>

View File

@@ -9,6 +9,7 @@ const $ = require("./lib/zjquery.cjs");
const user_pill = mock_esm("../src/user_pill");
const messages_overlay_ui = mock_esm("../src/messages_overlay_ui");
messages_overlay_ui.initialize_restore_overlay_message_tooltip = noop;
const compose_pm_pill = zrequire("compose_pm_pill");
const people = zrequire("people");