mirror of https://github.com/zulip/zulip.git
parent
a196b949f7
commit
8ea59f7f02
|
@ -13,12 +13,11 @@ async function check_compose_form_empty(page: Page): Promise<void> {
|
|||
}
|
||||
|
||||
async function close_compose_box(page: Page): Promise<void> {
|
||||
const recipient_dropdown_visible =
|
||||
(await page.$("#compose_select_recipient_widget .open")) !== null;
|
||||
const recipient_dropdown_visible = (await page.$(".dropdown-list-container")) !== null;
|
||||
|
||||
if (recipient_dropdown_visible) {
|
||||
await page.keyboard.press("Escape");
|
||||
await page.waitForSelector("#id_compose_select_recipient.open", {hidden: true});
|
||||
await page.waitForSelector(".dropdown-list-container", {hidden: true});
|
||||
}
|
||||
await page.keyboard.press("Escape");
|
||||
await page.waitForSelector("#compose-textarea", {hidden: true});
|
||||
|
@ -126,9 +125,7 @@ async function test_narrow_to_private_messages_with_cordelia(page: Page): Promis
|
|||
|
||||
await page.keyboard.press("KeyC");
|
||||
await page.waitForSelector("#compose", {visible: true});
|
||||
await page.waitForSelector(".compose_table #id_compose_select_recipient.open", {
|
||||
visible: true,
|
||||
});
|
||||
await page.waitForSelector(`.dropdown-list-container .list-item`, {visible: true});
|
||||
await close_compose_box(page);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ async function create_stream_message_draft(page: Page): Promise<void> {
|
|||
console.log("Creating stream message draft");
|
||||
await page.keyboard.press("KeyC");
|
||||
await page.waitForSelector("#stream_message_recipient_topic", {visible: true});
|
||||
await common.select_item_via_dropdown(page, "#compose_select_recipient_widget", "Denmark");
|
||||
await common.select_stream_in_compose_via_dropdown(page, "Denmark");
|
||||
await common.fill_form(page, "form#send_message_form", {
|
||||
stream_message_recipient_topic: "tests",
|
||||
content: "Test stream message.",
|
||||
|
@ -129,7 +129,7 @@ async function test_restore_message_draft_via_draft_overlay(page: Page): Promise
|
|||
}
|
||||
|
||||
async function edit_stream_message_draft(page: Page): Promise<void> {
|
||||
await common.select_item_via_dropdown(page, "#compose_select_recipient_widget", "Denmark");
|
||||
await common.select_stream_in_compose_via_dropdown(page, "Denmark");
|
||||
await common.fill_form(page, "form#send_message_form", {
|
||||
stream_message_recipient_topic: "tests",
|
||||
content: "Updated stream message",
|
||||
|
|
|
@ -384,24 +384,23 @@ export async function wait_for_fully_processed_message(page: Page, content: stri
|
|||
await scroll_delay;
|
||||
}
|
||||
|
||||
export async function select_item_via_dropdown(
|
||||
export async function select_stream_in_compose_via_dropdown(
|
||||
page: Page,
|
||||
dropdown_selector: string,
|
||||
item: string,
|
||||
stream_name: string,
|
||||
): Promise<void> {
|
||||
console.log(`Clicking on ${dropdown_selector} to select ${item}`);
|
||||
const menu_visible = (await page.$(`${dropdown_selector} .open`)) !== null;
|
||||
console.log(`Clicking on 'compose_select_recipient_widget' to select ${stream_name}`);
|
||||
const menu_visible = (await page.$(".dropdown-list-container")) !== null;
|
||||
if (!menu_visible) {
|
||||
await page.waitForSelector(dropdown_selector, {visible: true});
|
||||
await page.click(`${dropdown_selector} .dropdown-toggle`);
|
||||
await page.waitForSelector(`${dropdown_selector} .dropdown-menu`, {visible: true});
|
||||
await page.waitForSelector("#compose_select_recipient_widget", {visible: true});
|
||||
await page.click("#compose_select_recipient_widget");
|
||||
await page.waitForSelector(".dropdown-list-container .list-item", {
|
||||
visible: true,
|
||||
});
|
||||
}
|
||||
const entry_selector = `xpath///*[${has_class_x(
|
||||
"list_item",
|
||||
)} and contains(normalize-space(), "${item}")]`;
|
||||
await page.waitForSelector(entry_selector, {visible: true});
|
||||
await page.click(entry_selector);
|
||||
await page.waitForSelector(`.dropdown-menu`, {visible: false});
|
||||
const stream_to_select = `.dropdown-list-container .list-item[data-name="${stream_name}"]`;
|
||||
await page.waitForSelector(stream_to_select, {visible: true});
|
||||
await page.click(stream_to_select);
|
||||
assert((await page.$(".dropdown-list-container")) === null);
|
||||
}
|
||||
|
||||
// Wait for any previous send to finish, then send a message.
|
||||
|
@ -432,7 +431,7 @@ export async function send_message(
|
|||
}
|
||||
|
||||
if (params.stream) {
|
||||
await select_item_via_dropdown(page, "#compose_select_recipient_widget", params.stream);
|
||||
await select_stream_in_compose_via_dropdown(page, params.stream);
|
||||
delete params.stream;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ async function test_mention(page: Page): Promise<void> {
|
|||
await page.keyboard.press("KeyC");
|
||||
await page.waitForSelector("#compose", {visible: true});
|
||||
|
||||
await common.select_item_via_dropdown(page, "#compose_select_recipient_widget", "Verona");
|
||||
await common.select_stream_in_compose_via_dropdown(page, "Verona");
|
||||
await common.fill_form(page, 'form[action^="/json/messages"]', {
|
||||
stream_message_recipient_topic: "Test mention all",
|
||||
});
|
||||
|
|
|
@ -153,17 +153,16 @@ export function create_message_object() {
|
|||
} else {
|
||||
const stream_name = compose_state.stream_name();
|
||||
message.stream = stream_name;
|
||||
const sub = stream_data.get_sub(stream_name);
|
||||
if (sub) {
|
||||
message.stream_id = sub.stream_id;
|
||||
message.to = sub.stream_id;
|
||||
if (stream_name) {
|
||||
message.stream_id = compose_recipient.selected_recipient_id;
|
||||
message.to = compose_recipient.selected_recipient_id;
|
||||
} else {
|
||||
// We should be validating streams in calling code. We'll
|
||||
// try to fall back to stream_name here just in case the
|
||||
// user started composing to the old stream name and
|
||||
// manually entered the stream name, and it got past
|
||||
// validation. We should try to kill this code off eventually.
|
||||
blueslip.error("Trying to send message with bad stream name", {stream_name});
|
||||
blueslip.error("Trying to send message with bad stream name");
|
||||
message.to = stream_name;
|
||||
}
|
||||
message.topic = topic;
|
||||
|
|
|
@ -208,20 +208,19 @@ export function start(msg_type, opts) {
|
|||
clear_box();
|
||||
}
|
||||
|
||||
compose_recipient.compose_recipient_widget.render(opts.stream);
|
||||
const $stream_header_colorblock = $(
|
||||
"#compose_recipient_selection_dropdown .stream_header_colorblock",
|
||||
);
|
||||
stream_bar.decorate(opts.stream, $stream_header_colorblock);
|
||||
|
||||
// We set the stream/topic/private_message_recipient
|
||||
// unconditionally here, which assumes the caller will have passed
|
||||
// '' or undefined for these values if they are not appropriate
|
||||
// for this message.
|
||||
//
|
||||
// TODO: Move these into a conditional on message_type, using an
|
||||
// explicit "clear" function for compose_state.
|
||||
compose_state.set_stream_name(opts.stream);
|
||||
if (msg_type === "private") {
|
||||
compose_state.set_compose_recipient_id(compose_recipient.DIRECT_MESSAGE_ID);
|
||||
} else if (opts.stream) {
|
||||
compose_state.set_stream_name(opts.stream);
|
||||
} else {
|
||||
// Open stream selection dropdown if no stream is selected.
|
||||
compose_recipient.open_compose_recipient_dropdown();
|
||||
}
|
||||
compose_state.topic(opts.topic);
|
||||
|
||||
// Set the recipients with a space after each comma, so it looks nice.
|
||||
|
|
|
@ -137,12 +137,6 @@ export function show_stream_does_not_exist_error(stream_name: string): void {
|
|||
append_compose_banner_to_banner_list(new_row, $("#compose_banners"));
|
||||
hide_compose_spinner();
|
||||
|
||||
// A copy of `compose_recipient.open_compose_stream_dropup()` that
|
||||
// can't be imported due to typescript and import circles.
|
||||
// TODO: Once we use stream IDs, not names, as the fundamental
|
||||
// compose_state storage for streams, this error will be impossible.
|
||||
if ($("#id_compose_select_recipient").hasClass("open")) {
|
||||
return;
|
||||
}
|
||||
$("#id_compose_select_recipient button").trigger("click");
|
||||
// Open stream select dropdown.
|
||||
$("#compose_select_recipient_widget").trigger("click");
|
||||
}
|
||||
|
|
|
@ -3,13 +3,15 @@
|
|||
import $ from "jquery";
|
||||
import _ from "lodash";
|
||||
|
||||
import render_inline_decorated_stream_name from "../templates/inline_decorated_stream_name.hbs";
|
||||
|
||||
import * as compose_banner from "./compose_banner";
|
||||
import * as compose_fade from "./compose_fade";
|
||||
import * as compose_pm_pill from "./compose_pm_pill";
|
||||
import * as compose_state from "./compose_state";
|
||||
import * as compose_ui from "./compose_ui";
|
||||
import * as compose_validate from "./compose_validate";
|
||||
import {DropdownListWidget} from "./dropdown_list_widget";
|
||||
import * as dropdown_widget from "./dropdown_widget";
|
||||
import {$t} from "./i18n";
|
||||
import * as narrow_state from "./narrow_state";
|
||||
import {page_params} from "./page_params";
|
||||
|
@ -19,9 +21,17 @@ import * as stream_data from "./stream_data";
|
|||
import * as ui_util from "./ui_util";
|
||||
import * as util from "./util";
|
||||
|
||||
export let compose_recipient_widget;
|
||||
// selected_recipient_id is the current state for the stream picker widget:
|
||||
// "" -> stream message but no stream is selected
|
||||
// integer -> stream id of the selected stream.
|
||||
// "direct" -> Direct message is selected.
|
||||
export let selected_recipient_id = "";
|
||||
export const DIRECT_MESSAGE_ID = "direct";
|
||||
|
||||
const DIRECT_MESSAGE = "direct";
|
||||
export function set_selected_recipient_id(recipient_id) {
|
||||
selected_recipient_id = recipient_id;
|
||||
on_compose_select_recipient_update();
|
||||
}
|
||||
|
||||
function composing_to_current_topic_narrow() {
|
||||
return (
|
||||
|
@ -98,16 +108,6 @@ export function update_on_recipient_change() {
|
|||
update_narrow_to_recipient_visibility();
|
||||
}
|
||||
|
||||
export function open_compose_stream_dropup() {
|
||||
if ($("#id_compose_select_recipient").hasClass("open")) {
|
||||
return;
|
||||
}
|
||||
// We trigger a click rather than directly toggling the element;
|
||||
// this is important to ensure the filter text gets cleared when
|
||||
// reopening the widget after previous use.
|
||||
$("#id_compose_select_recipient > .dropdown-toggle").trigger("click");
|
||||
}
|
||||
|
||||
export function check_stream_posting_policy_for_compose_box(stream_name) {
|
||||
const stream = stream_data.get_sub_by_name(stream_name);
|
||||
if (!stream) {
|
||||
|
@ -145,13 +145,21 @@ function switch_message_type(message_type) {
|
|||
compose_ui.set_focus(message_type, opts);
|
||||
}
|
||||
|
||||
export function update_compose_for_message_type(message_type) {
|
||||
export function update_compose_for_message_type(message_type, opts) {
|
||||
if (message_type === "stream") {
|
||||
$("#compose-direct-recipient").hide();
|
||||
$("#stream_message_recipient_topic").show();
|
||||
$("#stream_toggle").addClass("active");
|
||||
$("#private_message_toggle").removeClass("active");
|
||||
$("#compose-recipient").removeClass("compose-recipient-direct-selected");
|
||||
const stream = stream_data.get_sub_by_name(opts.stream);
|
||||
if (stream === undefined) {
|
||||
$("#compose_select_recipient_name").text($t({defaultMessage: "Select a stream"}));
|
||||
} else {
|
||||
$("#compose_select_recipient_name").html(
|
||||
render_inline_decorated_stream_name({stream, show_colored_icon: true}),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$("#compose-direct-recipient").show();
|
||||
$("#stream_message_recipient_topic").hide();
|
||||
|
@ -171,9 +179,13 @@ export function update_compose_for_message_type(message_type) {
|
|||
compose_banner.clear_warnings();
|
||||
}
|
||||
|
||||
export function on_compose_select_recipient_update(new_value) {
|
||||
const message_type = compose_state.get_message_type();
|
||||
if (new_value === DIRECT_MESSAGE) {
|
||||
export function on_compose_select_recipient_update() {
|
||||
let message_type = "stream";
|
||||
if (selected_recipient_id === DIRECT_MESSAGE_ID) {
|
||||
message_type = "private";
|
||||
}
|
||||
compose_state.set_message_type(message_type);
|
||||
if (message_type === "private") {
|
||||
// TODO: In theory, we could do something more lightweight in
|
||||
// the case it's already that value, but doing nothing would
|
||||
// display the wrong and fail to update focus properly.
|
||||
|
@ -186,28 +198,33 @@ export function on_compose_select_recipient_update(new_value) {
|
|||
const $stream_header_colorblock = $(
|
||||
"#compose_recipient_selection_dropdown .stream_header_colorblock",
|
||||
);
|
||||
stream_bar.decorate(new_value, $stream_header_colorblock);
|
||||
if (message_type === "private") {
|
||||
switch_message_type("stream");
|
||||
}
|
||||
const stream_name = compose_state.stream_name();
|
||||
stream_bar.decorate(stream_name, $stream_header_colorblock);
|
||||
switch_message_type("stream");
|
||||
// Always move focus to the topic input even if it's not empty,
|
||||
// since it's likely the user will want to update the topic
|
||||
// after updating the stream.
|
||||
ui_util.place_caret_at_end($("#stream_message_recipient_topic")[0]);
|
||||
check_stream_posting_policy_for_compose_box(new_value);
|
||||
check_stream_posting_policy_for_compose_box(stream_name);
|
||||
}
|
||||
update_on_recipient_change();
|
||||
}
|
||||
|
||||
export function update_stream_dropdown_options() {
|
||||
compose_recipient_widget.replace_data(get_options_for_recipient_widget());
|
||||
export function possibly_update_stream_name_in_compose(stream_id) {
|
||||
if (selected_recipient_id === stream_id) {
|
||||
on_compose_select_recipient_update();
|
||||
}
|
||||
}
|
||||
|
||||
export function possibly_update_dropdown_selection(old_stream_name, new_stream_name) {
|
||||
const selected_stream = compose_state.stream_name();
|
||||
if (selected_stream === old_stream_name) {
|
||||
compose_state.set_stream_name(new_stream_name);
|
||||
function item_click_callback(event, dropdown) {
|
||||
let recipient_id = $(event.currentTarget).attr("data-unique-id");
|
||||
if (recipient_id !== DIRECT_MESSAGE_ID) {
|
||||
recipient_id = Number.parseInt(recipient_id, 10);
|
||||
}
|
||||
set_selected_recipient_id(recipient_id);
|
||||
dropdown.hide();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
function get_options_for_recipient_widget() {
|
||||
|
@ -215,7 +232,7 @@ function get_options_for_recipient_widget() {
|
|||
.subscribed_subs()
|
||||
.map((stream) => ({
|
||||
name: stream.name,
|
||||
value: stream.name,
|
||||
unique_id: stream.stream_id,
|
||||
stream,
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
|
@ -229,10 +246,11 @@ function get_options_for_recipient_widget() {
|
|||
});
|
||||
|
||||
const direct_messages_option = {
|
||||
name: $t({defaultMessage: "Direct message"}),
|
||||
value: DIRECT_MESSAGE,
|
||||
is_direct_message: true,
|
||||
unique_id: DIRECT_MESSAGE_ID,
|
||||
name: $t({defaultMessage: "Direct message"}),
|
||||
};
|
||||
|
||||
if (
|
||||
page_params.realm_private_message_policy ===
|
||||
settings_config.private_message_policy_values.by_anyone.code
|
||||
|
@ -244,23 +262,61 @@ function get_options_for_recipient_widget() {
|
|||
return options;
|
||||
}
|
||||
|
||||
export function initialize() {
|
||||
const opts = {
|
||||
widget_name: "compose_select_recipient",
|
||||
data: get_options_for_recipient_widget(),
|
||||
default_text: $t({defaultMessage: "Select a stream"}),
|
||||
value: null,
|
||||
on_update: on_compose_select_recipient_update,
|
||||
};
|
||||
compose_recipient_widget = new DropdownListWidget(opts);
|
||||
compose_recipient_widget.setup();
|
||||
function compose_recipient_dropdown_on_show(dropdown) {
|
||||
// Offset to display dropdown above compose.
|
||||
let top_offset = 5;
|
||||
const window_height = window.innerHeight;
|
||||
const search_box_and_padding_height = 50;
|
||||
// pixels above compose box.
|
||||
const recipient_input_top = $("#compose_recipient_selection_dropdown").offset().top;
|
||||
const top_space = recipient_input_top - top_offset - search_box_and_padding_height;
|
||||
// pixels below compose starting from top of compose box.
|
||||
const bottom_space = window_height - recipient_input_top - search_box_and_padding_height;
|
||||
// Show dropdown on top / bottom based on available space.
|
||||
let placement = "top-start";
|
||||
if (bottom_space > top_space) {
|
||||
placement = "bottom-start";
|
||||
top_offset = -30;
|
||||
}
|
||||
const offset = [-10, top_offset];
|
||||
dropdown.setProps({placement, offset});
|
||||
const height = Math.min(
|
||||
dropdown_widget.DEFAULT_DROPDOWN_HEIGHT,
|
||||
Math.max(top_space, bottom_space),
|
||||
);
|
||||
const $popper = $(dropdown.popper);
|
||||
$popper.find(".dropdown-list-wrapper").css("height", height + "px");
|
||||
}
|
||||
|
||||
$("#compose_select_recipient_widget").on("select", (e) => {
|
||||
// We often focus on input fields to bring the user to fill it out.
|
||||
// In this situation, a focus on the dropdown div opens the dropdown
|
||||
// menu so that the user can select an option.
|
||||
open_compose_stream_dropup();
|
||||
e.stopPropagation();
|
||||
export function open_compose_recipient_dropdown() {
|
||||
$("#compose_select_recipient_widget").trigger("click");
|
||||
}
|
||||
|
||||
function focus_compose_recipient() {
|
||||
$("#compose_recipient_selection_dropdown").trigger("focus");
|
||||
}
|
||||
|
||||
export function initialize() {
|
||||
dropdown_widget.setup(
|
||||
{
|
||||
target: "#compose_select_recipient_widget",
|
||||
},
|
||||
get_options_for_recipient_widget,
|
||||
item_click_callback,
|
||||
{
|
||||
on_show_callback: compose_recipient_dropdown_on_show,
|
||||
on_exit_with_escape_callback: focus_compose_recipient,
|
||||
// We want to focus on topic box if dropdown was closed via selecting an item.
|
||||
focus_target_on_hidden: false,
|
||||
},
|
||||
);
|
||||
|
||||
$("#compose_recipient_selection_dropdown").on("keydown", (e) => {
|
||||
if (e.key === "Enter") {
|
||||
open_compose_recipient_dropdown();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
// `keyup` isn't relevant for streams since it registers as a change only
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import $ from "jquery";
|
||||
|
||||
import * as blueslip from "./blueslip";
|
||||
import * as compose_pm_pill from "./compose_pm_pill";
|
||||
import * as compose_recipient from "./compose_recipient";
|
||||
import * as stream_data from "./stream_data";
|
||||
|
||||
let message_type = false; // 'stream', 'private', or false-y
|
||||
let recipient_edited_manually = false;
|
||||
|
@ -67,15 +69,40 @@ function get_or_set(fieldname, keep_leading_whitespace, no_trim) {
|
|||
};
|
||||
}
|
||||
|
||||
// NOTE: See `selected_recipient_id` in compose_recipient to for
|
||||
// documentation on the variable and how it is used.
|
||||
export function stream_name() {
|
||||
return compose_recipient.compose_recipient_widget.value();
|
||||
const stream_id = compose_recipient.selected_recipient_id;
|
||||
if (typeof stream_id === "number") {
|
||||
return stream_data.maybe_get_stream_name(stream_id) || "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export function set_stream_name(newval) {
|
||||
if (newval !== undefined && newval !== "" && compose_recipient.compose_recipient_widget) {
|
||||
compose_recipient.compose_recipient_widget.render(newval);
|
||||
compose_recipient.on_compose_select_recipient_update(newval);
|
||||
export function set_stream_name(stream_name) {
|
||||
if (!stream_name) {
|
||||
compose_recipient.set_selected_recipient_id("");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we fail to select a stream that the caller expects
|
||||
// us to do successfully, we should throw an error.
|
||||
const stream_id = stream_data.get_stream_id(stream_name);
|
||||
if (stream_id === undefined) {
|
||||
blueslip.error("Unable to select stream: " + stream_name);
|
||||
compose_recipient.set_selected_recipient_id("");
|
||||
return;
|
||||
}
|
||||
compose_recipient.set_selected_recipient_id(stream_id);
|
||||
}
|
||||
|
||||
export function set_compose_recipient_id(value) {
|
||||
let recipient_id = compose_recipient.DIRECT_MESSAGE_ID;
|
||||
if (typeof value === "number") {
|
||||
// value is stream name
|
||||
recipient_id = stream_data.maybe_get_stream_name(value) || "";
|
||||
}
|
||||
compose_recipient.set_selected_recipient_id(recipient_id);
|
||||
}
|
||||
|
||||
// TODO: Break out setter and getter into their own functions.
|
||||
|
|
|
@ -281,9 +281,6 @@ export function make_compose_box_full_size() {
|
|||
|
||||
// Set the `top` property of compose-box.
|
||||
set_compose_box_top(true);
|
||||
// The compose select dropup should now open down because it's
|
||||
// at the top of the screen.
|
||||
$("#id_compose_select_recipient").removeClass("dropup").addClass("dropdown");
|
||||
|
||||
$(".collapse_composebox_button").show();
|
||||
$(".expand_composebox_button").hide();
|
||||
|
@ -298,9 +295,6 @@ export function make_compose_box_original_size() {
|
|||
|
||||
// Unset the `top` property of compose-box.
|
||||
set_compose_box_top(false);
|
||||
// The compose select dropup should now open up because it's
|
||||
// near the bottom of the screen.
|
||||
$("#id_compose_select_recipient").removeClass("dropdown").addClass("dropup");
|
||||
|
||||
// Again initialise the compose textarea as it was destroyed
|
||||
// when compose box was made full screen
|
||||
|
|
|
@ -583,7 +583,7 @@ export function process_shift_tab_key() {
|
|||
}
|
||||
|
||||
if ($("#stream_message_recipient_topic").is(":focus")) {
|
||||
compose_recipient.open_compose_stream_dropup();
|
||||
compose_recipient.open_compose_recipient_dropdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -523,17 +523,19 @@ export function dispatch_normal_event(event) {
|
|||
const is_narrowed_to_stream = narrow_state.is_for_stream_id(
|
||||
stream.stream_id,
|
||||
);
|
||||
if (is_narrowed_to_stream) {
|
||||
message_lists.current.update_trailing_bookend();
|
||||
}
|
||||
stream_data.delete_sub(stream.stream_id);
|
||||
stream_settings_ui.remove_stream(stream.stream_id);
|
||||
if (was_subscribed) {
|
||||
stream_list.remove_sidebar_row(stream.stream_id);
|
||||
compose_recipient.update_stream_dropdown_options();
|
||||
if (stream.stream_id === compose_recipient.selected_recipient_id) {
|
||||
compose_recipient.set_selected_recipient_id("");
|
||||
}
|
||||
}
|
||||
settings_streams.update_default_streams_table();
|
||||
stream_data.remove_default_stream(stream.stream_id);
|
||||
if (is_narrowed_to_stream) {
|
||||
message_lists.current.update_trailing_bookend();
|
||||
}
|
||||
if (page_params.realm_notifications_stream_id === stream.stream_id) {
|
||||
page_params.realm_notifications_stream_id = -1;
|
||||
settings_org.sync_realm_settings("notifications_stream_id");
|
||||
|
|
|
@ -63,8 +63,7 @@ export function update_property(stream_id, property, value, other_values) {
|
|||
break;
|
||||
case "name":
|
||||
stream_settings_ui.update_stream_name(sub, value);
|
||||
compose_recipient.update_stream_dropdown_options();
|
||||
compose_recipient.possibly_update_dropdown_selection(sub.name, value);
|
||||
compose_recipient.possibly_update_stream_name_in_compose(sub.stream_id);
|
||||
break;
|
||||
case "description":
|
||||
stream_settings_ui.update_stream_description(
|
||||
|
@ -86,8 +85,7 @@ export function update_property(stream_id, property, value, other_values) {
|
|||
history_public_to_subscribers: other_values.history_public_to_subscribers,
|
||||
is_web_public: other_values.is_web_public,
|
||||
});
|
||||
// Force a re-render to get the right privacy icon
|
||||
compose_recipient.possibly_update_dropdown_selection(sub.name, sub.name);
|
||||
compose_recipient.on_compose_select_recipient_update();
|
||||
break;
|
||||
case "stream_post_policy":
|
||||
stream_settings_ui.update_stream_post_policy(sub, value);
|
||||
|
@ -132,7 +130,6 @@ export function mark_subscribed(sub, subscribers, color) {
|
|||
stream_settings_ui.set_color(sub.stream_id, color);
|
||||
}
|
||||
stream_data.subscribe_myself(sub);
|
||||
compose_recipient.update_stream_dropdown_options();
|
||||
if (subscribers) {
|
||||
peer_data.set_subscribers(sub.stream_id, subscribers);
|
||||
}
|
||||
|
@ -162,7 +159,6 @@ export function mark_unsubscribed(sub) {
|
|||
return;
|
||||
} else if (sub.subscribed) {
|
||||
stream_data.unsubscribe_myself(sub);
|
||||
compose_recipient.update_stream_dropdown_options();
|
||||
if (overlays.streams_open()) {
|
||||
stream_settings_ui.update_settings_for_unsubscribed(sub);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
flex: 1;
|
||||
|
||||
&.compose-recipient-direct-selected {
|
||||
#compose_recipient_selection_dropdown .dropdown-toggle {
|
||||
#compose_select_recipient_widget {
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
|
@ -520,11 +520,9 @@ input.recipient_box {
|
|||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#compose_select_recipient_widget,
|
||||
#compose_select_recipient_widget .button {
|
||||
margin: 0;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
#compose_select_recipient_widget {
|
||||
border-radius: 0 4px 4px 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#stream_message_recipient_topic.recipient_box {
|
||||
|
@ -828,10 +826,6 @@ a.compose_control_button.hide {
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
#id_compose_select_recipient {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
& ul {
|
||||
list-style: none;
|
||||
|
|
|
@ -55,12 +55,15 @@
|
|||
<button type="button" class="close fa fa-times" id='compose_close' data-tooltip-template-id="compose_close_tooltip_template"></button>
|
||||
</div>
|
||||
<div id="compose-recipient" class="order-1">
|
||||
<a role="button" class="narrow_to_compose_recipients zulip-icon zulip-icon-arrow-left-circle order-1" data-tooltip-template-id="narrow_to_compose_recipients_tooltip" tabindex="0"></a>
|
||||
<div id="compose_recipient_selection_dropdown" class="new-style">
|
||||
<a role="button" class="narrow_to_compose_recipients zulip-icon zulip-icon-arrow-left-circle order-1" data-tooltip-template-id="narrow_to_compose_recipients_tooltip"></a>
|
||||
<div id="compose_recipient_selection_dropdown" class="new-style" tabindex="0">
|
||||
<div class="stream_header_colorblock"></div>
|
||||
{{> settings/dropdown_list_widget
|
||||
widget_name="compose_select_recipient"
|
||||
list_placeholder=(t 'Filter')}}
|
||||
<div id="compose_select_recipient_widget" class="dropdown-widget-button" role="button">
|
||||
<span id="compose_select_recipient_name">
|
||||
{{t 'Select a stream'}}
|
||||
</span>
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
<i class="fa fa-angle-right" aria-hidden="true"></i>
|
||||
<input type="text" class="recipient_box" name="stream_message_recipient_topic" id="stream_message_recipient_topic" maxlength="{{ max_topic_length }}" value="" placeholder="{{t 'Topic' }}" autocomplete="off" tabindex="0" aria-label="{{t 'Topic' }}" />
|
||||
|
|
|
@ -304,18 +304,7 @@ test_ui("enter_with_preview_open", ({override, override_rewire}) => {
|
|||
mock_banners();
|
||||
$("#compose-textarea").toggleClass = noop;
|
||||
mock_stream_header_colorblock();
|
||||
compose_recipient.open_compose_stream_dropup = noop;
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", noop);
|
||||
let stream_value = "";
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return stream_value;
|
||||
},
|
||||
render(val) {
|
||||
stream_value = val;
|
||||
},
|
||||
};
|
||||
|
||||
override_rewire(compose_banner, "clear_message_sent_banners", () => {});
|
||||
override(document, "to_$", () => $("document-stub"));
|
||||
let show_button_spinner_called = false;
|
||||
|
@ -748,11 +737,11 @@ test_ui("create_message_object", ({override, override_rewire}) => {
|
|||
assert.equal(message.topic, "lunch");
|
||||
assert.equal(message.content, "burrito");
|
||||
|
||||
blueslip.expect("error", "Trying to send message with bad stream name");
|
||||
|
||||
blueslip.expect("error", "Unable to select stream: BOGUS STREAM");
|
||||
compose_state.set_stream_name("BOGUS STREAM");
|
||||
blueslip.expect("error", "Trying to send message with bad stream name.");
|
||||
message = compose.create_message_object();
|
||||
assert.equal(message.to, "BOGUS STREAM");
|
||||
assert.equal(message.to, "");
|
||||
assert.equal(message.topic, "lunch");
|
||||
assert.equal(message.content, "burrito");
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ const compose_ui = mock_esm("../src/compose_ui", {
|
|||
autosize_textarea: noop,
|
||||
is_full_size: () => false,
|
||||
set_focus: noop,
|
||||
compute_placeholder_text: noop,
|
||||
});
|
||||
const hash_util = mock_esm("../src/hash_util");
|
||||
const narrow_state = mock_esm("../src/narrow_state", {
|
||||
|
@ -68,16 +69,6 @@ const message_lists = zrequire("message_lists");
|
|||
const stream_data = zrequire("stream_data");
|
||||
const compose_recipient = zrequire("compose_recipient");
|
||||
|
||||
let stream_value = "";
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return stream_value;
|
||||
},
|
||||
render(val) {
|
||||
stream_value = val;
|
||||
},
|
||||
};
|
||||
|
||||
const start = compose_actions.start;
|
||||
const cancel = compose_actions.cancel;
|
||||
const respond_to_message = compose_actions.respond_to_message;
|
||||
|
@ -85,6 +76,7 @@ const reply_with_mention = compose_actions.reply_with_mention;
|
|||
const quote_and_reply = compose_actions.quote_and_reply;
|
||||
|
||||
compose_recipient.update_narrow_to_recipient_visibility = noop;
|
||||
compose_recipient.on_compose_select_recipient_update = noop;
|
||||
|
||||
function assert_visible(sel) {
|
||||
assert.ok($(sel).visible());
|
||||
|
@ -120,7 +112,7 @@ test("initial_state", () => {
|
|||
assert.equal(compose_state.has_message_content(), false);
|
||||
});
|
||||
|
||||
test("start", ({override, override_rewire}) => {
|
||||
test("start", ({override, override_rewire, mock_template}) => {
|
||||
mock_banners();
|
||||
override_private_message_recipient({override});
|
||||
override_rewire(compose_actions, "autosize_message_content", () => {});
|
||||
|
@ -130,6 +122,7 @@ test("start", ({override, override_rewire}) => {
|
|||
override_rewire(compose_actions, "clear_textarea", () => {});
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
override_rewire(compose_recipient, "check_stream_posting_policy_for_compose_box", () => {});
|
||||
mock_template("inline_decorated_stream_name.hbs", false, () => {});
|
||||
mock_stream_header_colorblock();
|
||||
|
||||
let compose_defaults;
|
||||
|
@ -137,7 +130,7 @@ test("start", ({override, override_rewire}) => {
|
|||
|
||||
// Start stream message
|
||||
compose_defaults = {
|
||||
stream: "stream1",
|
||||
stream: "",
|
||||
topic: "topic1",
|
||||
};
|
||||
|
||||
|
@ -147,7 +140,7 @@ test("start", ({override, override_rewire}) => {
|
|||
assert_visible("#stream_message_recipient_topic");
|
||||
assert_hidden("#compose-direct-recipient");
|
||||
|
||||
assert.equal(compose_state.stream_name(), "stream1");
|
||||
assert.equal(compose_state.stream_name(), "");
|
||||
assert.equal(compose_state.topic(), "topic1");
|
||||
assert.equal(compose_state.get_message_type(), "stream");
|
||||
assert.ok(compose_state.composing());
|
||||
|
@ -187,6 +180,7 @@ test("start", ({override, override_rewire}) => {
|
|||
};
|
||||
stream_data.add_sub(social);
|
||||
|
||||
compose_state.set_stream_name("");
|
||||
// More than 1 subscription, do not autofill
|
||||
opts = {};
|
||||
start("stream", opts);
|
||||
|
@ -246,12 +240,14 @@ test("start", ({override, override_rewire}) => {
|
|||
assert.ok(!compose_state.composing());
|
||||
});
|
||||
|
||||
test("respond_to_message", ({override, override_rewire}) => {
|
||||
test("respond_to_message", ({override, override_rewire, mock_template}) => {
|
||||
mock_banners();
|
||||
override_rewire(compose_actions, "complete_starting_tasks", () => {});
|
||||
override_rewire(compose_actions, "clear_textarea", () => {});
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", noop);
|
||||
override_rewire(compose_recipient, "check_stream_posting_policy_for_compose_box", noop);
|
||||
override_private_message_recipient({override});
|
||||
mock_template("inline_decorated_stream_name.hbs", false, () => {});
|
||||
mock_stream_header_colorblock();
|
||||
|
||||
// Test PM
|
||||
|
@ -278,17 +274,24 @@ test("respond_to_message", ({override, override_rewire}) => {
|
|||
// Test stream
|
||||
msg = {
|
||||
type: "stream",
|
||||
stream: "devel",
|
||||
stream: "Denmark",
|
||||
topic: "python",
|
||||
};
|
||||
|
||||
const denmark = {
|
||||
subscribed: true,
|
||||
color: "blue",
|
||||
name: "Denmark",
|
||||
stream_id: 1,
|
||||
};
|
||||
stream_data.add_sub(denmark);
|
||||
opts = {};
|
||||
|
||||
respond_to_message(opts);
|
||||
assert.equal(compose_state.stream_name(), "devel");
|
||||
assert.equal(compose_state.stream_name(), "Denmark");
|
||||
});
|
||||
|
||||
test("reply_with_mention", ({override, override_rewire}) => {
|
||||
test("reply_with_mention", ({override, override_rewire, mock_template}) => {
|
||||
mock_banners();
|
||||
mock_stream_header_colorblock();
|
||||
compose_state.set_message_type("stream");
|
||||
|
@ -296,10 +299,20 @@ test("reply_with_mention", ({override, override_rewire}) => {
|
|||
override_rewire(compose_actions, "complete_starting_tasks", () => {});
|
||||
override_rewire(compose_actions, "clear_textarea", () => {});
|
||||
override_private_message_recipient({override});
|
||||
override_rewire(compose_recipient, "check_stream_posting_policy_for_compose_box", noop);
|
||||
mock_template("inline_decorated_stream_name.hbs", false, () => {});
|
||||
|
||||
const denmark = {
|
||||
subscribed: true,
|
||||
color: "blue",
|
||||
name: "Denmark",
|
||||
stream_id: 1,
|
||||
};
|
||||
stream_data.add_sub(denmark);
|
||||
|
||||
const msg = {
|
||||
type: "stream",
|
||||
stream: "devel",
|
||||
stream: "Denmark",
|
||||
topic: "python",
|
||||
sender_full_name: "Bob Roberts",
|
||||
sender_id: 40,
|
||||
|
@ -314,7 +327,7 @@ test("reply_with_mention", ({override, override_rewire}) => {
|
|||
const opts = {};
|
||||
|
||||
reply_with_mention(opts);
|
||||
assert.equal(compose_state.stream_name(), "devel");
|
||||
assert.equal(compose_state.stream_name(), "Denmark");
|
||||
assert.equal(syntax_to_insert, "@**Bob Roberts**");
|
||||
|
||||
// Test for extended mention syntax
|
||||
|
@ -332,7 +345,7 @@ test("reply_with_mention", ({override, override_rewire}) => {
|
|||
people.add_active_user(bob_2);
|
||||
|
||||
reply_with_mention(opts);
|
||||
assert.equal(compose_state.stream_name(), "devel");
|
||||
assert.equal(compose_state.stream_name(), "Denmark");
|
||||
assert.equal(syntax_to_insert, "@**Bob Roberts|40**");
|
||||
});
|
||||
|
||||
|
@ -364,7 +377,7 @@ test("quote_and_reply", ({disallow, override, override_rewire}) => {
|
|||
|
||||
selected_message = {
|
||||
type: "stream",
|
||||
stream: "devel",
|
||||
stream: "Denmark",
|
||||
topic: "python",
|
||||
sender_full_name: "Steve Stephenson",
|
||||
sender_id: 90,
|
||||
|
@ -403,7 +416,7 @@ test("quote_and_reply", ({disallow, override, override_rewire}) => {
|
|||
|
||||
selected_message = {
|
||||
type: "stream",
|
||||
stream: "devel",
|
||||
stream: "Denmark",
|
||||
topic: "test",
|
||||
sender_full_name: "Steve Stephenson",
|
||||
sender_id: 90,
|
||||
|
@ -417,7 +430,7 @@ test("quote_and_reply", ({disallow, override, override_rewire}) => {
|
|||
|
||||
selected_message = {
|
||||
type: "stream",
|
||||
stream: "devel",
|
||||
stream: "Denmark",
|
||||
topic: "test",
|
||||
sender_full_name: "Steve Stephenson",
|
||||
sender_id: 90,
|
||||
|
|
|
@ -25,12 +25,10 @@ const people = zrequire("people");
|
|||
const compose_fade = zrequire("compose_fade");
|
||||
const compose_recipient = zrequire("compose_recipient");
|
||||
const compose_fade_helper = zrequire("compose_fade_helper");
|
||||
const compose_state = zrequire("compose_state");
|
||||
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return "social";
|
||||
},
|
||||
};
|
||||
compose_recipient.selected_stream_name = "social";
|
||||
compose_recipient.is_direct_message_selected = false;
|
||||
|
||||
const me = {
|
||||
email: "me@example.com",
|
||||
|
@ -56,7 +54,8 @@ people.initialize_current_user(me.user_id);
|
|||
people.add_active_user(alice);
|
||||
people.add_active_user(bob);
|
||||
|
||||
run_test("set_focused_recipient", () => {
|
||||
run_test("set_focused_recipient", ({override_rewire}) => {
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
const sub = {
|
||||
stream_id: 101,
|
||||
name: "social",
|
||||
|
@ -72,6 +71,7 @@ run_test("set_focused_recipient", () => {
|
|||
assert.equal(compose_fade_helper.would_receive_message(bob.user_id), true);
|
||||
|
||||
stream_data.add_sub(sub);
|
||||
compose_state.set_stream_name("social");
|
||||
peer_data.set_subscribers(sub.stream_id, [me.user_id, alice.user_id]);
|
||||
compose_fade.set_focused_recipient("stream");
|
||||
|
||||
|
|
|
@ -12,19 +12,10 @@ const compose_pm_pill = mock_esm("../src/compose_pm_pill");
|
|||
const compose_state = zrequire("compose_state");
|
||||
const compose_fade = zrequire("compose_fade");
|
||||
const compose_recipient = zrequire("compose_recipient");
|
||||
const stream_data = zrequire("stream_data");
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
let stream_value = "";
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return stream_value;
|
||||
},
|
||||
render(val) {
|
||||
stream_value = val;
|
||||
},
|
||||
};
|
||||
|
||||
run_test("private_message_recipient", ({override}) => {
|
||||
let emails;
|
||||
override(compose_pm_pill, "set_from_emails", (value) => {
|
||||
|
@ -59,6 +50,7 @@ run_test("has_full_recipient", ({override, override_rewire}) => {
|
|||
compose_state.topic("foo");
|
||||
assert.equal(compose_state.has_full_recipient(), false);
|
||||
|
||||
stream_data.add_sub({name: "bar", stream_id: 99});
|
||||
compose_state.set_stream_name("bar");
|
||||
assert.equal(compose_state.has_full_recipient(), true);
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ const $ = require("./lib/zjquery");
|
|||
const {page_params} = require("./lib/zpage_params");
|
||||
|
||||
const channel = mock_esm("../src/channel");
|
||||
|
||||
const compose_banner = zrequire("compose_banner");
|
||||
const compose_pm_pill = zrequire("compose_pm_pill");
|
||||
const compose_state = zrequire("compose_state");
|
||||
|
@ -22,17 +21,7 @@ const resolved_topic = zrequire("../shared/src/resolved_topic");
|
|||
const settings_config = zrequire("settings_config");
|
||||
const settings_data = mock_esm("../src/settings_data");
|
||||
const stream_data = zrequire("stream_data");
|
||||
const compose_recipient = zrequire("compose_recipient");
|
||||
|
||||
let stream_value = "";
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return stream_value;
|
||||
},
|
||||
render(val) {
|
||||
stream_value = val;
|
||||
},
|
||||
};
|
||||
const compose_recipient = zrequire("/compose_recipient");
|
||||
|
||||
const me = {
|
||||
email: "me@example.com",
|
||||
|
@ -146,9 +135,8 @@ test_ui("validate_stream_message_address_info", ({mock_template}) => {
|
|||
assert.ok(subscription_error_rendered);
|
||||
});
|
||||
|
||||
test_ui("validate", ({mock_template}) => {
|
||||
compose_recipient.update_placeholder_text = () => {};
|
||||
compose_recipient.on_compose_select_recipient_update = () => {};
|
||||
test_ui("validate", ({override_rewire, mock_template}) => {
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
|
||||
function initialize_pm_pill() {
|
||||
$.clear_all_elements();
|
||||
|
@ -273,6 +261,11 @@ test_ui("validate", ({mock_template}) => {
|
|||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(empty_stream_error_rendered);
|
||||
|
||||
const denmark = {
|
||||
stream_id: 100,
|
||||
name: "Denmark",
|
||||
};
|
||||
stream_data.add_sub(denmark);
|
||||
compose_state.set_stream_name("Denmark");
|
||||
page_params.realm_mandatory_topics = true;
|
||||
compose_state.topic("");
|
||||
|
@ -372,6 +365,7 @@ test_ui("validate_stream_message", ({override_rewire, mock_template}) => {
|
|||
// we are separating it up in different test. Though their relative position
|
||||
// of execution should not be changed.
|
||||
mock_banners();
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
$("#compose_banners .wildcard_warning").length = 0;
|
||||
page_params.user_id = me.user_id;
|
||||
page_params.realm_mandatory_topics = false;
|
||||
|
@ -419,116 +413,129 @@ test_ui("validate_stream_message", ({override_rewire, mock_template}) => {
|
|||
assert.ok(wildcards_not_allowed_rendered);
|
||||
});
|
||||
|
||||
test_ui("test_validate_stream_message_post_policy_admin_only", ({mock_template}) => {
|
||||
// This test is in continuation with test_validate but it has been separated out
|
||||
// for better readability. Their relative position of execution should not be changed.
|
||||
// Although the position with respect to test_validate_stream_message does not matter
|
||||
// as different stream is used for this test.
|
||||
mock_banners();
|
||||
page_params.is_admin = false;
|
||||
const sub = {
|
||||
stream_id: 102,
|
||||
name: "stream102",
|
||||
subscribed: true,
|
||||
stream_post_policy: stream_data.stream_post_policy_values.admins.code,
|
||||
};
|
||||
test_ui(
|
||||
"test_validate_stream_message_post_policy_admin_only",
|
||||
({override_rewire, mock_template}) => {
|
||||
// This test is in continuation with test_validate but it has been separated out
|
||||
// for better readability. Their relative position of execution should not be changed.
|
||||
// Although the position with respect to test_validate_stream_message does not matter
|
||||
// as different stream is used for this test.
|
||||
mock_banners();
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
page_params.is_admin = false;
|
||||
const sub = {
|
||||
stream_id: 102,
|
||||
name: "stream102",
|
||||
subscribed: true,
|
||||
stream_post_policy: stream_data.stream_post_policy_values.admins.code,
|
||||
};
|
||||
|
||||
compose_state.topic("topic102");
|
||||
compose_state.set_stream_name("stream102");
|
||||
stream_data.add_sub(sub);
|
||||
stream_data.add_sub(sub);
|
||||
compose_state.topic("topic102");
|
||||
compose_state.set_stream_name("stream102");
|
||||
|
||||
let banner_rendered = false;
|
||||
mock_template("compose_banner/compose_banner.hbs", false, (data) => {
|
||||
assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
|
||||
assert.equal(
|
||||
data.banner_text,
|
||||
$t({
|
||||
defaultMessage: "You do not have permission to post in this stream.",
|
||||
}),
|
||||
);
|
||||
banner_rendered = true;
|
||||
});
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
let banner_rendered = false;
|
||||
mock_template("compose_banner/compose_banner.hbs", false, (data) => {
|
||||
assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
|
||||
assert.equal(
|
||||
data.banner_text,
|
||||
$t({
|
||||
defaultMessage: "You do not have permission to post in this stream.",
|
||||
}),
|
||||
);
|
||||
banner_rendered = true;
|
||||
});
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
|
||||
// Reset error message.
|
||||
compose_state.set_stream_name("social");
|
||||
// Reset error message.
|
||||
compose_state.set_stream_name("social");
|
||||
|
||||
page_params.is_admin = false;
|
||||
page_params.is_guest = true;
|
||||
page_params.is_admin = false;
|
||||
page_params.is_guest = true;
|
||||
|
||||
compose_state.topic("topic102");
|
||||
compose_state.set_stream_name("stream102");
|
||||
banner_rendered = false;
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
});
|
||||
compose_state.topic("topic102");
|
||||
compose_state.set_stream_name("stream102");
|
||||
banner_rendered = false;
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
},
|
||||
);
|
||||
|
||||
test_ui("test_validate_stream_message_post_policy_moderators_only", ({mock_template}) => {
|
||||
mock_banners();
|
||||
page_params.is_admin = false;
|
||||
page_params.is_moderator = false;
|
||||
page_params.is_guest = false;
|
||||
test_ui(
|
||||
"test_validate_stream_message_post_policy_moderators_only",
|
||||
({override_rewire, mock_template}) => {
|
||||
mock_banners();
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
|
||||
const sub = {
|
||||
stream_id: 104,
|
||||
name: "stream104",
|
||||
subscribed: true,
|
||||
stream_post_policy: stream_data.stream_post_policy_values.moderators.code,
|
||||
};
|
||||
page_params.is_admin = false;
|
||||
page_params.is_moderator = false;
|
||||
page_params.is_guest = false;
|
||||
|
||||
compose_state.topic("topic104");
|
||||
compose_state.set_stream_name("stream104");
|
||||
stream_data.add_sub(sub);
|
||||
let banner_rendered = false;
|
||||
mock_template("compose_banner/compose_banner.hbs", false, (data) => {
|
||||
assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
|
||||
assert.equal(
|
||||
data.banner_text,
|
||||
$t({
|
||||
defaultMessage: "You do not have permission to post in this stream.",
|
||||
}),
|
||||
);
|
||||
banner_rendered = true;
|
||||
});
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
// Reset error message.
|
||||
compose_state.set_stream_name("social");
|
||||
const sub = {
|
||||
stream_id: 104,
|
||||
name: "stream104",
|
||||
subscribed: true,
|
||||
stream_post_policy: stream_data.stream_post_policy_values.moderators.code,
|
||||
};
|
||||
|
||||
page_params.is_guest = true;
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
});
|
||||
stream_data.add_sub(sub);
|
||||
compose_state.topic("topic104");
|
||||
compose_state.set_stream_name("stream104");
|
||||
let banner_rendered = false;
|
||||
mock_template("compose_banner/compose_banner.hbs", false, (data) => {
|
||||
assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
|
||||
assert.equal(
|
||||
data.banner_text,
|
||||
$t({
|
||||
defaultMessage: "You do not have permission to post in this stream.",
|
||||
}),
|
||||
);
|
||||
banner_rendered = true;
|
||||
});
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
// Reset error message.
|
||||
compose_state.set_stream_name("social");
|
||||
|
||||
test_ui("test_validate_stream_message_post_policy_full_members_only", ({mock_template}) => {
|
||||
mock_banners();
|
||||
page_params.is_admin = false;
|
||||
page_params.is_guest = true;
|
||||
const sub = {
|
||||
stream_id: 103,
|
||||
name: "stream103",
|
||||
subscribed: true,
|
||||
stream_post_policy: stream_data.stream_post_policy_values.non_new_members.code,
|
||||
};
|
||||
page_params.is_guest = true;
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
},
|
||||
);
|
||||
|
||||
compose_state.topic("topic103");
|
||||
compose_state.set_stream_name("stream103");
|
||||
stream_data.add_sub(sub);
|
||||
let banner_rendered = false;
|
||||
mock_template("compose_banner/compose_banner.hbs", false, (data) => {
|
||||
assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
|
||||
assert.equal(
|
||||
data.banner_text,
|
||||
$t({
|
||||
defaultMessage: "You do not have permission to post in this stream.",
|
||||
}),
|
||||
);
|
||||
banner_rendered = true;
|
||||
});
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
});
|
||||
test_ui(
|
||||
"test_validate_stream_message_post_policy_full_members_only",
|
||||
({override_rewire, mock_template}) => {
|
||||
mock_banners();
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
page_params.is_admin = false;
|
||||
page_params.is_guest = true;
|
||||
const sub = {
|
||||
stream_id: 103,
|
||||
name: "stream103",
|
||||
subscribed: true,
|
||||
stream_post_policy: stream_data.stream_post_policy_values.non_new_members.code,
|
||||
};
|
||||
|
||||
stream_data.add_sub(sub);
|
||||
compose_state.topic("topic103");
|
||||
compose_state.set_stream_name("stream103");
|
||||
let banner_rendered = false;
|
||||
mock_template("compose_banner/compose_banner.hbs", false, (data) => {
|
||||
assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
|
||||
assert.equal(
|
||||
data.banner_text,
|
||||
$t({
|
||||
defaultMessage: "You do not have permission to post in this stream.",
|
||||
}),
|
||||
);
|
||||
banner_rendered = true;
|
||||
});
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(banner_rendered);
|
||||
},
|
||||
);
|
||||
|
||||
test_ui("test_check_overflow_text", ({mock_template}) => {
|
||||
mock_banners();
|
||||
|
@ -665,9 +672,10 @@ test_ui("warn_if_private_stream_is_linked", ({mock_template}) => {
|
|||
assert.ok(banner_rendered);
|
||||
});
|
||||
|
||||
test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
||||
test_ui("warn_if_mentioning_unsubscribed_user", ({override, override_rewire, mock_template}) => {
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
const $textarea = $("<textarea>").attr("id", "compose-textarea");
|
||||
stream_value = "";
|
||||
compose_state.set_stream_name("");
|
||||
override(settings_data, "user_can_subscribe_other_users", () => true);
|
||||
|
||||
let mentioned_details = {
|
||||
|
@ -707,11 +715,12 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
|||
compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details, $textarea);
|
||||
assert.ok(!new_banner_rendered);
|
||||
|
||||
compose_state.set_stream_name("random");
|
||||
const sub = {
|
||||
stream_id: 111,
|
||||
name: "random",
|
||||
};
|
||||
stream_data.add_sub(sub);
|
||||
compose_state.set_stream_name("random");
|
||||
|
||||
// Test with invalid stream in compose box. It should return noop.
|
||||
new_banner_rendered = false;
|
||||
|
@ -726,7 +735,6 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
|||
};
|
||||
people.add_active_user(mentioned_details);
|
||||
|
||||
stream_data.add_sub(sub);
|
||||
new_banner_rendered = false;
|
||||
const $banner_container = $("#compose_banners");
|
||||
$banner_container.set_find_results(".recipient_not_subscribed", []);
|
||||
|
@ -752,8 +760,9 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
|||
assert.ok(!new_banner_rendered);
|
||||
});
|
||||
|
||||
test_ui("test warn_if_topic_resolved", ({override, mock_template}) => {
|
||||
test_ui("test warn_if_topic_resolved", ({override, override_rewire, mock_template}) => {
|
||||
mock_banners();
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
$("#compose_banners .topic_resolved").length = 0;
|
||||
override(settings_data, "user_can_move_messages_to_another_topic", () => true);
|
||||
|
||||
|
@ -778,6 +787,7 @@ test_ui("test warn_if_topic_resolved", ({override, mock_template}) => {
|
|||
stream_data.add_sub(sub);
|
||||
|
||||
compose_state.set_message_type("stream");
|
||||
blueslip.expect("error", "Unable to select stream: Do not exist");
|
||||
compose_state.set_stream_name("Do not exist");
|
||||
compose_state.topic(resolved_topic.resolve_name("hello"));
|
||||
compose_state.message_content("content");
|
||||
|
|
|
@ -56,16 +56,6 @@ const ct = composebox_typeahead;
|
|||
// broadcast-mentions/persons/groups.
|
||||
ct.__Rewire__("max_num_items", 15);
|
||||
|
||||
let stream_value = "";
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return stream_value;
|
||||
},
|
||||
render(val) {
|
||||
stream_value = val;
|
||||
},
|
||||
};
|
||||
|
||||
run_test("verify wildcard mentions typeahead for stream message", () => {
|
||||
const mention_all = ct.broadcast_mentions()[0];
|
||||
const mention_everyone = ct.broadcast_mentions()[1];
|
||||
|
|
|
@ -24,6 +24,7 @@ const stream_settings_ui = mock_esm("../src/stream_settings_ui");
|
|||
message_lists.current = {};
|
||||
|
||||
const compose_recipient = zrequire("compose_recipient");
|
||||
const compose_state = zrequire("compose_state");
|
||||
const peer_data = zrequire("peer_data");
|
||||
const people = zrequire("people");
|
||||
const server_events_dispatch = zrequire("server_events_dispatch");
|
||||
|
@ -198,9 +199,7 @@ test("stream create", ({override}) => {
|
|||
assert.deepEqual(sub_store.get(102).name, "test");
|
||||
});
|
||||
|
||||
test("stream delete (normal)", ({override, override_rewire}) => {
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
|
||||
test("stream delete (normal)", ({override}) => {
|
||||
const event = event_fixtures.stream__delete;
|
||||
|
||||
for (const stream of event.streams) {
|
||||
|
@ -241,9 +240,7 @@ test("stream delete (normal)", ({override, override_rewire}) => {
|
|||
assert.equal(removed_sidebar_rows, 1);
|
||||
});
|
||||
|
||||
test("stream delete (special streams)", ({override, override_rewire}) => {
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
|
||||
test("stream delete (special streams)", ({override}) => {
|
||||
const event = event_fixtures.stream__delete;
|
||||
|
||||
for (const stream of event.streams) {
|
||||
|
@ -267,3 +264,48 @@ test("stream delete (special streams)", ({override, override_rewire}) => {
|
|||
assert.equal(page_params.realm_notifications_stream_id, -1);
|
||||
assert.equal(page_params.realm_signup_notifications_stream_id, -1);
|
||||
});
|
||||
|
||||
test("stream delete (stream is selected in compose)", ({override, override_rewire}) => {
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
|
||||
const event = event_fixtures.stream__delete;
|
||||
|
||||
for (const stream of event.streams) {
|
||||
stream_data.add_sub(stream);
|
||||
}
|
||||
|
||||
stream_data.subscribe_myself(event.streams[0]);
|
||||
compose_state.set_stream_name(event.streams[0].name);
|
||||
|
||||
override(settings_streams, "update_default_streams_table", noop);
|
||||
|
||||
narrow_state.is_for_stream_id = () => true;
|
||||
|
||||
let bookend_updates = 0;
|
||||
override(message_lists.current, "update_trailing_bookend", () => {
|
||||
bookend_updates += 1;
|
||||
});
|
||||
|
||||
const removed_stream_ids = [];
|
||||
|
||||
override(stream_settings_ui, "remove_stream", (stream_id) => {
|
||||
removed_stream_ids.push(stream_id);
|
||||
});
|
||||
|
||||
let removed_sidebar_rows = 0;
|
||||
override(stream_list, "remove_sidebar_row", () => {
|
||||
removed_sidebar_rows += 1;
|
||||
});
|
||||
override(stream_list, "update_subscribe_to_more_streams_link", noop);
|
||||
|
||||
dispatch(event);
|
||||
|
||||
assert.equal(compose_state.stream_name(), "");
|
||||
assert.deepEqual(removed_stream_ids, [event.streams[0].stream_id, event.streams[1].stream_id]);
|
||||
|
||||
// We should possibly be able to make a single call to
|
||||
// update_trailing_bookend, but we currently do it for each stream.
|
||||
assert.equal(bookend_updates, 2);
|
||||
|
||||
assert.equal(removed_sidebar_rows, 1);
|
||||
});
|
||||
|
|
|
@ -19,16 +19,6 @@ const compose_recipient = zrequire("compose_recipient");
|
|||
const sub_store = zrequire("sub_store");
|
||||
const stream_data = zrequire("stream_data");
|
||||
|
||||
let stream_value = "";
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return stream_value;
|
||||
},
|
||||
render(val) {
|
||||
stream_value = val;
|
||||
},
|
||||
};
|
||||
|
||||
const aaron = {
|
||||
email: "aaron@zulip.com",
|
||||
user_id: 6,
|
||||
|
@ -167,6 +157,7 @@ test("snapshot_message", ({override_rewire}) => {
|
|||
override_rewire(user_pill, "get_user_ids", () => [aaron.user_id]);
|
||||
override_rewire(compose_pm_pill, "set_from_emails", noop);
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
compose_recipient.set_compose_recipient_id = () => {};
|
||||
mock_banners();
|
||||
|
||||
stream_data.get_sub = (stream_name) => {
|
||||
|
@ -184,11 +175,22 @@ test("snapshot_message", ({override_rewire}) => {
|
|||
function set_compose_state() {
|
||||
compose_state.set_message_type(curr_draft.type);
|
||||
compose_state.message_content(curr_draft.content);
|
||||
compose_state.set_stream_name(curr_draft.stream);
|
||||
if (curr_draft.type === "private") {
|
||||
compose_recipient.set_compose_recipient_id(compose_recipient.DIRECT_MESSAGE_ID);
|
||||
} else {
|
||||
compose_state.set_stream_name(curr_draft.stream);
|
||||
}
|
||||
compose_state.topic(curr_draft.topic);
|
||||
compose_state.private_message_recipient(curr_draft.private_message_recipient);
|
||||
}
|
||||
|
||||
const stream = {
|
||||
stream_id: draft_1.stream_id,
|
||||
name: draft_1.stream,
|
||||
};
|
||||
stream_data.add_sub(stream);
|
||||
compose_state.set_stream_name("stream");
|
||||
|
||||
curr_draft = draft_1;
|
||||
set_compose_state();
|
||||
assert.deepEqual(drafts.snapshot_message(), draft_1);
|
||||
|
|
|
@ -27,16 +27,6 @@ const recent_topics_util = mock_esm("../src/recent_topics_util", {
|
|||
is_visible() {},
|
||||
});
|
||||
|
||||
let stream_value = "";
|
||||
compose_recipient.compose_recipient_widget = {
|
||||
value() {
|
||||
return stream_value;
|
||||
},
|
||||
render(val) {
|
||||
stream_value = val;
|
||||
},
|
||||
};
|
||||
|
||||
function empty_narrow_html(title, html, search_data) {
|
||||
const opts = {
|
||||
title,
|
||||
|
@ -668,8 +658,8 @@ run_test("show_invalid_narrow_message", ({mock_template}) => {
|
|||
);
|
||||
});
|
||||
|
||||
run_test("narrow_to_compose_target errors", ({disallow_rewire}) => {
|
||||
compose_recipient.on_compose_select_recipient_update = () => {};
|
||||
run_test("narrow_to_compose_target errors", ({override_rewire, disallow_rewire}) => {
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
disallow_rewire(narrow, "activate");
|
||||
|
||||
// No-op when not composing.
|
||||
|
@ -683,6 +673,7 @@ run_test("narrow_to_compose_target errors", ({disallow_rewire}) => {
|
|||
});
|
||||
|
||||
run_test("narrow_to_compose_target streams", ({override_rewire}) => {
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", () => {});
|
||||
const args = {called: false};
|
||||
override_rewire(narrow, "activate", (operators, opts) => {
|
||||
args.operators = operators;
|
||||
|
|
|
@ -88,8 +88,8 @@ function test(label, f) {
|
|||
}
|
||||
|
||||
test("update_property", ({override, override_rewire}) => {
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
override_rewire(compose_recipient, "possibly_update_dropdown_selection", noop);
|
||||
override_rewire(compose_recipient, "possibly_update_stream_name_in_compose", noop);
|
||||
override_rewire(compose_recipient, "on_compose_select_recipient_update", noop);
|
||||
|
||||
const sub = {...frontend};
|
||||
stream_data.add_sub(sub);
|
||||
|
@ -280,11 +280,10 @@ test("marked_subscribed (error)", () => {
|
|||
blueslip.reset();
|
||||
});
|
||||
|
||||
test("marked_subscribed (normal)", ({override, override_rewire}) => {
|
||||
test("marked_subscribed (normal)", ({override}) => {
|
||||
const sub = {...frontend};
|
||||
stream_data.add_sub(sub);
|
||||
override(stream_color, "update_stream_color", noop);
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
|
||||
narrow_to_frontend();
|
||||
|
||||
|
@ -319,11 +318,10 @@ test("marked_subscribed (normal)", ({override, override_rewire}) => {
|
|||
narrow_state.reset_current_filter();
|
||||
});
|
||||
|
||||
test("marked_subscribed (color)", ({override, override_rewire}) => {
|
||||
test("marked_subscribed (color)", ({override}) => {
|
||||
override(stream_list, "add_sidebar_row", noop);
|
||||
override(stream_list, "update_subscribe_to_more_streams_link", noop);
|
||||
override(unread_ui, "update_unread_counts", noop);
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
|
||||
const sub = {
|
||||
subscribed: false,
|
||||
|
@ -352,11 +350,10 @@ test("marked_subscribed (color)", ({override, override_rewire}) => {
|
|||
}
|
||||
});
|
||||
|
||||
test("marked_subscribed (emails)", ({override, override_rewire}) => {
|
||||
test("marked_subscribed (emails)", ({override}) => {
|
||||
const sub = {...frontend};
|
||||
stream_data.add_sub(sub);
|
||||
override(stream_color, "update_stream_color", noop);
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
|
||||
// Test assigning subscriber emails
|
||||
// narrow state is undefined
|
||||
|
@ -380,7 +377,7 @@ test("marked_subscribed (emails)", ({override, override_rewire}) => {
|
|||
assert.deepEqual(sub, args.sub);
|
||||
});
|
||||
|
||||
test("mark_unsubscribed (update_settings_for_unsubscribed)", ({override, override_rewire}) => {
|
||||
test("mark_unsubscribed (update_settings_for_unsubscribed)", ({override}) => {
|
||||
// Test unsubscribe
|
||||
const sub = {...dev_help};
|
||||
stream_data.add_sub(sub);
|
||||
|
@ -395,13 +392,12 @@ test("mark_unsubscribed (update_settings_for_unsubscribed)", ({override, overrid
|
|||
|
||||
$("#streams_overlay_container .stream-row:not(.notdisplayed)").length = 0;
|
||||
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
stream_events.mark_unsubscribed(sub);
|
||||
const args = stub.get_args("sub");
|
||||
assert.deepEqual(args.sub, sub);
|
||||
});
|
||||
|
||||
test("mark_unsubscribed (render_title_area)", ({override, override_rewire}) => {
|
||||
test("mark_unsubscribed (render_title_area)", ({override}) => {
|
||||
const sub = {...frontend, subscribed: true};
|
||||
stream_data.add_sub(sub);
|
||||
|
||||
|
@ -422,7 +418,6 @@ test("mark_unsubscribed (render_title_area)", ({override, override_rewire}) => {
|
|||
|
||||
$("#streams_overlay_container .stream-row:not(.notdisplayed)").length = 0;
|
||||
|
||||
override_rewire(compose_recipient, "update_stream_dropdown_options", noop);
|
||||
stream_events.mark_unsubscribed(sub);
|
||||
|
||||
assert.equal(message_view_header_stub.num_calls, 1);
|
||||
|
|
Loading…
Reference in New Issue