mirror of https://github.com/zulip/zulip.git
Extract stream_create.js.
This new modules handles the UI to create streams. It mostly moves code from subs.js. It introduces an API around what used to be called meta.stream_created: reset_created_stream() set_name() get_name() It only partially moves new_stream_clicked().
This commit is contained in:
parent
86ebc2ccb1
commit
ca2aea8d01
|
@ -57,6 +57,7 @@
|
||||||
"compose_state": false,
|
"compose_state": false,
|
||||||
"compose_fade": false,
|
"compose_fade": false,
|
||||||
"modals": false,
|
"modals": false,
|
||||||
|
"stream_create": false,
|
||||||
"subs": false,
|
"subs": false,
|
||||||
"stream_muting": false,
|
"stream_muting": false,
|
||||||
"stream_events": false,
|
"stream_events": false,
|
||||||
|
|
|
@ -0,0 +1,295 @@
|
||||||
|
var stream_create = (function () {
|
||||||
|
|
||||||
|
var exports = {};
|
||||||
|
|
||||||
|
var created_stream;
|
||||||
|
|
||||||
|
exports.reset_created_stream = function () {
|
||||||
|
created_stream = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.set_name = function (stream) {
|
||||||
|
created_stream = stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.get_name = function () {
|
||||||
|
return created_stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ajaxSubscribeForCreation(stream, description, principals, invite_only, announce) {
|
||||||
|
// Subscribe yourself and possible other people to a new stream.
|
||||||
|
return channel.post({
|
||||||
|
url: "/json/users/me/subscriptions",
|
||||||
|
data: {subscriptions: JSON.stringify([{name: stream, description: description}]),
|
||||||
|
principals: JSON.stringify(principals),
|
||||||
|
invite_only: JSON.stringify(invite_only),
|
||||||
|
announce: JSON.stringify(announce),
|
||||||
|
},
|
||||||
|
success: function () {
|
||||||
|
$("#create_stream_name").val("");
|
||||||
|
$("#create_stream_description").val("");
|
||||||
|
$("#subscriptions-status").hide();
|
||||||
|
// The rest of the work is done via the subscribe event we will get
|
||||||
|
},
|
||||||
|
error: function (xhr) {
|
||||||
|
ui_report.error(i18n.t("Error creating stream"), xhr,
|
||||||
|
$("#subscriptions-status"), 'subscriptions-status');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Within the new stream modal...
|
||||||
|
function update_announce_stream_state() {
|
||||||
|
// If the stream is invite only, or everyone's added, disable
|
||||||
|
// the "Announce stream" option. Otherwise enable it.
|
||||||
|
var announce_stream_checkbox = $('#announce-new-stream input');
|
||||||
|
var disable_it = false;
|
||||||
|
var is_invite_only = $('input:radio[name=privacy]:checked').val() === 'invite-only';
|
||||||
|
|
||||||
|
if (is_invite_only) {
|
||||||
|
disable_it = true;
|
||||||
|
announce_stream_checkbox.prop('checked', false);
|
||||||
|
} else {
|
||||||
|
disable_it = $('#user-checkboxes input').length
|
||||||
|
=== $('#user-checkboxes input:checked').length;
|
||||||
|
}
|
||||||
|
|
||||||
|
announce_stream_checkbox.prop('disabled', disable_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.new_stream_clicked = function (stream) {
|
||||||
|
// this changes the tab switcher (settings/preview) which isn't necessary
|
||||||
|
// to a add new stream title.
|
||||||
|
$(".display-type #add_new_stream_title").show();
|
||||||
|
$(".display-type #stream_settings_title").hide();
|
||||||
|
|
||||||
|
$(".stream-row.active").removeClass("active");
|
||||||
|
|
||||||
|
$("#stream_settings_title, .subscriptions-container .settings, .nothing-selected").hide();
|
||||||
|
$("#stream-creation, #add_new_stream_title").show();
|
||||||
|
|
||||||
|
if (stream !== '') {
|
||||||
|
$('#create_stream_name').val(stream);
|
||||||
|
}
|
||||||
|
exports.show_new_stream_modal();
|
||||||
|
|
||||||
|
// at less than 700px we have a @media query that when you tap the
|
||||||
|
// #create_stream_button, the stream prompt slides in. However, when you
|
||||||
|
// focus the button on that page, the entire app view jumps over to
|
||||||
|
// the other tab, and the animation breaks.
|
||||||
|
// it is unclear whether this is a browser bug or "feature", however what
|
||||||
|
// is clear is that this shoudn't be touched unless you're also changing
|
||||||
|
// the mobile @media query at 700px.
|
||||||
|
if (window.innerWidth > 700) {
|
||||||
|
$('#create_stream_name').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// change the hash to #streams/new to allow for linking and
|
||||||
|
// easy discovery.
|
||||||
|
|
||||||
|
window.location.hash = "#streams/new";
|
||||||
|
};
|
||||||
|
|
||||||
|
// *Synchronously* check if a stream exists.
|
||||||
|
// This is deprecated and we hope to remove it.
|
||||||
|
exports.check_stream_existence = function (stream_name, autosubscribe) {
|
||||||
|
var result = "error";
|
||||||
|
var request = {stream: stream_name};
|
||||||
|
if (autosubscribe) {
|
||||||
|
request.autosubscribe = true;
|
||||||
|
}
|
||||||
|
channel.post({
|
||||||
|
url: "/json/subscriptions/exists",
|
||||||
|
data: request,
|
||||||
|
async: false,
|
||||||
|
success: function (data) {
|
||||||
|
if (data.subscribed) {
|
||||||
|
result = "subscribed";
|
||||||
|
} else {
|
||||||
|
result = "not-subscribed";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (xhr) {
|
||||||
|
if (xhr.status === 404) {
|
||||||
|
result = "does-not-exist";
|
||||||
|
} else {
|
||||||
|
result = "error";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.show_new_stream_modal = function () {
|
||||||
|
$("#stream-creation").removeClass("hide");
|
||||||
|
$(".right .settings").hide();
|
||||||
|
$('#people_to_add').html(templates.render('new_stream_users', {
|
||||||
|
users: people.get_rest_of_realm(),
|
||||||
|
streams: stream_data.get_streams_for_settings_page(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Make the options default to the same each time:
|
||||||
|
// public, "announce stream" on.
|
||||||
|
$('#make-invite-only input:radio[value=public]').prop('checked', true);
|
||||||
|
$('#announce-new-stream input').prop('disabled', false);
|
||||||
|
$('#announce-new-stream input').prop('checked', true);
|
||||||
|
|
||||||
|
$("#stream_name_error").hide();
|
||||||
|
|
||||||
|
$("#stream-checkboxes label.checkbox").on('change', function (e) {
|
||||||
|
var elem = $(this);
|
||||||
|
var stream_id = elem.attr('data-stream-id');
|
||||||
|
var checked = elem.find('input').prop('checked');
|
||||||
|
var subscriber_ids = stream_data.get_sub_by_id(stream_id).subscribers;
|
||||||
|
|
||||||
|
$('#user-checkboxes label.checkbox').each(function () {
|
||||||
|
var user_elem = $(this);
|
||||||
|
var user_id = user_elem.attr('data-user-id');
|
||||||
|
|
||||||
|
if (subscriber_ids.has(user_id)) {
|
||||||
|
user_elem.find('input').prop('checked', checked);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
update_announce_stream_state();
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
$('body').on('change', '#user-checkboxes input, #make-invite-only input', update_announce_stream_state);
|
||||||
|
|
||||||
|
// 'Check all' and 'Uncheck all' visible users
|
||||||
|
$(document).on('click', '.subs_set_all_users', function (e) {
|
||||||
|
$('#user-checkboxes .checkbox').each(function (idx, li) {
|
||||||
|
if (li.style.display !== "none") {
|
||||||
|
$(li.firstElementChild).prop('checked', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
e.preventDefault();
|
||||||
|
update_announce_stream_state();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.subs_unset_all_users', function (e) {
|
||||||
|
$('#user-checkboxes .checkbox').each(function (idx, li) {
|
||||||
|
if (li.style.display !== "none") {
|
||||||
|
$(li.firstElementChild).prop('checked', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
e.preventDefault();
|
||||||
|
update_announce_stream_state();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#copy-from-stream-expand-collapse', function (e) {
|
||||||
|
$('#stream-checkboxes').toggle();
|
||||||
|
$("#copy-from-stream-expand-collapse .toggle").toggleClass('icon-vector-caret-right icon-vector-caret-down');
|
||||||
|
e.preventDefault();
|
||||||
|
update_announce_stream_state();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search People or Streams
|
||||||
|
$(document).on('input', '.add-user-list-filter', function (e) {
|
||||||
|
var user_list = $(".add-user-list-filter");
|
||||||
|
if (user_list === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var search_term = user_list.expectOne().val().trim();
|
||||||
|
var search_terms = search_term.toLowerCase().split(",");
|
||||||
|
|
||||||
|
(function filter_user_checkboxes() {
|
||||||
|
var user_labels = $("#user-checkboxes label.add-user-label");
|
||||||
|
|
||||||
|
if (search_term === '') {
|
||||||
|
user_labels.css({display: 'block'});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var users = people.get_rest_of_realm();
|
||||||
|
var filtered_users = people.filter_people_by_search_terms(users, search_terms);
|
||||||
|
|
||||||
|
// Be careful about modifying the follow code. A naive implementation
|
||||||
|
// will work very poorly with a large user population (~1000 users).
|
||||||
|
//
|
||||||
|
// I tested using: `./manage.py populate_db --extra-users 3500`
|
||||||
|
//
|
||||||
|
// This would break the previous implementation, whereas the new
|
||||||
|
// implementation is merely sluggish.
|
||||||
|
user_labels.each(function () {
|
||||||
|
var elem = $(this);
|
||||||
|
var user_id = elem.attr('data-user-id');
|
||||||
|
var user_checked = filtered_users.has(user_id);
|
||||||
|
var display = user_checked ? "block" : "none";
|
||||||
|
elem.css({display: display});
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|
||||||
|
update_announce_stream_state();
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".subscriptions").on("submit", "#stream_creation_form", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var stream = $.trim($("#create_stream_name").val());
|
||||||
|
var description = $.trim($("#create_stream_description").val());
|
||||||
|
if (!$("#stream_name_error").is(":visible")) {
|
||||||
|
var principals = _.map(
|
||||||
|
$("#stream_creation_form input:checkbox[name=user]:checked"),
|
||||||
|
function (elem) {
|
||||||
|
return $(elem).val();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// You are always subscribed to streams you create.
|
||||||
|
principals.push(people.my_current_email());
|
||||||
|
|
||||||
|
created_stream = stream;
|
||||||
|
|
||||||
|
ajaxSubscribeForCreation(stream,
|
||||||
|
description,
|
||||||
|
principals,
|
||||||
|
$('#stream_creation_form input[name=privacy]:checked').val() === "invite-only",
|
||||||
|
$('#announce-new-stream input').prop('checked')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".subscriptions").on("focusout", "#create_stream_name", function () {
|
||||||
|
var stream = $.trim($("#create_stream_name").val());
|
||||||
|
if (stream.length !== 0) {
|
||||||
|
var stream_status = exports.check_stream_existence(stream);
|
||||||
|
|
||||||
|
if (stream_status !== "does-not-exist") {
|
||||||
|
$("#stream_name_error").text(i18n.t("A stream with this name already exists"));
|
||||||
|
$("#stream_name_error").show();
|
||||||
|
} else {
|
||||||
|
$("#stream_name_error").hide();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$("#stream_name_error").text(i18n.t("A stream needs to have a name"));
|
||||||
|
$("#stream_name_error").show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on("mouseover", "#announce-stream-docs", function (e) {
|
||||||
|
var announce_stream_docs = $("#announce-stream-docs");
|
||||||
|
announce_stream_docs.popover({placement: "right",
|
||||||
|
content: templates.render('announce_stream_docs'),
|
||||||
|
trigger: "manual"});
|
||||||
|
announce_stream_docs.popover('show');
|
||||||
|
announce_stream_docs.data('popover').tip().css('z-index', 2000);
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
$("body").on("mouseout", "#announce-stream-docs", function (e) {
|
||||||
|
$("#announce-stream-docs").popover('hide');
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
|
||||||
|
}());
|
||||||
|
if (typeof module !== 'undefined') {
|
||||||
|
module.exports = stream_create;
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ var subs = (function () {
|
||||||
|
|
||||||
var meta = {
|
var meta = {
|
||||||
callbacks: {},
|
callbacks: {},
|
||||||
stream_created: undefined,
|
|
||||||
is_open: false,
|
is_open: false,
|
||||||
};
|
};
|
||||||
var exports = {};
|
var exports = {};
|
||||||
|
@ -244,7 +243,7 @@ function add_email_hint(row, email_address_hint_content) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `meta.stream_created` flag tells us whether the stream was just
|
// 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
|
// 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
|
// 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
|
// this request. These should be appended to the top of the list so
|
||||||
|
@ -255,7 +254,7 @@ function add_sub_to_table(sub) {
|
||||||
stream_data.render_stream_description(sub);
|
stream_data.render_stream_description(sub);
|
||||||
var html = templates.render('subscription', sub);
|
var html = templates.render('subscription', sub);
|
||||||
var settings_html = templates.render('subscription_settings', sub);
|
var settings_html = templates.render('subscription_settings', sub);
|
||||||
if (meta.stream_created === sub.name) {
|
if (stream_create.get_name() === sub.name) {
|
||||||
$(".streams-list").prepend(html).scrollTop(0);
|
$(".streams-list").prepend(html).scrollTop(0);
|
||||||
} else {
|
} else {
|
||||||
$(".streams-list").append(html);
|
$(".streams-list").append(html);
|
||||||
|
@ -265,9 +264,10 @@ function add_sub_to_table(sub) {
|
||||||
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
||||||
add_email_hint(sub, email_address_hint_content);
|
add_email_hint(sub, email_address_hint_content);
|
||||||
|
|
||||||
if (meta.stream_created === sub.name) {
|
if (stream_create.get_name() === sub.name) {
|
||||||
$(".stream-row[data-stream-id='" + stream_data.get_sub(meta.stream_created).stream_id + "']").click();
|
var created_stream = stream_create.get_name();
|
||||||
meta.stream_created = undefined;
|
$(".stream-row[data-stream-id='" + stream_data.get_sub(created_stream).stream_id + "']").click();
|
||||||
|
stream_create.reset_created_stream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,82 +834,18 @@ function ajaxUnsubscribe(sub) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ajaxSubscribeForCreation(stream, description, principals, invite_only, announce) {
|
exports.new_stream_clicked = function () {
|
||||||
// Subscribe yourself and possible other people to a new stream.
|
var stream = $.trim($("#search_stream_name").val());
|
||||||
return channel.post({
|
|
||||||
url: "/json/users/me/subscriptions",
|
|
||||||
data: {subscriptions: JSON.stringify([{name: stream, description: description}]),
|
|
||||||
principals: JSON.stringify(principals),
|
|
||||||
invite_only: JSON.stringify(invite_only),
|
|
||||||
announce: JSON.stringify(announce),
|
|
||||||
},
|
|
||||||
success: function () {
|
|
||||||
$("#create_stream_name").val("");
|
|
||||||
$("#create_stream_description").val("");
|
|
||||||
$("#subscriptions-status").hide();
|
|
||||||
// The rest of the work is done via the subscribe event we will get
|
|
||||||
},
|
|
||||||
error: function (xhr) {
|
|
||||||
ui_report.error(i18n.t("Error creating stream"), xhr,
|
|
||||||
$("#subscriptions-status"), 'subscriptions-status');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Within the new stream modal...
|
if (!should_list_all_streams()) {
|
||||||
function update_announce_stream_state() {
|
// Realms that don't allow listing streams should simply be subscribed to.
|
||||||
// If the stream is invite only, or everyone's added, disable
|
stream_create.set_name(stream);
|
||||||
// the "Announce stream" option. Otherwise enable it.
|
ajaxSubscribe($("#search_stream_name").val());
|
||||||
var announce_stream_checkbox = $('#announce-new-stream input');
|
return;
|
||||||
var disable_it = false;
|
|
||||||
var is_invite_only = $('input:radio[name=privacy]:checked').val() === 'invite-only';
|
|
||||||
|
|
||||||
if (is_invite_only) {
|
|
||||||
disable_it = true;
|
|
||||||
announce_stream_checkbox.prop('checked', false);
|
|
||||||
} else {
|
|
||||||
disable_it = $('#user-checkboxes input').length
|
|
||||||
=== $('#user-checkboxes input:checked').length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
announce_stream_checkbox.prop('disabled', disable_it);
|
stream_create.new_stream_clicked(stream);
|
||||||
}
|
};
|
||||||
|
|
||||||
function show_new_stream_modal() {
|
|
||||||
$("#stream-creation").removeClass("hide");
|
|
||||||
$(".right .settings").hide();
|
|
||||||
$('#people_to_add').html(templates.render('new_stream_users', {
|
|
||||||
users: people.get_rest_of_realm(),
|
|
||||||
streams: stream_data.get_streams_for_settings_page(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Make the options default to the same each time:
|
|
||||||
// public, "announce stream" on.
|
|
||||||
$('#make-invite-only input:radio[value=public]').prop('checked', true);
|
|
||||||
$('#announce-new-stream input').prop('disabled', false);
|
|
||||||
$('#announce-new-stream input').prop('checked', true);
|
|
||||||
|
|
||||||
$("#stream_name_error").hide();
|
|
||||||
|
|
||||||
$("#stream-checkboxes label.checkbox").on('change', function (e) {
|
|
||||||
var elem = $(this);
|
|
||||||
var stream_id = elem.attr('data-stream-id');
|
|
||||||
var checked = elem.find('input').prop('checked');
|
|
||||||
var subscriber_ids = stream_data.get_sub_by_id(stream_id).subscribers;
|
|
||||||
|
|
||||||
$('#user-checkboxes label.checkbox').each(function () {
|
|
||||||
var user_elem = $(this);
|
|
||||||
var user_id = user_elem.attr('data-user-id');
|
|
||||||
|
|
||||||
if (subscriber_ids.has(user_id)) {
|
|
||||||
user_elem.find('input').prop('checked', checked);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
update_announce_stream_state();
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.invite_user_to_stream = function (user_email, sub, success, failure) {
|
exports.invite_user_to_stream = function (user_email, sub, success, failure) {
|
||||||
// TODO: use stream_id when backend supports it
|
// TODO: use stream_id when backend supports it
|
||||||
|
@ -1001,48 +937,6 @@ exports.sub_or_unsub = function (sub) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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.
|
|
||||||
meta.stream_created = stream;
|
|
||||||
ajaxSubscribe($("#search_stream_name").val());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this changes the tab switcher (settings/preview) which isn't necessary
|
|
||||||
// to a add new stream title.
|
|
||||||
$(".display-type #add_new_stream_title").show();
|
|
||||||
$(".display-type #stream_settings_title").hide();
|
|
||||||
|
|
||||||
$(".stream-row.active").removeClass("active");
|
|
||||||
|
|
||||||
$("#stream_settings_title, .subscriptions-container .settings, .nothing-selected").hide();
|
|
||||||
$("#stream-creation, #add_new_stream_title").show();
|
|
||||||
|
|
||||||
if (stream !== '') {
|
|
||||||
$('#create_stream_name').val(stream);
|
|
||||||
}
|
|
||||||
show_new_stream_modal();
|
|
||||||
|
|
||||||
// at less than 700px we have a @media query that when you tap the
|
|
||||||
// #create_stream_button, the stream prompt slides in. However, when you
|
|
||||||
// focus the button on that page, the entire app view jumps over to
|
|
||||||
// the other tab, and the animation breaks.
|
|
||||||
// it is unclear whether this is a browser bug or "feature", however what
|
|
||||||
// is clear is that this shoudn't be touched unless you're also changing
|
|
||||||
// the mobile @media query at 700px.
|
|
||||||
if (window.innerWidth > 700) {
|
|
||||||
$('#create_stream_name').focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// change the hash to #streams/new to allow for linking and
|
|
||||||
// easy discovery.
|
|
||||||
|
|
||||||
window.location.hash = "#streams/new";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
@ -1069,9 +963,6 @@ $(function () {
|
||||||
exports.new_stream_clicked();
|
exports.new_stream_clicked();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('body').on('change', '#user-checkboxes input, #make-invite-only input', update_announce_stream_state);
|
|
||||||
|
|
||||||
|
|
||||||
$(".subscriptions").on("click", "[data-dismiss]", function (e) {
|
$(".subscriptions").on("click", "[data-dismiss]", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// we want to make sure that the click is not just a simulated
|
// we want to make sure that the click is not just a simulated
|
||||||
|
@ -1082,129 +973,6 @@ $(function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 'Check all' and 'Uncheck all' visible users
|
|
||||||
$(document).on('click', '.subs_set_all_users', function (e) {
|
|
||||||
$('#user-checkboxes .checkbox').each(function (idx, li) {
|
|
||||||
if (li.style.display !== "none") {
|
|
||||||
$(li.firstElementChild).prop('checked', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
e.preventDefault();
|
|
||||||
update_announce_stream_state();
|
|
||||||
});
|
|
||||||
$(document).on('click', '.subs_unset_all_users', function (e) {
|
|
||||||
$('#user-checkboxes .checkbox').each(function (idx, li) {
|
|
||||||
if (li.style.display !== "none") {
|
|
||||||
$(li.firstElementChild).prop('checked', false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
e.preventDefault();
|
|
||||||
update_announce_stream_state();
|
|
||||||
});
|
|
||||||
$(document).on('click', '#copy-from-stream-expand-collapse', function (e) {
|
|
||||||
$('#stream-checkboxes').toggle();
|
|
||||||
$("#copy-from-stream-expand-collapse .toggle").toggleClass('icon-vector-caret-right icon-vector-caret-down');
|
|
||||||
e.preventDefault();
|
|
||||||
update_announce_stream_state();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Search People or Streams
|
|
||||||
$(document).on('input', '.add-user-list-filter', function (e) {
|
|
||||||
var user_list = $(".add-user-list-filter");
|
|
||||||
if (user_list === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var search_term = user_list.expectOne().val().trim();
|
|
||||||
var search_terms = search_term.toLowerCase().split(",");
|
|
||||||
|
|
||||||
(function filter_user_checkboxes() {
|
|
||||||
var user_labels = $("#user-checkboxes label.add-user-label");
|
|
||||||
|
|
||||||
if (search_term === '') {
|
|
||||||
user_labels.css({display: 'block'});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var users = people.get_rest_of_realm();
|
|
||||||
var filtered_users = people.filter_people_by_search_terms(users, search_terms);
|
|
||||||
|
|
||||||
// Be careful about modifying the follow code. A naive implementation
|
|
||||||
// will work very poorly with a large user population (~1000 users).
|
|
||||||
//
|
|
||||||
// I tested using: `./manage.py populate_db --extra-users 3500`
|
|
||||||
//
|
|
||||||
// This would break the previous implementation, whereas the new
|
|
||||||
// implementation is merely sluggish.
|
|
||||||
user_labels.each(function () {
|
|
||||||
var elem = $(this);
|
|
||||||
var user_id = elem.attr('data-user-id');
|
|
||||||
var user_checked = filtered_users.has(user_id);
|
|
||||||
var display = user_checked ? "block" : "none";
|
|
||||||
elem.css({display: display});
|
|
||||||
});
|
|
||||||
}());
|
|
||||||
|
|
||||||
update_announce_stream_state();
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on("mouseover", "#announce-stream-docs", function (e) {
|
|
||||||
var announce_stream_docs = $("#announce-stream-docs");
|
|
||||||
announce_stream_docs.popover({placement: "right",
|
|
||||||
content: templates.render('announce_stream_docs'),
|
|
||||||
trigger: "manual"});
|
|
||||||
announce_stream_docs.popover('show');
|
|
||||||
announce_stream_docs.data('popover').tip().css('z-index', 2000);
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
$("body").on("mouseout", "#announce-stream-docs", function (e) {
|
|
||||||
$("#announce-stream-docs").popover('hide');
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".subscriptions").on("focusout", "#create_stream_name", function () {
|
|
||||||
var stream = $.trim($("#create_stream_name").val());
|
|
||||||
if (stream.length !== 0) {
|
|
||||||
var stream_status = exports.check_stream_existence(stream);
|
|
||||||
|
|
||||||
if (stream_status !== "does-not-exist") {
|
|
||||||
$("#stream_name_error").text(i18n.t("A stream with this name already exists"));
|
|
||||||
$("#stream_name_error").show();
|
|
||||||
} else {
|
|
||||||
$("#stream_name_error").hide();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$("#stream_name_error").text(i18n.t("A stream needs to have a name"));
|
|
||||||
$("#stream_name_error").show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".subscriptions").on("submit", "#stream_creation_form", function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var stream = $.trim($("#create_stream_name").val());
|
|
||||||
var description = $.trim($("#create_stream_description").val());
|
|
||||||
if (!$("#stream_name_error").is(":visible")) {
|
|
||||||
var principals = _.map(
|
|
||||||
$("#stream_creation_form input:checkbox[name=user]:checked"),
|
|
||||||
function (elem) {
|
|
||||||
return $(elem).val();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// You are always subscribed to streams you create.
|
|
||||||
principals.push(people.my_current_email());
|
|
||||||
|
|
||||||
meta.stream_created = stream;
|
|
||||||
|
|
||||||
ajaxSubscribeForCreation(stream,
|
|
||||||
description,
|
|
||||||
principals,
|
|
||||||
$('#stream_creation_form input[name=privacy]:checked').val() === "invite-only",
|
|
||||||
$('#announce-new-stream input').prop('checked')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on("mouseover", ".subscribed-button", function (e) {
|
$("body").on("mouseover", ".subscribed-button", function (e) {
|
||||||
$(e.target).addClass("btn-danger").text(i18n.t("Unsubscribe"));
|
$(e.target).addClass("btn-danger").text(i18n.t("Unsubscribe"));
|
||||||
}).on("mouseout", ".subscribed-button", function (e) {
|
}).on("mouseout", ".subscribed-button", function (e) {
|
||||||
|
@ -1488,36 +1256,6 @@ exports.show_and_focus_on_narrow = function () {
|
||||||
ui_util.change_tab_to("#streams");
|
ui_util.change_tab_to("#streams");
|
||||||
};
|
};
|
||||||
|
|
||||||
// *Synchronously* check if a stream exists.
|
|
||||||
// This is deprecated and we hope to remove it.
|
|
||||||
exports.check_stream_existence = function (stream_name, autosubscribe) {
|
|
||||||
var result = "error";
|
|
||||||
var request = {stream: stream_name};
|
|
||||||
if (autosubscribe) {
|
|
||||||
request.autosubscribe = true;
|
|
||||||
}
|
|
||||||
channel.post({
|
|
||||||
url: "/json/subscriptions/exists",
|
|
||||||
data: request,
|
|
||||||
async: false,
|
|
||||||
success: function (data) {
|
|
||||||
if (data.subscribed) {
|
|
||||||
result = "subscribed";
|
|
||||||
} else {
|
|
||||||
result = "not-subscribed";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (xhr) {
|
|
||||||
if (xhr.status === 404) {
|
|
||||||
result = "does-not-exist";
|
|
||||||
} else {
|
|
||||||
result = "error";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
return exports;
|
return exports;
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -867,6 +867,7 @@ JS_SPECS = {
|
||||||
'js/stream_data.js',
|
'js/stream_data.js',
|
||||||
'js/stream_muting.js',
|
'js/stream_muting.js',
|
||||||
'js/stream_events.js',
|
'js/stream_events.js',
|
||||||
|
'js/stream_create.js',
|
||||||
'js/subs.js',
|
'js/subs.js',
|
||||||
'js/message_edit.js',
|
'js/message_edit.js',
|
||||||
'js/condense.js',
|
'js/condense.js',
|
||||||
|
|
Loading…
Reference in New Issue