mirror of
https://github.com/zulip/zulip.git
synced 2025-10-25 17:14:02 +00:00
Defer saved snippets dropdown creation until the compose box is opened for better performance. Fixes #31831.
158 lines
6.2 KiB
TypeScript
158 lines
6.2 KiB
TypeScript
import $ from "jquery";
|
|
import assert from "minimalistic-assert";
|
|
import type * as tippy from "tippy.js";
|
|
|
|
import render_add_saved_snippet_modal from "../templates/add_saved_snippet_modal.hbs";
|
|
import render_confirm_delete_saved_snippet from "../templates/confirm_dialog/confirm_delete_saved_snippet.hbs";
|
|
|
|
import * as channel from "./channel.ts";
|
|
import * as compose_ui from "./compose_ui.ts";
|
|
import * as confirm_dialog from "./confirm_dialog.ts";
|
|
import * as dialog_widget from "./dialog_widget.ts";
|
|
import * as dropdown_widget from "./dropdown_widget.ts";
|
|
import {$t, $t_html} from "./i18n.ts";
|
|
import * as rows from "./rows.ts";
|
|
import * as saved_snippets from "./saved_snippets.ts";
|
|
|
|
let saved_snippets_widget: dropdown_widget.DropdownWidget | undefined;
|
|
let saved_snippets_dropdown: tippy.Instance | undefined;
|
|
let composebox_saved_snippets_dropdown_widget = false;
|
|
|
|
function submit_create_saved_snippet_form(): void {
|
|
const title = $<HTMLInputElement>("#add-new-saved-snippet-modal .saved-snippet-title")
|
|
.val()
|
|
?.trim();
|
|
const content = $<HTMLInputElement>("#add-new-saved-snippet-modal .saved-snippet-content")
|
|
.val()
|
|
?.trim();
|
|
if (title && content) {
|
|
dialog_widget.submit_api_request(channel.post, "/json/saved_snippets", {title, content});
|
|
}
|
|
}
|
|
|
|
function update_submit_button_state(): void {
|
|
const title = $<HTMLInputElement>("#add-new-saved-snippet-modal .saved-snippet-title")
|
|
.val()
|
|
?.trim();
|
|
const content = $<HTMLInputElement>("#add-new-saved-snippet-modal .saved-snippet-content")
|
|
.val()
|
|
?.trim();
|
|
const $submit_button = $("#add-new-saved-snippet-modal .dialog_submit_button");
|
|
|
|
$submit_button.prop("disabled", true);
|
|
if (title && content) {
|
|
$submit_button.prop("disabled", false);
|
|
}
|
|
}
|
|
|
|
function saved_snippet_modal_post_render(): void {
|
|
$("#add-new-saved-snippet-modal").on("input", "input,textarea", update_submit_button_state);
|
|
}
|
|
|
|
export function rerender_dropdown_widget(): void {
|
|
if (saved_snippets_widget && saved_snippets_dropdown) {
|
|
const options = saved_snippets.get_options_for_dropdown_widget();
|
|
saved_snippets_widget.list_widget?.replace_list_data(options);
|
|
saved_snippets_widget.show_empty_if_no_items($(saved_snippets_dropdown.popper));
|
|
}
|
|
}
|
|
|
|
function delete_saved_snippet(saved_snippet_id: string): void {
|
|
void channel.del({
|
|
url: "/json/saved_snippets/" + saved_snippet_id,
|
|
});
|
|
}
|
|
|
|
function item_click_callback(
|
|
event: JQuery.ClickEvent,
|
|
dropdown: tippy.Instance,
|
|
widget: dropdown_widget.DropdownWidget,
|
|
is_sticky_bottom_option_clicked: boolean,
|
|
): void {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
if (
|
|
$(event.target).closest(".saved_snippets-dropdown-list-container .dropdown-list-delete")
|
|
.length > 0
|
|
) {
|
|
confirm_dialog.launch({
|
|
html_heading: $t_html({defaultMessage: "Delete saved snippet?"}),
|
|
html_body: render_confirm_delete_saved_snippet(),
|
|
on_click() {
|
|
const saved_snippet_id = $(event.currentTarget).attr("data-unique-id");
|
|
assert(saved_snippet_id !== undefined);
|
|
delete_saved_snippet(saved_snippet_id);
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
|
|
dropdown.hide();
|
|
// Get target textarea where the "Add saved snippet" button is clicked.
|
|
const $target_element = $(dropdown.reference);
|
|
let $target_textarea: JQuery<HTMLTextAreaElement>;
|
|
let edit_message_id: string | undefined;
|
|
if ($target_element.parents(".message_edit_form").length === 1) {
|
|
edit_message_id = rows.id($target_element.parents(".message_row")).toString();
|
|
$target_textarea = $(`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`);
|
|
} else {
|
|
$target_textarea = $<HTMLTextAreaElement>("textarea#compose-textarea");
|
|
}
|
|
if (is_sticky_bottom_option_clicked) {
|
|
dialog_widget.launch({
|
|
html_heading: $t_html({defaultMessage: "Create a new saved snippet"}),
|
|
html_body: render_add_saved_snippet_modal({
|
|
prepopulated_content: $target_textarea.val(),
|
|
}),
|
|
html_submit_button: $t_html({defaultMessage: "Save"}),
|
|
id: "add-new-saved-snippet-modal",
|
|
form_id: "add-new-saved-snippet-form",
|
|
update_submit_disabled_state_on_change: true,
|
|
on_click: submit_create_saved_snippet_form,
|
|
on_shown: () => $("#new-saved-snippet-title").trigger("focus"),
|
|
post_render: saved_snippet_modal_post_render,
|
|
});
|
|
} else {
|
|
const current_value = widget.current_value;
|
|
assert(typeof current_value === "number");
|
|
const saved_snippet = saved_snippets.get_saved_snippet_by_id(current_value);
|
|
assert(saved_snippet !== undefined);
|
|
const content = saved_snippet.content;
|
|
compose_ui.insert_syntax_and_focus(content, $target_textarea);
|
|
}
|
|
}
|
|
|
|
export function setup_saved_snippets_dropdown_widget(widget_selector: string): void {
|
|
new dropdown_widget.DropdownWidget({
|
|
widget_name: "saved_snippets",
|
|
widget_selector,
|
|
get_options: saved_snippets.get_options_for_dropdown_widget,
|
|
item_click_callback,
|
|
$events_container: $("body"),
|
|
unique_id_type: dropdown_widget.DataTypes.NUMBER,
|
|
sticky_bottom_option: $t({
|
|
defaultMessage: "Create a new saved snippet",
|
|
}),
|
|
on_show_callback(dropdown: tippy.Instance, widget: dropdown_widget.DropdownWidget) {
|
|
saved_snippets_widget = widget;
|
|
saved_snippets_dropdown = dropdown;
|
|
},
|
|
focus_target_on_hidden: false,
|
|
prefer_top_start_placement: true,
|
|
tippy_props: {
|
|
// Using -100 as x offset makes saved snippet icon be in the center
|
|
// of the dropdown widget and 5 as y offset is what we use in compose
|
|
// recipient dropdown widget.
|
|
offset: [-100, 5],
|
|
},
|
|
}).setup();
|
|
}
|
|
|
|
export function setup_saved_snippets_dropdown_widget_if_needed(): void {
|
|
if (!composebox_saved_snippets_dropdown_widget) {
|
|
composebox_saved_snippets_dropdown_widget = true;
|
|
setup_saved_snippets_dropdown_widget(".saved-snippets-composebox-widget");
|
|
}
|
|
}
|