mirror of
https://github.com/zulip/zulip.git
synced 2025-11-05 22:43:42 +00:00
Extract compose_actions.js.
This module extracts these two functions that get called by
several other modules:
start()
cancel()
It is a little bit arbitrary which functions got pulled over
with them, but it's generally functions that would have only
been called via start/cancel.
There are two goals for splitting out this code. The first
goal is simply to make `compose.js` have fewer responsibilities.
The second goal is to help break up circular dependencies.
The extraction of this module does more to clarify
dependencies than actually break them. The methods start()
and cancel() had actually been shimmed in an earlier commit,
and now they no longer have a shim.
Besides start/cancel, most of the functions here are only
exported to facilitate test stubbing. An exception is
decorate_stream_bar(), which is currently called from
ui_init.js. We probably should move the "blur" handler out
of there, but cleaning up ui_init.js is a project for another
day.
It may seem slightly odd that this commit doesn't pull over
finish() into this module, but finish() would bring in the
whole send-message codepath. You can think of it like this:
* compose_actions basically just populates the compose box
* compose.finish() makes the compose box do its real job,
which is to send a message
This commit is contained in:
@@ -3,6 +3,10 @@ var compose = (function () {
|
||||
var exports = {};
|
||||
var is_composing_message = false;
|
||||
|
||||
exports.set_message_type = function (msg_type) {
|
||||
is_composing_message = msg_type;
|
||||
};
|
||||
|
||||
/* Track the state of the @all warning. The user must acknowledge that they are spamming the entire
|
||||
stream before the warning will go away. If they try to send before explicitly dismissing the
|
||||
warning, they will get an error message too.
|
||||
@@ -47,43 +51,6 @@ exports.autosize_textarea = function () {
|
||||
$("#new_message_content").trigger("autosize.resize");
|
||||
};
|
||||
|
||||
// Show the compose box.
|
||||
function show_box(msg_type, opts) {
|
||||
if (msg_type === "stream") {
|
||||
$('#private-message').hide();
|
||||
$('#stream-message').show();
|
||||
$("#stream_toggle").addClass("active");
|
||||
$("#private_message_toggle").removeClass("active");
|
||||
} else {
|
||||
$('#private-message').show();
|
||||
$('#stream-message').hide();
|
||||
$("#stream_toggle").removeClass("active");
|
||||
$("#private_message_toggle").addClass("active");
|
||||
}
|
||||
$("#send-status").removeClass(status_classes).hide();
|
||||
$('#compose').css({visibility: "visible"});
|
||||
$(".new_message_textarea").css("min-height", "3em");
|
||||
|
||||
exports.set_focus(msg_type, opts);
|
||||
}
|
||||
|
||||
exports.maybe_scroll_up_selected_message = function () {
|
||||
// If the compose box is obscuring the currently selected message,
|
||||
// scroll up until the message is no longer occluded.
|
||||
if (current_msg_list.selected_id() === -1) {
|
||||
// If there's no selected message, there's no need to
|
||||
// scroll the compose box to avoid it.
|
||||
return;
|
||||
}
|
||||
var selected_row = current_msg_list.selected_row();
|
||||
var cover = selected_row.offset().top + selected_row.height()
|
||||
- $("#compose").offset().top;
|
||||
if (cover > 0) {
|
||||
message_viewport.user_initiated_animate_scroll(cover+5);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function show_all_everyone_warnings() {
|
||||
var current_stream = stream_data.get_sub(compose.stream_name());
|
||||
var stream_count = current_stream.subscribers.num_items();
|
||||
@@ -100,30 +67,20 @@ function show_all_everyone_warnings() {
|
||||
user_acknowledged_all_everyone = false;
|
||||
}
|
||||
|
||||
function clear_all_everyone_warnings() {
|
||||
exports.clear_all_everyone_warnings = function () {
|
||||
$("#compose-all-everyone").hide();
|
||||
$("#compose-all-everyone").empty();
|
||||
$("#send-status").hide();
|
||||
}
|
||||
|
||||
function clear_invites() {
|
||||
$("#compose_invite_users").hide();
|
||||
$("#compose_invite_users").empty();
|
||||
}
|
||||
|
||||
exports.clear_textarea = function () {
|
||||
$("#compose").find('input[type=text], textarea').val('');
|
||||
};
|
||||
|
||||
function clear_box() {
|
||||
clear_invites();
|
||||
clear_all_everyone_warnings();
|
||||
exports.clear_invites = function () {
|
||||
$("#compose_invite_users").hide();
|
||||
$("#compose_invite_users").empty();
|
||||
};
|
||||
|
||||
exports.reset_user_acknowledged_all_everyone_flag = function () {
|
||||
user_acknowledged_all_everyone = undefined;
|
||||
exports.clear_textarea();
|
||||
$("#new_message_content").removeData("draft-id");
|
||||
exports.autosize_textarea();
|
||||
$("#send-status").hide(0);
|
||||
}
|
||||
};
|
||||
|
||||
exports.clear_preview_area = function () {
|
||||
$("#new_message_content").show();
|
||||
@@ -133,46 +90,6 @@ exports.clear_preview_area = function () {
|
||||
$("#markdown_preview").show();
|
||||
};
|
||||
|
||||
exports.blur_textarea = function () {
|
||||
$('.message_comp').find('input, textarea, button').blur();
|
||||
};
|
||||
|
||||
function hide_box() {
|
||||
exports.blur_textarea();
|
||||
$('#stream-message').hide();
|
||||
$('#private-message').hide();
|
||||
$(".new_message_textarea").css("min-height", "");
|
||||
compose_fade.clear_compose();
|
||||
$('.message_comp').hide();
|
||||
$("#compose_controls").show();
|
||||
exports.clear_preview_area();
|
||||
}
|
||||
|
||||
function update_lock_icon_for_stream(stream_name) {
|
||||
var icon = $("#compose-lock-icon");
|
||||
var streamfield = $("#stream");
|
||||
if (stream_data.get_invite_only(stream_name)) {
|
||||
icon.show();
|
||||
streamfield.addClass("lock-padding");
|
||||
} else {
|
||||
icon.hide();
|
||||
streamfield.removeClass("lock-padding");
|
||||
}
|
||||
}
|
||||
|
||||
// In an attempt to decrease mixing, make the composebox's
|
||||
// stream bar look like what you're replying to.
|
||||
// (In particular, if there's a color associated with it,
|
||||
// have that color be reflected here too.)
|
||||
exports.decorate_stream_bar = function (stream_name) {
|
||||
var color = stream_data.get_color(stream_name);
|
||||
update_lock_icon_for_stream(stream_name);
|
||||
$("#stream-message .message_header_stream")
|
||||
.css('background-color', color)
|
||||
.removeClass(stream_color.color_classes)
|
||||
.addClass(stream_color.get_color_class(color));
|
||||
};
|
||||
|
||||
function update_fade() {
|
||||
if (!is_composing_message) {
|
||||
return;
|
||||
@@ -191,128 +108,6 @@ $(function () {
|
||||
});
|
||||
});
|
||||
|
||||
function fill_in_opts_from_current_narrowed_view(msg_type, opts) {
|
||||
var default_opts = {
|
||||
message_type: msg_type,
|
||||
stream: '',
|
||||
subject: '',
|
||||
private_message_recipient: '',
|
||||
trigger: 'unknown',
|
||||
};
|
||||
|
||||
// Set default parameters based on the current narrowed view.
|
||||
narrow_state.set_compose_defaults(default_opts);
|
||||
opts = _.extend(default_opts, opts);
|
||||
return opts;
|
||||
}
|
||||
|
||||
function same_recipient_as_before(msg_type, opts) {
|
||||
return (compose_state.composing() === msg_type) &&
|
||||
((msg_type === "stream" &&
|
||||
opts.stream === compose.stream_name() &&
|
||||
opts.subject === compose.subject()) ||
|
||||
(msg_type === "private" &&
|
||||
opts.private_message_recipient === compose_state.recipient()));
|
||||
}
|
||||
|
||||
function get_focus_area(msg_type, opts) {
|
||||
// Set focus to "Topic" when narrowed to a stream+topic and "New topic" button clicked.
|
||||
if (msg_type === 'stream' && opts.stream && ! opts.subject) {
|
||||
return 'subject';
|
||||
} else if ((msg_type === 'stream' && opts.stream)
|
||||
|| (msg_type === 'private' && opts.private_message_recipient)) {
|
||||
if (opts.trigger === "new topic button") {
|
||||
return 'subject';
|
||||
}
|
||||
return 'new_message_content';
|
||||
}
|
||||
|
||||
if (msg_type === 'stream') {
|
||||
return 'stream';
|
||||
}
|
||||
return 'private_message_recipient';
|
||||
}
|
||||
// Export for testing
|
||||
exports._get_focus_area = get_focus_area;
|
||||
|
||||
exports.set_focus = function (msg_type, opts) {
|
||||
var focus_area = get_focus_area(msg_type, opts);
|
||||
if (focus_area === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.getSelection().toString() === "" ||
|
||||
opts.trigger !== "message click") {
|
||||
var elt = $('#' + focus_area);
|
||||
elt.focus().select();
|
||||
}
|
||||
};
|
||||
|
||||
exports.autosize_message_content = function () {
|
||||
$("#new_message_content").autosize();
|
||||
};
|
||||
|
||||
exports.expand_compose_box = function () {
|
||||
$("#compose_close").show();
|
||||
$("#compose_controls").hide();
|
||||
$('.message_comp').show();
|
||||
};
|
||||
|
||||
exports.start = function (msg_type, opts) {
|
||||
exports.autosize_message_content();
|
||||
|
||||
if (reload.is_in_progress()) {
|
||||
return;
|
||||
}
|
||||
notifications.clear_compose_notifications();
|
||||
exports.expand_compose_box();
|
||||
|
||||
opts = fill_in_opts_from_current_narrowed_view(msg_type, opts);
|
||||
// If we are invoked by a compose hotkey (c or C), do not assume that we know
|
||||
// what the message's topic or PM recipient should be.
|
||||
if (opts.trigger === "compose_hotkey") {
|
||||
opts.subject = '';
|
||||
opts.private_message_recipient = '';
|
||||
}
|
||||
|
||||
if (compose_state.composing() && !same_recipient_as_before(msg_type, opts)) {
|
||||
// Clear the compose box if the existing message is to a different recipient
|
||||
clear_box();
|
||||
}
|
||||
|
||||
compose.stream_name(opts.stream);
|
||||
compose.subject(opts.subject);
|
||||
|
||||
// Set the recipients with a space after each comma, so it looks nice.
|
||||
compose_state.recipient(opts.private_message_recipient.replace(/,\s*/g, ", "));
|
||||
|
||||
// If the user opens the compose box, types some text, and then clicks on a
|
||||
// different stream/subject, we want to keep the text in the compose box
|
||||
if (opts.content !== undefined) {
|
||||
compose.message_content(opts.content);
|
||||
}
|
||||
|
||||
is_composing_message = msg_type;
|
||||
|
||||
// Show either stream/topic fields or "You and" field.
|
||||
show_box(msg_type, opts);
|
||||
|
||||
exports.complete_starting_tasks(msg_type, opts);
|
||||
};
|
||||
|
||||
exports.complete_starting_tasks = function (msg_type, opts) {
|
||||
// This is sort of a kitchen sink function, and it's called only
|
||||
// by compose.start() for now. Having this as a separate function
|
||||
// makes testing a bit easier.
|
||||
|
||||
exports.maybe_scroll_up_selected_message();
|
||||
ui_util.change_tab_to("#home");
|
||||
compose_fade.start_compose(msg_type);
|
||||
exports.decorate_stream_bar(opts.stream);
|
||||
$(document).trigger($.Event('compose_started.zulip', opts));
|
||||
resize.resize_bottom_whitespace();
|
||||
};
|
||||
|
||||
exports.abort_xhr = function () {
|
||||
$("#compose-send-button").removeAttr("disabled");
|
||||
var xhr = $("#compose").data("filedrop_xhr");
|
||||
@@ -322,30 +117,6 @@ exports.abort_xhr = function () {
|
||||
}
|
||||
};
|
||||
|
||||
exports.cancel = function () {
|
||||
$("#new_message_content").height(40 + "px");
|
||||
|
||||
if (page_params.narrow !== undefined) {
|
||||
// Never close the compose box in narrow embedded windows, but
|
||||
// at least clear the subject and unfade.
|
||||
compose_fade.clear_compose();
|
||||
if (page_params.narrow_topic !== undefined) {
|
||||
compose.subject(page_params.narrow_topic);
|
||||
} else {
|
||||
compose.subject("");
|
||||
}
|
||||
return;
|
||||
}
|
||||
hide_box();
|
||||
$("#compose_close").hide();
|
||||
resize.resize_bottom_whitespace();
|
||||
clear_box();
|
||||
notifications.clear_compose_notifications();
|
||||
abort_xhr();
|
||||
is_composing_message = false;
|
||||
$(document).trigger($.Event('compose_canceled.zulip'));
|
||||
};
|
||||
|
||||
exports.empty_topic_placeholder = function () {
|
||||
return i18n.t("(no topic)");
|
||||
};
|
||||
@@ -698,7 +469,7 @@ exports.test_send_many_messages = function (stream, subject, count) {
|
||||
};
|
||||
|
||||
exports.finish = function () {
|
||||
clear_invites();
|
||||
exports.clear_invites();
|
||||
|
||||
if (! compose.validate()) {
|
||||
return false;
|
||||
@@ -811,7 +582,7 @@ function validate_stream_message_mentions(stream_name) {
|
||||
}
|
||||
} else {
|
||||
// the message no longer contains @all or @everyone
|
||||
clear_all_everyone_warnings();
|
||||
exports.clear_all_everyone_warnings();
|
||||
}
|
||||
// at this point, the user has either acknowledged the warning or removed @all / @everyone
|
||||
user_acknowledged_all_everyone = undefined;
|
||||
@@ -1006,7 +777,7 @@ $(function () {
|
||||
|
||||
$(event.target).parents('.compose-all-everyone').remove();
|
||||
user_acknowledged_all_everyone = true;
|
||||
clear_all_everyone_warnings();
|
||||
exports.clear_all_everyone_warnings();
|
||||
compose.finish();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user