diff --git a/tools/test-js-with-node b/tools/test-js-with-node index 68a0351156..206630c176 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -255,7 +255,7 @@ EXEMPT_FILES = make_set( "web/src/tippyjs.ts", "web/src/todo_widget.ts", "web/src/topic_list.ts", - "web/src/topic_popover.js", + "web/src/topic_popover.ts", "web/src/typing.ts", "web/src/typing_events.ts", "web/src/ui_init.js", diff --git a/web/src/message_edit.ts b/web/src/message_edit.ts index 26785ba26c..6f90358816 100644 --- a/web/src/message_edit.ts +++ b/web/src/message_edit.ts @@ -785,7 +785,7 @@ export function toggle_resolve_topic( message_id: number, old_topic_name: string, report_errors_in_global_banner: boolean, - $row: JQuery, + $row?: JQuery, ): void { let new_topic_name; const topic_is_resolved = resolved_topic.is_resolved(old_topic_name); @@ -826,7 +826,7 @@ function do_toggle_resolve_topic( new_topic_name: string, topic_is_resolved: boolean, report_errors_in_global_banner: boolean, - $row: JQuery, + $row?: JQuery, ): void { if ($row) { show_toggle_resolve_topic_spinner($row); diff --git a/web/src/stream_popover.ts b/web/src/stream_popover.ts index aeeb906fef..76bf4bea06 100644 --- a/web/src/stream_popover.ts +++ b/web/src/stream_popover.ts @@ -342,7 +342,7 @@ export async function build_move_topic_to_stream_popover( current_stream_id: number, topic_name: string, only_topic_edit: boolean, - message: Message | undefined, + message?: Message, ): Promise { const current_stream_name = sub_store.get(current_stream_id)!.name; const args: { diff --git a/web/src/topic_popover.js b/web/src/topic_popover.ts similarity index 74% rename from web/src/topic_popover.js rename to web/src/topic_popover.ts index b47fa73442..0e2d1062b3 100644 --- a/web/src/topic_popover.js +++ b/web/src/topic_popover.ts @@ -1,5 +1,7 @@ import ClipboardJS from "clipboard"; import $ from "jquery"; +import assert from "minimalistic-assert"; +import type * as tippy from "tippy.js"; import render_delete_topic_modal from "../templates/confirm_dialog/confirm_delete_topic.hbs"; import render_left_sidebar_topic_actions_popover from "../templates/popovers/left_sidebar/left_sidebar_topic_actions_popover.hbs"; @@ -17,7 +19,32 @@ import * as unread_ops from "./unread_ops.ts"; import * as user_topics from "./user_topics.ts"; import * as util from "./util.ts"; -export function initialize() { +function get_conversation(instance: tippy.Instance): { + stream_id: number; + topic_name: string; + url: string; +} { + let stream_id; + let topic_name; + let url; + + if (instance.reference.classList.contains("inbox-topic-menu")) { + const $elt = $(instance.reference); + stream_id = Number.parseInt($elt.attr("data-stream-id")!, 10); + topic_name = $elt.attr("data-topic-name")!; + url = new URL($elt.attr("data-topic-url")!, realm.realm_url).href; + } else { + const $elt = $(instance.reference).closest(".topic-sidebar-menu-icon").expectOne(); + const $stream_li = $elt.closest(".narrow-filter").expectOne(); + topic_name = $elt.closest("li").expectOne().attr("data-topic-name")!; + url = util.the($elt.closest("li").find("a.sidebar-topic-name")).href; + stream_id = stream_popover.elem_to_stream_id($stream_li); + } + + return {stream_id, topic_name, url}; +} + +export function initialize(): void { popover_menus.register_popover_menu( "#stream_filters .topic-sidebar-menu-icon, .inbox-row .inbox-topic-menu", { @@ -26,37 +53,17 @@ export function initialize() { popover_menus.popover_instances.topics_menu = instance; ui_util.show_left_sidebar_menu_icon(instance.reference); popover_menus.on_show_prep(instance); - let stream_id; - let topic_name; - let url; - if (instance.reference.classList.contains("inbox-topic-menu")) { - const $elt = $(instance.reference); - stream_id = Number.parseInt($elt.attr("data-stream-id"), 10); - topic_name = $elt.attr("data-topic-name"); - url = new URL($elt.attr("data-topic-url"), realm.realm_url); - } else { - const $elt = $(instance.reference) - .closest(".topic-sidebar-menu-icon") - .expectOne(); - const $stream_li = $elt.closest(".narrow-filter").expectOne(); - topic_name = $elt.closest("li").expectOne().attr("data-topic-name"); - url = $elt.closest("li").find(".sidebar-topic-name").expectOne().prop("href"); - stream_id = stream_popover.elem_to_stream_id($stream_li); - } - - instance.context = popover_menus_data.get_topic_popover_content_context({ - stream_id, - topic_name, - url, - }); + const context = popover_menus_data.get_topic_popover_content_context( + get_conversation(instance), + ); instance.setContent( - ui_util.parse_html(render_left_sidebar_topic_actions_popover(instance.context)), + ui_util.parse_html(render_left_sidebar_topic_actions_popover(context)), ); }, onMount(instance) { const $popper = $(instance.popper); - const {stream_id, topic_name} = instance.context; + const {stream_id, topic_name} = get_conversation(instance); if (!stream_id) { popover_menus.hide_current_popover_if_visible(instance); @@ -66,11 +73,11 @@ export function initialize() { $popper.on("change", "input[name='sidebar-topic-visibility-select']", (e) => { const start_time = Date.now(); const visibility_policy = Number.parseInt( - $(e.currentTarget).attr("data-visibility-policy"), + $(e.currentTarget).attr("data-visibility-policy")!, 10, ); - const success_cb = () => { + const success_cb = (): void => { setTimeout( () => { popover_menus.hide_current_popover_if_visible(instance); @@ -79,7 +86,7 @@ export function initialize() { ); }; - const error_cb = () => { + const error_cb = (): void => { const prev_visibility_policy = user_topics.get_topic_visibility_policy( stream_id, topic_name, @@ -108,10 +115,7 @@ export function initialize() { }); $popper.one("click", ".sidebar-popover-unstar-all-in-topic", () => { - starred_messages_ui.confirm_unstar_all_messages_in_topic( - Number.parseInt(stream_id, 10), - topic_name, - ); + starred_messages_ui.confirm_unstar_all_messages_in_topic(stream_id, topic_name); popover_menus.hide_current_popover_if_visible(instance); }); @@ -142,6 +146,7 @@ export function initialize() { $popper.one("click", ".sidebar-popover-toggle-resolved", () => { message_edit.with_first_message_id(stream_id, topic_name, (message_id) => { + assert(message_id !== undefined); message_edit.toggle_resolve_topic(message_id, topic_name, true); }); @@ -149,16 +154,24 @@ export function initialize() { }); $popper.one("click", ".sidebar-popover-move-topic-messages", () => { - stream_popover.build_move_topic_to_stream_popover(stream_id, topic_name, false); + void stream_popover.build_move_topic_to_stream_popover( + stream_id, + topic_name, + false, + ); popover_menus.hide_current_popover_if_visible(instance); }); $popper.one("click", ".sidebar-popover-rename-topic-messages", () => { - stream_popover.build_move_topic_to_stream_popover(stream_id, topic_name, true); + void stream_popover.build_move_topic_to_stream_popover( + stream_id, + topic_name, + true, + ); popover_menus.hide_current_popover_if_visible(instance); }); - new ClipboardJS($popper.find(".sidebar-popover-copy-link-to-topic")[0]).on( + new ClipboardJS(util.the($popper.find(".sidebar-popover-copy-link-to-topic"))).on( "success", () => { popover_menus.hide_current_popover_if_visible(instance); @@ -167,7 +180,7 @@ export function initialize() { }, onHidden(instance) { instance.destroy(); - popover_menus.popover_instances.topics_menu = undefined; + popover_menus.popover_instances.topics_menu = null; ui_util.hide_left_sidebar_menu_icon(); }, }, diff --git a/web/src/ui_init.js b/web/src/ui_init.js index 0c0706731b..224c3dc3ed 100644 --- a/web/src/ui_init.js +++ b/web/src/ui_init.js @@ -133,7 +133,7 @@ import * as thumbnail from "./thumbnail.ts"; import * as timerender from "./timerender.ts"; import * as tippyjs from "./tippyjs.ts"; import * as topic_list from "./topic_list.ts"; -import * as topic_popover from "./topic_popover.js"; +import * as topic_popover from "./topic_popover.ts"; import * as transmit from "./transmit.js"; import * as typeahead_helper from "./typeahead_helper.ts"; import * as typing from "./typing.ts"; diff --git a/web/src/ui_util.ts b/web/src/ui_util.ts index 329fec5f39..af01023c76 100644 --- a/web/src/ui_util.ts +++ b/web/src/ui_util.ts @@ -202,7 +202,7 @@ export function listener_for_preferred_color_scheme_change(callback: () => void) } // Keep the menu icon over which the popover is based off visible. -export function show_left_sidebar_menu_icon(element: HTMLElement): void { +export function show_left_sidebar_menu_icon(element: Element): void { $(element).closest(".sidebar-menu-icon").addClass("left_sidebar_menu_icon_visible"); }