user_card_popover: Convert module to TypeScript.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2024-11-27 17:27:36 -08:00
committed by Tim Abbott
parent d8d8e620e7
commit ee11d73c1f
8 changed files with 183 additions and 138 deletions

View File

@@ -266,7 +266,7 @@ EXEMPT_FILES = make_set(
"web/src/unread_ui.ts", "web/src/unread_ui.ts",
"web/src/upload.ts", "web/src/upload.ts",
"web/src/upload_widget.ts", "web/src/upload_widget.ts",
"web/src/user_card_popover.js", "web/src/user_card_popover.ts",
"web/src/user_deactivation_ui.ts", "web/src/user_deactivation_ui.ts",
"web/src/user_events.js", "web/src/user_events.js",
"web/src/user_group_components.ts", "web/src/user_group_components.ts",

View File

@@ -3,10 +3,7 @@ import * as tippy from "tippy.js";
import {$t} from "./i18n.ts"; import {$t} from "./i18n.ts";
function show_copied_tooltip( function show_copied_tooltip(copy_button: Element, on_hide_callback?: () => void): tippy.Instance {
copy_button: HTMLElement,
on_hide_callback?: () => void,
): tippy.Instance {
// Display a tooltip to notify the user the message or code was copied. // Display a tooltip to notify the user the message or code was copied.
const instance = tippy.default(copy_button, { const instance = tippy.default(copy_button, {
placement: "top", placement: "top",
@@ -25,18 +22,18 @@ function show_copied_tooltip(
return instance; return instance;
} }
function show_check_icon(copy_button: HTMLElement): void { function show_check_icon(copy_button: Element): void {
$(copy_button).addClass("copy-button-success"); $(copy_button).addClass("copy-button-success");
$(copy_button).find(".zulip-icon").removeClass("zulip-icon-copy").addClass("zulip-icon-check"); $(copy_button).find(".zulip-icon").removeClass("zulip-icon-copy").addClass("zulip-icon-check");
} }
function remove_check_icon(copy_button: HTMLElement): void { function remove_check_icon(copy_button: Element): void {
$(copy_button).removeClass("copy-button-success"); $(copy_button).removeClass("copy-button-success");
$(copy_button).find(".zulip-icon").addClass("zulip-icon-copy").removeClass("zulip-icon-check"); $(copy_button).find(".zulip-icon").addClass("zulip-icon-copy").removeClass("zulip-icon-check");
} }
export function show_copied_confirmation( export function show_copied_confirmation(
copy_button: HTMLElement, copy_button: Element,
opts?: { opts?: {
show_check_icon?: boolean; show_check_icon?: boolean;
timeout_in_ms?: number; timeout_in_ms?: number;

View File

@@ -12,7 +12,7 @@ import * as messages_overlay_ui from "./messages_overlay_ui.ts";
import * as overlays from "./overlays.ts"; import * as overlays from "./overlays.ts";
import * as people from "./people.ts"; import * as people from "./people.ts";
import * as rendered_markdown from "./rendered_markdown.ts"; import * as rendered_markdown from "./rendered_markdown.ts";
import * as user_card_popover from "./user_card_popover.js"; import * as user_card_popover from "./user_card_popover.ts";
import * as user_group_popover from "./user_group_popover.ts"; import * as user_group_popover from "./user_group_popover.ts";
function restore_draft(draft_id) { function restore_draft(draft_id) {
@@ -193,9 +193,11 @@ export function launch() {
restore_draft(draft_id); restore_draft(draft_id);
}); });
$("#drafts_table .restore-overlay-message").on("click", ".user-mention", (e) => { $("#drafts_table .restore-overlay-message").on(
user_card_popover.unsaved_message_user_mention_event_handler(e); "click",
}); ".user-mention",
user_card_popover.unsaved_message_user_mention_event_handler,
);
$("#drafts_table .restore-overlay-message").on("click", ".user-group-mention", (e) => { $("#drafts_table .restore-overlay-message").on("click", ".user-group-mention", (e) => {
user_group_popover.toggle_user_group_info_popover(e.currentTarget, undefined); user_group_popover.toggle_user_group_info_popover(e.currentTarget, undefined);

View File

@@ -59,7 +59,7 @@ import * as stream_popover from "./stream_popover.ts";
import * as stream_settings_ui from "./stream_settings_ui.ts"; import * as stream_settings_ui from "./stream_settings_ui.ts";
import * as topic_list from "./topic_list.ts"; import * as topic_list from "./topic_list.ts";
import * as unread_ops from "./unread_ops.ts"; import * as unread_ops from "./unread_ops.ts";
import * as user_card_popover from "./user_card_popover.js"; import * as user_card_popover from "./user_card_popover.ts";
import * as user_group_popover from "./user_group_popover.ts"; import * as user_group_popover from "./user_group_popover.ts";
import {user_settings} from "./user_settings.ts"; import {user_settings} from "./user_settings.ts";
import * as user_topics_ui from "./user_topics_ui.ts"; import * as user_topics_ui from "./user_topics_ui.ts";

View File

@@ -78,7 +78,7 @@ export function popover_items_handle_keyboard(key: string, $items?: JQuery): voi
$items.eq(index).trigger("focus"); $items.eq(index).trigger("focus");
} }
export function focus_first_popover_item($items: JQuery, index = 0): void { export function focus_first_popover_item($items: JQuery | undefined, index = 0): void {
if (!$items) { if (!$items) {
return; return;
} }

View File

@@ -141,7 +141,7 @@ import * as unread from "./unread.ts";
import * as unread_ops from "./unread_ops.ts"; import * as unread_ops from "./unread_ops.ts";
import * as unread_ui from "./unread_ui.ts"; import * as unread_ui from "./unread_ui.ts";
import * as upload from "./upload.ts"; import * as upload from "./upload.ts";
import * as user_card_popover from "./user_card_popover.js"; import * as user_card_popover from "./user_card_popover.ts";
import * as user_group_edit from "./user_group_edit.js"; import * as user_group_edit from "./user_group_edit.js";
import * as user_group_edit_members from "./user_group_edit_members.ts"; import * as user_group_edit_members from "./user_group_edit_members.ts";
import * as user_group_popover from "./user_group_popover.ts"; import * as user_group_popover from "./user_group_popover.ts";

View File

@@ -28,6 +28,7 @@ import * as message_view from "./message_view.ts";
import * as muted_users from "./muted_users.ts"; import * as muted_users from "./muted_users.ts";
import * as overlays from "./overlays.ts"; import * as overlays from "./overlays.ts";
import {page_params} from "./page_params.ts"; import {page_params} from "./page_params.ts";
import type {User} from "./people.ts";
import * as people from "./people.ts"; import * as people from "./people.ts";
import * as popover_menus from "./popover_menus.ts"; import * as popover_menus from "./popover_menus.ts";
import {hide_all} from "./popovers.ts"; import {hide_all} from "./popovers.ts";
@@ -39,15 +40,17 @@ import * as timerender from "./timerender.ts";
import * as ui_report from "./ui_report.ts"; import * as ui_report from "./ui_report.ts";
import * as ui_util from "./ui_util.ts"; import * as ui_util from "./ui_util.ts";
import * as user_deactivation_ui from "./user_deactivation_ui.ts"; import * as user_deactivation_ui from "./user_deactivation_ui.ts";
import type {CustomProfileFieldData} from "./user_profile.ts";
import * as user_profile from "./user_profile.ts"; import * as user_profile from "./user_profile.ts";
import {user_settings} from "./user_settings.ts"; import {user_settings} from "./user_settings.ts";
import * as user_status from "./user_status.ts"; import * as user_status from "./user_status.ts";
import * as user_status_ui from "./user_status_ui.ts"; import * as user_status_ui from "./user_status_ui.ts";
import {the} from "./util.ts";
let current_user_sidebar_user_id; let current_user_sidebar_user_id: number | undefined;
export function confirm_mute_user(user_id) { export function confirm_mute_user(user_id: number): void {
function on_click() { function on_click(): void {
muted_users.mute_user(user_id); muted_users.mute_user(user_id);
} }
@@ -64,32 +67,30 @@ export function confirm_mute_user(user_id) {
} }
class PopoverMenu { class PopoverMenu {
instance: tippy.Instance | undefined;
constructor() { constructor() {
this.instance = null; this.instance = undefined;
} }
is_open() { is_open(): boolean {
return Boolean(this.instance); return Boolean(this.instance);
} }
hide() { hide(): void {
if (this.is_open()) { if (this.instance) {
this.instance.destroy(); this.instance.destroy();
this.instance = undefined; this.instance = undefined;
} }
} }
handle_keyboard(key) { handle_keyboard(key: string): void {
if (!this.is_open()) { if (!this.instance) {
blueslip.error("Trying to get the items when popover is closed."); blueslip.error("Trying to get the items when popover is closed.");
return; return;
} }
const $popover = $(this.instance?.popper); const $popover = $(this.instance.popper);
if (!$popover) {
blueslip.error("Cannot find popover data.");
return;
}
const $items = $("[tabindex='0']", $popover).filter(":visible"); const $items = $("[tabindex='0']", $popover).filter(":visible");
@@ -101,15 +102,11 @@ export const user_sidebar = new PopoverMenu();
export const message_user_card = new PopoverMenu(); export const message_user_card = new PopoverMenu();
export const user_card = new PopoverMenu(); export const user_card = new PopoverMenu();
function popover_items_handle_keyboard_with_overrides(key, $items) { function popover_items_handle_keyboard_with_overrides(key: string, $items: JQuery): void {
/* Variant of popover_items_handle_keyboard for focusing on the /* Variant of popover_items_handle_keyboard for focusing on the
user card popover menu options first, instead of other tabbable user card popover menu options first, instead of other tabbable
buttons and links which can be distracting. */ buttons and links which can be distracting. */
if (!$items) {
return;
}
const index = $items.index($items.filter(":focus")); const index = $items.index($items.filter(":focus"));
if (index === -1) { if (index === -1) {
@@ -124,7 +121,9 @@ function popover_items_handle_keyboard_with_overrides(key, $items) {
popover_menus.popover_items_handle_keyboard(key, $items); popover_menus.popover_items_handle_keyboard(key, $items);
} }
function get_popover_classname(popover) { function get_popover_classname(
popover: "user_sidebar" | "message_user_card" | "user_card",
): string {
const popovers = { const popovers = {
user_sidebar: "user-sidebar-popover-root", user_sidebar: "user-sidebar-popover-root",
message_user_card: "message-user-card-popover-root", message_user_card: "message-user-card-popover-root",
@@ -145,32 +144,30 @@ const user_card_popovers = {
user_card, user_card,
}; };
export function any_active() { export function any_active(): boolean {
return Object.values(user_card_popovers).some((instance) => instance.is_open()); return Object.values(user_card_popovers).some((instance) => instance.is_open());
} }
export function hide_all_instances() { export function hide_all_instances(): void {
for (const key in user_card_popovers) { for (const popover of Object.values(user_card_popovers)) {
if (user_card_popovers[key].hide) { popover.hide();
user_card_popovers[key].hide();
}
} }
} }
export function hide_all_user_card_popovers() { export function hide_all_user_card_popovers(): void {
hide_all_instances(); hide_all_instances();
} }
export function clear_for_testing() { export function clear_for_testing(): void {
message_user_card.instance = undefined; message_user_card.instance = undefined;
user_card.instance = undefined; user_card.instance = undefined;
} }
function elem_to_user_id($elem) { function elem_to_user_id($elem: JQuery): number {
return Number.parseInt($elem.attr("data-user-id"), 10); return Number.parseInt($elem.attr("data-user-id")!, 10);
} }
function clipboard_enable(arg) { function clipboard_enable(arg: HTMLElement | string): ClipboardJS {
// arg is a selector or element // arg is a selector or element
// We extract this function for testing purpose. // We extract this function for testing purpose.
return new ClipboardJS(arg); return new ClipboardJS(arg);
@@ -178,7 +175,7 @@ function clipboard_enable(arg) {
// Functions related to user card popover. // Functions related to user card popover.
export function toggle_user_card_popover(element, user) { export function toggle_user_card_popover(element: HTMLElement, user: User): void {
show_user_card_popover( show_user_card_popover(
user, user,
$(element), $(element),
@@ -190,7 +187,7 @@ export function toggle_user_card_popover(element, user) {
); );
} }
function toggle_user_card_popover_for_bot_owner(element, user) { function toggle_user_card_popover_for_bot_owner(element: HTMLElement, user: User): void {
show_user_card_popover( show_user_card_popover(
user, user,
$(element), $(element),
@@ -203,12 +200,49 @@ function toggle_user_card_popover_for_bot_owner(element, user) {
); );
} }
type UserCardPopoverData = {
invisible_mode: boolean;
can_send_private_message: boolean;
display_profile_fields: CustomProfileFieldData[];
has_message_context: boolean;
is_active: boolean;
is_bot: boolean;
is_me: boolean;
is_sender_popover: boolean;
pm_with_url: string;
user_circle_class: string;
private_message_class: string;
sent_by_url: string;
user_email: string | null;
user_full_name: string;
user_id: number;
user_last_seen_time_status: string;
user_time: string | undefined;
user_type: string | undefined;
status_content_available: boolean;
status_text: string | undefined;
status_emoji_info: user_status.UserStatusEmojiInfo | undefined;
show_placeholder_for_status_text: false | user_status.UserStatusEmojiInfo | undefined;
user_mention_syntax: string;
date_joined: string | undefined;
spectator_view: boolean;
should_add_guest_user_indicator: boolean;
user_avatar: string;
user_is_guest: boolean;
show_manage_section: boolean;
can_mute: boolean;
can_unmute: boolean;
can_manage_user: boolean;
is_system_bot?: boolean;
bot_owner?: User;
};
function get_user_card_popover_data( function get_user_card_popover_data(
user, user: User,
has_message_context, has_message_context: boolean,
is_sender_popover, is_sender_popover: boolean,
private_msg_class, private_msg_class: string,
) { ): UserCardPopoverData {
const is_me = people.is_my_user_id(user.user_id); const is_me = people.is_my_user_id(user.user_id);
let invisible_mode = false; let invisible_mode = false;
@@ -249,7 +283,7 @@ function get_user_card_popover_data(
const can_send_private_message = const can_send_private_message =
user_can_send_direct_message(user_id_string) && is_active && !is_me; user_can_send_direct_message(user_id_string) && is_active && !is_me;
const args = { const args: UserCardPopoverData = {
invisible_mode, invisible_mode,
can_send_private_message, can_send_private_message,
display_profile_fields, display_profile_fields,
@@ -268,7 +302,7 @@ function get_user_card_popover_data(
user_last_seen_time_status: buddy_data.user_last_seen_time_status(user.user_id), user_last_seen_time_status: buddy_data.user_last_seen_time_status(user.user_id),
user_time: people.get_user_time(user.user_id), user_time: people.get_user_time(user.user_id),
user_type: people.get_user_type(user.user_id), user_type: people.get_user_type(user.user_id),
status_content_available: Boolean(status_text || status_emoji_info), status_content_available: Boolean(status_text ?? status_emoji_info),
status_text, status_text,
status_emoji_info, status_emoji_info,
show_placeholder_for_status_text: !status_text && status_emoji_info, show_placeholder_for_status_text: !status_text && status_emoji_info,
@@ -289,7 +323,7 @@ function get_user_card_popover_data(
if (is_system_bot) { if (is_system_bot) {
args.is_system_bot = is_system_bot; args.is_system_bot = is_system_bot;
} else if (bot_owner_id) { } else if (bot_owner_id) {
const bot_owner = people.get_bot_owner_user(user); const bot_owner = people.get_user_by_id_assert_valid(bot_owner_id);
args.bot_owner = bot_owner; args.bot_owner = bot_owner;
} }
} }
@@ -298,16 +332,16 @@ function get_user_card_popover_data(
} }
function show_user_card_popover( function show_user_card_popover(
user, user: User,
$popover_element, $popover_element: JQuery,
is_sender_popover, is_sender_popover: boolean,
has_message_context, has_message_context: boolean,
private_msg_class, private_msg_class: string,
template_class, template_class: "user_sidebar" | "message_user_card" | "user_card",
popover_placement, popover_placement: tippy.Placement,
show_as_overlay, show_as_overlay = false,
on_mount, on_mount?: (instance: tippy.Instance) => void,
) { ): void {
let popover_html; let popover_html;
let args; let args;
if (user.is_inaccessible_user) { if (user.is_inaccessible_user) {
@@ -330,7 +364,7 @@ function show_user_card_popover(
} }
popover_menus.toggle_popover_menu( popover_menus.toggle_popover_menu(
$popover_element[0], the($popover_element),
{ {
theme: "popover-menu", theme: "popover-menu",
placement: popover_placement, placement: popover_placement,
@@ -369,7 +403,7 @@ function show_user_card_popover(
); );
} }
function init_email_clipboard() { function init_email_clipboard(): void {
/* /*
This shows (and enables) the copy-text icon for folks This shows (and enables) the copy-text icon for folks
who have names that would overflow past the right who have names that would overflow past the right
@@ -399,7 +433,7 @@ function init_email_clipboard() {
}); });
} }
function init_email_tooltip(user) { function init_email_tooltip(user: User): void {
/* /*
This displays the email tooltip for folks This displays the email tooltip for folks
who have names that would overflow past the right who have names that would overflow past the right
@@ -416,13 +450,13 @@ function init_email_tooltip(user) {
}); });
} }
function load_medium_avatar(user, $elt) { function load_medium_avatar(user: User, $elt: JQuery): void {
const user_avatar_url = people.medium_avatar_url_for_person(user); const user_avatar_url = people.medium_avatar_url_for_person(user);
const sender_avatar_medium = new Image(); const sender_avatar_medium = new Image();
sender_avatar_medium.src = user_avatar_url; sender_avatar_medium.src = user_avatar_url;
$(sender_avatar_medium).on("load", function () { $(sender_avatar_medium).on("load", function () {
$elt.attr("src", $(this).attr("src")); $elt.attr("src", $(this).attr("src")!);
}); });
} }
@@ -433,12 +467,12 @@ function load_medium_avatar(user, $elt) {
// sender_id is the user id of the sender for the message we are // sender_id is the user id of the sender for the message we are
// showing the popover from. // showing the popover from.
function toggle_user_card_popover_for_message( function toggle_user_card_popover_for_message(
element, element: HTMLElement,
user, user: User,
sender_id, sender_id: number,
has_message_context, has_message_context: boolean,
on_mount, on_mount?: (instance: tippy.Instance) => void,
) { ): void {
const $elt = $(element); const $elt = $(element);
const is_sender_popover = sender_id === user.user_id; const is_sender_popover = sender_id === user.user_id;
@@ -455,10 +489,13 @@ function toggle_user_card_popover_for_message(
); );
} }
export function unsaved_message_user_mention_event_handler(e) { export function unsaved_message_user_mention_event_handler(
this: HTMLElement,
e: JQuery.ClickEvent,
): void {
e.stopPropagation(); e.stopPropagation();
const id_string = $(e.currentTarget).attr("data-user-id"); const id_string = $(this).attr("data-user-id")!;
// Do not open popover for @all mention // Do not open popover for @all mention
if (id_string === "*") { if (id_string === "*") {
return; return;
@@ -467,12 +504,12 @@ export function unsaved_message_user_mention_event_handler(e) {
const user_id = Number.parseInt(id_string, 10); const user_id = Number.parseInt(id_string, 10);
const user = people.get_by_user_id(user_id); const user = people.get_by_user_id(user_id);
toggle_user_card_popover_for_message($(e.target), user, current_user.user_id, false); toggle_user_card_popover_for_message(this, user, current_user.user_id, false);
} }
// This function serves as the entry point for toggling // This function serves as the entry point for toggling
// the user card popover via keyboard shortcut. // the user card popover via keyboard shortcut.
export function toggle_sender_info() { export function toggle_sender_info(): void {
if (message_user_card.is_open()) { if (message_user_card.is_open()) {
// We need to call the hide method here because // We need to call the hide method here because
// the event wasn't triggered by the mouse. // the event wasn't triggered by the mouse.
@@ -491,32 +528,33 @@ export function toggle_sender_info() {
assert(message_lists.current !== undefined); assert(message_lists.current !== undefined);
const message = message_lists.current.get(rows.id($message)); const message = message_lists.current.get(rows.id($message));
assert(message !== undefined);
const user = people.get_by_user_id(message.sender_id); const user = people.get_by_user_id(message.sender_id);
toggle_user_card_popover_for_message($sender[0], user, message.sender_id, true, () => { toggle_user_card_popover_for_message(the($sender), user, message.sender_id, true, () => {
if (!page_params.is_spectator) { if (!page_params.is_spectator) {
focus_user_card_popover_item(); focus_user_card_popover_item();
} }
}); });
} }
function focus_user_card_popover_item() { function focus_user_card_popover_item(): void {
// For now I recommend only calling this when the user opens the menu with a hotkey. // For now I recommend only calling this when the user opens the menu with a hotkey.
// Our popup menus act kind of funny when you mix keyboard and mouse. // Our popup menus act kind of funny when you mix keyboard and mouse.
const $items = get_user_card_popover_for_message_items(); const $items = get_user_card_popover_for_message_items();
popover_menus.focus_first_popover_item($items); popover_menus.focus_first_popover_item($items);
} }
function get_user_card_popover_for_message_items() { function get_user_card_popover_for_message_items(): JQuery | undefined {
if (!message_user_card.is_open()) { if (!message_user_card.is_open()) {
blueslip.error("Trying to get menu items when message user card popover is closed."); blueslip.error("Trying to get menu items when message user card popover is closed.");
return undefined; return undefined;
} }
const $popover = $(message_user_card.instance.popper); if (message_user_card.instance === undefined) {
if (!$popover) {
blueslip.error("Cannot find popover data for message user card menu."); blueslip.error("Cannot find popover data for message user card menu.");
return undefined; return undefined;
} }
const $popover = $(message_user_card.instance.popper);
// Return only the popover menu options that are visible, and not the // Return only the popover menu options that are visible, and not the
// copy buttons or the link items in the custom profile fields. // copy buttons or the link items in the custom profile fields.
@@ -525,7 +563,7 @@ function get_user_card_popover_for_message_items() {
// Functions related to the user card popover in the user sidebar. // Functions related to the user card popover in the user sidebar.
function toggle_sidebar_user_card_popover($target) { function toggle_sidebar_user_card_popover($target: JQuery): void {
const user_id = elem_to_user_id($target); const user_id = elem_to_user_id($target);
const user = people.get_by_user_id(user_id); const user = people.get_by_user_id(user_id);
@@ -558,17 +596,22 @@ function toggle_sidebar_user_card_popover($target) {
current_user_sidebar_user_id = user.user_id; current_user_sidebar_user_id = user.user_id;
} }
function register_click_handlers() { function register_click_handlers(): void {
$("#main_div").on("click", ".sender_name, .inline_profile_picture", function (e) { $("#main_div").on(
"click",
".sender_name, .inline_profile_picture",
function (this: HTMLElement, e) {
const $row = $(this).closest(".message_row"); const $row = $(this).closest(".message_row");
e.stopPropagation(); e.stopPropagation();
assert(message_lists.current !== undefined); assert(message_lists.current !== undefined);
const message = message_lists.current.get(rows.id($row)); const message = message_lists.current.get(rows.id($row));
assert(message !== undefined);
const user = people.get_by_user_id(message.sender_id); const user = people.get_by_user_id(message.sender_id);
toggle_user_card_popover_for_message(this, user, message.sender_id, true); toggle_user_card_popover_for_message(this, user, message.sender_id, true);
}); },
);
$("#main_div").on("click", ".user-mention", function (e) { $("#main_div").on("click", ".user-mention", function (this: HTMLElement, e) {
const id_string = $(this).attr("data-user-id"); const id_string = $(this).attr("data-user-id");
// We fallback to email to handle legacy Markdown that was rendered // We fallback to email to handle legacy Markdown that was rendered
// before we cut over to using data-user-id // before we cut over to using data-user-id
@@ -580,12 +623,13 @@ function register_click_handlers() {
e.stopPropagation(); e.stopPropagation();
assert(message_lists.current !== undefined); assert(message_lists.current !== undefined);
const message = message_lists.current.get(rows.id($row)); const message = message_lists.current.get(rows.id($row));
assert(message !== undefined);
let user; let user;
if (id_string) { if (id_string) {
const user_id = Number.parseInt(id_string, 10); const user_id = Number.parseInt(id_string, 10);
user = people.get_by_user_id(user_id); user = people.get_by_user_id(user_id);
} else { } else {
user = people.get_by_email(email); user = email === undefined ? undefined : people.get_by_email(email);
if (user === undefined) { if (user === undefined) {
// There can be a case when user is undefined if // There can be a case when user is undefined if
// the user is an inaccessible user as we do not // the user is an inaccessible user as we do not
@@ -603,8 +647,8 @@ function register_click_handlers() {
// that run before this one and call stopPropagation. // that run before this one and call stopPropagation.
$("body").on("click", ".messagebox .user-mention", unsaved_message_user_mention_event_handler); $("body").on("click", ".messagebox .user-mention", unsaved_message_user_mention_event_handler);
$("body").on("click", ".user-card-popover-actions .narrow_to_private_messages", (e) => { $("body").on("click", ".user-card-popover-actions .narrow_to_private_messages", function (e) {
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
const email = people.get_by_user_id(user_id).email; const email = people.get_by_user_id(user_id).email;
message_view.show( message_view.show(
[ [
@@ -623,8 +667,8 @@ function register_click_handlers() {
e.preventDefault(); e.preventDefault();
}); });
$("body").on("click", ".user-card-popover-actions .narrow_to_messages_sent", (e) => { $("body").on("click", ".user-card-popover-actions .narrow_to_messages_sent", function (e) {
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
const email = people.get_by_user_id(user_id).email; const email = people.get_by_user_id(user_id).email;
message_view.show( message_view.show(
[ [
@@ -645,9 +689,7 @@ function register_click_handlers() {
$("body").on("click", ".user-card-popover-actions .user-card-clear-status-button", (e) => { $("body").on("click", ".user-card-popover-actions .user-card-clear-status-button", (e) => {
e.preventDefault(); e.preventDefault();
const me = elem_to_user_id($(e.target).parents("ul"));
user_status.server_update_status({ user_status.server_update_status({
user_id: me,
status_text: "", status_text: "",
emoji_name: "", emoji_name: "",
emoji_code: "", emoji_code: "",
@@ -657,12 +699,12 @@ function register_click_handlers() {
}); });
}); });
$("body").on("click", ".sidebar-popover-reactivate-user", (e) => { $("body").on("click", ".sidebar-popover-reactivate-user", function (e) {
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
hide_all(); hide_all();
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
function handle_confirm() { function handle_confirm(): void {
const url = "/json/users/" + encodeURIComponent(user_id) + "/reactivate"; const url = "/json/users/" + encodeURIComponent(user_id) + "/reactivate";
channel.post({ channel.post({
url, url,
@@ -678,8 +720,8 @@ function register_click_handlers() {
user_deactivation_ui.confirm_reactivation(user_id, handle_confirm, true); user_deactivation_ui.confirm_reactivation(user_id, handle_confirm, true);
}); });
$("body").on("click", ".user-card-popover-actions .view_full_user_profile", (e) => { $("body").on("click", ".user-card-popover-actions .view_full_user_profile", function (e) {
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
const current_hash = window.location.hash; const current_hash = window.location.hash;
// If any overlay is already open, we want the user profile to behave // If any overlay is already open, we want the user profile to behave
// as a modal rather than an overlay. // as a modal rather than an overlay.
@@ -692,7 +734,7 @@ function register_click_handlers() {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
}); });
$("body").on("click", ".user-card-popover-root .mention_user", (e) => { $("body").on("click", ".user-card-popover-root .mention_user", function (e) {
if (!compose_state.composing()) { if (!compose_state.composing()) {
compose_actions.start({ compose_actions.start({
message_type: "stream", message_type: "stream",
@@ -700,7 +742,7 @@ function register_click_handlers() {
keep_composebox_empty: true, keep_composebox_empty: true,
}); });
} }
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
const name = people.get_by_user_id(user_id).full_name; const name = people.get_by_user_id(user_id).full_name;
const mention = people.get_mention_syntax(name, user_id); const mention = people.get_mention_syntax(name, user_id);
compose_ui.insert_syntax_and_focus(mention); compose_ui.insert_syntax_and_focus(mention);
@@ -710,14 +752,14 @@ function register_click_handlers() {
e.preventDefault(); e.preventDefault();
}); });
$("body").on("click", ".message-user-card-popover-root .mention_user", (e) => { $("body").on("click", ".message-user-card-popover-root .mention_user", function (e) {
if (!compose_state.composing()) { if (!compose_state.composing()) {
compose_reply.respond_to_message({ compose_reply.respond_to_message({
trigger: "user sidebar popover", trigger: "user sidebar popover",
keep_composebox_empty: true, keep_composebox_empty: true,
}); });
} }
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
const name = people.get_by_user_id(user_id).full_name; const name = people.get_by_user_id(user_id).full_name;
const is_active = people.is_active_user_for_popover(user_id); const is_active = people.is_active_user_for_popover(user_id);
const mention = people.get_mention_syntax(name, user_id, !is_active); const mention = people.get_mention_syntax(name, user_id, !is_active);
@@ -727,18 +769,22 @@ function register_click_handlers() {
e.preventDefault(); e.preventDefault();
}); });
$("body").on("click", ".view_user_profile, .person_picker .pill[data-user-id]", (e) => { $("body").on(
const user_id = Number.parseInt($(e.currentTarget).attr("data-user-id"), 10); "click",
".view_user_profile, .person_picker .pill[data-user-id]",
function (this: HTMLElement, e) {
const user_id = Number.parseInt($(e.currentTarget).attr("data-user-id")!, 10);
const user = people.get_by_user_id(user_id); const user = people.get_by_user_id(user_id);
if ($(e.target).closest(".user-card-popover-bot-owner-field").length > 0) { if ($(this).closest(".user-card-popover-bot-owner-field").length > 0) {
hide_all_user_card_popovers(); hide_all_user_card_popovers();
toggle_user_card_popover_for_bot_owner(e.target, user); toggle_user_card_popover_for_bot_owner(this, user);
} else { } else {
toggle_user_card_popover(e.target, user); toggle_user_card_popover(this, user);
} }
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
}); },
);
/* These click handlers are implemented as just deep links to the /* These click handlers are implemented as just deep links to the
* relevant part of the Zulip UI, so we don't want preventDefault, * relevant part of the Zulip UI, so we don't want preventDefault,
@@ -758,7 +804,7 @@ function register_click_handlers() {
e.preventDefault(); e.preventDefault();
}); });
function open_user_status_modal(e) { function open_user_status_modal(e: JQuery.ClickEvent): void {
hide_all(); hide_all();
user_status_ui.open_user_status_modal(); user_status_ui.open_user_status_modal();
@@ -790,24 +836,24 @@ function register_click_handlers() {
toggle_sidebar_user_card_popover($target); toggle_sidebar_user_card_popover($target);
}); });
$("body").on("click", ".sidebar-popover-mute-user", (e) => { $("body").on("click", ".sidebar-popover-mute-user", function (e) {
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
hide_all_user_card_popovers(); hide_all_user_card_popovers();
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
confirm_mute_user(user_id); confirm_mute_user(user_id);
}); });
$("body").on("click", ".sidebar-popover-unmute-user", (e) => { $("body").on("click", ".sidebar-popover-unmute-user", function (e) {
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
hide_all_user_card_popovers(); hide_all_user_card_popovers();
muted_users.unmute_user(user_id); muted_users.unmute_user(user_id);
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
}); });
$("body").on("click", ".respond_personal_button, .compose_private_message", (e) => { $("body").on("click", ".respond_personal_button, .compose_private_message", function (e) {
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
const email = people.get_by_user_id(user_id).email; const email = people.get_by_user_id(user_id).email;
compose_actions.start({ compose_actions.start({
message_type: "private", message_type: "private",
@@ -828,9 +874,9 @@ function register_click_handlers() {
e.preventDefault(); e.preventDefault();
}); });
$("body").on("click", ".sidebar-popover-manage-user", (e) => { $("body").on("click", ".sidebar-popover-manage-user", function () {
hide_all(); hide_all();
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(this).parents("ul"));
const user = people.get_by_user_id(user_id); const user = people.get_by_user_id(user_id);
user_profile.show_user_profile(user, "manage-profile-tab"); user_profile.show_user_profile(user, "manage-profile-tab");
}); });
@@ -842,8 +888,8 @@ function register_click_handlers() {
}); });
new ClipboardJS(".copy-custom-profile-field-link", { new ClipboardJS(".copy-custom-profile-field-link", {
text(trigger) { text(trigger): string {
return $(trigger).parent().find(".custom-profile-field-link").attr("href"); return $(trigger).parent().find(".custom-profile-field-link").attr("href")!;
}, },
}).on("success", (e) => { }).on("success", (e) => {
show_copied_confirmation(e.trigger, { show_copied_confirmation(e.trigger, {
@@ -852,7 +898,7 @@ function register_click_handlers() {
}); });
} }
export function initialize() { export function initialize(): void {
register_click_handlers(); register_click_handlers();
clipboard_enable(".copy_mention_syntax"); clipboard_enable(".copy_mention_syntax");
} }

View File

@@ -61,7 +61,7 @@ import type {UserGroup} from "./user_groups.ts";
import * as user_pill from "./user_pill.ts"; import * as user_pill from "./user_pill.ts";
import * as util from "./util.ts"; import * as util from "./util.ts";
type CustomProfileFieldData = { export type CustomProfileFieldData = {
id: number; id: number;
name: string; name: string;
is_user_field: boolean; is_user_field: boolean;