compose: Fix restoring big drafts freezes the app.

We are using `.val` to set compose box content which is very fast vs
`setFieldText` which is very slow due to it doing a lot of
forced repaints. The major downside of using `val` here is that
user will not able to perform `undo` operation on this which doesn't
seem something user would want to do here.

Note that this effects compose content restored from drafts,
scheduled messages and on reload.
This commit is contained in:
Aman Agrawal 2024-08-13 09:12:10 +00:00 committed by Tim Abbott
parent 84be0a300b
commit 970dd30f96
3 changed files with 24 additions and 6 deletions

View File

@ -347,7 +347,13 @@ export function start(raw_opts: ComposeActionsStartOpts): void {
}
if (opts.content !== undefined) {
compose_ui.insert_and_scroll_into_view(opts.content, $("textarea#compose-textarea"), true);
const replace_all_without_undo_support = true;
compose_ui.insert_and_scroll_into_view(
opts.content,
$("textarea#compose-textarea"),
false,
replace_all_without_undo_support,
);
$(".compose_control_button_container:has(.add-poll)").addClass("disabled-on-hover");
// If we were provided with message content, we might need to
// display that it's too long.

View File

@ -114,8 +114,15 @@ export function insert_and_scroll_into_view(
content: string,
$textarea: JQuery<HTMLTextAreaElement>,
replace_all = false,
replace_all_without_undo_support = false,
): void {
if (replace_all) {
if (replace_all_without_undo_support) {
// setFieldText is very slow and noticeable when inserting 10k+
// characters of text like from a drafted response,
// but we use it since we want to support `undo`. If we don't want
// to support `undo`, we can use a faster method.
$textarea.val(content);
} else if (replace_all) {
setFieldText($textarea[0]!, content);
} else {
insertTextIntoField($textarea[0]!, content);

View File

@ -143,10 +143,15 @@ test("start", ({override, override_rewire, mock_template}) => {
let compose_defaults;
override(narrow_state, "set_compose_defaults", () => compose_defaults);
override(compose_ui, "insert_and_scroll_into_view", (content, $textarea, replace_all) => {
$textarea.val(content);
assert.ok(replace_all);
});
override(
compose_ui,
"insert_and_scroll_into_view",
(content, $textarea, replace_all, replace_all_without_undo_support) => {
$textarea.val(content);
assert.ok(!replace_all);
assert.ok(replace_all_without_undo_support);
},
);
// Start stream message
compose_defaults = {