mirror of
https://github.com/zulip/zulip.git
synced 2025-11-15 03:11:54 +00:00
compose: Migrate upload banner to new banner styling.
Fixes #22524. This affects both the banner in the main compose box and the banner in the message edit compose box. The use of ProgressBar has been replaced with a more simple CSS (with light Javascript) solution. The classnames are changing because the upload banner is now a template rendered and remove()-ed from a banner container (#compose_banners in the composebox, and a new div for banners in the message edit view). It used to be in the send_status container so there are a lot of class renames across the codebase.
This commit is contained in:
@@ -18,7 +18,6 @@ mock_esm("@uppy/core", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
mock_esm("@uppy/xhr-upload", {default: class XHRUpload {}});
|
mock_esm("@uppy/xhr-upload", {default: class XHRUpload {}});
|
||||||
mock_esm("@uppy/progress-bar", {default: class ProgressBar {}});
|
|
||||||
|
|
||||||
const compose_actions = mock_esm("../../static/js/compose_actions");
|
const compose_actions = mock_esm("../../static/js/compose_actions");
|
||||||
mock_esm("../../static/js/csrf", {csrf_token: "csrf_token"});
|
mock_esm("../../static/js/csrf", {csrf_token: "csrf_token"});
|
||||||
@@ -29,7 +28,7 @@ const upload = zrequire("upload");
|
|||||||
function test(label, f) {
|
function test(label, f) {
|
||||||
run_test(label, (helpers) => {
|
run_test(label, (helpers) => {
|
||||||
page_params.max_file_upload_size_mib = 25;
|
page_params.max_file_upload_size_mib = 25;
|
||||||
f(helpers);
|
return f(helpers);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +47,11 @@ test("get_item", () => {
|
|||||||
assert.equal(upload.get_item("textarea", {mode: "compose"}), $("#compose-textarea"));
|
assert.equal(upload.get_item("textarea", {mode: "compose"}), $("#compose-textarea"));
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.get_item("send_status_message", {mode: "compose"}),
|
upload.get_item("send_status_message", {mode: "compose"}),
|
||||||
$("#compose-error-msg"),
|
$("#compose_banners .upload_banner .upload_msg"),
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
upload.get_item("send_status_close_button", {mode: "compose"}),
|
||||||
|
$("#compose_banners .upload_banner .compose_banner_close_button"),
|
||||||
);
|
);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.get_item("file_input_identifier", {mode: "compose"}),
|
upload.get_item("file_input_identifier", {mode: "compose"}),
|
||||||
@@ -74,27 +77,30 @@ test("get_item", () => {
|
|||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.get_item("send_status_identifier", {mode: "edit", row: 11}),
|
upload.get_item("send_status_identifier", {mode: "edit", row: 11}),
|
||||||
`#message-edit-send-status-${CSS.escape(11)}`,
|
`#edit_form_${CSS.escape(11)} .upload_banner`,
|
||||||
);
|
);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.get_item("send_status", {mode: "edit", row: 75}),
|
upload.get_item("send_status", {mode: "edit", row: 75}),
|
||||||
$(`#message-edit-send-status-${CSS.escape(75)}`),
|
$(`#edit_form_${CSS.escape(75)} .upload_banner`),
|
||||||
);
|
);
|
||||||
|
|
||||||
$(`#message-edit-send-status-${CSS.escape(2)}`).set_find_results(
|
$(`#edit_form_${CSS.escape(2)} .upload_banner`).set_find_results(
|
||||||
".send-status-close",
|
".compose_banner_close_button",
|
||||||
$(".send-status-close"),
|
$(".compose_banner_close_button"),
|
||||||
);
|
);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.get_item("send_status_close_button", {mode: "edit", row: 2}),
|
upload.get_item("send_status_close_button", {mode: "edit", row: 2}),
|
||||||
$(".send-status-close"),
|
$(`#edit_form_${CSS.escape(2)} .upload_banner .compose_banner_close_button`),
|
||||||
);
|
);
|
||||||
|
|
||||||
$(`#message-edit-send-status-${CSS.escape(22)}`).set_find_results(
|
$(`#edit_form_${CSS.escape(22)} .upload_banner`).set_find_results(
|
||||||
".error-msg",
|
".upload_msg",
|
||||||
$(".error-msg"),
|
$(".upload_msg"),
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
upload.get_item("send_status_message", {mode: "edit", row: 22}),
|
||||||
|
$(`#edit_form_${CSS.escape(22)} .upload_banner .upload_msg`),
|
||||||
);
|
);
|
||||||
assert.equal(upload.get_item("send_status_message", {mode: "edit", row: 22}), $(".error-msg"));
|
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
upload.get_item("file_input_identifier", {mode: "edit", row: 123}),
|
upload.get_item("file_input_identifier", {mode: "edit", row: 123}),
|
||||||
@@ -158,34 +164,49 @@ test("get_item", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("hide_upload_status", () => {
|
test("hide_upload_status", () => {
|
||||||
|
let banner_removed = false;
|
||||||
|
$("#compose_banners .upload_banner").remove = () => {
|
||||||
|
banner_removed = true;
|
||||||
|
};
|
||||||
$("#compose-send-button").prop("disabled", true);
|
$("#compose-send-button").prop("disabled", true);
|
||||||
$("#compose-send-status").addClass("alert-info").show();
|
|
||||||
|
|
||||||
upload.hide_upload_status({mode: "compose"});
|
upload.hide_upload_status({mode: "compose"});
|
||||||
|
|
||||||
|
assert.ok(banner_removed);
|
||||||
assert.equal($("#compose-send-button").prop("disabled"), false);
|
assert.equal($("#compose-send-button").prop("disabled"), false);
|
||||||
assert.equal($("#compose-send-button").hasClass("alert-info"), false);
|
|
||||||
assert.equal($("#compose-send-button").visible(), false);
|
assert.equal($("#compose-send-button").visible(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("show_error_message", () => {
|
test("show_error_message", ({mock_template}) => {
|
||||||
|
$("#compose_banners .upload_banner .moving_bar").css = () => {};
|
||||||
|
$("#compose_banners .upload_banner").length = 0;
|
||||||
|
|
||||||
|
let banner_shown = false;
|
||||||
|
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||||
|
assert.equal(data.banner_type, "error");
|
||||||
|
assert.equal(data.banner_text, "Error message");
|
||||||
|
banner_shown = true;
|
||||||
|
});
|
||||||
|
|
||||||
$("#compose-send-button").prop("disabled", true);
|
$("#compose-send-button").prop("disabled", true);
|
||||||
$("#compose-send-status").addClass("alert-info").removeClass("alert-error").hide();
|
|
||||||
$("#compose-error-msg").text("");
|
|
||||||
$("#compose-error-msg").hide();
|
|
||||||
|
|
||||||
upload.show_error_message({mode: "compose"}, "Error message");
|
upload.show_error_message({mode: "compose"}, "Error message");
|
||||||
assert.equal($("#compose-send-button").prop("disabled"), false);
|
assert.equal($("#compose-send-button").prop("disabled"), false);
|
||||||
assert.ok($("#compose-send-status").hasClass("alert-error"));
|
assert.ok(banner_shown);
|
||||||
assert.equal($("#compose-send-status").hasClass("alert-info"), false);
|
|
||||||
assert.ok($("#compose-send-status").visible());
|
|
||||||
assert.equal($("#compose-error-msg").text(), "Error message");
|
|
||||||
|
|
||||||
|
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||||
|
assert.equal(data.banner_type, "error");
|
||||||
|
assert.equal(data.banner_text, "translated: An unknown error occurred.");
|
||||||
|
banner_shown = true;
|
||||||
|
});
|
||||||
upload.show_error_message({mode: "compose"});
|
upload.show_error_message({mode: "compose"});
|
||||||
assert.equal($("#compose-error-msg").text(), "translated: An unknown error occurred.");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("upload_files", ({override_rewire}) => {
|
test("upload_files", async ({mock_template, override_rewire}) => {
|
||||||
|
$("#compose_banners .upload_banner").remove = () => {};
|
||||||
|
$("#compose_banners .upload_banner .moving_bar").css = () => {};
|
||||||
|
$("#compose_banners .upload_banner").length = 0;
|
||||||
|
|
||||||
let uppy_cancel_all_called = false;
|
let uppy_cancel_all_called = false;
|
||||||
let files = [
|
let files = [
|
||||||
{
|
{
|
||||||
@@ -214,20 +235,26 @@ test("upload_files", ({override_rewire}) => {
|
|||||||
});
|
});
|
||||||
const config = {mode: "compose"};
|
const config = {mode: "compose"};
|
||||||
$("#compose-send-button").prop("disabled", false);
|
$("#compose-send-button").prop("disabled", false);
|
||||||
upload.upload_files(uppy, config, []);
|
await upload.upload_files(uppy, config, []);
|
||||||
assert.ok(!$("#compose-send-button").prop("disabled"));
|
assert.ok(!$("#compose-send-button").prop("disabled"));
|
||||||
|
|
||||||
|
let banner_shown = false;
|
||||||
|
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||||
|
assert.equal(data.banner_type, "error");
|
||||||
|
assert.equal(
|
||||||
|
data.banner_text,
|
||||||
|
"translated: File and image uploads have been disabled for this organization.",
|
||||||
|
);
|
||||||
|
banner_shown = true;
|
||||||
|
});
|
||||||
page_params.max_file_upload_size_mib = 0;
|
page_params.max_file_upload_size_mib = 0;
|
||||||
$("#compose-error-msg").text("");
|
$("#compose_banners .upload_banner .upload_msg").text("");
|
||||||
upload.upload_files(uppy, config, files);
|
await upload.upload_files(uppy, config, files);
|
||||||
assert.equal(
|
assert.ok(banner_shown);
|
||||||
$("#compose-error-msg").text(),
|
|
||||||
"translated: File and image uploads have been disabled for this organization.",
|
|
||||||
);
|
|
||||||
|
|
||||||
page_params.max_file_upload_size_mib = 25;
|
page_params.max_file_upload_size_mib = 25;
|
||||||
let on_click_close_button_callback;
|
let on_click_close_button_callback;
|
||||||
$(".compose-send-status-close").one = (event, callback) => {
|
$("#compose_banners .upload_banner .compose_banner_close_button").one = (event, callback) => {
|
||||||
assert.equal(event, "click");
|
assert.equal(event, "click");
|
||||||
on_click_close_button_callback = callback;
|
on_click_close_button_callback = callback;
|
||||||
};
|
};
|
||||||
@@ -246,18 +273,24 @@ test("upload_files", ({override_rewire}) => {
|
|||||||
markdown_preview_hide_button_clicked = true;
|
markdown_preview_hide_button_clicked = true;
|
||||||
});
|
});
|
||||||
$("#compose-send-button").prop("disabled", false);
|
$("#compose-send-button").prop("disabled", false);
|
||||||
$("#compose-send-status").removeClass("alert-info").hide();
|
$("#compose_banners .upload_banner").remove();
|
||||||
$("#compose .undo_markdown_preview").show();
|
$("#compose .undo_markdown_preview").show();
|
||||||
upload.upload_files(uppy, config, files);
|
|
||||||
|
banner_shown = false;
|
||||||
|
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||||
|
assert.equal(data.banner_type, "info");
|
||||||
|
assert.equal(data.banner_text, "translated: Uploading…");
|
||||||
|
banner_shown = true;
|
||||||
|
});
|
||||||
|
await upload.upload_files(uppy, config, files);
|
||||||
assert.ok($("#compose-send-button").prop("disabled"));
|
assert.ok($("#compose-send-button").prop("disabled"));
|
||||||
assert.ok($("#compose-send-status").hasClass("alert-info"));
|
assert.ok(banner_shown);
|
||||||
assert.ok($("#compose-send-status").visible());
|
|
||||||
assert.equal($("<p>").text(), "translated: Uploading…");
|
|
||||||
assert.ok(compose_ui_insert_syntax_and_focus_called);
|
assert.ok(compose_ui_insert_syntax_and_focus_called);
|
||||||
assert.ok(compose_ui_autosize_textarea_called);
|
assert.ok(compose_ui_autosize_textarea_called);
|
||||||
assert.ok(markdown_preview_hide_button_clicked);
|
assert.ok(markdown_preview_hide_button_clicked);
|
||||||
assert.ok(uppy_add_file_called);
|
assert.ok(uppy_add_file_called);
|
||||||
|
|
||||||
|
banner_shown = false;
|
||||||
files = [
|
files = [
|
||||||
{
|
{
|
||||||
name: "budapest.png",
|
name: "budapest.png",
|
||||||
@@ -274,7 +307,8 @@ test("upload_files", ({override_rewire}) => {
|
|||||||
add_file_counter += 1;
|
add_file_counter += 1;
|
||||||
throw new Error("some error");
|
throw new Error("some error");
|
||||||
};
|
};
|
||||||
upload.upload_files(uppy, config, files);
|
await upload.upload_files(uppy, config, files);
|
||||||
|
assert.ok(banner_shown);
|
||||||
assert.equal(add_file_counter, 1);
|
assert.equal(add_file_counter, 1);
|
||||||
|
|
||||||
hide_upload_status_called = false;
|
hide_upload_status_called = false;
|
||||||
@@ -311,7 +345,6 @@ test("uppy_config", () => {
|
|||||||
let uppy_stub_called = false;
|
let uppy_stub_called = false;
|
||||||
let uppy_set_meta_called = false;
|
let uppy_set_meta_called = false;
|
||||||
let uppy_used_xhrupload = false;
|
let uppy_used_xhrupload = false;
|
||||||
let uppy_used_progressbar = false;
|
|
||||||
|
|
||||||
uppy_stub = function (config) {
|
uppy_stub = function (config) {
|
||||||
uppy_stub_called = true;
|
uppy_stub_called = true;
|
||||||
@@ -336,10 +369,6 @@ test("uppy_config", () => {
|
|||||||
assert.equal(params.limit, 5);
|
assert.equal(params.limit, 5);
|
||||||
assert.equal(Object.keys(params.locale.strings).length, 1);
|
assert.equal(Object.keys(params.locale.strings).length, 1);
|
||||||
assert.ok("timedOut" in params.locale.strings);
|
assert.ok("timedOut" in params.locale.strings);
|
||||||
} else if (func_name === "ProgressBar") {
|
|
||||||
uppy_used_progressbar = true;
|
|
||||||
assert.equal(params.target, "#compose-send-status");
|
|
||||||
assert.equal(params.hideAfterFinish, false);
|
|
||||||
} else {
|
} else {
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
assert.fail(`Missing tests for ${func_name}`);
|
assert.fail(`Missing tests for ${func_name}`);
|
||||||
@@ -353,7 +382,6 @@ test("uppy_config", () => {
|
|||||||
assert.equal(uppy_stub_called, true);
|
assert.equal(uppy_stub_called, true);
|
||||||
assert.equal(uppy_set_meta_called, true);
|
assert.equal(uppy_set_meta_called, true);
|
||||||
assert.equal(uppy_used_xhrupload, true);
|
assert.equal(uppy_used_xhrupload, true);
|
||||||
assert.equal(uppy_used_progressbar, true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("file_input", ({override_rewire}) => {
|
test("file_input", ({override_rewire}) => {
|
||||||
@@ -454,7 +482,10 @@ test("copy_paste", ({override_rewire}) => {
|
|||||||
assert.equal(upload_files_called, false);
|
assert.equal(upload_files_called, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("uppy_events", ({override, override_rewire}) => {
|
test("uppy_events", ({override, override_rewire, mock_template}) => {
|
||||||
|
$("#compose_banners .upload_banner .moving_bar").css = () => {};
|
||||||
|
$("#compose_banners .upload_banner").length = 0;
|
||||||
|
|
||||||
const callbacks = {};
|
const callbacks = {};
|
||||||
let uppy_cancel_all_called = false;
|
let uppy_cancel_all_called = false;
|
||||||
let state = {};
|
let state = {};
|
||||||
@@ -486,7 +517,7 @@ test("uppy_events", ({override, override_rewire}) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
upload.setup_upload({mode: "compose"});
|
upload.setup_upload({mode: "compose"});
|
||||||
assert.equal(Object.keys(callbacks).length, 5);
|
assert.equal(Object.keys(callbacks).length, 6);
|
||||||
|
|
||||||
const on_upload_success_callback = callbacks["upload-success"];
|
const on_upload_success_callback = callbacks["upload-success"];
|
||||||
const file = {
|
const file = {
|
||||||
@@ -541,7 +572,7 @@ test("uppy_events", ({override, override_rewire}) => {
|
|||||||
override_rewire(upload, "hide_upload_status", () => {
|
override_rewire(upload, "hide_upload_status", () => {
|
||||||
hide_upload_status_called = true;
|
hide_upload_status_called = true;
|
||||||
});
|
});
|
||||||
$("#compose-send-status").removeClass("alert-error");
|
$("#compose_banner .upload_banner").removeClass("error");
|
||||||
files = [
|
files = [
|
||||||
{
|
{
|
||||||
id: "uppy-zulip/jpeg-1e-image/jpeg-163515-1578367331279",
|
id: "uppy-zulip/jpeg-1e-image/jpeg-163515-1578367331279",
|
||||||
@@ -561,11 +592,11 @@ test("uppy_events", ({override, override_rewire}) => {
|
|||||||
assert.equal(files.length, 0);
|
assert.equal(files.length, 0);
|
||||||
|
|
||||||
hide_upload_status_called = false;
|
hide_upload_status_called = false;
|
||||||
$("#compose-send-status").addClass("alert-error");
|
$("#compose_banners .upload_banner").addClass("error");
|
||||||
on_complete_callback();
|
on_complete_callback();
|
||||||
assert.ok(!hide_upload_status_called);
|
assert.ok(!hide_upload_status_called);
|
||||||
|
|
||||||
$("#compose-send-status").removeClass("alert-error");
|
$("#compose_banners .upload_banner").removeClass("error");
|
||||||
hide_upload_status_called = false;
|
hide_upload_status_called = false;
|
||||||
files = [
|
files = [
|
||||||
{
|
{
|
||||||
@@ -585,19 +616,22 @@ test("uppy_events", ({override, override_rewire}) => {
|
|||||||
assert.ok(!hide_upload_status_called);
|
assert.ok(!hide_upload_status_called);
|
||||||
assert.equal(files.length, 1);
|
assert.equal(files.length, 1);
|
||||||
|
|
||||||
|
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||||
|
assert.equal(data.banner_type, "error");
|
||||||
|
assert.equal(data.banner_text, "Some error message");
|
||||||
|
});
|
||||||
state = {
|
state = {
|
||||||
type: "error",
|
type: "error",
|
||||||
details: "Some error",
|
details: "Some error",
|
||||||
message: "Some error message",
|
message: "Some error message",
|
||||||
};
|
};
|
||||||
const on_info_visible_callback = callbacks["info-visible"];
|
const on_info_visible_callback = callbacks["info-visible"];
|
||||||
$("#compose-error-msg").text("");
|
$("#compose_banners .upload_banner .upload_msg").text("");
|
||||||
uppy_cancel_all_called = false;
|
uppy_cancel_all_called = false;
|
||||||
compose_ui_replace_syntax_called = false;
|
compose_ui_replace_syntax_called = false;
|
||||||
const on_restriction_failed_callback = callbacks["restriction-failed"];
|
const on_restriction_failed_callback = callbacks["restriction-failed"];
|
||||||
on_info_visible_callback();
|
on_info_visible_callback();
|
||||||
assert.ok(uppy_cancel_all_called);
|
assert.ok(uppy_cancel_all_called);
|
||||||
assert.equal($("#compose-error-msg").text(), "Some error message");
|
|
||||||
override_rewire(compose_ui, "replace_syntax", (old_syntax, new_syntax, textarea) => {
|
override_rewire(compose_ui, "replace_syntax", (old_syntax, new_syntax, textarea) => {
|
||||||
compose_ui_replace_syntax_called = true;
|
compose_ui_replace_syntax_called = true;
|
||||||
assert.equal(old_syntax, "[translated: Uploading copenhagen.png…]()");
|
assert.equal(old_syntax, "[translated: Uploading copenhagen.png…]()");
|
||||||
@@ -627,7 +661,11 @@ test("uppy_events", ({override, override_rewire}) => {
|
|||||||
on_info_visible_callback();
|
on_info_visible_callback();
|
||||||
|
|
||||||
const on_upload_error_callback = callbacks["upload-error"];
|
const on_upload_error_callback = callbacks["upload-error"];
|
||||||
$("#compose-error-msg").text("");
|
$("#compose_banners .upload_banner .upload_msg").text("");
|
||||||
|
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||||
|
assert.equal(data.banner_type, "error");
|
||||||
|
assert.equal(data.banner_text, "Response message");
|
||||||
|
});
|
||||||
compose_ui_replace_syntax_called = false;
|
compose_ui_replace_syntax_called = false;
|
||||||
response = {
|
response = {
|
||||||
body: {
|
body: {
|
||||||
@@ -637,21 +675,22 @@ test("uppy_events", ({override, override_rewire}) => {
|
|||||||
uppy_cancel_all_called = false;
|
uppy_cancel_all_called = false;
|
||||||
on_upload_error_callback(file, null, response);
|
on_upload_error_callback(file, null, response);
|
||||||
assert.ok(uppy_cancel_all_called);
|
assert.ok(uppy_cancel_all_called);
|
||||||
assert.equal($("#compose-error-msg").text(), "Response message");
|
|
||||||
assert.ok(compose_ui_replace_syntax_called);
|
assert.ok(compose_ui_replace_syntax_called);
|
||||||
|
|
||||||
|
mock_template("compose_banner/upload_banner.hbs", false, (data) => {
|
||||||
|
assert.equal(data.banner_type, "error");
|
||||||
|
assert.equal(data.banner_text, "translated: An unknown error occurred.");
|
||||||
|
});
|
||||||
compose_ui_replace_syntax_called = false;
|
compose_ui_replace_syntax_called = false;
|
||||||
uppy_cancel_all_called = false;
|
uppy_cancel_all_called = false;
|
||||||
on_upload_error_callback(file, null, null);
|
on_upload_error_callback(file, null, null);
|
||||||
assert.ok(uppy_cancel_all_called);
|
assert.ok(uppy_cancel_all_called);
|
||||||
assert.equal($("#compose-error-msg").text(), "translated: An unknown error occurred.");
|
|
||||||
assert.ok(compose_ui_replace_syntax_called);
|
assert.ok(compose_ui_replace_syntax_called);
|
||||||
$("#compose-error-msg").text("");
|
$("#compose_banners .upload_banner .upload_msg").text("");
|
||||||
$("#compose-textarea").val("user modified text");
|
$("#compose-textarea").val("user modified text");
|
||||||
uppy_cancel_all_called = false;
|
uppy_cancel_all_called = false;
|
||||||
on_upload_error_callback(file, null);
|
on_upload_error_callback(file, null);
|
||||||
assert.ok(uppy_cancel_all_called);
|
assert.ok(uppy_cancel_all_called);
|
||||||
assert.equal($("#compose-error-msg").text(), "translated: An unknown error occurred.");
|
|
||||||
assert.ok(compose_ui_replace_syntax_called);
|
assert.ok(compose_ui_replace_syntax_called);
|
||||||
assert.equal($("#compose-textarea").val(), "user modified text");
|
assert.equal($("#compose-textarea").val(), "user modified text");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -229,6 +229,14 @@ function FakeElement(selector, opts) {
|
|||||||
shown = show;
|
shown = show;
|
||||||
return $self;
|
return $self;
|
||||||
},
|
},
|
||||||
|
toggleClass(class_name, add) {
|
||||||
|
if (add) {
|
||||||
|
classes.set(class_name, true);
|
||||||
|
} else {
|
||||||
|
classes.delete(class_name);
|
||||||
|
}
|
||||||
|
return $self;
|
||||||
|
},
|
||||||
trigger(ev) {
|
trigger(ev) {
|
||||||
event_store.trigger($self, ev);
|
event_store.trigger($self, ev);
|
||||||
return $self;
|
return $self;
|
||||||
|
|||||||
@@ -337,11 +337,6 @@ export function initialize() {
|
|||||||
ui_util.blur_active_element();
|
ui_util.blur_active_element();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$(".message_edit_form .send-status-close").on("click", function () {
|
|
||||||
const row_id = rows.id($(this).closest(".message_row"));
|
|
||||||
const $send_status = $(`#message-edit-send-status-${CSS.escape(row_id)}`);
|
|
||||||
$send_status.stop(true).fadeOut(200);
|
|
||||||
});
|
|
||||||
$("body").on("click", ".message_edit_form .compose_upload_file", function (e) {
|
$("body").on("click", ".message_edit_form .compose_upload_file", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import {Uppy} from "@uppy/core";
|
import {Uppy} from "@uppy/core";
|
||||||
import ProgressBar from "@uppy/progress-bar";
|
|
||||||
import XHRUpload from "@uppy/xhr-upload";
|
import XHRUpload from "@uppy/xhr-upload";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
|
import render_upload_banner from "../templates/compose_banner/upload_banner.hbs";
|
||||||
|
|
||||||
import * as compose_actions from "./compose_actions";
|
import * as compose_actions from "./compose_actions";
|
||||||
import * as compose_state from "./compose_state";
|
import * as compose_state from "./compose_state";
|
||||||
import * as compose_ui from "./compose_ui";
|
import * as compose_ui from "./compose_ui";
|
||||||
@@ -32,14 +33,16 @@ export function get_item(key, config) {
|
|||||||
return $("#compose-textarea");
|
return $("#compose-textarea");
|
||||||
case "send_button":
|
case "send_button":
|
||||||
return $("#compose-send-button");
|
return $("#compose-send-button");
|
||||||
|
case "banner_container":
|
||||||
|
return $("#compose_banners");
|
||||||
case "send_status_identifier":
|
case "send_status_identifier":
|
||||||
return "#compose-send-status";
|
return "#compose_banners .upload_banner";
|
||||||
case "send_status":
|
case "send_status":
|
||||||
return $("#compose-send-status");
|
return $("#compose_banners .upload_banner");
|
||||||
case "send_status_close_button":
|
case "send_status_close_button":
|
||||||
return $(".compose-send-status-close");
|
return $("#compose_banners .upload_banner .compose_banner_close_button");
|
||||||
case "send_status_message":
|
case "send_status_message":
|
||||||
return $("#compose-error-msg");
|
return $("#compose_banners .upload_banner .upload_msg");
|
||||||
case "file_input_identifier":
|
case "file_input_identifier":
|
||||||
return "#compose .file_input";
|
return "#compose .file_input";
|
||||||
case "source":
|
case "source":
|
||||||
@@ -62,16 +65,20 @@ export function get_item(key, config) {
|
|||||||
return $(`#edit_form_${CSS.escape(config.row)} .message_edit_content`)
|
return $(`#edit_form_${CSS.escape(config.row)} .message_edit_content`)
|
||||||
.closest(".message_edit_form")
|
.closest(".message_edit_form")
|
||||||
.find(".message_edit_save");
|
.find(".message_edit_save");
|
||||||
|
case "banner_container":
|
||||||
|
return $(`#edit_form_${CSS.escape(config.row)} .banners`);
|
||||||
case "send_status_identifier":
|
case "send_status_identifier":
|
||||||
return `#message-edit-send-status-${CSS.escape(config.row)}`;
|
return `#edit_form_${CSS.escape(config.row)} .upload_banner`;
|
||||||
case "send_status":
|
case "send_status":
|
||||||
return $(`#message-edit-send-status-${CSS.escape(config.row)}`);
|
return $(`#edit_form_${CSS.escape(config.row)} .upload_banner`);
|
||||||
case "send_status_close_button":
|
case "send_status_close_button":
|
||||||
return $(`#message-edit-send-status-${CSS.escape(config.row)}`).find(
|
return $(
|
||||||
".send-status-close",
|
`#edit_form_${CSS.escape(
|
||||||
|
config.row,
|
||||||
|
)} .upload_banner .compose_banner_close_button`,
|
||||||
);
|
);
|
||||||
case "send_status_message":
|
case "send_status_message":
|
||||||
return $(`#message-edit-send-status-${CSS.escape(config.row)}`).find(".error-msg");
|
return $(`#edit_form_${CSS.escape(config.row)} .upload_banner .upload_msg`);
|
||||||
case "file_input_identifier":
|
case "file_input_identifier":
|
||||||
return `#edit_form_${CSS.escape(config.row)} .file_input`;
|
return `#edit_form_${CSS.escape(config.row)} .file_input`;
|
||||||
case "source":
|
case "source":
|
||||||
@@ -90,7 +97,36 @@ export function get_item(key, config) {
|
|||||||
|
|
||||||
export function hide_upload_status(config) {
|
export function hide_upload_status(config) {
|
||||||
get_item("send_button", config).prop("disabled", false);
|
get_item("send_button", config).prop("disabled", false);
|
||||||
get_item("send_status", config).removeClass("alert-info").hide();
|
get_item("send_status", config).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_upload_banner(config, banner_type, banner_text) {
|
||||||
|
// We only show one upload banner at a time per compose box,
|
||||||
|
// and all uploads are combined into the same progress bar.
|
||||||
|
// TODO: It would be nice to separate the error banner into
|
||||||
|
// a different element, so that we can show it at the same
|
||||||
|
// time as the upload bar and other uploads can still continue
|
||||||
|
// when an error occurs.
|
||||||
|
const $upload_banner = get_item("send_status", config);
|
||||||
|
if ($upload_banner.length) {
|
||||||
|
if (banner_type === "error") {
|
||||||
|
// Hide moving bar so that it doesn't do the 1s transition to 0
|
||||||
|
const $moving_bar = $(`${get_item("send_status_identifier", config)} .moving_bar`);
|
||||||
|
$moving_bar.hide();
|
||||||
|
$upload_banner.removeClass("info").addClass("error");
|
||||||
|
// Show it again once the animation is complete.
|
||||||
|
setTimeout(() => $moving_bar.show(), 1000);
|
||||||
|
} else {
|
||||||
|
$upload_banner.removeClass("error").addClass("info");
|
||||||
|
}
|
||||||
|
get_item("send_status_message", config).text(banner_text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const $new_banner = render_upload_banner({
|
||||||
|
banner_type,
|
||||||
|
banner_text,
|
||||||
|
});
|
||||||
|
get_item("banner_container", config).append($new_banner);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function show_error_message(
|
export function show_error_message(
|
||||||
@@ -98,11 +134,10 @@ export function show_error_message(
|
|||||||
message = $t({defaultMessage: "An unknown error occurred."}),
|
message = $t({defaultMessage: "An unknown error occurred."}),
|
||||||
) {
|
) {
|
||||||
get_item("send_button", config).prop("disabled", false);
|
get_item("send_button", config).prop("disabled", false);
|
||||||
get_item("send_status", config).addClass("alert-error").removeClass("alert-info").show();
|
show_upload_banner(config, "error", message);
|
||||||
get_item("send_status_message", config).text(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function upload_files(uppy, config, files) {
|
export async function upload_files(uppy, config, files) {
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -128,8 +163,7 @@ export function upload_files(uppy, config, files) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_item("send_button", config).prop("disabled", true);
|
get_item("send_button", config).prop("disabled", true);
|
||||||
get_item("send_status", config).addClass("alert-info").removeClass("alert-error").show();
|
show_upload_banner(config, "info", $t({defaultMessage: "Uploading…"}));
|
||||||
get_item("send_status_message", config).html($("<p>").text($t({defaultMessage: "Uploading…"})));
|
|
||||||
get_item("send_status_close_button", config).one("click", () => {
|
get_item("send_status_close_button", config).one("click", () => {
|
||||||
for (const file of uppy.getFiles()) {
|
for (const file of uppy.getFiles()) {
|
||||||
compose_ui.replace_syntax(
|
compose_ui.replace_syntax(
|
||||||
@@ -280,7 +314,7 @@ export function setup_upload(config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const has_errors = get_item("send_status", config).hasClass("alert-error");
|
const has_errors = get_item("send_status", config).hasClass("error");
|
||||||
if (!uploads_in_progress && !has_errors) {
|
if (!uploads_in_progress && !has_errors) {
|
||||||
// Hide upload status for 100ms after the 1s transition to 100%
|
// Hide upload status for 100ms after the 1s transition to 100%
|
||||||
// so that the user can see the progress bar at 100%.
|
// so that the user can see the progress bar at 100%.
|
||||||
@@ -314,6 +348,8 @@ export function setup_upload(config) {
|
|||||||
if (info.type === "error") {
|
if (info.type === "error") {
|
||||||
// The remaining errors are mostly frontend errors like file being too large
|
// The remaining errors are mostly frontend errors like file being too large
|
||||||
// for upload.
|
// for upload.
|
||||||
|
// TODO: It would be nice to keep the other uploads going if one fails,
|
||||||
|
// and show both an error message and the upload bar.
|
||||||
uppy.cancelAll();
|
uppy.cancelAll();
|
||||||
show_error_message(config, info.message);
|
show_error_message(config, info.message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,10 +399,53 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.info {
|
||||||
|
background-color: hsl(204, 58%, 92%);
|
||||||
|
border-color: hsla(204, 49%, 29%, 0.4);
|
||||||
|
position: relative;
|
||||||
|
color: hsl(204, 49%, 29%);
|
||||||
|
|
||||||
|
.compose_banner_close_button {
|
||||||
|
color: hsla(204, 49%, 29%, 0.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: hsl(204, 49%, 29%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: hsla(204, 49%, 29%, 0.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload_banner {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moving_bar {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
/* The progress updates seem to come every second or so,
|
||||||
|
so this is the smoothest it can probably get. */
|
||||||
|
transition: width 1s ease-in-out;
|
||||||
|
background: hsl(204, 63%, 85%);
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload_msg,
|
||||||
|
.compose_banner_close_button {
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like .nav-tabs > li > a */
|
/* Like .nav-tabs > li > a */
|
||||||
div[id^="message-edit-send-status"],
|
|
||||||
#compose-send-status {
|
#compose-send-status {
|
||||||
padding: 8px 14px;
|
padding: 8px 14px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
|||||||
@@ -251,6 +251,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.info {
|
||||||
|
background-color: hsl(204, 100%, 12%);
|
||||||
|
border-color: hsla(205, 58%, 69%, 0.4);
|
||||||
|
position: relative;
|
||||||
|
color: hsl(205, 58%, 69%);
|
||||||
|
|
||||||
|
.compose_banner_close_button {
|
||||||
|
color: hsla(205, 58%, 69%, 0.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: hsl(205, 58%, 69%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: hsla(205, 58%, 69%, 0.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload_banner {
|
||||||
|
.moving_bar {
|
||||||
|
background: hsl(204, 63%, 18%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.message_embed .data-container::after {
|
.message_embed .data-container::after {
|
||||||
|
|||||||
5
static/templates/compose_banner/upload_banner.hbs
Normal file
5
static/templates/compose_banner/upload_banner.hbs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<div class="upload_banner compose_banner {{banner_type}}">
|
||||||
|
<div class="moving_bar"></div>
|
||||||
|
<p class="upload_msg">{{banner_text}}</p>
|
||||||
|
<a role="button" class="zulip-icon zulip-icon-close compose_banner_close_button"></a>
|
||||||
|
</div>
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
{{! Client-side Mustache template for rendering the message edit form. }}
|
{{! Client-side Mustache template for rendering the message edit form. }}
|
||||||
|
|
||||||
<form id="edit_form_{{message_id}}" class="new-style">
|
<form id="edit_form_{{message_id}}" class="new-style">
|
||||||
<div class="alert" id="message-edit-send-status-{{message_id}}">
|
<div class="banners"></div>
|
||||||
<span class="send-status-close">×</span>
|
|
||||||
<span class="error-msg"></span>
|
|
||||||
</div>
|
|
||||||
<div class="edit-controls">
|
<div class="edit-controls">
|
||||||
{{> copy_message_button message_id=this.message_id}}
|
{{> copy_message_button message_id=this.message_id}}
|
||||||
<textarea class="message_edit_content" maxlength="{{ max_message_length }}">{{content}}</textarea>
|
<textarea class="message_edit_content" maxlength="{{ max_message_length }}">{{content}}</textarea>
|
||||||
|
|||||||
Reference in New Issue
Block a user