var topic_generator = (function () { var exports = {}; exports.sub_list_generator = function (lst, lower, upper) { // lower/upper has Python range semantics so if you pass // in lower=5 and upper=8, you get elements 5/6/7 var i = lower; return { next: function () { if (i >= upper) { return; } var res = lst[i]; i += 1; return res; }, }; }; exports.reverse_sub_list_generator = function (lst, lower, upper) { // lower/upper has Python range semantics so if you pass // in lower=5 and upper=8, you get elements 7/6/5 var i = upper - 1; return { next: function () { if (i < lower) { return; } var res = lst[i]; i -= 1; return res; }, }; }; exports.list_generator = function (lst) { return exports.sub_list_generator(lst, 0, lst.length); }; exports.reverse_list_generator = function (lst) { return exports.reverse_sub_list_generator(lst, 0, lst.length); }; exports.fchain = function (outer_gen, get_inner_gen) { var outer_val = outer_gen.next(); var inner_gen; return { next: function () { while (outer_val !== undefined) { if (inner_gen === undefined) { inner_gen = get_inner_gen(outer_val); if (!inner_gen || !inner_gen.next) { blueslip.error('Invalid generator returned.'); return; } } var inner = inner_gen.next(); if (inner !== undefined) { return inner; } outer_val = outer_gen.next(); inner_gen = undefined; } }, }; }; exports.chain = function (gen_lst) { function get(which) { return which; } var outer_gen = exports.list_generator(gen_lst); return exports.fchain(outer_gen, get); }; exports.wrap = function (lst, val) { if (val === undefined) { return exports.list_generator(lst); } var i = _.indexOf(lst, val); if (i < 0) { return exports.list_generator(lst); } var inners = [ exports.sub_list_generator(lst, i, lst.length), exports.sub_list_generator(lst, 0, i), ]; return exports.chain(inners); }; exports.wrap_exclude = function (lst, val) { if (val === undefined) { return exports.list_generator(lst); } var i = _.indexOf(lst, val); if (i < 0) { return exports.list_generator(lst); } var inners = [ exports.sub_list_generator(lst, i + 1, lst.length), exports.sub_list_generator(lst, 0, i), ]; return exports.chain(inners); }; exports.reverse_wrap_exclude = function (lst, val) { if (val === undefined) { return exports.reverse_list_generator(lst); } var i = _.indexOf(lst, val); if (i < 0) { return exports.reverse_list_generator(lst); } var inners = [ exports.reverse_sub_list_generator(lst, 0, i), exports.reverse_sub_list_generator(lst, i + 1, lst.length), ]; return exports.chain(inners); }; exports.filter = function (gen, filter_func) { return { next: function () { while (true) { var val = gen.next(); if (val === undefined) { return; } if (filter_func(val)) { return val; } } }, }; }; exports.map = function (gen, map_func) { return { next: function () { var val = gen.next(); if (val === undefined) { return; } return map_func(val); }, }; }; exports.next_topic = function (streams, get_topics, has_unread_messages, curr_stream, curr_topic) { var stream_gen = exports.wrap(streams, curr_stream); function get_topic_gen(which_stream) { var gen; if (which_stream === curr_stream) { gen = exports.wrap_exclude(get_topics(which_stream), curr_topic); } else { gen = exports.list_generator(get_topics(which_stream)); } function has_unread(topic) { return has_unread_messages(which_stream, topic); } function make_object(topic) { return { stream: which_stream, topic: topic, }; } gen = exports.filter(gen, has_unread); gen = exports.map(gen, make_object); return gen; } var outer_gen = exports.fchain(stream_gen, get_topic_gen); return outer_gen.next(); }; exports.get_next_topic = function (curr_stream, curr_topic) { var my_streams = stream_sort.get_streams(); my_streams = _.filter(my_streams, function (stream_name) { if (stream_data.name_in_home_view(stream_name)) { return true; } if (stream_name === curr_stream) { // We can use n within a muted stream if we are // currently narrowed to it. return true; } return false; }); function get_unmuted_topics(stream_name) { var stream_id = stream_data.get_stream_id(stream_name); var topics = topic_data.get_recent_names(stream_id); topics = _.reject(topics, function (topic) { return muting.is_topic_muted(stream_name, topic); }); return topics; } function has_unread_messages(stream_name, topic) { var stream_id = stream_data.get_stream_id(stream_name); return unread.topic_has_any_unread(stream_id, topic); } return exports.next_topic( my_streams, get_unmuted_topics, has_unread_messages, curr_stream, curr_topic ); }; exports._get_pm_gen = function (curr_pm) { var my_pm_strings = pm_conversations.recent.get_strings(); var gen = exports.wrap_exclude(my_pm_strings, curr_pm); return gen; }; exports._get_unread_pm_gen = function (curr_pm) { var pm_gen = exports._get_pm_gen(curr_pm); function has_unread(user_ids_string) { var num_unread = unread.num_unread_for_person(user_ids_string); return num_unread > 0; } var gen = exports.filter(pm_gen, has_unread); return gen; }; exports.get_next_unread_pm_string = function (curr_pm) { var gen = exports._get_unread_pm_gen(curr_pm); return gen.next(); }; exports.get_next_stream = function (curr_stream) { var my_streams = stream_sort.get_streams(); var stream_gen = exports.wrap_exclude(my_streams, curr_stream); return stream_gen.next(); }; exports.get_prev_stream = function (curr_stream) { var my_streams = stream_sort.get_streams(); var stream_gen = exports.reverse_wrap_exclude(my_streams, curr_stream); return stream_gen.next(); }; return exports; }()); if (typeof module !== 'undefined') { module.exports = topic_generator; }