2012-10-18 21:37:07 +02:00
|
|
|
var subs = (function () {
|
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
var meta = {
|
|
|
|
callbacks: {},
|
|
|
|
};
|
2012-10-18 21:37:07 +02:00
|
|
|
var exports = {};
|
|
|
|
|
2017-04-24 04:11:25 +02:00
|
|
|
exports.show_subs_pane = {
|
|
|
|
nothing_selected: function () {
|
|
|
|
$(".nothing-selected, #stream_settings_title").show();
|
|
|
|
$("#add_new_stream_title, .settings, #stream-creation").hide();
|
|
|
|
},
|
|
|
|
settings: function () {
|
|
|
|
$(".settings, #stream_settings_title").show();
|
|
|
|
$("#add_new_stream_title, #stream-creation, .nothing-selected").hide();
|
|
|
|
},
|
|
|
|
};
|
2016-11-04 22:18:23 +01:00
|
|
|
|
|
|
|
function button_for_sub(sub) {
|
|
|
|
var id = parseInt(sub.stream_id, 10);
|
|
|
|
return $(".stream-row[data-stream-id='" + id + "'] .check");
|
|
|
|
}
|
|
|
|
|
2017-02-15 17:38:44 +01:00
|
|
|
function row_for_stream_id(stream_id) {
|
|
|
|
return $(".stream-row[data-stream-id='" + stream_id + "']");
|
|
|
|
}
|
|
|
|
|
2017-01-27 00:40:42 +01:00
|
|
|
function settings_button_for_sub(sub) {
|
|
|
|
var id = parseInt(sub.stream_id, 10);
|
|
|
|
return $(".subscription_settings[data-stream-id='" + id + "'] .subscribe-button");
|
|
|
|
}
|
|
|
|
|
2017-03-23 05:15:16 +01:00
|
|
|
function get_row_data(row) {
|
|
|
|
var row_id = row.attr('data-stream-id');
|
|
|
|
if (row_id) {
|
|
|
|
var row_object = stream_data.get_sub_by_id(row_id);
|
2017-03-25 01:27:52 +01:00
|
|
|
return {
|
|
|
|
id: row_id,
|
|
|
|
object: row_object,
|
|
|
|
};
|
2017-03-23 05:15:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_active_data() {
|
|
|
|
var active_row = $('div.stream-row.active');
|
|
|
|
var valid_active_id = active_row.attr('data-stream-id');
|
|
|
|
var active_tab = $('.subscriptions-container').find('div.ind-tab.selected');
|
2017-03-25 01:27:52 +01:00
|
|
|
return {
|
|
|
|
row: active_row,
|
|
|
|
id: valid_active_id,
|
|
|
|
tab: active_tab,
|
|
|
|
};
|
2017-03-23 05:15:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function export_hash(hash) {
|
|
|
|
var hash_components = {
|
|
|
|
base: hash.shift(),
|
|
|
|
arguments: hash,
|
|
|
|
};
|
|
|
|
exports.change_state(hash_components);
|
|
|
|
}
|
|
|
|
|
2013-11-08 10:12:05 +01:00
|
|
|
function selectText(element) {
|
2016-12-02 17:09:31 +01:00
|
|
|
var range;
|
|
|
|
var sel;
|
2013-11-08 10:12:05 +01:00
|
|
|
if (window.getSelection) {
|
|
|
|
sel = window.getSelection();
|
|
|
|
range = document.createRange();
|
|
|
|
range.selectNodeContents(element);
|
|
|
|
|
|
|
|
sel.removeAllRanges();
|
|
|
|
sel.addRange(range);
|
2016-06-09 23:05:34 +02:00
|
|
|
} else if (document.body.createTextRange) {
|
2013-11-08 10:12:05 +01:00
|
|
|
range = document.body.createTextRange();
|
|
|
|
range.moveToElementText(element);
|
|
|
|
range.select();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-23 17:51:01 +01:00
|
|
|
function should_list_all_streams() {
|
2017-04-20 08:03:44 +02:00
|
|
|
return !page_params.realm_is_zephyr_mirror_realm;
|
2013-01-23 17:51:01 +01:00
|
|
|
}
|
|
|
|
|
2017-03-04 20:27:37 +01:00
|
|
|
exports.toggle_home = function (sub) {
|
2017-03-19 16:00:35 +01:00
|
|
|
stream_muting.update_in_home_view(sub, ! sub.in_home_view);
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.set_stream_property(sub, 'in_home_view', sub.in_home_view);
|
2013-05-14 21:00:28 +02:00
|
|
|
};
|
2013-02-12 22:32:14 +01:00
|
|
|
|
2017-03-04 20:32:30 +01:00
|
|
|
exports.toggle_pin_to_top_stream = function (sub) {
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.set_stream_property(sub, 'pin_to_top', !sub.pin_to_top);
|
2016-07-01 07:26:09 +02:00
|
|
|
};
|
|
|
|
|
2017-03-19 16:03:07 +01:00
|
|
|
exports.update_stream_name = function (sub, new_name) {
|
2013-08-21 23:21:31 +02:00
|
|
|
// Rename the stream internally.
|
2017-03-05 00:35:45 +01:00
|
|
|
stream_data.rename_sub(sub, new_name);
|
|
|
|
var stream_id = sub.stream_id;
|
2013-08-21 23:21:31 +02:00
|
|
|
|
2013-10-21 22:26:19 +02:00
|
|
|
// Update the left sidebar.
|
2016-10-30 17:33:23 +01:00
|
|
|
stream_list.rename_stream(sub, new_name);
|
2013-08-21 23:21:31 +02:00
|
|
|
|
2016-11-05 00:11:45 +01:00
|
|
|
// Update the stream settings
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.update_stream_name(sub, new_name);
|
2016-11-05 00:11:45 +01:00
|
|
|
|
2016-10-29 01:30:51 +02:00
|
|
|
// Update the subscriptions page
|
2017-03-05 00:35:45 +01:00
|
|
|
var sub_row = $(".stream-row[data-stream-id='" + stream_id + "']");
|
2016-11-05 00:10:01 +01:00
|
|
|
sub_row.find(".stream-name").text(new_name);
|
2016-10-29 01:30:51 +02:00
|
|
|
|
2013-08-21 23:21:31 +02:00
|
|
|
// Update the message feed.
|
2017-01-05 17:34:27 +01:00
|
|
|
message_live_update.update_stream_name(stream_id, new_name);
|
2017-03-19 16:03:07 +01:00
|
|
|
};
|
2013-08-21 23:21:31 +02:00
|
|
|
|
2017-03-19 16:03:07 +01:00
|
|
|
exports.update_stream_description = function (sub, description) {
|
2014-01-24 18:19:27 +01:00
|
|
|
sub.description = description;
|
|
|
|
|
2016-11-04 22:11:23 +01:00
|
|
|
// Update stream row
|
|
|
|
var sub_row = $('.stream-row[data-stream-id=' + sub.stream_id + ']');
|
2017-03-18 19:08:36 +01:00
|
|
|
stream_data.render_stream_description(sub);
|
|
|
|
sub_row.find(".description").html(sub.rendered_description);
|
2016-11-04 22:11:23 +01:00
|
|
|
|
|
|
|
// Update stream settings
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.update_stream_description(sub);
|
2017-03-21 07:19:14 +01:00
|
|
|
};
|
2014-01-24 18:19:27 +01:00
|
|
|
|
2016-11-05 00:24:55 +01:00
|
|
|
exports.set_color = function (stream_id, color) {
|
|
|
|
var sub = stream_data.get_sub_by_id(stream_id);
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.set_stream_property(sub, 'color', color);
|
2013-05-17 21:35:17 +02:00
|
|
|
};
|
|
|
|
|
2016-03-14 06:38:43 +01:00
|
|
|
exports.rerender_subscribers_count = function (sub) {
|
|
|
|
var id = parseInt(sub.stream_id, 10);
|
|
|
|
stream_data.update_subscribers_count(sub);
|
2016-11-01 22:32:10 +01:00
|
|
|
$(".stream-row[data-stream-id='" + id + "'] .subscriber-count-text").text(sub.subscriber_count);
|
2016-03-14 06:38:43 +01:00
|
|
|
};
|
|
|
|
|
2016-07-07 14:50:21 +02:00
|
|
|
function add_email_hint(row, email_address_hint_content) {
|
2013-08-26 20:22:22 +02:00
|
|
|
// Add a popover explaining stream e-mail addresses on hover.
|
2014-07-16 23:31:03 +02:00
|
|
|
var hint_id = "#email-address-hint-" + row.stream_id;
|
2013-08-26 20:22:22 +02:00
|
|
|
var email_address_hint = $(hint_id);
|
2016-12-03 03:08:47 +01:00
|
|
|
email_address_hint.popover({placement: "bottom",
|
|
|
|
title: "Email integration",
|
|
|
|
content: email_address_hint_content,
|
|
|
|
trigger: "manual"});
|
2016-07-07 14:50:21 +02:00
|
|
|
|
2013-08-26 20:22:22 +02:00
|
|
|
$("body").on("mouseover", hint_id, function (e) {
|
|
|
|
email_address_hint.popover('show');
|
|
|
|
e.stopPropagation();
|
|
|
|
});
|
|
|
|
$("body").on("mouseout", hint_id, function (e) {
|
|
|
|
email_address_hint.popover('hide');
|
|
|
|
e.stopPropagation();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-04-22 22:22:25 +02:00
|
|
|
// The `stream_create.get_name()` value tells us whether the stream was just
|
2017-02-18 00:03:43 +01:00
|
|
|
// created in this browser window; it's a hack to work around the
|
|
|
|
// server_events code flow not having a good way to associate with
|
|
|
|
// this request. These should be appended to the top of the list so
|
|
|
|
// they are more visible.
|
2013-01-23 19:43:11 +01:00
|
|
|
function add_sub_to_table(sub) {
|
2017-04-28 17:55:22 +02:00
|
|
|
stream_data.update_calculated_fields(sub);
|
2014-01-03 20:35:52 +01:00
|
|
|
var html = templates.render('subscription', sub);
|
2016-11-01 22:32:10 +01:00
|
|
|
var settings_html = templates.render('subscription_settings', sub);
|
2017-04-22 22:22:25 +02:00
|
|
|
if (stream_create.get_name() === sub.name) {
|
2017-02-18 00:03:43 +01:00
|
|
|
$(".streams-list").prepend(html).scrollTop(0);
|
|
|
|
} else {
|
|
|
|
$(".streams-list").append(html);
|
|
|
|
}
|
2016-11-01 22:32:10 +01:00
|
|
|
$(".subscriptions .settings").append($(settings_html));
|
|
|
|
|
2016-07-07 14:50:21 +02:00
|
|
|
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
|
|
|
add_email_hint(sub, email_address_hint_content);
|
2016-11-01 22:32:10 +01:00
|
|
|
|
2017-04-22 22:22:25 +02:00
|
|
|
if (stream_create.get_name() === sub.name) {
|
|
|
|
var created_stream = stream_create.get_name();
|
|
|
|
$(".stream-row[data-stream-id='" + stream_data.get_sub(created_stream).stream_id + "']").click();
|
|
|
|
stream_create.reset_created_stream();
|
2016-11-01 22:32:10 +01:00
|
|
|
}
|
2013-01-23 19:43:11 +01:00
|
|
|
}
|
|
|
|
|
2017-02-15 17:38:44 +01:00
|
|
|
exports.remove_stream = function (stream_id) {
|
|
|
|
// It is possible that row is empty when we deactivate a
|
|
|
|
// stream, but we let jQuery silently handle that.
|
|
|
|
var row = row_for_stream_id(stream_id);
|
|
|
|
row.remove();
|
|
|
|
};
|
|
|
|
|
2017-03-19 16:47:30 +01:00
|
|
|
exports.update_settings_for_subscribed = function (sub) {
|
2017-01-20 22:03:52 +01:00
|
|
|
var button = button_for_sub(sub);
|
2017-01-27 00:40:42 +01:00
|
|
|
var settings_button = settings_button_for_sub(sub).removeClass("unsubscribed");
|
2017-01-20 22:03:52 +01:00
|
|
|
|
|
|
|
if (button.length !== 0) {
|
|
|
|
exports.rerender_subscribers_count(sub);
|
2013-01-23 22:08:34 +01:00
|
|
|
|
2017-01-20 22:03:52 +01:00
|
|
|
button.toggleClass("checked");
|
2017-01-27 00:40:42 +01:00
|
|
|
settings_button.text(i18n.t("Unsubscribe"));
|
2017-04-24 04:11:25 +02:00
|
|
|
|
|
|
|
stream_edit.add_me_to_member_list(sub);
|
2013-01-22 23:16:04 +01:00
|
|
|
} else {
|
2017-01-20 22:03:52 +01:00
|
|
|
add_sub_to_table(sub);
|
2012-10-18 21:37:07 +02:00
|
|
|
}
|
2013-03-21 22:13:17 +01:00
|
|
|
|
2017-03-17 23:07:20 +01:00
|
|
|
// Display the swatch and subscription stream_settings
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.show_sub(sub);
|
2014-02-05 22:53:53 +01:00
|
|
|
};
|
2012-10-18 21:37:07 +02:00
|
|
|
|
2017-03-19 16:47:30 +01:00
|
|
|
exports.update_settings_for_unsubscribed = function (sub) {
|
|
|
|
var button = button_for_sub(sub);
|
|
|
|
var settings_button = settings_button_for_sub(sub).addClass("unsubscribed");
|
2013-01-23 22:08:34 +01:00
|
|
|
|
2017-03-19 16:47:30 +01:00
|
|
|
button.toggleClass("checked");
|
|
|
|
settings_button.text(i18n.t("Subscribe"));
|
2016-03-14 06:38:43 +01:00
|
|
|
|
2017-03-19 16:47:30 +01:00
|
|
|
exports.rerender_subscribers_count(sub);
|
2016-11-01 22:32:10 +01:00
|
|
|
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.collapse(sub);
|
|
|
|
|
2017-03-19 16:47:30 +01:00
|
|
|
row_for_stream_id(subs.stream_id).attr("data-temp-view", true);
|
2014-02-05 22:53:53 +01:00
|
|
|
};
|
2013-03-29 20:27:41 +01:00
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
// these streams are miscategorized so they don't jump off the page when being
|
|
|
|
// unsubscribed from, but should be cleared and sorted when you apply an actual
|
|
|
|
// filter.
|
|
|
|
function remove_temporarily_miscategorized_streams() {
|
|
|
|
$("[data-temp-view]").removeAttr("data-temp-view", "false");
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.remove_miscategorized_streams = remove_temporarily_miscategorized_streams;
|
|
|
|
|
2017-01-03 13:26:48 +01:00
|
|
|
function stream_matches_query(query, sub, attr) {
|
2016-11-04 23:56:38 +01:00
|
|
|
var search_terms = query.input.toLowerCase().split(",").map(function (s) {
|
2016-10-12 08:53:57 +02:00
|
|
|
return s.trim();
|
|
|
|
});
|
|
|
|
|
2016-12-26 10:14:18 +01:00
|
|
|
var flag = true;
|
|
|
|
flag = flag && (function () {
|
2017-01-03 13:26:48 +01:00
|
|
|
var sub_attr = sub[attr].toLowerCase();
|
2016-12-28 03:13:21 +01:00
|
|
|
return _.any(search_terms, function (o) {
|
2017-01-03 13:26:48 +01:00
|
|
|
if (sub_attr.indexOf(o) !== -1) {
|
2017-02-04 13:02:31 +01:00
|
|
|
return true;
|
|
|
|
}
|
2016-12-28 03:13:21 +01:00
|
|
|
});
|
2016-12-26 10:14:18 +01:00
|
|
|
}());
|
|
|
|
flag = flag && ((sub.subscribed || !query.subscribed_only) ||
|
|
|
|
sub.data_temp_view === "true");
|
|
|
|
return flag;
|
|
|
|
}
|
2017-01-03 13:26:48 +01:00
|
|
|
exports.stream_name_match_stream_ids = [];
|
|
|
|
exports.stream_description_match_stream_ids = [];
|
2016-12-26 10:14:18 +01:00
|
|
|
|
|
|
|
// query is now an object rather than a string.
|
|
|
|
// Query { input: String, subscribed_only: Boolean }
|
|
|
|
exports.filter_table = function (query) {
|
2017-01-03 13:26:48 +01:00
|
|
|
exports.stream_name_match_stream_ids = [];
|
|
|
|
exports.stream_description_match_stream_ids = [];
|
|
|
|
var others = [];
|
|
|
|
var stream_id_to_stream_name = {};
|
|
|
|
var widgets = {};
|
|
|
|
|
|
|
|
function sort_by_stream_name(a, b) {
|
|
|
|
var stream_a_name = stream_id_to_stream_name[a].toLocaleLowerCase();
|
|
|
|
var stream_b_name = stream_id_to_stream_name[b].toLocaleLowerCase();
|
|
|
|
return String.prototype.localeCompare.call(stream_a_name, stream_b_name);
|
|
|
|
}
|
|
|
|
|
2016-11-04 23:56:38 +01:00
|
|
|
_.each($("#subscriptions_table .stream-row"), function (row) {
|
|
|
|
var sub = stream_data.get_sub_by_id($(row).attr("data-stream-id"));
|
2016-12-26 10:14:18 +01:00
|
|
|
sub.data_temp_view = $(row).attr("data-temp-view");
|
2016-10-12 08:53:57 +02:00
|
|
|
|
2017-01-03 13:26:48 +01:00
|
|
|
if (stream_matches_query(query, sub, 'name')) {
|
2016-11-04 23:56:38 +01:00
|
|
|
$(row).removeClass("notdisplayed");
|
2017-01-03 13:26:48 +01:00
|
|
|
|
|
|
|
stream_id_to_stream_name[sub.stream_id] = sub.name;
|
|
|
|
exports.stream_name_match_stream_ids.push(sub.stream_id);
|
|
|
|
|
|
|
|
widgets[sub.stream_id] = $(row).detach();
|
|
|
|
} else if (stream_matches_query(query, sub, 'description')) {
|
|
|
|
$(row).removeClass("notdisplayed");
|
|
|
|
|
|
|
|
stream_id_to_stream_name[sub.stream_id] = sub.name;
|
|
|
|
exports.stream_description_match_stream_ids.push(sub.stream_id);
|
|
|
|
|
|
|
|
widgets[sub.stream_id] = $(row).detach();
|
|
|
|
} else {
|
2016-11-04 23:56:38 +01:00
|
|
|
$(row).addClass("notdisplayed");
|
2017-01-03 13:26:48 +01:00
|
|
|
others.push($(row).detach());
|
2016-10-12 08:53:57 +02:00
|
|
|
}
|
|
|
|
});
|
2016-11-01 22:32:10 +01:00
|
|
|
|
2017-01-03 13:26:48 +01:00
|
|
|
exports.stream_name_match_stream_ids.sort(sort_by_stream_name);
|
|
|
|
exports.stream_description_match_stream_ids.sort(sort_by_stream_name);
|
|
|
|
|
|
|
|
_.each(exports.stream_name_match_stream_ids, function (stream_id) {
|
|
|
|
$('#subscriptions_table .streams-list').append(widgets[stream_id]);
|
|
|
|
});
|
|
|
|
|
|
|
|
_.each(exports.stream_description_match_stream_ids, function (stream_id) {
|
|
|
|
$('#subscriptions_table .streams-list').append(widgets[stream_id]);
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#subscriptions_table .streams-list').append(others);
|
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
if ($(".stream-row.active").hasClass("notdisplayed")) {
|
|
|
|
$(".right .settings").hide();
|
|
|
|
$(".nothing-selected").show();
|
|
|
|
$(".stream-row.active").removeClass("active");
|
|
|
|
}
|
2016-10-12 08:53:57 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
function actually_filter_streams() {
|
2016-11-01 22:32:10 +01:00
|
|
|
var search_box = $("#add_new_subscription input[type='text']");
|
2016-10-12 08:53:57 +02:00
|
|
|
var query = search_box.expectOne().val().trim();
|
2016-11-01 22:32:10 +01:00
|
|
|
var subscribed_only;
|
|
|
|
if (components.toggle.lookup("stream-filter-toggle")) {
|
|
|
|
subscribed_only = components.toggle.lookup("stream-filter-toggle").value() === "Subscribed";
|
|
|
|
} else {
|
|
|
|
subscribed_only = false;
|
|
|
|
}
|
|
|
|
exports.filter_table({ input: query, subscribed_only: subscribed_only });
|
2016-10-12 08:53:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var filter_streams = _.throttle(actually_filter_streams, 50);
|
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
exports.setup_page = function (callback) {
|
|
|
|
function initialize_components() {
|
|
|
|
var stream_filter_toggle = components.toggle({
|
|
|
|
name: "stream-filter-toggle",
|
|
|
|
selected: 0,
|
|
|
|
values: [
|
2017-03-25 11:21:37 +01:00
|
|
|
{ label: i18n.t("Subscribed") },
|
|
|
|
{ label: i18n.t("All streams") },
|
2016-11-01 22:32:10 +01:00
|
|
|
],
|
2016-12-15 07:26:09 +01:00
|
|
|
callback: function () {
|
2016-11-01 22:32:10 +01:00
|
|
|
actually_filter_streams();
|
|
|
|
remove_temporarily_miscategorized_streams();
|
2017-01-12 00:17:43 +01:00
|
|
|
},
|
2016-11-01 22:32:10 +01:00
|
|
|
}).get();
|
|
|
|
|
|
|
|
if (should_list_all_streams()) {
|
|
|
|
$("#subscriptions_table .search-container").prepend(stream_filter_toggle);
|
|
|
|
}
|
|
|
|
|
2017-01-15 20:21:33 +01:00
|
|
|
// show the "Stream settings" header by default.
|
2016-11-01 22:32:10 +01:00
|
|
|
$(".display-type #stream_settings_title").show();
|
|
|
|
}
|
2013-10-25 17:27:07 +02:00
|
|
|
|
2016-10-25 21:50:14 +02:00
|
|
|
function _populate_and_fill() {
|
2016-10-25 21:45:19 +02:00
|
|
|
var sub_rows = stream_data.get_streams_for_settings_page();
|
2013-01-23 17:41:04 +01:00
|
|
|
|
2013-07-26 20:43:14 +02:00
|
|
|
$('#subscriptions_table').empty();
|
2016-10-12 08:53:57 +02:00
|
|
|
|
2014-01-15 23:30:36 +01:00
|
|
|
var template_data = {
|
|
|
|
can_create_streams: page_params.can_create_streams,
|
2016-10-12 08:53:57 +02:00
|
|
|
subscriptions: sub_rows,
|
2017-01-12 00:17:43 +01:00
|
|
|
hide_all_streams: !should_list_all_streams(),
|
2014-01-15 23:30:36 +01:00
|
|
|
};
|
|
|
|
var rendered = templates.render('subscription_table_body', template_data);
|
2013-07-26 20:43:14 +02:00
|
|
|
$('#subscriptions_table').append(rendered);
|
2016-11-01 22:32:10 +01:00
|
|
|
initialize_components();
|
|
|
|
actually_filter_streams();
|
2016-07-07 14:50:21 +02:00
|
|
|
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
2013-08-26 20:22:22 +02:00
|
|
|
_.each(sub_rows, function (row) {
|
2016-07-07 14:50:21 +02:00
|
|
|
add_email_hint(row, email_address_hint_content);
|
2013-08-26 20:22:22 +02:00
|
|
|
});
|
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
$("#add_new_subscription input[type='text']").on("input", function () {
|
|
|
|
remove_temporarily_miscategorized_streams();
|
2016-12-15 07:36:30 +01:00
|
|
|
// Debounce filtering in case a user is typing quickly
|
|
|
|
filter_streams();
|
2016-11-01 22:32:10 +01:00
|
|
|
});
|
|
|
|
|
2013-07-25 22:48:55 +02:00
|
|
|
$(document).trigger($.Event('subs_page_loaded.zulip'));
|
2016-11-01 22:32:10 +01:00
|
|
|
|
|
|
|
if (callback) {
|
|
|
|
callback();
|
|
|
|
exports.onlaunchtrigger();
|
|
|
|
}
|
2013-01-23 17:41:04 +01:00
|
|
|
}
|
|
|
|
|
2016-10-25 21:50:14 +02:00
|
|
|
function populate_and_fill() {
|
2016-06-10 09:03:36 +02:00
|
|
|
i18n.ensure_i18n(function () {
|
2016-10-25 21:50:14 +02:00
|
|
|
_populate_and_fill();
|
2016-06-10 09:03:36 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-10-25 21:50:14 +02:00
|
|
|
populate_and_fill();
|
2013-04-04 22:30:28 +02:00
|
|
|
|
2016-10-25 21:50:14 +02:00
|
|
|
if (!should_list_all_streams()) {
|
2016-06-13 08:40:35 +02:00
|
|
|
$('#create_stream_button').val(i18n.t("Subscribe"));
|
2013-01-23 17:51:01 +01:00
|
|
|
}
|
2012-10-18 21:37:07 +02:00
|
|
|
};
|
2012-10-03 22:24:17 +02:00
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
// add a function to run on subscription page launch by name,
|
|
|
|
// and specify whether it should be kept or just run once (boolean).
|
|
|
|
exports.onlaunch = function (name, callback, keep) {
|
|
|
|
meta.callbacks[name] = {
|
|
|
|
func: callback,
|
2017-01-12 00:17:43 +01:00
|
|
|
keep: keep,
|
2016-11-01 22:32:10 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.onlaunchtrigger = function () {
|
|
|
|
for (var x in meta.callbacks) {
|
|
|
|
if (typeof meta.callbacks[x].func === "function") {
|
|
|
|
meta.callbacks[x].func();
|
|
|
|
|
|
|
|
// delete if it should not be kept.
|
|
|
|
if (!meta.callbacks[x].keep) {
|
|
|
|
delete meta.callbacks[x];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-02-21 18:13:32 +01:00
|
|
|
exports.change_state = (function () {
|
|
|
|
var prevent_next = false;
|
|
|
|
|
|
|
|
var func = function (hash) {
|
|
|
|
if (prevent_next) {
|
|
|
|
prevent_next = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if there are any arguments the state should be modified.
|
|
|
|
if (hash.arguments.length > 0) {
|
2017-03-09 00:20:22 +01:00
|
|
|
// if in #streams/new form.
|
2017-02-21 18:13:32 +01:00
|
|
|
if (hash.arguments[0] === "new") {
|
2017-03-23 07:54:10 +01:00
|
|
|
exports.new_stream_clicked();
|
2017-02-21 18:13:32 +01:00
|
|
|
components.toggle.lookup("stream-filter-toggle").goto("All streams");
|
2017-02-23 20:04:56 +01:00
|
|
|
} else if (hash.arguments[0] === "all") {
|
|
|
|
components.toggle.lookup("stream-filter-toggle").goto("All streams");
|
|
|
|
} else if (hash.arguments[0] === "subscribed") {
|
|
|
|
components.toggle.lookup("stream-filter-toggle").goto("Subscribed");
|
2017-02-21 18:13:32 +01:00
|
|
|
// if the first argument is a valid number.
|
|
|
|
} else if (/\d+/.test(hash.arguments[0])) {
|
|
|
|
var $stream_row = $(".stream-row[data-stream-id='" + hash.arguments[0] + "']");
|
|
|
|
var top = $stream_row.click()[0].offsetTop;
|
|
|
|
|
|
|
|
$(".streams-list").animate({ scrollTop: top }, 200);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
func.prevent_once = function () {
|
|
|
|
prevent_next = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
return func;
|
|
|
|
}());
|
|
|
|
|
|
|
|
exports.launch = function (hash) {
|
2016-11-01 22:32:10 +01:00
|
|
|
exports.setup_page(function () {
|
2017-05-27 15:40:54 +02:00
|
|
|
overlays.open_overlay({
|
2017-05-06 01:11:18 +02:00
|
|
|
name: 'subscriptions',
|
|
|
|
overlay: $("#subscription_overlay"),
|
|
|
|
on_close: exports.close,
|
|
|
|
});
|
2017-02-21 18:13:32 +01:00
|
|
|
exports.change_state(hash);
|
2016-11-01 22:32:10 +01:00
|
|
|
});
|
2017-03-26 12:26:22 +02:00
|
|
|
if (!get_active_data().id) {
|
|
|
|
$('#search_stream_name').focus();
|
|
|
|
}
|
2016-11-01 22:32:10 +01:00
|
|
|
};
|
|
|
|
|
2017-01-19 23:23:25 +01:00
|
|
|
exports.close = function () {
|
2017-05-27 18:55:41 +02:00
|
|
|
hashchange.exit_overlay();
|
2017-01-19 23:23:25 +01:00
|
|
|
subs.remove_miscategorized_streams();
|
|
|
|
};
|
|
|
|
|
2017-03-22 22:18:34 +01:00
|
|
|
exports.switch_rows = function (event) {
|
2017-03-23 05:15:16 +01:00
|
|
|
var active_data = get_active_data();
|
|
|
|
var switch_row;
|
2017-04-05 10:49:19 +02:00
|
|
|
if (window.location.hash === '#streams/new') {
|
|
|
|
// Prevent switching stream rows when creating a new stream
|
|
|
|
return false;
|
|
|
|
} else if (!active_data.id || active_data.row.hasClass('notdisplayed')) {
|
2017-03-23 05:15:16 +01:00
|
|
|
switch_row = $('div.stream-row:not(.notdisplayed):first');
|
2017-03-26 12:26:22 +02:00
|
|
|
if ($('#search_stream_name').is(":focus")) {
|
|
|
|
$('#search_stream_name').blur();
|
|
|
|
}
|
2017-05-25 23:53:19 +02:00
|
|
|
} else {
|
|
|
|
if (event === 'up_arrow') {
|
|
|
|
switch_row = active_data.row.prevAll().not('.notdisplayed').first();
|
|
|
|
} else if (event === 'down_arrow') {
|
|
|
|
switch_row = active_data.row.nextAll().not('.notdisplayed').first();
|
|
|
|
}
|
2017-03-26 12:26:22 +02:00
|
|
|
if ($('#search_stream_name').is(":focus")) {
|
|
|
|
// remove focus from Filter streams input instead of switching rows
|
|
|
|
// if Filter streams input is focused
|
|
|
|
return $('#search_stream_name').blur();
|
|
|
|
}
|
2017-03-22 02:49:52 +01:00
|
|
|
}
|
|
|
|
|
2017-03-23 05:15:16 +01:00
|
|
|
var row_data = get_row_data(switch_row);
|
2017-05-25 23:53:19 +02:00
|
|
|
if (row_data) {
|
2017-03-25 01:27:52 +01:00
|
|
|
var switch_row_name = row_data.object.name;
|
|
|
|
var hash = ['#streams', row_data.id, switch_row_name];
|
2017-03-23 05:15:16 +01:00
|
|
|
export_hash(hash);
|
2017-03-23 06:15:47 +01:00
|
|
|
} else if (event === 'up_arrow' && !row_data) {
|
|
|
|
$('#search_stream_name').focus();
|
2017-03-22 02:49:52 +01:00
|
|
|
}
|
2017-04-05 10:49:19 +02:00
|
|
|
return true;
|
2017-03-22 02:49:52 +01:00
|
|
|
};
|
|
|
|
|
2017-03-23 03:06:38 +01:00
|
|
|
exports.keyboard_sub = function () {
|
2017-03-23 05:15:16 +01:00
|
|
|
var active_data = get_active_data();
|
2017-03-25 01:27:52 +01:00
|
|
|
var row_data = get_row_data(active_data.row);
|
2017-03-23 05:15:16 +01:00
|
|
|
if (row_data) {
|
2017-03-25 01:27:52 +01:00
|
|
|
subs.sub_or_unsub(row_data.object);
|
|
|
|
if (row_data.object.subscribed && active_data.tab.text() === 'Subscribed') {
|
|
|
|
active_data.row.addClass('notdisplayed');
|
|
|
|
active_data.row.removeClass('active');
|
2017-03-23 05:15:16 +01:00
|
|
|
}
|
2017-03-23 03:06:38 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-03-23 06:02:01 +01:00
|
|
|
exports.toggle_view = function (event) {
|
|
|
|
var active_data = get_active_data();
|
|
|
|
var hash;
|
2017-03-25 01:27:52 +01:00
|
|
|
if (event === 'right_arrow' && active_data.tab.text() === 'Subscribed') {
|
2017-03-23 06:02:01 +01:00
|
|
|
hash = ['#streams', 'all'];
|
|
|
|
export_hash(hash);
|
2017-03-25 01:27:52 +01:00
|
|
|
} else if (event === 'left_arrow' && active_data.tab.text() === 'All streams') {
|
2017-03-23 06:02:01 +01:00
|
|
|
hash = ['#streams', 'subscribed'];
|
|
|
|
export_hash(hash);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-03-23 06:41:31 +01:00
|
|
|
exports.view_stream = function () {
|
|
|
|
var active_data = get_active_data();
|
2017-03-25 01:27:52 +01:00
|
|
|
var row_data = get_row_data(active_data.row);
|
2017-03-23 06:41:31 +01:00
|
|
|
if (row_data) {
|
2017-03-25 01:27:52 +01:00
|
|
|
window.location.hash = '#narrow/stream/' + row_data.object.name;
|
2017-03-23 06:41:31 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-22 23:16:04 +01:00
|
|
|
function ajaxSubscribe(stream) {
|
2013-01-31 21:09:34 +01:00
|
|
|
// Subscribe yourself to a single stream.
|
|
|
|
var true_stream_name;
|
|
|
|
|
2013-12-18 19:55:18 +01:00
|
|
|
return channel.post({
|
2015-11-30 21:39:40 +01:00
|
|
|
url: "/json/users/me/subscriptions",
|
2016-12-03 03:08:47 +01:00
|
|
|
data: {subscriptions: JSON.stringify([{name: stream}]) },
|
2016-12-02 14:06:06 +01:00
|
|
|
success: function (resp, statusText, xhr) {
|
2017-05-27 15:40:54 +02:00
|
|
|
if (overlays.streams_open()) {
|
2017-01-19 23:23:37 +01:00
|
|
|
$("#create_stream_name").val("");
|
2016-11-01 22:32:10 +01:00
|
|
|
|
2017-01-19 23:23:37 +01:00
|
|
|
actually_filter_streams();
|
|
|
|
}
|
2013-01-31 21:09:34 +01:00
|
|
|
|
2016-08-24 23:56:23 +02:00
|
|
|
var res = JSON.parse(xhr.responseText);
|
2013-01-31 21:09:34 +01:00
|
|
|
if (!$.isEmptyObject(res.already_subscribed)) {
|
|
|
|
// Display the canonical stream capitalization.
|
2017-01-20 23:11:08 +01:00
|
|
|
true_stream_name = res.already_subscribed[people.my_current_email()][0];
|
2017-03-18 21:17:41 +01:00
|
|
|
ui_report.success(i18n.t("Already subscribed to __stream__", {stream: true_stream_name}),
|
2016-03-15 18:22:20 +01:00
|
|
|
$("#subscriptions-status"), 'subscriptions-status');
|
2012-11-07 23:25:04 +01:00
|
|
|
}
|
2013-03-29 20:49:05 +01:00
|
|
|
// The rest of the work is done via the subscribe event we will get
|
2012-11-07 23:25:04 +01:00
|
|
|
},
|
|
|
|
error: function (xhr) {
|
2017-03-18 21:17:41 +01:00
|
|
|
ui_report.error(i18n.t("Error adding subscription"), xhr,
|
2016-03-15 18:22:20 +01:00
|
|
|
$("#subscriptions-status"), 'subscriptions-status');
|
2017-01-12 00:17:43 +01:00
|
|
|
},
|
2012-11-07 23:25:04 +01:00
|
|
|
});
|
|
|
|
}
|
2012-10-09 21:01:41 +02:00
|
|
|
|
2017-03-05 03:47:28 +01:00
|
|
|
function ajaxUnsubscribe(sub) {
|
|
|
|
// TODO: use stream_id when backend supports it
|
2016-12-23 02:37:10 +01:00
|
|
|
return channel.del({
|
|
|
|
url: "/json/users/me/subscriptions",
|
2017-03-05 03:47:28 +01:00
|
|
|
data: {subscriptions: JSON.stringify([sub.name]) },
|
2016-12-02 14:06:06 +01:00
|
|
|
success: function () {
|
2013-02-06 00:58:03 +01:00
|
|
|
$("#subscriptions-status").hide();
|
2013-03-29 20:49:05 +01:00
|
|
|
// The rest of the work is done via the unsubscribe event we will get
|
2012-10-03 22:24:17 +02:00
|
|
|
},
|
|
|
|
error: function (xhr) {
|
2017-03-18 21:17:41 +01:00
|
|
|
ui_report.error(i18n.t("Error removing subscription"), xhr,
|
2016-03-15 18:22:20 +01:00
|
|
|
$("#subscriptions-status"), 'subscriptions-status');
|
2017-01-12 00:17:43 +01:00
|
|
|
},
|
2012-10-03 22:24:17 +02:00
|
|
|
});
|
2013-01-10 22:15:55 +01:00
|
|
|
}
|
2012-11-16 20:11:08 +01:00
|
|
|
|
2017-04-22 22:22:25 +02:00
|
|
|
exports.new_stream_clicked = function () {
|
|
|
|
var stream = $.trim($("#search_stream_name").val());
|
2013-01-31 21:09:34 +01:00
|
|
|
|
2017-04-22 22:22:25 +02:00
|
|
|
if (!should_list_all_streams()) {
|
|
|
|
// Realms that don't allow listing streams should simply be subscribed to.
|
|
|
|
stream_create.set_name(stream);
|
|
|
|
ajaxSubscribe($("#search_stream_name").val());
|
|
|
|
return;
|
2013-08-27 19:14:18 +02:00
|
|
|
}
|
|
|
|
|
2017-04-22 22:22:25 +02:00
|
|
|
stream_create.new_stream_clicked(stream);
|
|
|
|
};
|
2013-01-31 21:09:34 +01:00
|
|
|
|
2017-03-04 18:10:23 +01:00
|
|
|
exports.sub_or_unsub = function (sub) {
|
2017-03-04 17:55:16 +01:00
|
|
|
if (sub.subscribed) {
|
2017-03-05 03:47:28 +01:00
|
|
|
ajaxUnsubscribe(sub);
|
2017-03-04 17:55:16 +01:00
|
|
|
} else {
|
2017-03-04 18:10:23 +01:00
|
|
|
ajaxSubscribe(sub.name);
|
2017-03-04 17:55:16 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-11-16 20:11:08 +01:00
|
|
|
$(function () {
|
2013-10-21 19:37:52 +02:00
|
|
|
|
Clean up startup code for streams.
The startup code in subs.js used to intermingle data
stuff and UI stuff in a loop inside a called function,
which made the code hard to reason about.
Now there is a clear separation of concerns, with these methods
being called in succession:
stream_data.initialize_from_page_params();
stream_list.create_initial_sidebar_rows();
The first method was mostly extracted from subs.js, but I simplified
some things, like not needing to make a copy of the hashes
we were passed in, plus I now garbage collect email_dict. Also,
the code path that initialize_from_page_params() mostly replaces
used to call create_sub(), which fired a trigger, but now it
just does data stuff.
Once the data structure is built up, it's a very simple matter
to build the initial sidebar rows, and that's what the second
method does.
2016-10-17 19:34:58 +02:00
|
|
|
stream_data.initialize_from_page_params();
|
|
|
|
stream_list.create_initial_sidebar_rows();
|
2014-01-23 21:13:04 +01:00
|
|
|
|
2014-01-23 21:19:26 +01:00
|
|
|
// We build the stream_list now. It may get re-built again very shortly
|
|
|
|
// when new messages come in, but it's fairly quick.
|
|
|
|
stream_list.build_stream_list();
|
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
$("#subscriptions_table").on("click", "#create_stream_button", function (e) {
|
2012-10-31 18:36:08 +01:00
|
|
|
e.preventDefault();
|
2017-03-23 07:54:10 +01:00
|
|
|
exports.new_stream_clicked();
|
2013-01-31 21:09:34 +01:00
|
|
|
});
|
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
$(".subscriptions").on("click", "[data-dismiss]", function (e) {
|
|
|
|
e.preventDefault();
|
2016-12-13 21:58:11 +01:00
|
|
|
// we want to make sure that the click is not just a simulated
|
|
|
|
// click; this fixes an issue where hitting "enter" would
|
|
|
|
// trigger this code path due to bootstrap magic.
|
|
|
|
if (e.clientY !== 0) {
|
2017-04-24 04:11:25 +02:00
|
|
|
exports.show_subs_pane.nothing_selected();
|
2016-12-13 21:58:11 +01:00
|
|
|
}
|
2016-11-01 22:32:10 +01:00
|
|
|
});
|
2013-08-27 19:14:18 +02:00
|
|
|
|
2013-11-08 10:12:05 +01:00
|
|
|
$("body").on("mouseover", ".subscribed-button", function (e) {
|
2016-06-13 08:40:35 +02:00
|
|
|
$(e.target).addClass("btn-danger").text(i18n.t("Unsubscribe"));
|
2013-11-08 10:12:05 +01:00
|
|
|
}).on("mouseout", ".subscribed-button", function (e) {
|
2016-06-13 08:40:35 +02:00
|
|
|
$(e.target).removeClass("btn-danger").text(i18n.t("Subscribed"));
|
2013-11-08 10:12:05 +01:00
|
|
|
});
|
|
|
|
|
2016-12-02 14:06:06 +01:00
|
|
|
$(".subscriptions").on("click", "#close-subscriptions-status", function () {
|
2016-03-15 18:22:20 +01:00
|
|
|
$("#subscriptions-status").hide();
|
|
|
|
});
|
|
|
|
|
2016-12-02 14:06:06 +01:00
|
|
|
$("#subscriptions_table").on("click", ".email-address", function () {
|
2013-11-08 10:12:05 +01:00
|
|
|
selectText(this);
|
|
|
|
});
|
|
|
|
|
2016-03-22 16:50:09 +01:00
|
|
|
$('.empty_feed_sub_unsub').click(function (e) {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
$('#subscription-status').hide();
|
2017-04-25 15:25:31 +02:00
|
|
|
var stream_name = narrow_state.stream();
|
2016-03-22 16:50:09 +01:00
|
|
|
if (stream_name === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var sub = stream_data.get_sub(stream_name);
|
2017-03-04 18:40:46 +01:00
|
|
|
exports.sub_or_unsub(sub);
|
2016-03-22 16:50:09 +01:00
|
|
|
|
|
|
|
$('.empty_feed_notice').hide();
|
|
|
|
$('#empty_narrow_message').show();
|
|
|
|
});
|
|
|
|
|
2017-02-09 00:07:52 +01:00
|
|
|
$("#subscriptions_table").on("click", ".stream-row, #create_stream_button", function () {
|
|
|
|
$(".right").addClass("show");
|
|
|
|
$(".subscriptions-header").addClass("slide-left");
|
|
|
|
});
|
|
|
|
|
|
|
|
$("#subscriptions_table").on("click", ".icon-vector-chevron-left", function () {
|
|
|
|
$(".right").removeClass("show");
|
|
|
|
$(".subscriptions-header").removeClass("slide-left");
|
|
|
|
});
|
|
|
|
|
2013-04-08 20:53:12 +02:00
|
|
|
$("#subscriptions_table").on("click", ".sub_setting_checkbox", function (e) {
|
|
|
|
var control = $(e.target).closest('.sub_setting_checkbox').find('.sub_setting_control');
|
|
|
|
// A hack. Don't change the state of the checkbox if we
|
|
|
|
// clicked on the checkbox itself.
|
|
|
|
if (control[0] !== e.target) {
|
|
|
|
control.prop("checked", ! control.prop("checked"));
|
|
|
|
}
|
|
|
|
});
|
2016-10-28 02:44:40 +02:00
|
|
|
|
2016-11-01 22:32:10 +01:00
|
|
|
(function defocus_sub_settings() {
|
|
|
|
var sel = ".search-container, .streams-list, .subscriptions-header";
|
|
|
|
|
|
|
|
$("#subscriptions_table").on("click", sel, function (e) {
|
|
|
|
if ($(e.target).is(sel)) {
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_edit.show_stream_row(this, false);
|
2016-11-01 22:32:10 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}());
|
|
|
|
|
2013-06-25 17:49:48 +02:00
|
|
|
$("#subscriptions_table").on("hide", ".subscription_settings", function (e) {
|
2016-10-28 23:25:00 +02:00
|
|
|
var sub_arrow = $(e.target).closest('.stream-row').find('.sub_arrow i');
|
2013-06-25 17:49:48 +02:00
|
|
|
sub_arrow.removeClass('icon-vector-chevron-up');
|
|
|
|
sub_arrow.addClass('icon-vector-chevron-down');
|
|
|
|
});
|
2016-10-25 23:12:28 +02:00
|
|
|
|
|
|
|
$(document).on('peer_subscribe.zulip', function (e, data) {
|
|
|
|
var sub = stream_data.get_sub(data.stream_name);
|
|
|
|
exports.rerender_subscribers_count(sub);
|
|
|
|
});
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2016-10-25 23:12:28 +02:00
|
|
|
$(document).on('peer_unsubscribe.zulip', function (e, data) {
|
|
|
|
var sub = stream_data.get_sub(data.stream_name);
|
|
|
|
exports.rerender_subscribers_count(sub);
|
|
|
|
});
|
|
|
|
|
2012-10-03 22:24:17 +02:00
|
|
|
});
|
2012-10-18 21:37:07 +02:00
|
|
|
|
2013-03-29 19:55:28 +01:00
|
|
|
function focus_on_narrowed_stream() {
|
2017-04-25 15:25:31 +02:00
|
|
|
var stream_name = narrow_state.stream();
|
2013-06-13 19:44:36 +02:00
|
|
|
if (stream_name === undefined) {
|
2013-03-29 19:55:28 +01:00
|
|
|
return;
|
|
|
|
}
|
2013-08-15 21:11:07 +02:00
|
|
|
var sub = stream_data.get_sub(stream_name);
|
2016-10-28 02:44:40 +02:00
|
|
|
if (sub === undefined) {
|
2013-03-29 19:55:28 +01:00
|
|
|
// This stream doesn't exist, so prep for creating it.
|
|
|
|
$("#create_stream_name").val(stream_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.show_and_focus_on_narrow = function () {
|
2013-11-25 17:44:06 +01:00
|
|
|
$(document).one('subs_page_loaded.zulip', focus_on_narrowed_stream);
|
2017-03-18 21:35:35 +01:00
|
|
|
ui_util.change_tab_to("#streams");
|
2013-03-29 19:55:28 +01:00
|
|
|
};
|
|
|
|
|
2012-10-18 21:37:07 +02:00
|
|
|
return exports;
|
|
|
|
|
|
|
|
}());
|
2013-08-09 02:05:23 +02:00
|
|
|
if (typeof module !== 'undefined') {
|
|
|
|
module.exports = subs;
|
|
|
|
}
|