uploads: Fix the upload progress bar.

There was already a progress bar set up, but it became non-functional
after refactoring.  This fixes it.

The default animation was getting cut off when `uploadFinished` is
called, so we add a delay before removing the upload bar to make it
get to the end.

Tweaked by tabbott to have a more natural feeling animation setup
(where we don't animate the width adjustments; just the disappearance
of the bar).

Fixes #8863.
This commit is contained in:
Marco Burstein
2018-04-04 19:29:21 -07:00
committed by Tim Abbott
parent a4def8d409
commit c36a658fee
2 changed files with 44 additions and 11 deletions

View File

@@ -33,11 +33,10 @@ var upload_opts = upload.options({ mode: "compose" });
}; };
$("#compose-error-msg").html(''); $("#compose-error-msg").html('');
var test_html = '<div class="progress progress-striped active">' + var test_html = '<div class="progress progress-striped active">' +
'<div class="bar" id="compose-upload-bar" style="width: 00%;">' + '<div class="bar" id="compose-upload-bar" style="width: 00%;"></div>' +
'</div></div>'; '</div>';
$("<p>").after = function (html) { $("#compose-send-status").append = function (html) {
assert.equal(html, test_html); assert.equal(html, test_html);
return 'fake-html';
}; };
upload_opts.drop(); upload_opts.drop();
@@ -46,7 +45,6 @@ var upload_opts = upload.options({ mode: "compose" });
assert($("#compose-send-status").hasClass("alert-info")); assert($("#compose-send-status").hasClass("alert-info"));
assert($("#compose-send-status").visible()); assert($("#compose-send-status").visible());
assert.equal($("<p>").text(), 'translated: Uploading…'); assert.equal($("<p>").text(), 'translated: Uploading…');
assert.equal($("#compose-error-msg").html(), 'fake-html');
}()); }());
(function test_progress_updated() { (function test_progress_updated() {
@@ -65,6 +63,10 @@ var upload_opts = upload.options({ mode: "compose" });
$("#compose-send-status").addClass("alert-info"); $("#compose-send-status").addClass("alert-info");
$("#compose-send-button").attr("disabled", 'disabled'); $("#compose-send-button").attr("disabled", 'disabled');
$("#compose-error-msg").text(''); $("#compose-error-msg").text('');
$("#compose-upload-bar").parent = function () {
return { remove: function () {} };
};
} }
function assert_side_effects(msg) { function assert_side_effects(msg) {
@@ -144,8 +146,17 @@ var upload_opts = upload.options({ mode: "compose" });
} }
} }
global.patch_builtin('setTimeout', function (func) {
func();
});
$("#compose-upload-bar").width = function (width_percent) {
assert.equal(width_percent, '100%');
};
setup(); setup();
upload_opts.uploadFinished(i, {}, response); upload_opts.uploadFinished(i, {}, response);
upload_opts.progressUpdated(1, '', 100);
assert_side_effects(); assert_side_effects();
} }

View File

@@ -24,6 +24,7 @@ exports.options = function (config) {
var send_status_close; var send_status_close;
var error_msg; var error_msg;
var upload_bar; var upload_bar;
var should_hide_upload_status;
var file_input; var file_input;
switch (config.mode) { switch (config.mode) {
@@ -49,18 +50,38 @@ exports.options = function (config) {
throw Error("Invalid upload mode!"); throw Error("Invalid upload mode!");
} }
var maybe_hide_upload_status = function () {
// The first time `maybe_hide_upload_status`, it will not hide the
// status; the second time it will. This guarantees that whether
// `progressUpdated` or `uploadFinished` is called first, the status
// is hidden only after the animation is finished.
if (should_hide_upload_status) {
setTimeout(function () {
send_button.prop("disabled", false);
send_status.removeClass("alert-info").hide();
$("#" + upload_bar).parent().remove();
}, 500);
} else {
should_hide_upload_status = true;
}
};
var uploadStarted = function () { var uploadStarted = function () {
send_button.attr("disabled", ""); send_button.attr("disabled", "");
send_status.addClass("alert-info").show(); send_status.addClass("alert-info").show();
send_status_close.one('click', compose.abort_xhr); send_status_close.one('click', compose.abort_xhr);
error_msg.html($("<p>").text(i18n.t("Uploading…")) error_msg.html($("<p>").text(i18n.t("Uploading…")));
.after('<div class="progress progress-striped active">' + send_status.append('<div class="progress progress-striped active">' +
'<div class="bar" id="' + upload_bar + '" style="width: 00%;"></div>' + '<div class="bar" id="' + upload_bar + '" style="width: 00%;"></div>' +
'</div>')); '</div>');
should_hide_upload_status = false;
}; };
var progressUpdated = function (i, file, progress) { var progressUpdated = function (i, file, progress) {
$("#" + upload_bar).width(progress + "%"); $("#" + upload_bar).width(progress + "%");
if (progress === 100) {
maybe_hide_upload_status();
}
}; };
var uploadError = function (error_code, server_response, file) { var uploadError = function (error_code, server_response, file) {
@@ -68,6 +89,7 @@ exports.options = function (config) {
send_status.addClass("alert-error") send_status.addClass("alert-error")
.removeClass("alert-info"); .removeClass("alert-info");
send_button.prop("disabled", false); send_button.prop("disabled", false);
$("#" + upload_bar).parent().remove();
switch (error_code) { switch (error_code) {
case 'BrowserNotSupported': case 'BrowserNotSupported':
msg = i18n.t("File upload is not yet available for your browser."); msg = i18n.t("File upload is not yet available for your browser.");
@@ -120,8 +142,8 @@ exports.options = function (config) {
compose_ui.insert_syntax_and_focus(filename_uri, textarea); compose_ui.insert_syntax_and_focus(filename_uri, textarea);
} }
compose_ui.autosize_textarea(); compose_ui.autosize_textarea();
send_button.prop("disabled", false);
send_status.removeClass("alert-info").hide(); maybe_hide_upload_status();
// In order to upload the same file twice in a row, we need to clear out // In order to upload the same file twice in a row, we need to clear out
// the file input element, so that the next time we use the file dialog, // the file input element, so that the next time we use the file dialog,