Files
zulip/static/js/message_list.js
Tim Abbott 7ab8a8e820 js: Fix a bunch of indentation issues found by eslint.
This is preparation for enabling an eslint indentation configuration.
90% of these changes are just fixes for indentation errors that have
snuck into the codebase over the years; the others are more
significant reformatting to make eslint happy (that are not otherwise
actually improvements).

The one area that we do not attempt to work on here is the
"switch/case" indentation.
2018-05-06 16:25:02 -07:00

430 lines
13 KiB
JavaScript

var message_list = (function () {
var exports = {};
exports.narrowed = undefined;
exports.MessageList = function (table_name, filter, opts) {
_.extend(this, {
collapse_messages: true,
muting_enabled: true,
}, opts);
this.data = new MessageListData({
muting_enabled: this.muting_enabled,
filter: filter,
});
this.view = new MessageListView(this, table_name, this.collapse_messages);
this.fetch_status = FetchStatus();
this.table_name = table_name;
this.narrowed = this.table_name === "zfilt";
this.num_appends = 0;
return this;
};
exports.MessageList.prototype = {
add_messages: function MessageList_add_messages(messages, opts) {
var self = this;
var info = this.data.triage_messages(messages);
var top_messages = info.top_messages;
var bottom_messages = info.bottom_messages;
var interior_messages = info.interior_messages;
if (interior_messages.length > 0) {
self.add_and_rerender(top_messages.concat(interior_messages).concat(bottom_messages));
return true;
}
if (top_messages.length > 0) {
self.prepend(top_messages);
}
if (bottom_messages.length > 0) {
self.append(bottom_messages, opts);
}
if ((self === exports.narrowed) && !self.empty()) {
// If adding some new messages to the message tables caused
// our current narrow to no longer be empty, hide the empty
// feed placeholder text.
narrow.hide_empty_narrow_message();
}
if ((self === exports.narrowed) && !self.empty() &&
(self.selected_id() === -1) && !opts.delay_render) {
// And also select the newly arrived message.
self.select_id(self.selected_id(), {then_scroll: true, use_closest: true});
}
},
get: function (id) {
return this.data.get(id);
},
num_items: function () {
return this.data.num_items();
},
empty: function () {
return this.data.empty();
},
first: function () {
return this.data.first();
},
last: function () {
return this.data.last();
},
nth_most_recent_id: function (n) {
return this.data.nth_most_recent_id(n);
},
is_search: function () {
return this.data.is_search();
},
clear: function MessageList_clear(opts) {
opts = _.extend({clear_selected_id: true}, opts);
this.data.clear();
this.view.clear_rendering_state(true);
if (opts.clear_selected_id) {
this.data.clear_selected_id();
}
},
selected_id: function () {
return this.data.selected_id();
},
select_id: function MessageList_select_id(id, opts) {
opts = _.extend({
then_scroll: false,
target_scroll_offset: undefined,
use_closest: false,
empty_ok: false,
mark_read: true,
force_rerender: false,
}, opts, {
id: id,
msg_list: this,
previously_selected: this.data.selected_id(),
});
function convert_id(str_id) {
var id = parseFloat(str_id);
if (isNaN(id)) {
blueslip.fatal("Bad message id " + str_id);
}
return id;
}
id = convert_id(id);
var closest_id = this.closest_id(id);
var error_data;
// The name "use_closest" option is a bit legacy. We
// are always gonna move to the closest visible id; the flag
// just says whether we call blueslip.error or not. The caller
// sets use_closest to true when it expects us to move the
// pointer as needed, so only generate an error if the flag is
// false.
if (!opts.use_closest && closest_id !== id) {
error_data = {
table_name: this.table_name,
id: id,
closest_id: closest_id,
};
blueslip.error("Selected message id not in MessageList",
error_data);
}
if (closest_id === -1 && !opts.empty_ok) {
error_data = {
table_name: this.table_name,
id: id,
items_length: this.data.num_items(),
};
blueslip.fatal("Cannot select id -1", error_data);
}
id = closest_id;
opts.id = id;
this.data.set_selected_id(id);
if (opts.force_rerender) {
this.rerender();
} else if (!opts.from_rendering) {
this.view.maybe_rerender();
}
$(document).trigger($.Event('message_selected.zulip', opts));
},
reselect_selected_id: function MessageList_select_closest_id() {
this.select_id(this.data.selected_id(), {from_rendering: true});
},
selected_message: function MessageList_selected_message() {
return this.get(this.data.selected_id());
},
selected_row: function MessageList_selected_row() {
return this.get_row(this.data.selected_id());
},
closest_id: function (id) {
return this.data.closest_id(id);
},
advance_past_messages: function (msg_ids) {
return this.data.advance_past_messages(msg_ids);
},
selected_idx: function () {
return this.data.selected_idx();
},
subscribed_bookend_content: function (stream_name) {
return i18n.t("You subscribed to stream __stream__",
{stream: stream_name});
},
unsubscribed_bookend_content: function (stream_name) {
return i18n.t("You unsubscribed from stream __stream__",
{stream: stream_name});
},
not_subscribed_bookend_content: function (stream_name) {
return i18n.t("You are not subscribed to stream __stream__",
{stream: stream_name});
},
// Maintains a trailing bookend element explaining any changes in
// your subscribed/unsubscribed status at the bottom of the
// message list.
update_trailing_bookend: function MessageList_update_trailing_bookend() {
this.view.clear_trailing_bookend();
if (!this.narrowed) {
return;
}
var stream_name = narrow_state.stream();
if (stream_name === undefined) {
return;
}
var trailing_bookend_content;
var show_button = true;
var subscribed = stream_data.is_subscribed(stream_name);
if (subscribed) {
trailing_bookend_content = this.subscribed_bookend_content(stream_name);
} else {
if (!this.last_message_historical) {
trailing_bookend_content = this.unsubscribed_bookend_content(stream_name);
// For invite only streams or streams that no longer
// exist, hide the resubscribe button
var sub = stream_data.get_sub(stream_name);
if (sub !== undefined) {
show_button = !sub.invite_only;
} else {
show_button = false;
}
} else {
trailing_bookend_content = this.not_subscribed_bookend_content(stream_name);
}
}
if (trailing_bookend_content !== undefined) {
this.view.render_trailing_bookend(trailing_bookend_content, subscribed, show_button);
}
},
unmuted_messages: function (messages) {
return this.data.unmuted_messages(messages);
},
append: function MessageList_append(messages, opts) {
opts = _.extend({delay_render: false, messages_are_new: false}, opts);
var viewable_messages = this.data.append(messages);
this.num_appends += 1;
if (!opts.delay_render) {
this.view.append(viewable_messages, opts.messages_are_new);
}
},
prepend: function MessageList_prepend(messages) {
var viewable_messages = this.data.prepend(messages);
this.view.prepend(viewable_messages);
},
add_and_rerender: function MessageList_add_and_rerender(messages) {
// To add messages that might be in the interior of our
// existing messages list, we just add the new messages and
// then rerender the whole thing.
this.data.add(messages);
this.view.rerender_the_whole_thing();
},
remove_and_rerender: function MessageList_remove_and_rerender(messages) {
this.data.remove(messages);
this.rerender();
},
show_edit_message: function MessageList_show_edit_message(row, edit_obj) {
row.find(".message_edit_form").empty().append(edit_obj.form);
row.find(".message_content, .status-message").hide();
row.find(".message_edit").css("display", "block");
row.find(".message_edit_content").autosize();
},
hide_edit_message: function MessageList_hide_edit_message(row) {
row.find(".message_content, .status-message").show();
row.find(".message_edit").hide();
row.trigger("mouseleave");
},
show_edit_topic: function MessageList_show_edit_topic(recipient_row, form) {
recipient_row.find(".topic_edit_form").empty().append(form);
recipient_row.find('.icon-vector-pencil').hide();
recipient_row.find(".stream_topic").hide();
recipient_row.find(".topic_edit").show();
},
hide_edit_topic: function MessageList_hide_edit_topic(recipient_row) {
recipient_row.find(".stream_topic").show();
recipient_row.find('.icon-vector-pencil').show();
recipient_row.find(".topic_edit").hide();
},
show_message_as_read: function (message, options) {
var row = this.get_row(message.id);
if ((options.from === 'pointer' && feature_flags.mark_read_at_bottom) ||
options.from === "server") {
row.find('.unread_marker').addClass('fast_fade');
} else {
row.find('.unread_marker').addClass('slow_fade');
}
row.removeClass('unread');
},
rerender: function MessageList_rerender() {
// We need to clear the rendering state, rather than just
// doing clear_table, since we want to potentially recollapse
// things.
this.data.reset_select_to_closest();
this.view.clear_rendering_state(false);
this.view.update_render_window(this.selected_idx(), false);
if (this === exports.narrowed) {
if (this.empty()) {
narrow.show_empty_narrow_message();
} else {
narrow.hide_empty_narrow_message();
}
}
this.view.rerender_preserving_scrolltop();
this.redo_selection();
},
redo_selection: function () {
var selected_id = this.data.selected_id();
if (selected_id !== -1) {
this.select_id(selected_id);
}
},
update_muting_and_rerender: function MessageList_update_muting_and_rerender() {
if (!this.muting_enabled) {
return;
}
this.data.update_items_for_muting();
this.rerender();
},
all_messages: function MessageList_all_messages() {
return this.data.all_messages();
},
first_unread_message_id: function () {
return this.data.first_unread_message_id();
},
message_range: function (start, end) {
return this.data.message_range(start, end);
},
get_row: function (id) {
return this.view.get_row(id);
},
update_user_full_name: function (user_id, full_name) {
this.data.update_user_full_name(user_id, full_name);
if (this.table_name !== undefined) {
this.view.rerender_preserving_scrolltop();
}
},
update_user_avatar: function (user_id, avatar_url) {
this.data.update_user_avatar(user_id, avatar_url);
if (this.table_name !== undefined) {
this.view.rerender_preserving_scrolltop();
}
},
update_stream_name: function (stream_id, new_stream_name) {
this.data.update_stream_name(stream_id, new_stream_name);
if (this.table_name !== undefined) {
this.view.rerender_preserving_scrolltop();
}
},
change_message_id: function MessageList_change_message_id(old_id, new_id) {
var self = this;
var opts = {
is_current_list: function () {
return current_msg_list === self;
},
re_render: function () {
self.view.rerender_preserving_scrolltop();
self.redo_selection();
},
};
this.data.change_message_id(old_id, new_id, opts);
},
get_last_message_sent_by_me: function () {
return this.data.get_last_message_sent_by_me();
},
};
exports.all = new exports.MessageList(
undefined, undefined,
{muting_enabled: false}
);
// We stop autoscrolling when the user is clearly in the middle of
// doing something. Be careful, though, if you try to capture
// mousemove, then you will have to contend with the autoscroll
// itself generating mousemove events.
$(document).on('message_selected.zulip zuliphashchange.zulip wheel', function () {
message_viewport.stop_auto_scrolling();
});
return exports;
}());
if (typeof module !== 'undefined') {
module.exports = message_list;
}