mirror of
https://github.com/zulip/zulip.git
synced 2025-11-10 08:56:10 +00:00
We used to have code scattered in multiple places to calculate things like admin options, preview urls, subscriber counts, and rendered descriptions for streams before we rendered templates in the "Manage Stream" code. These are all consolidated into a new function called stream_data.update_calculated_fields(). This is mostly code cleanup, but it also fixes a bug where the "View Stream" button would not work for a newly created stream.
732 lines
24 KiB
JavaScript
732 lines
24 KiB
JavaScript
var subs = (function () {
|
|
|
|
var meta = {
|
|
callbacks: {},
|
|
is_open: false,
|
|
};
|
|
var exports = {};
|
|
|
|
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();
|
|
},
|
|
};
|
|
|
|
function button_for_sub(sub) {
|
|
var id = parseInt(sub.stream_id, 10);
|
|
return $(".stream-row[data-stream-id='" + id + "'] .check");
|
|
}
|
|
|
|
function row_for_stream_id(stream_id) {
|
|
return $(".stream-row[data-stream-id='" + stream_id + "']");
|
|
}
|
|
|
|
function settings_button_for_sub(sub) {
|
|
var id = parseInt(sub.stream_id, 10);
|
|
return $(".subscription_settings[data-stream-id='" + id + "'] .subscribe-button");
|
|
}
|
|
|
|
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);
|
|
return {
|
|
id: row_id,
|
|
object: row_object,
|
|
};
|
|
}
|
|
}
|
|
|
|
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');
|
|
return {
|
|
row: active_row,
|
|
id: valid_active_id,
|
|
tab: active_tab,
|
|
};
|
|
}
|
|
|
|
function export_hash(hash) {
|
|
var hash_components = {
|
|
base: hash.shift(),
|
|
arguments: hash,
|
|
};
|
|
exports.change_state(hash_components);
|
|
}
|
|
|
|
function selectText(element) {
|
|
var range;
|
|
var sel;
|
|
if (window.getSelection) {
|
|
sel = window.getSelection();
|
|
range = document.createRange();
|
|
range.selectNodeContents(element);
|
|
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
} else if (document.body.createTextRange) {
|
|
range = document.body.createTextRange();
|
|
range.moveToElementText(element);
|
|
range.select();
|
|
}
|
|
}
|
|
|
|
function should_list_all_streams() {
|
|
return !page_params.is_zephyr_mirror_realm;
|
|
}
|
|
|
|
exports.toggle_home = function (sub) {
|
|
stream_muting.update_in_home_view(sub, ! sub.in_home_view);
|
|
stream_edit.set_stream_property(sub, 'in_home_view', sub.in_home_view);
|
|
};
|
|
|
|
exports.toggle_pin_to_top_stream = function (sub) {
|
|
stream_edit.set_stream_property(sub, 'pin_to_top', !sub.pin_to_top);
|
|
};
|
|
|
|
exports.update_stream_name = function (sub, new_name) {
|
|
// Rename the stream internally.
|
|
stream_data.rename_sub(sub, new_name);
|
|
var stream_id = sub.stream_id;
|
|
|
|
// Update the left sidebar.
|
|
stream_list.rename_stream(sub, new_name);
|
|
|
|
// Update the stream settings
|
|
stream_edit.update_stream_name(sub, new_name);
|
|
|
|
// Update the subscriptions page
|
|
var sub_row = $(".stream-row[data-stream-id='" + stream_id + "']");
|
|
sub_row.find(".stream-name").text(new_name);
|
|
|
|
// Update the message feed.
|
|
message_live_update.update_stream_name(stream_id, new_name);
|
|
};
|
|
|
|
exports.update_stream_description = function (sub, description) {
|
|
sub.description = description;
|
|
|
|
// Update stream row
|
|
var sub_row = $('.stream-row[data-stream-id=' + sub.stream_id + ']');
|
|
stream_data.render_stream_description(sub);
|
|
sub_row.find(".description").html(sub.rendered_description);
|
|
|
|
// Update stream settings
|
|
stream_edit.update_stream_description(sub);
|
|
};
|
|
|
|
exports.set_color = function (stream_id, color) {
|
|
var sub = stream_data.get_sub_by_id(stream_id);
|
|
stream_edit.set_stream_property(sub, 'color', color);
|
|
};
|
|
|
|
exports.rerender_subscribers_count = function (sub) {
|
|
var id = parseInt(sub.stream_id, 10);
|
|
stream_data.update_subscribers_count(sub);
|
|
$(".stream-row[data-stream-id='" + id + "'] .subscriber-count-text").text(sub.subscriber_count);
|
|
};
|
|
|
|
function add_email_hint(row, email_address_hint_content) {
|
|
// Add a popover explaining stream e-mail addresses on hover.
|
|
var hint_id = "#email-address-hint-" + row.stream_id;
|
|
var email_address_hint = $(hint_id);
|
|
email_address_hint.popover({placement: "bottom",
|
|
title: "Email integration",
|
|
content: email_address_hint_content,
|
|
trigger: "manual"});
|
|
|
|
$("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();
|
|
});
|
|
}
|
|
|
|
// The `stream_create.get_name()` value tells us whether the stream was just
|
|
// 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.
|
|
function add_sub_to_table(sub) {
|
|
stream_data.update_calculated_fields(sub);
|
|
var html = templates.render('subscription', sub);
|
|
var settings_html = templates.render('subscription_settings', sub);
|
|
if (stream_create.get_name() === sub.name) {
|
|
$(".streams-list").prepend(html).scrollTop(0);
|
|
} else {
|
|
$(".streams-list").append(html);
|
|
}
|
|
$(".subscriptions .settings").append($(settings_html));
|
|
|
|
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
|
add_email_hint(sub, email_address_hint_content);
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
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();
|
|
};
|
|
|
|
exports.update_settings_for_subscribed = function (sub) {
|
|
var button = button_for_sub(sub);
|
|
var settings_button = settings_button_for_sub(sub).removeClass("unsubscribed");
|
|
|
|
if (button.length !== 0) {
|
|
exports.rerender_subscribers_count(sub);
|
|
|
|
button.toggleClass("checked");
|
|
settings_button.text(i18n.t("Unsubscribe"));
|
|
|
|
stream_edit.add_me_to_member_list(sub);
|
|
} else {
|
|
add_sub_to_table(sub);
|
|
}
|
|
|
|
// Display the swatch and subscription stream_settings
|
|
stream_edit.show_sub(sub);
|
|
};
|
|
|
|
exports.update_settings_for_unsubscribed = function (sub) {
|
|
var button = button_for_sub(sub);
|
|
var settings_button = settings_button_for_sub(sub).addClass("unsubscribed");
|
|
|
|
button.toggleClass("checked");
|
|
settings_button.text(i18n.t("Subscribe"));
|
|
|
|
exports.rerender_subscribers_count(sub);
|
|
|
|
stream_edit.collapse(sub);
|
|
|
|
row_for_stream_id(subs.stream_id).attr("data-temp-view", true);
|
|
};
|
|
|
|
// 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;
|
|
|
|
function stream_matches_query(query, sub, attr) {
|
|
var search_terms = query.input.toLowerCase().split(",").map(function (s) {
|
|
return s.trim();
|
|
});
|
|
|
|
var flag = true;
|
|
flag = flag && (function () {
|
|
var sub_attr = sub[attr].toLowerCase();
|
|
return _.any(search_terms, function (o) {
|
|
if (sub_attr.indexOf(o) !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
}());
|
|
flag = flag && ((sub.subscribed || !query.subscribed_only) ||
|
|
sub.data_temp_view === "true");
|
|
return flag;
|
|
}
|
|
exports.stream_name_match_stream_ids = [];
|
|
exports.stream_description_match_stream_ids = [];
|
|
|
|
// query is now an object rather than a string.
|
|
// Query { input: String, subscribed_only: Boolean }
|
|
exports.filter_table = function (query) {
|
|
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);
|
|
}
|
|
|
|
_.each($("#subscriptions_table .stream-row"), function (row) {
|
|
var sub = stream_data.get_sub_by_id($(row).attr("data-stream-id"));
|
|
sub.data_temp_view = $(row).attr("data-temp-view");
|
|
|
|
if (stream_matches_query(query, sub, 'name')) {
|
|
$(row).removeClass("notdisplayed");
|
|
|
|
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 {
|
|
$(row).addClass("notdisplayed");
|
|
others.push($(row).detach());
|
|
}
|
|
});
|
|
|
|
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);
|
|
|
|
if ($(".stream-row.active").hasClass("notdisplayed")) {
|
|
$(".right .settings").hide();
|
|
$(".nothing-selected").show();
|
|
$(".stream-row.active").removeClass("active");
|
|
}
|
|
};
|
|
|
|
function actually_filter_streams() {
|
|
var search_box = $("#add_new_subscription input[type='text']");
|
|
var query = search_box.expectOne().val().trim();
|
|
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 });
|
|
}
|
|
|
|
var filter_streams = _.throttle(actually_filter_streams, 50);
|
|
|
|
exports.setup_page = function (callback) {
|
|
function initialize_components() {
|
|
var stream_filter_toggle = components.toggle({
|
|
name: "stream-filter-toggle",
|
|
selected: 0,
|
|
values: [
|
|
{ label: i18n.t("Subscribed") },
|
|
{ label: i18n.t("All streams") },
|
|
],
|
|
callback: function () {
|
|
actually_filter_streams();
|
|
remove_temporarily_miscategorized_streams();
|
|
},
|
|
}).get();
|
|
|
|
if (should_list_all_streams()) {
|
|
$("#subscriptions_table .search-container").prepend(stream_filter_toggle);
|
|
}
|
|
|
|
// show the "Stream settings" header by default.
|
|
$(".display-type #stream_settings_title").show();
|
|
}
|
|
|
|
function _populate_and_fill() {
|
|
var sub_rows = stream_data.get_streams_for_settings_page();
|
|
|
|
$('#subscriptions_table').empty();
|
|
|
|
var template_data = {
|
|
can_create_streams: page_params.can_create_streams,
|
|
subscriptions: sub_rows,
|
|
hide_all_streams: !should_list_all_streams(),
|
|
};
|
|
var rendered = templates.render('subscription_table_body', template_data);
|
|
$('#subscriptions_table').append(rendered);
|
|
initialize_components();
|
|
actually_filter_streams();
|
|
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
|
_.each(sub_rows, function (row) {
|
|
add_email_hint(row, email_address_hint_content);
|
|
});
|
|
|
|
$("#add_new_subscription input[type='text']").on("input", function () {
|
|
remove_temporarily_miscategorized_streams();
|
|
// Debounce filtering in case a user is typing quickly
|
|
filter_streams();
|
|
});
|
|
|
|
$(document).trigger($.Event('subs_page_loaded.zulip'));
|
|
|
|
if (callback) {
|
|
callback();
|
|
exports.onlaunchtrigger();
|
|
}
|
|
}
|
|
|
|
function populate_and_fill() {
|
|
i18n.ensure_i18n(function () {
|
|
_populate_and_fill();
|
|
});
|
|
}
|
|
|
|
populate_and_fill();
|
|
|
|
if (!should_list_all_streams()) {
|
|
$('#create_stream_button').val(i18n.t("Subscribe"));
|
|
}
|
|
};
|
|
|
|
// 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,
|
|
keep: keep,
|
|
};
|
|
};
|
|
|
|
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];
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
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) {
|
|
// if in #streams/new form.
|
|
if (hash.arguments[0] === "new") {
|
|
exports.new_stream_clicked();
|
|
components.toggle.lookup("stream-filter-toggle").goto("All streams");
|
|
} 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");
|
|
// 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) {
|
|
meta.is_open = true;
|
|
exports.setup_page(function () {
|
|
$("#subscription_overlay").addClass("show");
|
|
|
|
exports.change_state(hash);
|
|
});
|
|
};
|
|
|
|
Object.defineProperty(exports, "is_open", {
|
|
get: function () {
|
|
return meta.is_open;
|
|
},
|
|
enumerable: false,
|
|
});
|
|
|
|
exports.close = function () {
|
|
hashchange.exit_modal();
|
|
meta.is_open = false;
|
|
subs.remove_miscategorized_streams();
|
|
};
|
|
|
|
exports.switch_rows = function (event) {
|
|
var active_data = get_active_data();
|
|
var switch_row;
|
|
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')) {
|
|
switch_row = $('div.stream-row:not(.notdisplayed):first');
|
|
} else if (event === 'up_arrow') {
|
|
switch_row = active_data.row.prev();
|
|
} else if (event === 'down_arrow') {
|
|
switch_row = active_data.row.next();
|
|
if ($('#search_stream_name').is(":focus")) {
|
|
// When going from the filter box, go the first row.
|
|
$('#search_stream_name').blur();
|
|
switch_row = $('div.stream-row:not(.notdisplayed):first');
|
|
}
|
|
}
|
|
|
|
var row_data = get_row_data(switch_row);
|
|
if (row_data && !switch_row.hasClass('notdisplayed')) {
|
|
var switch_row_name = row_data.object.name;
|
|
var hash = ['#streams', row_data.id, switch_row_name];
|
|
export_hash(hash);
|
|
} else if (event === 'up_arrow' && !row_data) {
|
|
$('#search_stream_name').focus();
|
|
}
|
|
return true;
|
|
};
|
|
|
|
exports.keyboard_sub = function () {
|
|
var active_data = get_active_data();
|
|
var row_data = get_row_data(active_data.row);
|
|
if (row_data) {
|
|
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');
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.toggle_view = function (event) {
|
|
var active_data = get_active_data();
|
|
var hash;
|
|
if (event === 'right_arrow' && active_data.tab.text() === 'Subscribed') {
|
|
hash = ['#streams', 'all'];
|
|
export_hash(hash);
|
|
} else if (event === 'left_arrow' && active_data.tab.text() === 'All streams') {
|
|
hash = ['#streams', 'subscribed'];
|
|
export_hash(hash);
|
|
}
|
|
};
|
|
|
|
exports.view_stream = function () {
|
|
var active_data = get_active_data();
|
|
var row_data = get_row_data(active_data.row);
|
|
if (row_data) {
|
|
window.location.hash = '#narrow/stream/' + row_data.object.name;
|
|
}
|
|
};
|
|
|
|
function ajaxSubscribe(stream) {
|
|
// Subscribe yourself to a single stream.
|
|
var true_stream_name;
|
|
|
|
return channel.post({
|
|
url: "/json/users/me/subscriptions",
|
|
data: {subscriptions: JSON.stringify([{name: stream}]) },
|
|
success: function (resp, statusText, xhr) {
|
|
if (subs.is_open) {
|
|
$("#create_stream_name").val("");
|
|
|
|
actually_filter_streams();
|
|
}
|
|
|
|
var res = JSON.parse(xhr.responseText);
|
|
if (!$.isEmptyObject(res.already_subscribed)) {
|
|
// Display the canonical stream capitalization.
|
|
true_stream_name = res.already_subscribed[people.my_current_email()][0];
|
|
ui_report.success(i18n.t("Already subscribed to __stream__", {stream: true_stream_name}),
|
|
$("#subscriptions-status"), 'subscriptions-status');
|
|
}
|
|
// The rest of the work is done via the subscribe event we will get
|
|
},
|
|
error: function (xhr) {
|
|
ui_report.error(i18n.t("Error adding subscription"), xhr,
|
|
$("#subscriptions-status"), 'subscriptions-status');
|
|
},
|
|
});
|
|
}
|
|
|
|
function ajaxUnsubscribe(sub) {
|
|
// TODO: use stream_id when backend supports it
|
|
return channel.del({
|
|
url: "/json/users/me/subscriptions",
|
|
data: {subscriptions: JSON.stringify([sub.name]) },
|
|
success: function () {
|
|
$("#subscriptions-status").hide();
|
|
// The rest of the work is done via the unsubscribe event we will get
|
|
},
|
|
error: function (xhr) {
|
|
ui_report.error(i18n.t("Error removing subscription"), xhr,
|
|
$("#subscriptions-status"), 'subscriptions-status');
|
|
},
|
|
});
|
|
}
|
|
|
|
exports.new_stream_clicked = function () {
|
|
var stream = $.trim($("#search_stream_name").val());
|
|
|
|
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;
|
|
}
|
|
|
|
stream_create.new_stream_clicked(stream);
|
|
};
|
|
|
|
exports.sub_or_unsub = function (sub) {
|
|
if (sub.subscribed) {
|
|
ajaxUnsubscribe(sub);
|
|
} else {
|
|
ajaxSubscribe(sub.name);
|
|
}
|
|
};
|
|
|
|
|
|
$(function () {
|
|
|
|
stream_data.initialize_from_page_params();
|
|
stream_list.create_initial_sidebar_rows();
|
|
|
|
// 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();
|
|
|
|
$("#subscriptions_table").on("click", "#create_stream_button", function (e) {
|
|
e.preventDefault();
|
|
exports.new_stream_clicked();
|
|
});
|
|
|
|
$(".subscriptions").on("click", "[data-dismiss]", function (e) {
|
|
e.preventDefault();
|
|
// 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) {
|
|
exports.show_subs_pane.nothing_selected();
|
|
}
|
|
});
|
|
|
|
$("body").on("mouseover", ".subscribed-button", function (e) {
|
|
$(e.target).addClass("btn-danger").text(i18n.t("Unsubscribe"));
|
|
}).on("mouseout", ".subscribed-button", function (e) {
|
|
$(e.target).removeClass("btn-danger").text(i18n.t("Subscribed"));
|
|
});
|
|
|
|
$(".subscriptions").on("click", "#close-subscriptions-status", function () {
|
|
$("#subscriptions-status").hide();
|
|
});
|
|
|
|
$("#subscriptions_table").on("click", ".email-address", function () {
|
|
selectText(this);
|
|
});
|
|
|
|
$('.empty_feed_sub_unsub').click(function (e) {
|
|
e.preventDefault();
|
|
|
|
$('#subscription-status').hide();
|
|
var stream_name = narrow_state.stream();
|
|
if (stream_name === undefined) {
|
|
return;
|
|
}
|
|
var sub = stream_data.get_sub(stream_name);
|
|
exports.sub_or_unsub(sub);
|
|
|
|
$('.empty_feed_notice').hide();
|
|
$('#empty_narrow_message').show();
|
|
});
|
|
|
|
$("#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");
|
|
});
|
|
|
|
$("#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"));
|
|
}
|
|
});
|
|
|
|
(function defocus_sub_settings() {
|
|
var sel = ".search-container, .streams-list, .subscriptions-header";
|
|
|
|
$("#subscriptions_table").on("click", sel, function (e) {
|
|
if ($(e.target).is(sel)) {
|
|
stream_edit.show_stream_row(this, false);
|
|
}
|
|
});
|
|
}());
|
|
|
|
$("#subscriptions_table").on("hide", ".subscription_settings", function (e) {
|
|
var sub_arrow = $(e.target).closest('.stream-row').find('.sub_arrow i');
|
|
sub_arrow.removeClass('icon-vector-chevron-up');
|
|
sub_arrow.addClass('icon-vector-chevron-down');
|
|
});
|
|
|
|
$(document).on('peer_subscribe.zulip', function (e, data) {
|
|
var sub = stream_data.get_sub(data.stream_name);
|
|
exports.rerender_subscribers_count(sub);
|
|
});
|
|
|
|
$(document).on('peer_unsubscribe.zulip', function (e, data) {
|
|
var sub = stream_data.get_sub(data.stream_name);
|
|
exports.rerender_subscribers_count(sub);
|
|
});
|
|
|
|
function subscriptions_close_modal() {
|
|
exports.close();
|
|
}
|
|
|
|
modals.set_close_handler("subscriptions", subscriptions_close_modal);
|
|
|
|
});
|
|
|
|
function focus_on_narrowed_stream() {
|
|
var stream_name = narrow_state.stream();
|
|
if (stream_name === undefined) {
|
|
return;
|
|
}
|
|
var sub = stream_data.get_sub(stream_name);
|
|
if (sub === undefined) {
|
|
// This stream doesn't exist, so prep for creating it.
|
|
$("#create_stream_name").val(stream_name);
|
|
}
|
|
}
|
|
|
|
exports.show_and_focus_on_narrow = function () {
|
|
$(document).one('subs_page_loaded.zulip', focus_on_narrowed_stream);
|
|
ui_util.change_tab_to("#streams");
|
|
};
|
|
|
|
return exports;
|
|
|
|
}());
|
|
if (typeof module !== 'undefined') {
|
|
module.exports = subs;
|
|
}
|