tooltips: Refactor left sidebar tooltips to its own module.

This commit refactors tooltip targeting left sidebar elements
into its separate module in `left_sidebar_tooltips`.
This commit is contained in:
Pratik Chanda
2025-02-02 20:25:39 +05:30
committed by Tim Abbott
parent 56ba72c0b7
commit 1545a75645
4 changed files with 219 additions and 197 deletions

View File

@@ -128,6 +128,7 @@ EXEMPT_FILES = make_set(
"web/src/invite_stream_picker_pill.ts",
"web/src/left_sidebar_navigation_area.ts",
"web/src/left_sidebar_navigation_area_popovers.ts",
"web/src/left_sidebar_tooltips.ts",
"web/src/lightbox.ts",
"web/src/list_util.ts",
"web/src/list_widget.ts",

View File

@@ -0,0 +1,215 @@
import $ from "jquery";
import * as tippy from "tippy.js";
import * as drafts from "./drafts.ts";
import {$t} from "./i18n.ts";
import * as scheduled_messages from "./scheduled_messages.ts";
import * as starred_messages from "./starred_messages.ts";
import {
EXTRA_LONG_HOVER_DELAY,
LONG_HOVER_DELAY,
get_tooltip_content,
topic_visibility_policy_tooltip_props,
} from "./tippyjs.ts";
import * as unread from "./unread.ts";
import {user_settings} from "./user_settings.ts";
export function initialize(): void {
tippy.delegate("body", {
target: ".tippy-left-sidebar-tooltip",
placement: "right",
delay: EXTRA_LONG_HOVER_DELAY,
appendTo: () => document.body,
onShow(instance) {
const $container = $(instance.popper).find(".views-tooltip-container");
let display_count = 0;
const sidebar_option = $container.attr("data-view-code");
switch (sidebar_option) {
case user_settings.web_home_view:
$container.find(".views-tooltip-home-view-note").removeClass("hide");
display_count = unread.get_counts().home_unread_messages;
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no unread messages} one {# unread message} other {# unread messages}}.",
},
{display_count},
),
);
break;
case "mentions":
display_count = unread.unread_mentions_counter.size;
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no unread mentions} one {# unread mention} other {# unread mentions}}.",
},
{display_count},
),
);
break;
case "starred_message":
display_count = starred_messages.get_count();
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no starred messages} one {# starred message} other {# starred messages}}.",
},
{display_count},
),
);
break;
case "drafts":
display_count = drafts.draft_model.getDraftCount();
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no drafts} one {# draft} other {# drafts}}.",
},
{display_count},
),
);
break;
case "scheduled_message":
display_count = scheduled_messages.get_count();
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no scheduled messages} one {# scheduled message} other {# scheduled messages}}.",
},
{display_count},
),
);
break;
}
// Since the tooltip is attached to the anchor tag which doesn't
// include width of the ellipsis icon, we need to offset the
// tooltip so that the tooltip is displayed to right of the
// ellipsis icon.
if (instance.reference.classList.contains("left-sidebar-navigation-label-container")) {
instance.setProps({
offset: [0, 40],
});
}
},
onHidden(instance) {
instance.destroy();
},
popperOptions: {
modifiers: [
{
name: "flip",
options: {
fallbackPlacements: "bottom",
},
},
],
},
});
// Variant of .tippy-left-sidebar-tooltip configuration. Since
// some elements don't have an always visible label, and
// thus hovering them is a way to find out what they do, give
// them the shorter LONG_HOVER_DELAY.
tippy.delegate("body", {
target: ".tippy-left-sidebar-tooltip-no-label-delay",
placement: "right",
delay: LONG_HOVER_DELAY,
appendTo: () => document.body,
popperOptions: {
modifiers: [
{
name: "flip",
options: {
fallbackPlacements: "bottom",
},
},
],
},
});
tippy.delegate("body", {
target: [
"#streams_header .streams-tooltip-target",
"#add_streams_tooltip",
"#filter_streams_tooltip",
].join(","),
appendTo: () => document.body,
});
tippy.delegate("body", {
target: ".views-tooltip-target",
onShow(instance) {
if ($("#toggle-top-left-navigation-area-icon").hasClass("rotate-icon-down")) {
instance.setContent(
$t({
defaultMessage: "Collapse views",
}),
);
} else {
instance.setContent($t({defaultMessage: "Expand views"}));
}
},
delay: EXTRA_LONG_HOVER_DELAY,
appendTo: () => document.body,
});
tippy.delegate("body", {
target: ".dm-tooltip-target",
onShow(instance) {
if ($(".direct-messages-container").hasClass("zoom-in")) {
return false;
}
if ($("#toggle-direct-messages-section-icon").hasClass("rotate-icon-down")) {
instance.setContent(
$t({
defaultMessage: "Collapse direct messages",
}),
);
} else {
instance.setContent($t({defaultMessage: "Expand direct messages"}));
}
return undefined;
},
delay: EXTRA_LONG_HOVER_DELAY,
appendTo: () => document.body,
onHidden(instance) {
instance.destroy();
},
});
tippy.delegate("body", {
target: ".header-main .column-left .left-sidebar-toggle-button",
delay: LONG_HOVER_DELAY,
placement: "bottom",
appendTo: () => document.body,
onShow(instance) {
let template = "show-left-sidebar-tooltip-template";
if ($("#left-sidebar-container").is(":visible")) {
template = "hide-left-sidebar-tooltip-template";
}
$(instance.reference).attr("data-tooltip-template-id", template);
instance.setContent(get_tooltip_content(instance.reference));
},
onHidden(instance) {
instance.destroy();
},
});
tippy.delegate("body", {
target: [
"#recent_view .recipient_bar_icon",
"#inbox-view .recipient_bar_icon",
"#left-sidebar-container .visibility-policy-icon",
].join(","),
...topic_visibility_policy_tooltip_props,
});
}

View File

@@ -7,21 +7,17 @@ import render_change_visibility_policy_button_tooltip from "../templates/change_
import render_org_logo_tooltip from "../templates/org_logo_tooltip.hbs";
import render_tooltip_templates from "../templates/tooltip_templates.hbs";
import * as drafts from "./drafts.ts";
import {$t} from "./i18n.ts";
import * as people from "./people.ts";
import * as scheduled_messages from "./scheduled_messages.ts";
import * as settings_config from "./settings_config.ts";
import * as starred_messages from "./starred_messages.ts";
import * as stream_data from "./stream_data.ts";
import * as ui_util from "./ui_util.ts";
import * as unread from "./unread.ts";
import {user_settings} from "./user_settings.ts";
import * as util from "./util.ts";
// For tooltips without data-tippy-content, we use the HTML content of
// a <template> whose id is given by data-tooltip-template-id.
function get_tooltip_content(reference: Element): string | Element | DocumentFragment {
export function get_tooltip_content(reference: Element): string | Element | DocumentFragment {
if (reference instanceof HTMLElement && reference.dataset.tooltipTemplateId !== undefined) {
const template = document.querySelector<HTMLTemplateElement>(
`template#${CSS.escape(reference.dataset.tooltipTemplateId)}`,
@@ -187,126 +183,6 @@ export function initialize(): void {
},
});
tippy.delegate("body", {
target: ".tippy-left-sidebar-tooltip",
placement: "right",
delay: EXTRA_LONG_HOVER_DELAY,
appendTo: () => document.body,
onShow(instance) {
const $container = $(instance.popper).find(".views-tooltip-container");
let display_count = 0;
const sidebar_option = $container.attr("data-view-code");
switch (sidebar_option) {
case user_settings.web_home_view:
$container.find(".views-tooltip-home-view-note").removeClass("hide");
display_count = unread.get_counts().home_unread_messages;
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no unread messages} one {# unread message} other {# unread messages}}.",
},
{display_count},
),
);
break;
case "mentions":
display_count = unread.unread_mentions_counter.size;
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no unread mentions} one {# unread mention} other {# unread mentions}}.",
},
{display_count},
),
);
break;
case "starred_message":
display_count = starred_messages.get_count();
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no starred messages} one {# starred message} other {# starred messages}}.",
},
{display_count},
),
);
break;
case "drafts":
display_count = drafts.draft_model.getDraftCount();
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no drafts} one {# draft} other {# drafts}}.",
},
{display_count},
),
);
break;
case "scheduled_message":
display_count = scheduled_messages.get_count();
$container.find(".views-message-count").text(
$t(
{
defaultMessage:
"You have {display_count, plural, =0 {no scheduled messages} one {# scheduled message} other {# scheduled messages}}.",
},
{display_count},
),
);
break;
}
// Since the tooltip is attached to the anchor tag which doesn't
// include width of the ellipsis icon, we need to offset the
// tooltip so that the tooltip is displayed to right of the
// ellipsis icon.
if (instance.reference.classList.contains("left-sidebar-navigation-label-container")) {
instance.setProps({
offset: [0, 40],
});
}
},
onHidden(instance) {
instance.destroy();
},
popperOptions: {
modifiers: [
{
name: "flip",
options: {
fallbackPlacements: "bottom",
},
},
],
},
});
// Variant of .tippy-left-sidebar-tooltip configuration. Since
// some elements don't have an always visible label, and
// thus hovering them is a way to find out what they do, give
// them the shorter LONG_HOVER_DELAY.
tippy.delegate("body", {
target: ".tippy-left-sidebar-tooltip-no-label-delay",
placement: "right",
delay: LONG_HOVER_DELAY,
appendTo: () => document.body,
popperOptions: {
modifiers: [
{
name: "flip",
options: {
fallbackPlacements: "bottom",
},
},
],
},
});
// The below definitions are for specific tooltips that require
// custom JavaScript code or configuration. Note that since the
// below specify the target directly, elements using those should
@@ -368,12 +244,9 @@ export function initialize(): void {
tippy.delegate("body", {
target: [
"#streams_header .streams-tooltip-target",
"#scroll-to-bottom-button-clickable-area",
".spectator_narrow_login_button",
"#stream-specific-notify-table .unmute_stream",
"#add_streams_tooltip",
"#filter_streams_tooltip",
".error-icon-message-recipient .zulip-icon",
"#personal-menu-dropdown .status-circle",
".popover-group-menu-member-list .popover-group-menu-user-presence",
@@ -596,48 +469,6 @@ export function initialize(): void {
appendTo: () => document.body,
});
tippy.delegate("body", {
target: ".views-tooltip-target",
onShow(instance) {
if ($("#toggle-top-left-navigation-area-icon").hasClass("rotate-icon-down")) {
instance.setContent(
$t({
defaultMessage: "Collapse views",
}),
);
} else {
instance.setContent($t({defaultMessage: "Expand views"}));
}
},
delay: EXTRA_LONG_HOVER_DELAY,
appendTo: () => document.body,
});
tippy.delegate("body", {
target: ".dm-tooltip-target",
onShow(instance) {
if ($(".direct-messages-container").hasClass("zoom-in")) {
return false;
}
if ($("#toggle-direct-messages-section-icon").hasClass("rotate-icon-down")) {
instance.setContent(
$t({
defaultMessage: "Collapse direct messages",
}),
);
} else {
instance.setContent($t({defaultMessage: "Expand direct messages"}));
}
return undefined;
},
delay: EXTRA_LONG_HOVER_DELAY,
appendTo: () => document.body,
onHidden(instance) {
instance.destroy();
},
});
tippy.delegate("body", {
target: "#stream_creation_form .add_subscribers_disabled",
content: $t({
@@ -752,24 +583,6 @@ export function initialize(): void {
},
});
tippy.delegate("body", {
target: ".header-main .column-left .left-sidebar-toggle-button",
delay: LONG_HOVER_DELAY,
placement: "bottom",
appendTo: () => document.body,
onShow(instance) {
let template = "show-left-sidebar-tooltip-template";
if ($("#left-sidebar-container").is(":visible")) {
template = "hide-left-sidebar-tooltip-template";
}
$(instance.reference).attr("data-tooltip-template-id", template);
instance.setContent(get_tooltip_content(instance.reference));
},
onHidden(instance) {
instance.destroy();
},
});
tippy.delegate("body", {
target: "#userlist-toggle-button",
delay: LONG_HOVER_DELAY,
@@ -804,15 +617,6 @@ export function initialize(): void {
},
});
tippy.delegate("body", {
target: [
"#recent_view .recipient_bar_icon",
"#inbox-view .recipient_bar_icon",
"#left-sidebar-container .visibility-policy-icon",
].join(","),
...topic_visibility_policy_tooltip_props,
});
tippy.delegate("body", {
target: ".custom-user-field-label-wrapper.required-field-wrapper",
content: $t({

View File

@@ -56,6 +56,7 @@ import * as information_density from "./information_density.ts";
import * as invite from "./invite.ts";
import * as left_sidebar_navigation_area from "./left_sidebar_navigation_area.ts";
import * as left_sidebar_navigation_area_popovers from "./left_sidebar_navigation_area_popovers.ts";
import * as left_sidebar_tooltips from "./left_sidebar_tooltips.ts";
import * as lightbox from "./lightbox.ts";
import * as linkifiers from "./linkifiers.ts";
import * as local_message from "./local_message.ts";
@@ -444,6 +445,7 @@ export function initialize_everything(state_data) {
tippyjs.initialize();
compose_tooltips.initialize();
message_list_tooltips.initialize();
left_sidebar_tooltips.initialize();
// This populates data for scheduled messages.
scheduled_messages.initialize(state_data.scheduled_messages);
scheduled_messages_ui.initialize();