2021-03-11 05:43:45 +01:00
|
|
|
import $ from "jquery";
|
|
|
|
|
2021-06-21 11:01:44 +02:00
|
|
|
import render_settings_deactivation_stream_modal from "../templates/confirm_dialog/confirm_deactivate_stream.hbs";
|
2021-06-21 09:40:03 +02:00
|
|
|
import render_unsubscribe_private_stream_modal from "../templates/confirm_dialog/confirm_unsubscribe_private_stream.hbs";
|
2021-07-18 14:53:17 +02:00
|
|
|
import render_change_stream_info_modal from "../templates/stream_settings/change_stream_info_modal.hbs";
|
2021-07-17 21:24:41 +02:00
|
|
|
import render_stream_description from "../templates/stream_settings/stream_description.hbs";
|
2021-07-17 21:11:45 +02:00
|
|
|
import render_stream_member_list_entry from "../templates/stream_settings/stream_member_list_entry.hbs";
|
2021-07-18 13:49:31 +02:00
|
|
|
import render_stream_settings from "../templates/stream_settings/stream_settings.hbs";
|
2021-07-19 12:12:30 +02:00
|
|
|
import render_stream_subscription_request_result from "../templates/stream_settings/stream_subscription_request_result.hbs";
|
2021-07-20 14:53:33 +02:00
|
|
|
import render_stream_types from "../templates/stream_settings/stream_types.hbs";
|
2021-02-28 00:55:38 +01:00
|
|
|
|
2021-03-16 23:38:59 +01:00
|
|
|
import * as blueslip from "./blueslip";
|
2021-03-22 16:09:12 +01:00
|
|
|
import * as browser_history from "./browser_history";
|
2021-02-28 00:55:38 +01:00
|
|
|
import * as channel from "./channel";
|
2021-06-26 15:28:24 +02:00
|
|
|
import * as components from "./components";
|
2020-08-07 00:38:19 +02:00
|
|
|
import * as confirm_dialog from "./confirm_dialog";
|
2021-07-17 16:44:31 +02:00
|
|
|
import * as dialog_widget from "./dialog_widget";
|
2021-02-28 01:07:13 +01:00
|
|
|
import * as hash_util from "./hash_util";
|
2021-04-13 06:51:54 +02:00
|
|
|
import {$t, $t_html} from "./i18n";
|
2021-02-28 21:29:50 +01:00
|
|
|
import * as input_pill from "./input_pill";
|
2021-02-28 00:57:45 +01:00
|
|
|
import * as ListWidget from "./list_widget";
|
2021-02-28 00:55:38 +01:00
|
|
|
import * as narrow_state from "./narrow_state";
|
2021-03-25 22:35:45 +01:00
|
|
|
import {page_params} from "./page_params";
|
2021-02-28 00:55:38 +01:00
|
|
|
import * as peer_data from "./peer_data";
|
|
|
|
import * as people from "./people";
|
|
|
|
import * as pill_typeahead from "./pill_typeahead";
|
|
|
|
import * as settings_config from "./settings_config";
|
|
|
|
import * as settings_data from "./settings_data";
|
|
|
|
import * as settings_ui from "./settings_ui";
|
|
|
|
import * as stream_color from "./stream_color";
|
|
|
|
import * as stream_data from "./stream_data";
|
|
|
|
import * as stream_pill from "./stream_pill";
|
2021-12-15 15:07:39 +01:00
|
|
|
import * as stream_settings_containers from "./stream_settings_containers";
|
2021-04-04 15:15:18 +02:00
|
|
|
import * as stream_settings_data from "./stream_settings_data";
|
2021-07-09 15:51:31 +02:00
|
|
|
import * as stream_settings_ui from "./stream_settings_ui";
|
2021-02-28 00:55:38 +01:00
|
|
|
import * as stream_ui_updates from "./stream_ui_updates";
|
2021-04-15 17:02:54 +02:00
|
|
|
import * as sub_store from "./sub_store";
|
2021-02-28 21:33:10 +01:00
|
|
|
import * as ui from "./ui";
|
2021-02-28 00:58:55 +01:00
|
|
|
import * as ui_report from "./ui_report";
|
2021-04-05 12:54:38 +02:00
|
|
|
import * as user_group_pill from "./user_group_pill";
|
2021-02-28 00:55:38 +01:00
|
|
|
import * as user_pill from "./user_pill";
|
2021-07-28 16:00:58 +02:00
|
|
|
import {user_settings} from "./user_settings";
|
2021-02-28 00:55:38 +01:00
|
|
|
import * as util from "./util";
|
|
|
|
|
|
|
|
export let pill_widget;
|
2021-06-26 15:28:24 +02:00
|
|
|
export let toggler;
|
|
|
|
export let select_tab = "personal_settings";
|
2019-07-09 21:24:00 +02:00
|
|
|
|
2017-10-03 00:15:42 +02:00
|
|
|
function setup_subscriptions_stream_hash(sub) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const hash = hash_util.stream_edit_uri(sub);
|
2021-03-22 16:09:12 +01:00
|
|
|
browser_history.update(hash);
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function setup_subscriptions_tab_hash(tab_key_value) {
|
2019-04-06 12:55:16 +02:00
|
|
|
if (tab_key_value === "all-streams") {
|
2021-03-22 16:09:12 +01:00
|
|
|
browser_history.update("#streams/all");
|
2019-04-06 12:55:16 +02:00
|
|
|
} else if (tab_key_value === "subscribed") {
|
2021-03-22 16:09:12 +01:00
|
|
|
browser_history.update("#streams/subscribed");
|
2019-04-06 12:55:16 +02:00
|
|
|
} else {
|
|
|
|
blueslip.debug("Unknown tab_key_value: " + tab_key_value);
|
|
|
|
}
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2019-04-06 12:55:16 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function is_sub_settings_active(sub) {
|
2018-04-10 15:49:03 +02:00
|
|
|
// This function return whether the provided given sub object is
|
|
|
|
// currently being viewed/edited in the stream edit UI. This is
|
|
|
|
// used to determine whether we need to rerender the stream edit
|
|
|
|
// UI when a sub object is modified by an event.
|
2021-03-15 06:57:14 +01:00
|
|
|
const active_stream = hash_util.active_stream();
|
2018-04-06 06:48:46 +02:00
|
|
|
if (active_stream !== undefined && active_stream.id === sub.stream_id) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2018-04-06 06:48:46 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function get_retention_policy_text_for_subscription_type(sub) {
|
2020-06-16 13:59:02 +02:00
|
|
|
let message_retention_days = sub.message_retention_days;
|
|
|
|
// If both this stream and the organization-level policy are to retain forever,
|
|
|
|
// there's no need to comment on retention policies when describing the stream.
|
2020-07-15 00:34:28 +02:00
|
|
|
if (
|
|
|
|
page_params.realm_message_retention_days === settings_config.retain_message_forever &&
|
|
|
|
(sub.message_retention_days === null ||
|
|
|
|
sub.message_retention_days === settings_config.retain_message_forever)
|
|
|
|
) {
|
2020-09-24 07:50:36 +02:00
|
|
|
return undefined;
|
2020-06-16 13:59:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Forever for this stream, overriding the organization default
|
2020-06-26 00:10:17 +02:00
|
|
|
if (sub.message_retention_days === settings_config.retain_message_forever) {
|
2021-04-13 06:51:54 +02:00
|
|
|
return $t({defaultMessage: "Messages in this stream will be retained forever."});
|
2020-06-16 13:59:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we are deleting messages, even if it's the organization
|
|
|
|
// default, it's worth commenting on the policy.
|
2020-07-16 23:29:01 +02:00
|
|
|
if (message_retention_days === null) {
|
2020-06-16 13:59:02 +02:00
|
|
|
message_retention_days = page_params.realm_message_retention_days;
|
|
|
|
}
|
|
|
|
|
2021-04-13 06:51:54 +02:00
|
|
|
return $t(
|
|
|
|
{
|
|
|
|
defaultMessage:
|
|
|
|
"Messages in this stream will be automatically deleted after {retention_days} days.",
|
|
|
|
},
|
2020-07-15 00:34:28 +02:00
|
|
|
{retention_days: message_retention_days},
|
|
|
|
);
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2020-06-16 13:59:02 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function get_display_text_for_realm_message_retention_setting() {
|
2020-06-15 17:00:00 +02:00
|
|
|
const realm_message_retention_days = page_params.realm_message_retention_days;
|
2020-06-26 00:10:17 +02:00
|
|
|
if (realm_message_retention_days === settings_config.retain_message_forever) {
|
2021-04-13 06:51:54 +02:00
|
|
|
return $t({defaultMessage: "(forever)"});
|
2020-06-15 17:00:00 +02:00
|
|
|
}
|
2021-04-13 06:51:54 +02:00
|
|
|
return $t(
|
|
|
|
{defaultMessage: "({message_retention_days} days)"},
|
|
|
|
{message_retention_days: realm_message_retention_days},
|
|
|
|
);
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2020-06-15 17:00:00 +02:00
|
|
|
|
|
|
|
function change_stream_message_retention_days_block_display_property(value) {
|
|
|
|
if (value === "retain_for_period") {
|
stream_edit: Be more specific w/ ".stream_message_retention_setting".
The stream creation form also uses the same stream_types template as
the stream privacy modal, however, it currently does not setup its own
handler for displaying the "N:" input when
".stream_message_retention_setting" is changed.
Previously, if one opened the stream creation form, then opened the
stream edit modal, and then went back to the stream creation form, the
drop down would correctly also .show() the input, because the handler
here would also target that selector. This is incorrect since we can't
always expect the stream_edit modal to be opened first, stream_create
should set up its own handlers.
Hence, as a prep commit to fixing stream_creation, and to ensure we
don't add duplicate handlers, in this commit we change all selectors
that targeted ".stream_message_retention_setting" to
"#stream_privacy_modal .stream_message_retention_setting" in this
file.
2021-11-23 18:34:43 +01:00
|
|
|
$("#stream_privacy_modal .stream-message-retention-days-input").show();
|
2020-06-15 17:00:00 +02:00
|
|
|
} else {
|
stream_edit: Be more specific w/ ".stream_message_retention_setting".
The stream creation form also uses the same stream_types template as
the stream privacy modal, however, it currently does not setup its own
handler for displaying the "N:" input when
".stream_message_retention_setting" is changed.
Previously, if one opened the stream creation form, then opened the
stream edit modal, and then went back to the stream creation form, the
drop down would correctly also .show() the input, because the handler
here would also target that selector. This is incorrect since we can't
always expect the stream_edit modal to be opened first, stream_create
should set up its own handlers.
Hence, as a prep commit to fixing stream_creation, and to ensure we
don't add duplicate handlers, in this commit we change all selectors
that targeted ".stream_message_retention_setting" to
"#stream_privacy_modal .stream_message_retention_setting" in this
file.
2021-11-23 18:34:43 +01:00
|
|
|
$("#stream_privacy_modal .stream-message-retention-days-input").hide();
|
2020-06-15 17:00:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function set_stream_message_retention_setting_dropdown(stream) {
|
|
|
|
let value = "retain_for_period";
|
|
|
|
if (stream.message_retention_days === null) {
|
|
|
|
value = "realm_default";
|
2020-06-26 00:10:17 +02:00
|
|
|
} else if (stream.message_retention_days === settings_config.retain_message_forever) {
|
2021-08-02 18:43:08 +02:00
|
|
|
value = "unlimited";
|
2020-06-15 17:00:00 +02:00
|
|
|
}
|
|
|
|
|
stream_edit: Be more specific w/ ".stream_message_retention_setting".
The stream creation form also uses the same stream_types template as
the stream privacy modal, however, it currently does not setup its own
handler for displaying the "N:" input when
".stream_message_retention_setting" is changed.
Previously, if one opened the stream creation form, then opened the
stream edit modal, and then went back to the stream creation form, the
drop down would correctly also .show() the input, because the handler
here would also target that selector. This is incorrect since we can't
always expect the stream_edit modal to be opened first, stream_create
should set up its own handlers.
Hence, as a prep commit to fixing stream_creation, and to ensure we
don't add duplicate handlers, in this commit we change all selectors
that targeted ".stream_message_retention_setting" to
"#stream_privacy_modal .stream_message_retention_setting" in this
file.
2021-11-23 18:34:43 +01:00
|
|
|
$("#stream_privacy_modal .stream_message_retention_setting").val(value);
|
2020-06-15 17:00:00 +02:00
|
|
|
change_stream_message_retention_days_block_display_property(value);
|
|
|
|
}
|
|
|
|
|
2019-04-03 07:14:10 +02:00
|
|
|
function get_stream_id(target) {
|
2021-06-26 15:28:24 +02:00
|
|
|
const row = $(target).closest(
|
|
|
|
".stream-row, .stream_settings_header, .subscription_settings, .save-button",
|
|
|
|
);
|
2020-10-07 09:17:30 +02:00
|
|
|
return Number.parseInt(row.attr("data-stream-id"), 10);
|
2019-04-03 07:14:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function get_sub_for_target(target) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_id = get_stream_id(target);
|
2019-04-03 07:14:10 +02:00
|
|
|
if (!stream_id) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error("Cannot find stream id for target");
|
2020-09-24 07:50:36 +02:00
|
|
|
return undefined;
|
2019-04-03 07:14:10 +02:00
|
|
|
}
|
|
|
|
|
2021-04-15 17:02:54 +02:00
|
|
|
const sub = sub_store.get(stream_id);
|
2019-04-03 07:14:10 +02:00
|
|
|
if (!sub) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error("get_sub_for_target() failed id lookup: " + stream_id);
|
2020-09-24 07:50:36 +02:00
|
|
|
return undefined;
|
2019-04-03 07:14:10 +02:00
|
|
|
}
|
|
|
|
return sub;
|
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function open_edit_panel_for_row(stream_row) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const sub = get_sub_for_target(stream_row);
|
2019-04-03 07:14:10 +02:00
|
|
|
|
2020-07-08 23:54:13 +02:00
|
|
|
$(".stream-row.active").removeClass("active");
|
2021-07-09 15:51:31 +02:00
|
|
|
stream_settings_ui.show_subs_pane.settings(sub.name);
|
2018-12-01 21:53:09 +01:00
|
|
|
$(stream_row).addClass("active");
|
2019-04-03 07:14:10 +02:00
|
|
|
setup_subscriptions_stream_hash(sub);
|
2021-06-26 15:28:24 +02:00
|
|
|
setup_stream_settings(stream_row);
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2018-12-01 21:53:09 +01:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function open_edit_panel_empty() {
|
2021-07-09 15:51:31 +02:00
|
|
|
const tab_key = $(stream_settings_ui.get_active_data().tabs[0]).attr("data-tab-key");
|
2020-07-08 23:54:13 +02:00
|
|
|
$(".stream-row.active").removeClass("active");
|
2021-07-09 15:51:31 +02:00
|
|
|
stream_settings_ui.show_subs_pane.nothing_selected();
|
2021-02-28 00:55:38 +01:00
|
|
|
setup_subscriptions_tab_hash(tab_key);
|
|
|
|
}
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2020-03-08 18:45:44 +01:00
|
|
|
function format_member_list_elem(person) {
|
2019-07-09 21:24:00 +02:00
|
|
|
return render_stream_member_list_entry({
|
2020-03-08 20:37:48 +01:00
|
|
|
name: person.full_name,
|
|
|
|
user_id: person.user_id,
|
2020-03-08 18:45:44 +01:00
|
|
|
email: settings_data.email_for_user_settings(person),
|
2019-07-09 21:24:00 +02:00
|
|
|
displaying_for_admin: page_params.is_admin,
|
2020-03-08 18:45:44 +01:00
|
|
|
show_email: settings_data.show_email(),
|
2019-07-09 21:24:00 +02:00
|
|
|
});
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function update_stream_name(sub, new_name) {
|
2021-12-15 15:07:39 +01:00
|
|
|
const edit_container = stream_settings_containers.get_edit_container(sub);
|
|
|
|
edit_container.find(".email-address").text(sub.email_address);
|
|
|
|
edit_container.find(".sub-stream-name").text(new_name);
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function update_stream_description(sub) {
|
2021-12-15 15:07:39 +01:00
|
|
|
const edit_container = stream_settings_containers.get_edit_container(sub);
|
|
|
|
edit_container.find("input.description").val(sub.description);
|
2021-07-08 23:21:47 +02:00
|
|
|
const html = render_stream_description({
|
|
|
|
rendered_description: util.clean_user_content_links(sub.rendered_description),
|
|
|
|
});
|
2021-12-15 15:07:39 +01:00
|
|
|
edit_container.find(".stream-description").html(html);
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function invite_user_to_stream(user_ids, sub, success, failure) {
|
2017-04-24 04:11:25 +02:00
|
|
|
// TODO: use stream_id when backend supports it
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_name = sub.name;
|
2017-04-24 04:11:25 +02:00
|
|
|
return channel.post({
|
|
|
|
url: "/json/users/me/subscriptions",
|
2020-07-15 00:34:28 +02:00
|
|
|
data: {
|
|
|
|
subscriptions: JSON.stringify([{name: stream_name}]),
|
|
|
|
principals: JSON.stringify(user_ids),
|
|
|
|
},
|
2020-07-20 22:18:43 +02:00
|
|
|
success,
|
2017-04-24 04:11:25 +02:00
|
|
|
error: failure,
|
|
|
|
});
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-06-30 22:57:50 +02:00
|
|
|
function show_stream_subscription_request_result({
|
2021-06-22 21:36:06 +02:00
|
|
|
message,
|
|
|
|
add_class,
|
|
|
|
remove_class,
|
|
|
|
subscribed_users,
|
|
|
|
already_subscribed_users,
|
2021-06-22 21:18:36 +02:00
|
|
|
ignored_deactivated_users,
|
2021-06-22 21:36:06 +02:00
|
|
|
}) {
|
2021-06-30 22:57:50 +02:00
|
|
|
const stream_subscription_req_result_elem = $(
|
|
|
|
".stream_subscription_request_result",
|
|
|
|
).expectOne();
|
|
|
|
const html = render_stream_subscription_request_result({
|
2021-06-22 21:36:06 +02:00
|
|
|
message,
|
|
|
|
subscribed_users,
|
|
|
|
already_subscribed_users,
|
2021-06-22 21:18:36 +02:00
|
|
|
ignored_deactivated_users,
|
2021-06-22 21:36:06 +02:00
|
|
|
});
|
2021-06-30 22:57:50 +02:00
|
|
|
ui.get_content_element(stream_subscription_req_result_elem).html(html);
|
2021-06-22 21:36:06 +02:00
|
|
|
if (add_class) {
|
2021-06-30 22:57:50 +02:00
|
|
|
stream_subscription_req_result_elem.addClass(add_class);
|
2021-06-22 21:36:06 +02:00
|
|
|
}
|
|
|
|
if (remove_class) {
|
2021-06-30 22:57:50 +02:00
|
|
|
stream_subscription_req_result_elem.removeClass(remove_class);
|
2021-06-22 21:36:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-21 18:46:53 +02:00
|
|
|
function submit_add_subscriber_form(e) {
|
2020-08-28 12:27:18 +02:00
|
|
|
const sub = get_sub_for_target(e.target);
|
2020-06-21 18:46:53 +02:00
|
|
|
if (!sub) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error(".subscriber_list_add form submit fails");
|
2020-06-21 18:46:53 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
let user_ids = user_pill.get_user_ids(pill_widget);
|
|
|
|
user_ids = user_ids.concat(stream_pill.get_user_ids(pill_widget));
|
2021-04-05 12:54:38 +02:00
|
|
|
user_ids = user_ids.concat(user_group_pill.get_user_ids(pill_widget));
|
2021-06-22 21:18:36 +02:00
|
|
|
const deactivated_users = new Set();
|
|
|
|
user_ids = user_ids.filter((user_id) => {
|
|
|
|
if (!people.is_person_active(user_id)) {
|
|
|
|
deactivated_users.add(user_id);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
2021-04-05 12:54:38 +02:00
|
|
|
|
2020-07-18 17:41:07 +02:00
|
|
|
user_ids = new Set(user_ids);
|
|
|
|
|
|
|
|
if (user_ids.has(page_params.user_id) && sub.subscribed) {
|
|
|
|
// We don't want to send a request to subscribe ourselves
|
|
|
|
// if we are already subscribed to this stream. This
|
|
|
|
// case occurs when creating user pills from a stream.
|
|
|
|
user_ids.delete(page_params.user_id);
|
|
|
|
}
|
2021-06-22 21:18:36 +02:00
|
|
|
let ignored_deactivated_users;
|
|
|
|
if (deactivated_users.size > 0) {
|
|
|
|
ignored_deactivated_users = Array.from(deactivated_users);
|
|
|
|
ignored_deactivated_users = ignored_deactivated_users.map((user_id) =>
|
|
|
|
people.get_by_user_id(user_id),
|
|
|
|
);
|
|
|
|
}
|
2020-07-18 17:41:07 +02:00
|
|
|
if (user_ids.size === 0) {
|
2021-06-30 22:57:50 +02:00
|
|
|
show_stream_subscription_request_result({
|
2021-06-22 21:36:06 +02:00
|
|
|
message: $t({defaultMessage: "No user to subscribe."}),
|
|
|
|
add_class: "text-error",
|
|
|
|
remove_class: "text-success",
|
2021-06-22 21:18:36 +02:00
|
|
|
ignored_deactivated_users,
|
2021-06-22 21:36:06 +02:00
|
|
|
});
|
2020-06-21 18:46:53 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-07-18 17:41:07 +02:00
|
|
|
user_ids = Array.from(user_ids);
|
2020-06-21 18:46:53 +02:00
|
|
|
|
|
|
|
function invite_success(data) {
|
2021-02-28 00:55:38 +01:00
|
|
|
pill_widget.clear();
|
2021-01-23 02:36:54 +01:00
|
|
|
const subscribed_users = Object.keys(data.subscribed).map((email) =>
|
|
|
|
people.get_by_email(email),
|
|
|
|
);
|
|
|
|
const already_subscribed_users = Object.keys(data.already_subscribed).map((email) =>
|
|
|
|
people.get_by_email(email),
|
2020-09-16 11:48:50 +02:00
|
|
|
);
|
|
|
|
|
2021-06-30 22:57:50 +02:00
|
|
|
show_stream_subscription_request_result({
|
2021-06-22 21:36:06 +02:00
|
|
|
add_class: "text-success",
|
|
|
|
remove_class: "text-error",
|
|
|
|
subscribed_users,
|
|
|
|
already_subscribed_users,
|
2021-06-22 21:18:36 +02:00
|
|
|
ignored_deactivated_users,
|
2021-06-22 21:36:06 +02:00
|
|
|
});
|
2020-06-21 18:46:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function invite_failure(xhr) {
|
|
|
|
const error = JSON.parse(xhr.responseText);
|
2021-06-30 22:57:50 +02:00
|
|
|
show_stream_subscription_request_result({
|
2021-06-22 21:36:06 +02:00
|
|
|
message: error.msg,
|
|
|
|
add_class: "text-error",
|
|
|
|
remove_class: "text-success",
|
|
|
|
});
|
2020-06-21 18:46:53 +02:00
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
invite_user_to_stream(user_ids, sub, invite_success, invite_failure);
|
2020-06-21 18:46:53 +02:00
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function remove_user_from_stream(user_id, sub, success, failure) {
|
2017-04-24 04:11:25 +02:00
|
|
|
// TODO: use stream_id when backend supports it
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_name = sub.name;
|
2017-04-24 04:11:25 +02:00
|
|
|
return channel.del({
|
|
|
|
url: "/json/users/me/subscriptions",
|
2020-07-15 00:34:28 +02:00
|
|
|
data: {subscriptions: JSON.stringify([stream_name]), principals: JSON.stringify([user_id])},
|
2020-07-20 22:18:43 +02:00
|
|
|
success,
|
2017-04-24 04:11:25 +02:00
|
|
|
error: failure,
|
|
|
|
});
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function create_item_from_text(text, current_items) {
|
2021-04-04 22:31:02 +02:00
|
|
|
const funcs = [
|
|
|
|
stream_pill.create_item_from_stream_name,
|
|
|
|
user_group_pill.create_item_from_group_name,
|
|
|
|
user_pill.create_item_from_email,
|
|
|
|
];
|
|
|
|
for (const func of funcs) {
|
|
|
|
const item = func(text, current_items);
|
|
|
|
if (item) {
|
|
|
|
return item;
|
|
|
|
}
|
2021-01-16 08:42:53 +01:00
|
|
|
}
|
2021-04-04 22:31:02 +02:00
|
|
|
return undefined;
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2021-01-16 08:42:53 +01:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function get_text_from_item(item) {
|
2021-04-04 22:31:02 +02:00
|
|
|
const funcs = [
|
|
|
|
stream_pill.get_stream_name_from_item,
|
|
|
|
user_group_pill.get_group_name_from_item,
|
|
|
|
user_pill.get_email_from_item,
|
|
|
|
];
|
|
|
|
for (const func of funcs) {
|
|
|
|
const text = func(item);
|
|
|
|
if (text) {
|
|
|
|
return text;
|
|
|
|
}
|
2021-01-16 08:42:53 +01:00
|
|
|
}
|
2021-04-04 22:31:02 +02:00
|
|
|
return undefined;
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2021-01-16 08:42:53 +01:00
|
|
|
|
2020-08-28 10:40:00 +02:00
|
|
|
function show_subscription_settings(sub) {
|
2021-12-15 15:07:39 +01:00
|
|
|
const edit_container = stream_settings_containers.get_edit_container(sub);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-12-15 15:07:39 +01:00
|
|
|
const colorpicker = edit_container.find(".colorpicker");
|
2019-11-02 00:06:25 +01:00
|
|
|
const color = stream_data.get_color(sub.name);
|
2017-04-24 04:11:25 +02:00
|
|
|
stream_color.set_colorpicker_color(colorpicker, color);
|
2019-05-03 07:59:31 +02:00
|
|
|
stream_ui_updates.update_add_subscriptions_elements(sub);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-05-04 18:47:17 +02:00
|
|
|
if (!sub.render_subscribers) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-19 15:41:15 +01:00
|
|
|
if (!stream_data.can_toggle_subscription(sub)) {
|
|
|
|
stream_ui_updates.initialize_cant_subscribe_popover(sub);
|
|
|
|
}
|
|
|
|
|
2021-12-15 16:12:08 +01:00
|
|
|
enable_subscriber_management({sub, parent_container: edit_container});
|
|
|
|
}
|
|
|
|
|
|
|
|
function enable_subscriber_management({sub, parent_container}) {
|
|
|
|
const stream_id = sub.stream_id;
|
|
|
|
|
|
|
|
const pill_container = parent_container.find(".pill-container");
|
2020-07-24 17:44:09 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
pill_widget = input_pill.create({
|
2021-12-15 15:33:56 +01:00
|
|
|
container: pill_container,
|
2021-02-28 00:55:38 +01:00
|
|
|
create_item_from_text,
|
|
|
|
get_text_from_item,
|
2020-04-11 21:49:51 +02:00
|
|
|
});
|
|
|
|
|
2021-12-15 16:12:08 +01:00
|
|
|
const user_ids = peer_data.get_subscribers(stream_id);
|
2021-12-15 16:49:15 +01:00
|
|
|
const users = people.get_users_from_ids(user_ids);
|
2021-12-15 18:48:33 +01:00
|
|
|
people.sort_but_pin_current_user_on_top(users);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2020-04-11 21:49:51 +02:00
|
|
|
function get_users_for_subscriber_typeahead() {
|
2021-01-12 21:38:01 +01:00
|
|
|
const potential_subscribers = peer_data.potential_subscribers(stream_id);
|
2021-02-28 00:55:38 +01:00
|
|
|
return user_pill.filter_taken_users(potential_subscribers, pill_widget);
|
2020-04-11 21:49:51 +02:00
|
|
|
}
|
|
|
|
|
2021-12-15 20:12:45 +01:00
|
|
|
const list_container = parent_container.find(".subscriber_table");
|
|
|
|
list_container.empty();
|
|
|
|
|
|
|
|
const simplebar_container = parent_container.find(".subscriber_list_container");
|
|
|
|
|
|
|
|
ListWidget.create(list_container, users, {
|
2017-04-17 23:21:37 +02:00
|
|
|
name: "stream_subscribers/" + stream_id,
|
2020-07-20 22:18:43 +02:00
|
|
|
modifier(item) {
|
2017-04-17 23:21:37 +02:00
|
|
|
return format_member_list_elem(item);
|
|
|
|
},
|
|
|
|
filter: {
|
2021-02-03 23:23:32 +01:00
|
|
|
element: $(`[data-stream-id='${CSS.escape(stream_id)}'] .search`),
|
2021-07-20 17:31:09 +02:00
|
|
|
predicate(person, value) {
|
|
|
|
const matcher = people.build_person_matcher(value);
|
|
|
|
const match = matcher(person);
|
|
|
|
|
|
|
|
return match;
|
2017-04-17 23:21:37 +02:00
|
|
|
},
|
|
|
|
},
|
2021-12-15 20:12:45 +01:00
|
|
|
simplebar_container,
|
2020-04-11 16:23:29 +02:00
|
|
|
});
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-05-25 10:11:21 +02:00
|
|
|
const opts = {
|
2021-05-24 21:35:57 +02:00
|
|
|
user_source: get_users_for_subscriber_typeahead,
|
2021-05-25 10:11:21 +02:00
|
|
|
stream: true,
|
|
|
|
user_group: true,
|
|
|
|
user: true,
|
|
|
|
};
|
2021-12-15 15:33:56 +01:00
|
|
|
pill_typeahead.set_up(pill_container.find(".input"), pill_widget, opts);
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function is_notification_setting(setting_label) {
|
js: Convert a.indexOf(…) !== -1 to a.includes(…).
Babel polyfills this for us for Internet Explorer.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import K from "ast-types/gen/kinds";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
recast.visit(ast, {
visitBinaryExpression(path) {
const { operator, left, right } = path.node;
if (
n.CallExpression.check(left) &&
n.MemberExpression.check(left.callee) &&
!left.callee.computed &&
n.Identifier.check(left.callee.property) &&
left.callee.property.name === "indexOf" &&
left.arguments.length === 1 &&
checkExpression(left.arguments[0]) &&
((["===", "!==", "==", "!=", ">", "<="].includes(operator) &&
n.UnaryExpression.check(right) &&
right.operator == "-" &&
n.Literal.check(right.argument) &&
right.argument.value === 1) ||
([">=", "<"].includes(operator) &&
n.Literal.check(right) &&
right.value === 0))
) {
const test = b.callExpression(
b.memberExpression(left.callee.object, b.identifier("includes")),
[left.arguments[0]]
);
path.replace(
["!==", "!=", ">", ">="].includes(operator)
? test
: b.unaryExpression("!", test)
);
changed = true;
}
this.traverse(path);
},
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-08 04:55:06 +01:00
|
|
|
if (setting_label.includes("_notifications")) {
|
2019-06-14 14:42:48 +02:00
|
|
|
return true;
|
js: Convert a.indexOf(…) !== -1 to a.includes(…).
Babel polyfills this for us for Internet Explorer.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import K from "ast-types/gen/kinds";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
recast.visit(ast, {
visitBinaryExpression(path) {
const { operator, left, right } = path.node;
if (
n.CallExpression.check(left) &&
n.MemberExpression.check(left.callee) &&
!left.callee.computed &&
n.Identifier.check(left.callee.property) &&
left.callee.property.name === "indexOf" &&
left.arguments.length === 1 &&
checkExpression(left.arguments[0]) &&
((["===", "!==", "==", "!=", ">", "<="].includes(operator) &&
n.UnaryExpression.check(right) &&
right.operator == "-" &&
n.Literal.check(right.argument) &&
right.argument.value === 1) ||
([">=", "<"].includes(operator) &&
n.Literal.check(right) &&
right.value === 0))
) {
const test = b.callExpression(
b.memberExpression(left.callee.object, b.identifier("includes")),
[left.arguments[0]]
);
path.replace(
["!==", "!=", ">", ">="].includes(operator)
? test
: b.unaryExpression("!", test)
);
changed = true;
}
this.traverse(path);
},
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-08 04:55:06 +01:00
|
|
|
} else if (setting_label.includes("_notify")) {
|
2019-11-26 02:37:12 +01:00
|
|
|
return true;
|
2019-06-14 14:42:48 +02:00
|
|
|
}
|
|
|
|
return false;
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2019-06-14 14:42:48 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function stream_settings(sub) {
|
2020-04-01 19:43:34 +02:00
|
|
|
const settings_labels = settings_config.general_notifications_table_labels.stream;
|
2021-08-27 15:46:23 +02:00
|
|
|
const check_realm_setting =
|
|
|
|
settings_config.all_notifications(user_settings).show_push_notifications_tooltip;
|
2020-04-01 19:43:34 +02:00
|
|
|
|
2020-01-27 13:18:04 +01:00
|
|
|
const settings = Object.keys(settings_labels).map((setting) => {
|
|
|
|
const ret = {
|
|
|
|
name: setting,
|
|
|
|
label: settings_labels[setting],
|
2020-01-27 18:54:44 +01:00
|
|
|
disabled_realm_setting: check_realm_setting[setting],
|
2020-01-27 18:50:49 +01:00
|
|
|
is_disabled: check_realm_setting[setting],
|
2021-02-28 00:55:38 +01:00
|
|
|
is_notification_setting: is_notification_setting(setting),
|
2020-01-27 13:18:04 +01:00
|
|
|
};
|
2021-02-28 00:55:38 +01:00
|
|
|
if (is_notification_setting(setting)) {
|
2021-04-04 19:35:45 +02:00
|
|
|
// This block ensures we correctly display to users the
|
|
|
|
// current state of stream-level notification settings
|
|
|
|
// with a value of `null`, which inherit the user's global
|
|
|
|
// notification settings for streams.
|
|
|
|
ret.is_checked =
|
|
|
|
stream_data.receives_notifications(sub.stream_id, setting) &&
|
|
|
|
!check_realm_setting[setting];
|
2020-01-27 18:50:49 +01:00
|
|
|
ret.is_disabled = ret.is_disabled || sub.is_muted;
|
2020-01-27 13:18:04 +01:00
|
|
|
return ret;
|
2019-06-14 14:42:48 +02:00
|
|
|
}
|
2020-01-27 18:42:35 +01:00
|
|
|
ret.is_checked = sub[setting] && !check_realm_setting[setting];
|
2020-01-27 13:18:04 +01:00
|
|
|
return ret;
|
2019-06-14 14:42:48 +02:00
|
|
|
});
|
|
|
|
return settings;
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2019-06-14 14:42:48 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function show_settings_for(node) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_id = get_stream_id(node);
|
2021-04-15 17:02:54 +02:00
|
|
|
const slim_sub = sub_store.get(stream_id);
|
2021-04-04 20:00:22 +02:00
|
|
|
stream_data.clean_up_description(slim_sub);
|
|
|
|
const sub = stream_settings_data.get_sub_for_settings(slim_sub);
|
2021-08-06 09:45:45 +02:00
|
|
|
const all_settings = stream_settings(sub);
|
|
|
|
|
|
|
|
const other_settings = [];
|
|
|
|
const notification_settings = all_settings.filter((setting) => {
|
|
|
|
if (setting.is_notification_setting) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
other_settings.push(setting);
|
|
|
|
return false;
|
|
|
|
});
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-07-18 13:49:31 +02:00
|
|
|
const html = render_stream_settings({
|
2020-07-20 22:18:43 +02:00
|
|
|
sub,
|
2021-08-06 09:45:45 +02:00
|
|
|
notification_settings,
|
|
|
|
other_settings,
|
2020-02-04 21:50:55 +01:00
|
|
|
stream_post_policy_values: stream_data.stream_post_policy_values,
|
2021-02-28 00:55:38 +01:00
|
|
|
message_retention_text: get_retention_policy_text_for_subscription_type(sub),
|
2019-06-14 14:42:48 +02:00
|
|
|
});
|
2021-06-26 15:28:24 +02:00
|
|
|
ui.get_content_element($("#stream_settings")).html(html);
|
|
|
|
|
|
|
|
$("#stream_settings .tab-container").prepend(toggler.get());
|
|
|
|
stream_ui_updates.update_toggler_for_sub(sub);
|
2017-05-10 20:02:21 +02:00
|
|
|
|
2021-12-15 15:07:39 +01:00
|
|
|
const edit_container = stream_settings_containers.get_edit_container(sub);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2017-05-10 20:02:21 +02:00
|
|
|
$(".nothing-selected").hide();
|
2021-07-05 11:26:23 +02:00
|
|
|
$("#subscription_overlay .stream_change_property_info").hide();
|
2017-07-28 14:07:58 +02:00
|
|
|
|
2021-12-15 15:07:39 +01:00
|
|
|
edit_container.addClass("show");
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2020-08-28 10:40:00 +02:00
|
|
|
show_subscription_settings(sub);
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-06-26 15:28:24 +02:00
|
|
|
export function setup_stream_settings(node) {
|
|
|
|
toggler = components.toggle({
|
|
|
|
child_wants_focus: true,
|
|
|
|
values: [
|
|
|
|
{label: $t({defaultMessage: "General"}), key: "general_settings"},
|
|
|
|
{label: $t({defaultMessage: "Personal"}), key: "personal_settings"},
|
|
|
|
{label: $t({defaultMessage: "Subscribers"}), key: "subscriber_settings"},
|
|
|
|
],
|
|
|
|
callback(name, key) {
|
|
|
|
$(".stream_section").hide();
|
|
|
|
$("." + key).show();
|
|
|
|
select_tab = key;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
show_settings_for(node);
|
|
|
|
}
|
|
|
|
|
2020-07-22 00:43:11 +02:00
|
|
|
function stream_is_muted_changed(e) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const sub = get_sub_for_target(e.target);
|
2017-04-24 04:11:25 +02:00
|
|
|
if (!sub) {
|
2020-07-22 00:43:11 +02:00
|
|
|
blueslip.error("stream_is_muted_changed() fails");
|
2017-04-24 04:11:25 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-15 15:07:39 +01:00
|
|
|
const edit_container = stream_settings_containers.get_edit_container(sub);
|
|
|
|
const notification_checkboxes = edit_container.find(".sub_notification_setting");
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-07-09 15:51:31 +02:00
|
|
|
stream_settings_ui.set_muted(
|
2021-02-03 23:23:32 +01:00
|
|
|
sub,
|
|
|
|
e.target.checked,
|
|
|
|
`#stream_change_property_status${CSS.escape(sub.stream_id)}`,
|
|
|
|
);
|
2021-12-15 15:07:39 +01:00
|
|
|
edit_container.find(".mute-note").toggleClass("hide-mute-note", !sub.is_muted);
|
2020-07-22 00:43:11 +02:00
|
|
|
notification_checkboxes.toggleClass("muted-sub", sub.is_muted);
|
|
|
|
notification_checkboxes.find("input[type='checkbox']").prop("disabled", sub.is_muted);
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function stream_setting_changed(e, from_notification_settings) {
|
2020-07-22 00:43:11 +02:00
|
|
|
if (e.target.name === "is_muted") {
|
2020-02-04 11:46:36 +01:00
|
|
|
return;
|
|
|
|
}
|
2020-02-04 13:36:10 +01:00
|
|
|
|
2020-04-06 19:31:58 +02:00
|
|
|
const sub = get_sub_for_target(e.target);
|
2020-07-22 00:43:11 +02:00
|
|
|
const status_element = from_notification_settings
|
|
|
|
? $(e.target).closest(".subsection-parent").find(".alert-notification")
|
2021-02-03 23:23:32 +01:00
|
|
|
: $(`#stream_change_property_status${CSS.escape(sub.stream_id)}`);
|
2020-07-22 00:43:11 +02:00
|
|
|
const setting = e.target.name;
|
2019-06-14 15:41:28 +02:00
|
|
|
if (!sub) {
|
2020-07-22 00:43:11 +02:00
|
|
|
blueslip.error("undefined sub in stream_setting_changed()");
|
2019-06-14 15:41:28 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-02-28 00:55:38 +01:00
|
|
|
if (is_notification_setting(setting) && sub[setting] === null) {
|
2020-07-15 01:29:15 +02:00
|
|
|
if (setting === "wildcard_mentions_notify") {
|
2021-07-28 16:00:58 +02:00
|
|
|
sub[setting] = user_settings[setting];
|
2019-11-26 02:37:12 +01:00
|
|
|
} else {
|
2021-07-28 16:00:58 +02:00
|
|
|
sub[setting] = user_settings["enable_stream_" + setting];
|
2019-11-26 02:37:12 +01:00
|
|
|
}
|
2019-06-14 15:41:28 +02:00
|
|
|
}
|
2021-02-28 00:55:38 +01:00
|
|
|
set_stream_property(sub, setting, e.target.checked, status_element);
|
|
|
|
}
|
2019-06-14 15:41:28 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function bulk_set_stream_property(sub_data, status_element) {
|
2020-07-15 01:29:15 +02:00
|
|
|
const url = "/json/users/me/subscriptions/properties";
|
2020-03-28 11:16:11 +01:00
|
|
|
const data = {subscription_data: JSON.stringify(sub_data)};
|
|
|
|
if (!status_element) {
|
2020-04-06 19:31:58 +02:00
|
|
|
return channel.post({
|
2020-07-20 22:18:43 +02:00
|
|
|
url,
|
|
|
|
data,
|
2020-04-06 19:31:58 +02:00
|
|
|
timeout: 10 * 1000,
|
|
|
|
});
|
2020-03-28 11:16:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
settings_ui.do_settings_change(channel.post, url, data, status_element);
|
2020-09-24 07:50:36 +02:00
|
|
|
return undefined;
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function set_stream_property(sub, property, value, status_element) {
|
2020-07-20 22:18:43 +02:00
|
|
|
const sub_data = {stream_id: sub.stream_id, property, value};
|
2021-02-28 00:55:38 +01:00
|
|
|
bulk_set_stream_property([sub_data], status_element);
|
|
|
|
}
|
2018-02-14 14:53:10 +01:00
|
|
|
|
2020-08-04 16:40:46 +02:00
|
|
|
function get_message_retention_days_from_sub(sub) {
|
|
|
|
if (sub.message_retention_days === null) {
|
|
|
|
return "realm_default";
|
|
|
|
}
|
|
|
|
if (sub.message_retention_days === -1) {
|
2021-08-02 18:43:08 +02:00
|
|
|
return "unlimited";
|
2020-08-04 16:40:46 +02:00
|
|
|
}
|
|
|
|
return sub.message_retention_days;
|
|
|
|
}
|
|
|
|
|
2017-04-24 04:11:25 +02:00
|
|
|
function change_stream_privacy(e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
|
2021-07-08 22:15:28 +02:00
|
|
|
const data = {};
|
2021-07-20 14:53:33 +02:00
|
|
|
const stream_id = $(e.target).closest(".dialog_submit_button").data("stream-id");
|
2021-07-08 22:15:28 +02:00
|
|
|
const url = "/json/streams/" + stream_id;
|
|
|
|
const status_element = $(".stream_permission_change_info");
|
2021-04-15 17:02:54 +02:00
|
|
|
const sub = sub_store.get(stream_id);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const privacy_setting = $("#stream_privacy_modal input[name=privacy]:checked").val();
|
2020-10-07 09:17:30 +02:00
|
|
|
const stream_post_policy = Number.parseInt(
|
2020-07-15 00:34:28 +02:00
|
|
|
$("#stream_privacy_modal input[name=stream-post-policy]:checked").val(),
|
|
|
|
10,
|
|
|
|
);
|
2018-05-03 18:52:39 +02:00
|
|
|
|
2020-08-04 16:40:46 +02:00
|
|
|
if (sub.stream_post_policy !== stream_post_policy) {
|
|
|
|
data.stream_post_policy = JSON.stringify(stream_post_policy);
|
|
|
|
}
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let invite_only;
|
|
|
|
let history_public_to_subscribers;
|
2020-11-10 15:57:14 +01:00
|
|
|
let is_web_public;
|
2018-05-03 18:52:39 +02:00
|
|
|
|
2021-09-20 07:42:24 +02:00
|
|
|
switch (privacy_setting) {
|
|
|
|
case stream_data.stream_privacy_policy_values.public.code: {
|
|
|
|
invite_only = false;
|
|
|
|
history_public_to_subscribers = true;
|
2020-11-10 15:57:14 +01:00
|
|
|
is_web_public = false;
|
2021-09-20 07:42:24 +02:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case stream_data.stream_privacy_policy_values.private.code: {
|
|
|
|
invite_only = true;
|
|
|
|
history_public_to_subscribers = false;
|
2020-11-10 15:57:14 +01:00
|
|
|
is_web_public = false;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case stream_data.stream_privacy_policy_values.web_public.code: {
|
|
|
|
invite_only = false;
|
|
|
|
history_public_to_subscribers = true;
|
|
|
|
is_web_public = true;
|
2021-09-20 07:42:24 +02:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
invite_only = true;
|
|
|
|
history_public_to_subscribers = true;
|
2020-11-10 15:57:14 +01:00
|
|
|
is_web_public = false;
|
2021-09-20 07:42:24 +02:00
|
|
|
}
|
2018-05-03 18:52:39 +02:00
|
|
|
}
|
|
|
|
|
2020-08-04 16:40:46 +02:00
|
|
|
if (
|
|
|
|
sub.invite_only !== invite_only ||
|
2020-11-10 15:57:14 +01:00
|
|
|
sub.history_public_to_subscribers !== history_public_to_subscribers ||
|
|
|
|
sub.is_web_public !== is_web_public
|
2020-08-04 16:40:46 +02:00
|
|
|
) {
|
|
|
|
data.is_private = JSON.stringify(invite_only);
|
|
|
|
data.history_public_to_subscribers = JSON.stringify(history_public_to_subscribers);
|
2020-11-10 15:57:14 +01:00
|
|
|
data.is_web_public = JSON.stringify(is_web_public);
|
2020-08-04 16:40:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
let message_retention_days = $(
|
|
|
|
"#stream_privacy_modal select[name=stream_message_retention_setting]",
|
|
|
|
).val();
|
|
|
|
if (message_retention_days === "retain_for_period") {
|
2020-10-07 09:17:30 +02:00
|
|
|
message_retention_days = Number.parseInt(
|
2020-08-04 16:40:46 +02:00
|
|
|
$("#stream_privacy_modal input[name=stream-message-retention-days]").val(),
|
|
|
|
10,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const message_retention_days_from_sub = get_message_retention_days_from_sub(sub);
|
|
|
|
|
|
|
|
if (message_retention_days_from_sub !== message_retention_days) {
|
2020-06-25 23:26:17 +02:00
|
|
|
data.message_retention_days = JSON.stringify(message_retention_days);
|
|
|
|
}
|
|
|
|
|
2020-08-04 16:40:46 +02:00
|
|
|
if (Object.keys(data).length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-07-08 22:15:28 +02:00
|
|
|
settings_ui.do_settings_change(channel.patch, url, data, status_element);
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
|
2021-03-31 16:15:24 +02:00
|
|
|
export function archive_stream(stream_id, alert_element, stream_row) {
|
2018-04-30 14:08:10 +02:00
|
|
|
channel.del({
|
2020-07-15 01:29:15 +02:00
|
|
|
url: "/json/streams/" + stream_id,
|
2020-07-20 22:18:43 +02:00
|
|
|
error(xhr) {
|
2021-04-13 05:18:25 +02:00
|
|
|
ui_report.error($t_html({defaultMessage: "Failed"}), xhr, alert_element);
|
2018-04-30 14:08:10 +02:00
|
|
|
},
|
2020-07-20 22:18:43 +02:00
|
|
|
success() {
|
2018-04-30 14:08:10 +02:00
|
|
|
stream_row.remove();
|
|
|
|
},
|
|
|
|
});
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|
2018-04-30 14:08:10 +02:00
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
export function initialize() {
|
2020-07-02 01:45:54 +02:00
|
|
|
$("#main_div").on("click", ".stream_sub_unsub_button", (e) => {
|
2017-04-24 04:11:25 +02:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
|
2020-07-08 22:45:35 +02:00
|
|
|
const sub = narrow_state.stream_sub();
|
|
|
|
if (sub === undefined) {
|
2017-04-24 04:11:25 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-07-08 22:45:35 +02:00
|
|
|
|
2021-07-09 15:51:31 +02:00
|
|
|
stream_settings_ui.sub_or_unsub(sub);
|
2017-04-24 04:11:25 +02:00
|
|
|
});
|
|
|
|
|
2020-07-02 01:45:54 +02:00
|
|
|
$("#subscriptions_table").on("click", ".change-stream-privacy", (e) => {
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_id = get_stream_id(e.target);
|
2021-04-15 17:02:54 +02:00
|
|
|
const stream = sub_store.get(stream_id);
|
2020-07-10 14:25:21 +02:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const template_data = {
|
2020-07-10 14:25:21 +02:00
|
|
|
stream_privacy_policy_values: stream_data.stream_privacy_policy_values,
|
|
|
|
stream_privacy_policy: stream_data.get_stream_privacy_policy(stream_id),
|
2020-02-04 21:50:55 +01:00
|
|
|
stream_post_policy_values: stream_data.stream_post_policy_values,
|
|
|
|
stream_post_policy: stream.stream_post_policy,
|
2020-06-25 23:26:17 +02:00
|
|
|
is_owner: page_params.is_owner,
|
2020-06-15 17:00:00 +02:00
|
|
|
zulip_plan_is_not_limited: page_params.zulip_plan_is_not_limited,
|
2020-07-15 00:34:28 +02:00
|
|
|
disable_message_retention_setting:
|
|
|
|
!page_params.zulip_plan_is_not_limited || !page_params.is_owner,
|
2020-06-15 17:00:00 +02:00
|
|
|
stream_message_retention_days: stream.message_retention_days,
|
2021-06-17 22:16:08 +02:00
|
|
|
org_level_message_retention_setting:
|
|
|
|
get_display_text_for_realm_message_retention_setting(),
|
2020-06-15 17:00:00 +02:00
|
|
|
upgrade_text_for_wide_organization_logo:
|
|
|
|
page_params.upgrade_text_for_wide_organization_logo,
|
2020-06-25 23:26:17 +02:00
|
|
|
is_stream_edit: true,
|
2017-04-24 04:11:25 +02:00
|
|
|
};
|
2021-07-20 14:53:33 +02:00
|
|
|
const change_privacy_modal = render_stream_types(template_data);
|
|
|
|
|
|
|
|
dialog_widget.launch({
|
|
|
|
html_heading: $t_html(
|
|
|
|
{defaultMessage: "Change stream permissions for #{stream_name}"},
|
|
|
|
{stream_name: stream.name},
|
|
|
|
),
|
|
|
|
html_body: change_privacy_modal,
|
|
|
|
close_on_submit: true,
|
|
|
|
id: "stream_privacy_modal",
|
|
|
|
on_click: change_stream_privacy,
|
|
|
|
post_render: () => {
|
|
|
|
$("#stream_privacy_modal .dialog_submit_button").attr("data-stream-id", stream_id);
|
|
|
|
set_stream_message_retention_setting_dropdown(stream);
|
|
|
|
|
stream_edit: Be more specific w/ ".stream_message_retention_setting".
The stream creation form also uses the same stream_types template as
the stream privacy modal, however, it currently does not setup its own
handler for displaying the "N:" input when
".stream_message_retention_setting" is changed.
Previously, if one opened the stream creation form, then opened the
stream edit modal, and then went back to the stream creation form, the
drop down would correctly also .show() the input, because the handler
here would also target that selector. This is incorrect since we can't
always expect the stream_edit modal to be opened first, stream_create
should set up its own handlers.
Hence, as a prep commit to fixing stream_creation, and to ensure we
don't add duplicate handlers, in this commit we change all selectors
that targeted ".stream_message_retention_setting" to
"#stream_privacy_modal .stream_message_retention_setting" in this
file.
2021-11-23 18:34:43 +01:00
|
|
|
$("#stream_privacy_modal .stream_message_retention_setting").on("change", (e) => {
|
2021-07-20 14:53:33 +02:00
|
|
|
const dropdown_value = e.target.value;
|
|
|
|
change_stream_message_retention_days_block_display_property(dropdown_value);
|
|
|
|
});
|
|
|
|
},
|
2021-11-19 10:29:39 +01:00
|
|
|
on_show: () => {
|
|
|
|
stream_settings_ui.hide_or_disable_stream_privacy_options_if_required(
|
|
|
|
$("#stream_privacy_modal"),
|
|
|
|
);
|
|
|
|
},
|
2021-07-20 14:53:33 +02:00
|
|
|
});
|
2019-06-06 20:45:30 +02:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2017-04-24 04:11:25 +02:00
|
|
|
});
|
|
|
|
|
2021-07-05 11:26:23 +02:00
|
|
|
$("#subscriptions_table").on("click", "#open_stream_info_modal", (e) => {
|
|
|
|
e.preventDefault();
|
2018-05-31 19:20:23 +02:00
|
|
|
e.stopPropagation();
|
2021-07-05 11:26:23 +02:00
|
|
|
const stream_id = get_stream_id(e.target);
|
|
|
|
const stream = sub_store.get(stream_id);
|
|
|
|
const template_data = {
|
|
|
|
stream_name: stream.name,
|
|
|
|
stream_description: stream.description,
|
|
|
|
};
|
|
|
|
const change_stream_info_modal = render_change_stream_info_modal(template_data);
|
2021-07-17 16:44:31 +02:00
|
|
|
dialog_widget.launch({
|
|
|
|
html_heading: $t_html(
|
|
|
|
{defaultMessage: "Edit #{stream_name}"},
|
|
|
|
{stream_name: stream.name},
|
|
|
|
),
|
|
|
|
html_body: change_stream_info_modal,
|
|
|
|
id: "change_stream_info_modal",
|
|
|
|
on_click: save_stream_info,
|
|
|
|
post_render: () => {
|
|
|
|
$("#change_stream_info_modal .dialog_submit_button")
|
|
|
|
.addClass("save-button")
|
|
|
|
.attr("data-stream-id", stream_id);
|
|
|
|
},
|
|
|
|
});
|
2017-04-24 04:11:25 +02:00
|
|
|
});
|
|
|
|
|
2021-07-05 11:26:23 +02:00
|
|
|
$("#subscriptions_table").on("keypress", "#change_stream_description", (e) => {
|
|
|
|
// Stream descriptions can not be multiline, so disable enter key
|
|
|
|
// to prevent new line
|
|
|
|
if (e.key === "Enter") {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
2021-07-17 16:44:31 +02:00
|
|
|
function save_stream_info(e) {
|
2021-07-05 11:26:23 +02:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
const sub = get_sub_for_target(e.currentTarget);
|
|
|
|
|
|
|
|
const url = `/json/streams/${sub.stream_id}`;
|
|
|
|
const data = {};
|
|
|
|
const new_name = $("#change_stream_name").val().trim();
|
|
|
|
const new_description = $("#change_stream_description").val().trim();
|
|
|
|
|
|
|
|
if (new_name === sub.name && new_description === sub.description) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (new_name !== sub.name) {
|
|
|
|
data.new_name = new_name;
|
|
|
|
}
|
|
|
|
if (new_description !== sub.description) {
|
|
|
|
data.description = new_description;
|
|
|
|
}
|
|
|
|
|
|
|
|
const status_element = $(".stream_change_property_info");
|
2021-07-17 16:44:31 +02:00
|
|
|
dialog_widget.close_modal();
|
2021-07-05 11:26:23 +02:00
|
|
|
settings_ui.do_settings_change(channel.patch, url, data, status_element);
|
2021-07-17 16:44:31 +02:00
|
|
|
}
|
2021-07-05 11:26:23 +02:00
|
|
|
|
|
|
|
$("#subscriptions_table").on(
|
|
|
|
"click",
|
|
|
|
".close-modal-btn, .close-change-stream-info-modal",
|
|
|
|
(e) => {
|
|
|
|
// This fixes a weird bug in which, subscription_settings hides
|
|
|
|
// unexpectedly by clicking the cancel button in a modal on top of it.
|
|
|
|
e.stopPropagation();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2020-07-22 00:43:11 +02:00
|
|
|
$("#subscriptions_table").on(
|
|
|
|
"change",
|
|
|
|
"#sub_is_muted_setting .sub_setting_control",
|
|
|
|
stream_is_muted_changed,
|
|
|
|
);
|
2019-06-14 15:41:28 +02:00
|
|
|
|
2020-07-22 00:43:11 +02:00
|
|
|
$("#subscriptions_table").on(
|
|
|
|
"change",
|
|
|
|
".sub_setting_checkbox .sub_setting_control",
|
2021-02-28 00:55:38 +01:00
|
|
|
stream_setting_changed,
|
2020-07-22 00:43:11 +02:00
|
|
|
);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2020-07-02 01:45:54 +02:00
|
|
|
$("#subscriptions_table").on("keyup", ".subscriber_list_add form", (e) => {
|
2021-05-31 19:16:18 +02:00
|
|
|
if (e.key === "Enter") {
|
2020-06-21 16:28:07 +02:00
|
|
|
e.preventDefault();
|
|
|
|
submit_add_subscriber_form(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-07-02 01:45:54 +02:00
|
|
|
$("#subscriptions_table").on("submit", ".subscriber_list_add form", (e) => {
|
2017-04-24 04:11:25 +02:00
|
|
|
e.preventDefault();
|
2020-06-21 18:46:53 +02:00
|
|
|
submit_add_subscriber_form(e);
|
2017-04-24 04:11:25 +02:00
|
|
|
});
|
|
|
|
|
2020-07-02 01:45:54 +02:00
|
|
|
$("#subscriptions_table").on("submit", ".subscriber_list_remove form", (e) => {
|
2017-04-24 04:11:25 +02:00
|
|
|
e.preventDefault();
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const list_entry = $(e.target).closest("tr");
|
2020-10-07 09:17:30 +02:00
|
|
|
const target_user_id = Number.parseInt(list_entry.attr("data-subscriber-id"), 10);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
2020-08-28 12:27:18 +02:00
|
|
|
const sub = get_sub_for_target(e.target);
|
2017-04-24 04:11:25 +02:00
|
|
|
if (!sub) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error(".subscriber_list_remove form submit fails");
|
2017-04-24 04:11:25 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-06-22 21:36:06 +02:00
|
|
|
let message;
|
2017-04-24 04:11:25 +02:00
|
|
|
|
|
|
|
function removal_success(data) {
|
|
|
|
if (data.removed.length > 0) {
|
|
|
|
// Remove the user from the subscriber list.
|
|
|
|
list_entry.remove();
|
2021-06-22 21:36:06 +02:00
|
|
|
message = $t({defaultMessage: "Unsubscribed successfully!"});
|
2018-03-14 03:29:33 +01:00
|
|
|
// The rest of the work is done via the subscription -> remove event we will get
|
2017-04-24 04:11:25 +02:00
|
|
|
} else {
|
2021-06-22 21:36:06 +02:00
|
|
|
message = $t({defaultMessage: "User is already not subscribed."});
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
2021-06-30 22:57:50 +02:00
|
|
|
show_stream_subscription_request_result({
|
2021-06-22 21:36:06 +02:00
|
|
|
message,
|
|
|
|
add_class: "text-success",
|
|
|
|
remove_class: "text-remove",
|
|
|
|
});
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function removal_failure() {
|
2021-06-30 22:57:50 +02:00
|
|
|
show_stream_subscription_request_result({
|
2021-06-22 21:36:06 +02:00
|
|
|
message: $t({defaultMessage: "Error removing user from this stream."}),
|
|
|
|
add_class: "text-error",
|
|
|
|
remove_class: "text-success",
|
|
|
|
});
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
|
2020-08-07 00:38:19 +02:00
|
|
|
function remove_user_from_private_stream() {
|
|
|
|
remove_user_from_stream(target_user_id, sub, removal_success, removal_failure);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sub.invite_only && people.is_my_user_id(target_user_id)) {
|
|
|
|
const html_body = render_unsubscribe_private_stream_modal();
|
|
|
|
|
|
|
|
confirm_dialog.launch({
|
2021-04-13 05:24:31 +02:00
|
|
|
html_heading: $t_html(
|
|
|
|
{defaultMessage: "Unsubscribe from {stream_name}"},
|
|
|
|
{stream_name: sub.name},
|
|
|
|
),
|
2020-08-07 00:38:19 +02:00
|
|
|
html_body,
|
|
|
|
on_click: remove_user_from_private_stream,
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-02-28 00:55:38 +01:00
|
|
|
remove_user_from_stream(target_user_id, sub, removal_success, removal_failure);
|
2017-04-24 04:11:25 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
// This handler isn't part of the normal edit interface; it's the convenient
|
|
|
|
// checkmark in the subscriber list.
|
2020-07-07 23:04:47 +02:00
|
|
|
$("#subscriptions_table").on("click", ".sub_unsub_button", (e) => {
|
2019-11-02 00:06:25 +01:00
|
|
|
const sub = get_sub_for_target(e.target);
|
2020-04-26 21:36:28 +02:00
|
|
|
// Makes sure we take the correct stream_row.
|
2020-07-15 00:34:28 +02:00
|
|
|
const stream_row = $(
|
2021-02-03 23:23:32 +01:00
|
|
|
`#subscriptions_table div.stream-row[data-stream-id='${CSS.escape(sub.stream_id)}']`,
|
2020-07-15 00:34:28 +02:00
|
|
|
);
|
2021-07-04 08:03:07 +02:00
|
|
|
stream_settings_ui.sub_or_unsub(sub, stream_row);
|
2020-04-23 23:49:50 +02:00
|
|
|
|
2017-04-24 04:11:25 +02:00
|
|
|
if (!sub.subscribed) {
|
2021-02-28 00:55:38 +01:00
|
|
|
open_edit_panel_for_row(stream_row);
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
2019-04-02 18:37:24 +02:00
|
|
|
stream_ui_updates.update_regular_sub_settings(sub);
|
2017-04-24 04:11:25 +02:00
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
});
|
|
|
|
|
2020-07-02 01:45:54 +02:00
|
|
|
$("#subscriptions_table").on("click", ".deactivate", (e) => {
|
2018-02-13 11:47:17 +01:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_id = get_stream_id(e.target);
|
2018-02-13 11:47:17 +01:00
|
|
|
if (!stream_id) {
|
2021-04-13 05:18:25 +02:00
|
|
|
ui_report.client_error(
|
|
|
|
$t_html({defaultMessage: "Invalid stream id"}),
|
|
|
|
$(".stream_change_property_info"),
|
|
|
|
);
|
2018-02-13 11:47:17 +01:00
|
|
|
return;
|
|
|
|
}
|
2021-05-26 18:27:48 +02:00
|
|
|
|
|
|
|
function do_archive_stream() {
|
2021-07-05 12:41:37 +02:00
|
|
|
const stream_id = $(".dialog_submit_button").data("stream-id");
|
2021-05-26 18:27:48 +02:00
|
|
|
if (!stream_id) {
|
|
|
|
ui_report.client_error(
|
|
|
|
$t_html({defaultMessage: "Invalid stream id"}),
|
|
|
|
$(".stream_change_property_info"),
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const row = $(".stream-row.active");
|
|
|
|
archive_stream(stream_id, $(".stream_change_property_info"), row);
|
|
|
|
}
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_name = stream_data.maybe_get_stream_name(stream_id);
|
2021-05-26 18:27:48 +02:00
|
|
|
const html_body = render_settings_deactivation_stream_modal({
|
2020-07-20 22:18:43 +02:00
|
|
|
stream_name,
|
2019-06-12 21:01:38 +02:00
|
|
|
});
|
2018-02-13 11:47:17 +01:00
|
|
|
|
2021-05-26 18:27:48 +02:00
|
|
|
confirm_dialog.launch({
|
|
|
|
html_heading: $t_html(
|
|
|
|
{defaultMessage: "Archive stream {stream}"},
|
|
|
|
{stream: stream_name},
|
|
|
|
),
|
|
|
|
help_link: "/help/archive-a-stream",
|
|
|
|
html_body,
|
|
|
|
on_click: do_archive_stream,
|
|
|
|
});
|
|
|
|
|
2021-07-05 12:41:37 +02:00
|
|
|
$(".dialog_submit_button").attr("data-stream-id", stream_id);
|
2018-02-13 11:47:17 +01:00
|
|
|
});
|
|
|
|
|
2017-04-24 04:11:25 +02:00
|
|
|
$("#subscriptions_table").on("click", ".stream-row", function (e) {
|
|
|
|
if ($(e.target).closest(".check, .subscription_settings").length === 0) {
|
2021-02-28 00:55:38 +01:00
|
|
|
open_edit_panel_for_row(this);
|
2017-04-24 04:11:25 +02:00
|
|
|
}
|
|
|
|
});
|
2021-02-28 00:55:38 +01:00
|
|
|
}
|