mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 06:53:25 +00:00
There are also one or two places we don't need to use it for security purposes, but we do so for consistencey. (imported from commit aa111f5a22a0e8597ec3cf8504adae66d5fb6768)
332 lines
11 KiB
JavaScript
332 lines
11 KiB
JavaScript
var stream_list = (function () {
|
|
|
|
var exports = {};
|
|
|
|
var last_private_message_count = 0;
|
|
var last_mention_count = 0;
|
|
var previous_sort_order;
|
|
|
|
exports.sort_narrow_list = function () {
|
|
var streams = subs.subscribed_streams();
|
|
if (streams.length === 0) {
|
|
return;
|
|
}
|
|
|
|
var sort_recent = (streams.length > 40);
|
|
|
|
streams.sort(function (a, b) {
|
|
if (sort_recent) {
|
|
if (recent_subjects.has(b) && ! recent_subjects.has(a)) {
|
|
return 1;
|
|
} else if (! recent_subjects.has(b) && recent_subjects.has(a)) {
|
|
return -1;
|
|
}
|
|
}
|
|
return util.strcmp(a, b);
|
|
});
|
|
|
|
if (previous_sort_order !== undefined
|
|
&& util.array_compare(previous_sort_order, streams)) {
|
|
return;
|
|
}
|
|
|
|
previous_sort_order = streams;
|
|
|
|
var parent = $('#stream_filters');
|
|
parent.empty();
|
|
|
|
var elems = [];
|
|
_.each(streams, function (stream) {
|
|
var li = $(subs.get(stream).sidebar_li);
|
|
if (sort_recent) {
|
|
if (! recent_subjects.has(stream)) {
|
|
li.addClass('inactive_stream');
|
|
} else {
|
|
li.removeClass('inactive_stream');
|
|
}
|
|
}
|
|
elems.push(li.get(0));
|
|
});
|
|
$(elems).appendTo(parent);
|
|
};
|
|
|
|
function iterate_to_find(selector, name_to_find, context) {
|
|
var lowercase_name = name_to_find.toLowerCase();
|
|
var found = _.find($(selector, context), function (elem) {
|
|
return $(elem).attr('data-name').toLowerCase() === lowercase_name;
|
|
});
|
|
return found ? $(found) : $();
|
|
}
|
|
|
|
// TODO: Now that the unread count functions support the user sidebar
|
|
// as well, we probably should consider moving them to a different file.
|
|
function get_filter_li(type, name) {
|
|
if (type === 'stream') {
|
|
return $("#stream_sidebar_" + subs.stream_id(name));
|
|
} else if (type === "private") {
|
|
return $(".user_sidebar_entry > a[data-email='" + name + "']");
|
|
}
|
|
return iterate_to_find("#" + type + "_filters > li", name);
|
|
}
|
|
|
|
function get_subject_filter_li(stream, subject) {
|
|
var stream_li = get_filter_li('stream', stream);
|
|
return iterate_to_find(".expanded_subjects li", subject, stream_li);
|
|
}
|
|
|
|
exports.set_in_home_view = function (stream, in_home) {
|
|
var li = get_filter_li('stream', stream);
|
|
if (in_home) {
|
|
li.removeClass("out_of_home_view");
|
|
} else {
|
|
li.addClass("out_of_home_view");
|
|
}
|
|
};
|
|
|
|
// Adds the sidebar stream name that, when clicked,
|
|
// narrows to that stream
|
|
function add_narrow_filter(name, type) {
|
|
if (get_filter_li(type, name).length) {
|
|
// already exists
|
|
return false;
|
|
}
|
|
|
|
var args = {name: name,
|
|
id: subs.stream_id(name),
|
|
uri: narrow.by_stream_uri(name),
|
|
not_in_home_view: (subs.in_home_view(name) === false),
|
|
invite_only: subs.get(name).invite_only,
|
|
color: subs.get_color(name)};
|
|
var list_item = $(templates.render('stream_sidebar_row', args));
|
|
$("#" + type + "_filters").append(list_item);
|
|
return list_item;
|
|
}
|
|
|
|
exports.get_count = function (type, name) {
|
|
return get_filter_li(type, name).find('.count .value').text();
|
|
};
|
|
|
|
function update_count_in_dom(count_span, value_span, count) {
|
|
if (count === 0) {
|
|
count_span.hide();
|
|
value_span.text('');
|
|
return;
|
|
}
|
|
|
|
count_span.show();
|
|
value_span.text(count);
|
|
}
|
|
|
|
exports.set_count = function (type, name, count) {
|
|
var count_span = get_filter_li(type, name).find('.count');
|
|
var value_span = count_span.find('.value');
|
|
update_count_in_dom(count_span, value_span, count);
|
|
};
|
|
|
|
exports.set_subject_count = function (stream, subject, count) {
|
|
var subject_li = get_subject_filter_li(stream, subject);
|
|
var count_span = subject_li.find('.subject_count');
|
|
var value_span = count_span.find('.value');
|
|
|
|
if (count_span.length === 0 || value_span.length === 0) {
|
|
return;
|
|
}
|
|
|
|
count_span.removeClass("zero_count");
|
|
update_count_in_dom(count_span, value_span, count);
|
|
};
|
|
|
|
exports.remove_narrow_filter = function (name, type) {
|
|
get_filter_li(type, name).remove();
|
|
};
|
|
|
|
exports.remove_all_narrow_filters = function () {
|
|
$("#stream_filters").children().remove();
|
|
};
|
|
|
|
function rebuild_recent_subjects(stream, subject) {
|
|
// TODO: Call rebuild_recent_subjects less, not on every new
|
|
// message.
|
|
$('.expanded_subjects').remove();
|
|
var max_subjects = 5;
|
|
var stream_li = get_filter_li('stream', stream);
|
|
var subjects = recent_subjects.get(stream) || [];
|
|
var active_orig_subject = subject;
|
|
var display_subjects = _.filter(subjects, function (subject_obj, idx) {
|
|
var num_unread = unread.num_unread_for_subject(stream, subject_obj.canon_subject);
|
|
subject_obj.unread = num_unread;
|
|
subject_obj.is_zero = num_unread === 0;
|
|
|
|
if (subject === subject_obj.canon_subject) {
|
|
active_orig_subject = subject_obj.subject;
|
|
}
|
|
subject_obj.url = narrow.by_stream_subject_uri(stream, subject_obj.subject);
|
|
|
|
// Show the most recent subjects, as well as any with unread messages
|
|
return idx < max_subjects || subject_obj.unread > 0;
|
|
});
|
|
|
|
stream_li.append(templates.render('sidebar_subject_list',
|
|
{subjects: display_subjects,
|
|
stream: stream}));
|
|
|
|
if (active_orig_subject !== undefined) {
|
|
get_subject_filter_li(stream, active_orig_subject).addClass('active-subject-filter');
|
|
}
|
|
}
|
|
|
|
exports.update_streams_sidebar = function () {
|
|
exports.sort_narrow_list();
|
|
|
|
if (! narrow.active()) {
|
|
return;
|
|
}
|
|
|
|
var op_stream = narrow.filter().operands('stream');
|
|
var op_subject = narrow.filter().operands('topic');
|
|
var subject;
|
|
if (op_stream.length !== 0) {
|
|
if (op_subject.length !== 0) {
|
|
subject = op_subject[0];
|
|
}
|
|
if (subs.is_subscribed(op_stream[0])) {
|
|
rebuild_recent_subjects(op_stream[0], subject);
|
|
}
|
|
}
|
|
};
|
|
|
|
function do_new_messages_animation(message_type) {
|
|
var li = get_filter_li("global", message_type);
|
|
li.addClass("new_messages");
|
|
function mid_animation() {
|
|
li.removeClass("new_messages");
|
|
li.addClass("new_messages_fadeout");
|
|
}
|
|
function end_animation() {
|
|
li.removeClass("new_messages_fadeout");
|
|
}
|
|
setTimeout(mid_animation, 3000);
|
|
setTimeout(end_animation, 6000);
|
|
}
|
|
|
|
function animate_private_message_changes(new_private_message_count) {
|
|
if (new_private_message_count > last_private_message_count) {
|
|
do_new_messages_animation('private');
|
|
}
|
|
last_private_message_count = new_private_message_count;
|
|
}
|
|
|
|
function animate_mention_changes(new_mention_count) {
|
|
if (new_mention_count > last_mention_count) {
|
|
do_new_messages_animation('mentioned');
|
|
}
|
|
last_mention_count = new_mention_count;
|
|
}
|
|
|
|
exports.update_dom_with_unread_counts = function (counts) {
|
|
// counts is just a data object that gets calculated elsewhere
|
|
// Our job is to update some DOM elements.
|
|
|
|
// counts.stream_count maps streams to counts
|
|
_.each(counts.stream_count.items(), function (item) {
|
|
var stream = item[0];
|
|
var count = item[1];
|
|
exports.set_count("stream", stream, count);
|
|
});
|
|
|
|
// counts.subject_count maps streams to hashes of subjects to counts
|
|
_.each(counts.subject_count.items(), function (item) {
|
|
var stream = item[0];
|
|
var subject_hash = item[1];
|
|
_.each(subject_hash.items(), function (item) {
|
|
var subject = item[0];
|
|
var count = item[1];
|
|
exports.set_subject_count(stream, subject, count);
|
|
});
|
|
});
|
|
|
|
// counts.pm_count maps people to counts
|
|
_.each(counts.pm_count.items(), function (item) {
|
|
var person = item[0];
|
|
var count = item[1];
|
|
exports.set_count("private", person, count);
|
|
});
|
|
|
|
// integer counts
|
|
exports.set_count("global", "private", counts.private_message_count);
|
|
exports.set_count("global", "mentioned", counts.mentioned_message_count);
|
|
exports.set_count("global", "home", counts.home_unread_messages);
|
|
|
|
animate_private_message_changes(counts.private_message_count);
|
|
animate_mention_changes(counts.mentioned_message_count);
|
|
};
|
|
|
|
$(function () {
|
|
$(document).on('narrow_activated.zulip', function (event) {
|
|
$("ul.filters li").removeClass('active-filter active-subject-filter');
|
|
$('.expanded_subjects').remove();
|
|
|
|
// TODO: handle confused filters like "in:all stream:foo"
|
|
var op_in = event.filter.operands('in');
|
|
if (op_in.length !== 0) {
|
|
if (['all', 'home'].indexOf(op_in[0]) !== -1) {
|
|
$("#global_filters li[data-name='" + op_in[0] + "']").addClass('active-filter');
|
|
}
|
|
}
|
|
var op_is = event.filter.operands('is');
|
|
if (op_is.length !== 0) {
|
|
if (['private', 'starred', 'mentioned'].indexOf(op_is[0]) !== -1) {
|
|
$("#global_filters li[data-name='" + op_is[0] + "']").addClass('active-filter');
|
|
}
|
|
}
|
|
var op_stream = event.filter.operands('stream');
|
|
if (op_stream.length !== 0 && subs.is_subscribed(op_stream[0])) {
|
|
var stream_li = get_filter_li('stream', op_stream[0]);
|
|
var op_subject = event.filter.operands('topic');
|
|
var subject;
|
|
if (op_subject.length !== 0) {
|
|
subject = op_subject[0];
|
|
} else {
|
|
stream_li.addClass('active-filter');
|
|
}
|
|
rebuild_recent_subjects(op_stream[0], subject);
|
|
process_visible_unread_messages();
|
|
}
|
|
});
|
|
|
|
$(document).on('narrow_deactivated.zulip', function (event) {
|
|
$("ul.filters li").removeClass('active-filter active-subject-filter');
|
|
$("ul.expanded_subjects").remove();
|
|
$("#global_filters li[data-name='home']").addClass('active-filter');
|
|
});
|
|
|
|
$(document).on('sub_obj_created.zulip', function (event) {
|
|
if (event.sub.subscribed) {
|
|
var stream_name = event.sub.name;
|
|
var li = add_narrow_filter(stream_name, "stream");
|
|
if (li) {
|
|
event.sub.sidebar_li = li;
|
|
}
|
|
}
|
|
});
|
|
|
|
$(document).on('subscription_add_done.zulip', function (event) {
|
|
var stream_name = event.sub.name;
|
|
var li = add_narrow_filter(stream_name, "stream");
|
|
if (li) {
|
|
event.sub.sidebar_li = li;
|
|
}
|
|
exports.sort_narrow_list();
|
|
});
|
|
|
|
$(document).on('subscription_remove_done.zulip', function (event) {
|
|
var stream_name = event.sub.name;
|
|
exports.remove_narrow_filter(stream_name, 'stream');
|
|
// We need to make sure we resort if the removed sub gets added again
|
|
previous_sort_order = undefined;
|
|
});
|
|
});
|
|
|
|
return exports;
|
|
}());
|