mirror of https://github.com/zulip/zulip.git
web: Add setters for rewired variables.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
e2cc125583
commit
52e59a9605
|
@ -55,19 +55,27 @@ function same_recipient(a: Recipient | null, b: Recipient | null): boolean {
|
||||||
/** Exported only for tests. */
|
/** Exported only for tests. */
|
||||||
export let state: TypingStatusState | null = null;
|
export let state: TypingStatusState | null = null;
|
||||||
|
|
||||||
|
export function rewire_state(value: typeof state): void {
|
||||||
|
state = value;
|
||||||
|
}
|
||||||
|
|
||||||
/** Exported only for tests. */
|
/** Exported only for tests. */
|
||||||
export function stop_last_notification(worker: TypingStatusWorker): void {
|
export let stop_last_notification = (worker: TypingStatusWorker): void => {
|
||||||
assert(state !== null, "State object should not be null here.");
|
assert(state !== null, "State object should not be null here.");
|
||||||
clearTimeout(state.idle_timer);
|
clearTimeout(state.idle_timer);
|
||||||
worker.notify_server_stop(state.current_recipient);
|
worker.notify_server_stop(state.current_recipient);
|
||||||
state = null;
|
state = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_stop_last_notification(value: typeof stop_last_notification): void {
|
||||||
|
stop_last_notification = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Exported only for tests. */
|
/** Exported only for tests. */
|
||||||
export function start_or_extend_idle_timer(
|
export let start_or_extend_idle_timer = (
|
||||||
worker: TypingStatusWorker,
|
worker: TypingStatusWorker,
|
||||||
typing_stopped_wait_period: number,
|
typing_stopped_wait_period: number,
|
||||||
): ReturnType<typeof setTimeout> {
|
): ReturnType<typeof setTimeout> => {
|
||||||
function on_idle_timeout(): void {
|
function on_idle_timeout(): void {
|
||||||
// We don't do any real error checking here, because
|
// We don't do any real error checking here, because
|
||||||
// if we've been idle, we need to tell folks, and if
|
// if we've been idle, we need to tell folks, and if
|
||||||
|
@ -80,6 +88,10 @@ export function start_or_extend_idle_timer(
|
||||||
clearTimeout(state.idle_timer);
|
clearTimeout(state.idle_timer);
|
||||||
}
|
}
|
||||||
return setTimeout(on_idle_timeout, typing_stopped_wait_period);
|
return setTimeout(on_idle_timeout, typing_stopped_wait_period);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_start_or_extend_idle_timer(value: typeof start_or_extend_idle_timer): void {
|
||||||
|
start_or_extend_idle_timer = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_next_start_time(current_time: number, typing_started_wait_period: number): void {
|
function set_next_start_time(current_time: number, typing_started_wait_period: number): void {
|
||||||
|
@ -88,27 +100,35 @@ function set_next_start_time(current_time: number, typing_started_wait_period: n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported for tests
|
// Exported for tests
|
||||||
export function actually_ping_server(
|
export let actually_ping_server = (
|
||||||
worker: TypingStatusWorker,
|
worker: TypingStatusWorker,
|
||||||
recipient: Recipient,
|
recipient: Recipient,
|
||||||
current_time: number,
|
current_time: number,
|
||||||
typing_started_wait_period: number,
|
typing_started_wait_period: number,
|
||||||
): void {
|
): void => {
|
||||||
worker.notify_server_start(recipient);
|
worker.notify_server_start(recipient);
|
||||||
set_next_start_time(current_time, typing_started_wait_period);
|
set_next_start_time(current_time, typing_started_wait_period);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_actually_ping_server(value: typeof actually_ping_server): void {
|
||||||
|
actually_ping_server = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Exported only for tests. */
|
/** Exported only for tests. */
|
||||||
export function maybe_ping_server(
|
export let maybe_ping_server = (
|
||||||
worker: TypingStatusWorker,
|
worker: TypingStatusWorker,
|
||||||
recipient: Recipient,
|
recipient: Recipient,
|
||||||
typing_started_wait_period: number,
|
typing_started_wait_period: number,
|
||||||
): void {
|
): void => {
|
||||||
assert(state !== null, "State object should not be null here.");
|
assert(state !== null, "State object should not be null here.");
|
||||||
const current_time = worker.get_current_time();
|
const current_time = worker.get_current_time();
|
||||||
if (current_time > state.next_send_start_time) {
|
if (current_time > state.next_send_start_time) {
|
||||||
actually_ping_server(worker, recipient, current_time, typing_started_wait_period);
|
actually_ping_server(worker, recipient, current_time, typing_started_wait_period);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_maybe_ping_server(value: typeof maybe_ping_server): void {
|
||||||
|
maybe_ping_server = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -114,7 +114,7 @@ export function compute_active_status(): ActivityState {
|
||||||
return ActivityState.IDLE;
|
return ActivityState.IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function send_presence_to_server(redraw?: () => void): void {
|
export let send_presence_to_server = (redraw?: () => void): void => {
|
||||||
// Zulip has 2 data feeds coming from the server to the client:
|
// Zulip has 2 data feeds coming from the server to the client:
|
||||||
// The server_events data, and this presence feed. Data from
|
// The server_events data, and this presence feed. Data from
|
||||||
// server_events is nicely serialized, but if we've been offline
|
// server_events is nicely serialized, but if we've been offline
|
||||||
|
@ -180,6 +180,10 @@ export function send_presence_to_server(redraw?: () => void): void {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_send_presence_to_server(value: typeof send_presence_to_server): void {
|
||||||
|
send_presence_to_server = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mark_client_active(): void {
|
export function mark_client_active(): void {
|
||||||
|
|
|
@ -59,7 +59,7 @@ export function clear_for_testing(): void {
|
||||||
user_filter = undefined;
|
user_filter = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_presence_indicators(): void {
|
export let update_presence_indicators = (): void => {
|
||||||
$("[data-presence-indicator-user-id]").each(function () {
|
$("[data-presence-indicator-user-id]").each(function () {
|
||||||
const user_id = Number.parseInt($(this).attr("data-presence-indicator-user-id") ?? "", 10);
|
const user_id = Number.parseInt($(this).attr("data-presence-indicator-user-id") ?? "", 10);
|
||||||
assert(!Number.isNaN(user_id));
|
assert(!Number.isNaN(user_id));
|
||||||
|
@ -68,6 +68,10 @@ export function update_presence_indicators(): void {
|
||||||
.removeClass("user_circle_empty user_circle_green user_circle_idle")
|
.removeClass("user_circle_empty user_circle_green user_circle_idle")
|
||||||
.addClass(user_circle_class);
|
.addClass(user_circle_class);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_presence_indicators(value: typeof update_presence_indicators): void {
|
||||||
|
update_presence_indicators = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function redraw_user(user_id: number): void {
|
export function redraw_user(user_id: number): void {
|
||||||
|
@ -115,7 +119,7 @@ export function render_empty_user_list_message_if_needed($container: JQuery): vo
|
||||||
$container.append($(empty_list_widget_html));
|
$container.append($(empty_list_widget_html));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function build_user_sidebar(): number[] | undefined {
|
export let build_user_sidebar = (): number[] | undefined => {
|
||||||
if (realm.realm_presence_disabled) {
|
if (realm.realm_presence_disabled) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -131,6 +135,10 @@ export function build_user_sidebar(): number[] | undefined {
|
||||||
render_empty_user_list_message_if_needed(buddy_list.$other_users_list);
|
render_empty_user_list_message_if_needed(buddy_list.$other_users_list);
|
||||||
|
|
||||||
return all_user_ids; // for testing
|
return all_user_ids; // for testing
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_build_user_sidebar(value: typeof build_user_sidebar): void {
|
||||||
|
build_user_sidebar = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function do_update_users_for_search(): void {
|
function do_update_users_for_search(): void {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import * as ui_report from "./ui_report";
|
||||||
|
|
||||||
export let loaded = false;
|
export let loaded = false;
|
||||||
|
|
||||||
export function rerender_alert_words_ui(): void {
|
export let rerender_alert_words_ui = (): void => {
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,10 @@ export function rerender_alert_words_ui(): void {
|
||||||
...ListWidget.generic_sort_functions("alphabetic", ["word"]),
|
...ListWidget.generic_sort_functions("alphabetic", ["word"]),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_rerender_alert_words_ui(value: typeof rerender_alert_words_ui): void {
|
||||||
|
rerender_alert_words_ui = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_alert_word_status(status_text: string, is_error: boolean): void {
|
function update_alert_word_status(status_text: string, is_error: boolean): void {
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import {Filter} from "./filter";
|
import {Filter} from "./filter";
|
||||||
import {MessageListData} from "./message_list_data";
|
import {MessageListData} from "./message_list_data";
|
||||||
|
|
||||||
export const all_messages_data = new MessageListData({
|
export let all_messages_data = new MessageListData({
|
||||||
excludes_muted_topics: false,
|
excludes_muted_topics: false,
|
||||||
filter: new Filter([]),
|
filter: new Filter([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function rewire_all_messages_data(value: typeof all_messages_data): void {
|
||||||
|
all_messages_data = value;
|
||||||
|
}
|
||||||
|
|
|
@ -186,7 +186,11 @@ export function defaultSorter(items: string[], query: string): string[] {
|
||||||
return [...beginswith, ...caseSensitive, ...caseInsensitive];
|
return [...beginswith, ...caseSensitive, ...caseInsensitive];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MAX_ITEMS = 50;
|
export let MAX_ITEMS = 50;
|
||||||
|
|
||||||
|
export function rewire_MAX_ITEMS(value: typeof MAX_ITEMS): void {
|
||||||
|
MAX_ITEMS = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* TYPEAHEAD PUBLIC CLASS DEFINITION
|
/* TYPEAHEAD PUBLIC CLASS DEFINITION
|
||||||
* ================================= */
|
* ================================= */
|
||||||
|
|
|
@ -58,7 +58,7 @@ export function save_old_hash(): boolean {
|
||||||
return was_internal_change;
|
return was_internal_change;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update(new_hash: string): void {
|
export let update = (new_hash: string): void => {
|
||||||
const old_hash = window.location.hash;
|
const old_hash = window.location.hash;
|
||||||
|
|
||||||
if (!new_hash.startsWith("#")) {
|
if (!new_hash.startsWith("#")) {
|
||||||
|
@ -78,6 +78,10 @@ export function update(new_hash: string): void {
|
||||||
state.old_hash = old_hash;
|
state.old_hash = old_hash;
|
||||||
state.is_internal_change = true;
|
state.is_internal_change = true;
|
||||||
window.location.hash = new_hash;
|
window.location.hash = new_hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update(value: typeof update): void {
|
||||||
|
update = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function exit_overlay(): void {
|
export function exit_overlay(): void {
|
||||||
|
|
|
@ -27,8 +27,19 @@ import * as util from "./util";
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const max_size_before_shrinking = 600;
|
export let max_size_before_shrinking = 600;
|
||||||
export const max_channel_size_to_show_all_subscribers = 75;
|
|
||||||
|
export function rewire_max_size_before_shrinking(value: typeof max_size_before_shrinking): void {
|
||||||
|
max_size_before_shrinking = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export let max_channel_size_to_show_all_subscribers = 75;
|
||||||
|
|
||||||
|
export function rewire_max_channel_size_to_show_all_subscribers(
|
||||||
|
value: typeof max_channel_size_to_show_all_subscribers,
|
||||||
|
): void {
|
||||||
|
max_channel_size_to_show_all_subscribers = value;
|
||||||
|
}
|
||||||
|
|
||||||
let is_searching_users = false;
|
let is_searching_users = false;
|
||||||
|
|
||||||
|
@ -71,11 +82,11 @@ export function level(user_id: number): number {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function user_matches_narrow(
|
export let user_matches_narrow = (
|
||||||
user_id: number,
|
user_id: number,
|
||||||
pm_ids: Set<number>,
|
pm_ids: Set<number>,
|
||||||
stream_id?: number | null,
|
stream_id?: number | null,
|
||||||
): boolean {
|
): boolean => {
|
||||||
if (stream_id) {
|
if (stream_id) {
|
||||||
return stream_data.is_user_subscribed(stream_id, user_id);
|
return stream_data.is_user_subscribed(stream_id, user_id);
|
||||||
}
|
}
|
||||||
|
@ -83,6 +94,10 @@ export function user_matches_narrow(
|
||||||
return pm_ids.has(user_id) || people.is_my_user_id(user_id);
|
return pm_ids.has(user_id) || people.is_my_user_id(user_id);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_user_matches_narrow(value: typeof user_matches_narrow): void {
|
||||||
|
user_matches_narrow = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compare_function(
|
export function compare_function(
|
||||||
|
|
|
@ -170,7 +170,7 @@ export function send_message_success(request, data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function send_message(request = create_message_object()) {
|
export let send_message = (request = create_message_object()) => {
|
||||||
compose_state.set_recipient_edited_manually(false);
|
compose_state.set_recipient_edited_manually(false);
|
||||||
compose_state.set_is_content_unedited_restored_draft(false);
|
compose_state.set_is_content_unedited_restored_draft(false);
|
||||||
if (request.type === "private") {
|
if (request.type === "private") {
|
||||||
|
@ -269,6 +269,10 @@ export function send_message(request = create_message_object()) {
|
||||||
// taking a longtime to send.
|
// taking a longtime to send.
|
||||||
setTimeout(() => echo.display_slow_send_loading_spinner(message), 5000);
|
setTimeout(() => echo.display_slow_send_loading_spinner(message), 5000);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_send_message(value) {
|
||||||
|
send_message = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function enter_with_preview_open(ctrl_pressed = false) {
|
export function enter_with_preview_open(ctrl_pressed = false) {
|
||||||
|
@ -287,7 +291,7 @@ export function enter_with_preview_open(ctrl_pressed = false) {
|
||||||
// Common entrypoint for asking the server to send the message
|
// Common entrypoint for asking the server to send the message
|
||||||
// currently drafted in the compose box, including for scheduled
|
// currently drafted in the compose box, including for scheduled
|
||||||
// messages.
|
// messages.
|
||||||
export function finish(scheduling_message = false) {
|
export let finish = (scheduling_message = false) => {
|
||||||
if (compose_ui.compose_spinner_visible) {
|
if (compose_ui.compose_spinner_visible) {
|
||||||
// Avoid sending a message twice in parallel in races where
|
// Avoid sending a message twice in parallel in races where
|
||||||
// the user clicks the `Send` button very quickly twice or
|
// the user clicks the `Send` button very quickly twice or
|
||||||
|
@ -326,6 +330,10 @@ export function finish(scheduling_message = false) {
|
||||||
}
|
}
|
||||||
do_post_send_tasks();
|
do_post_send_tasks();
|
||||||
return true;
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_finish(value) {
|
||||||
|
finish = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function do_post_send_tasks() {
|
export function do_post_send_tasks() {
|
||||||
|
|
|
@ -70,8 +70,12 @@ function call_hooks(hooks: ComposeHook[]): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function blur_compose_inputs(): void {
|
export let blur_compose_inputs = (): void => {
|
||||||
$(".message_comp").find("input, textarea, button, #private_message_recipient").trigger("blur");
|
$(".message_comp").find("input, textarea, button, #private_message_recipient").trigger("blur");
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_blur_compose_inputs(value: typeof blur_compose_inputs): void {
|
||||||
|
blur_compose_inputs = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide_box(): void {
|
function hide_box(): void {
|
||||||
|
@ -109,8 +113,12 @@ function show_compose_box(opts: ComposeActionsOpts): void {
|
||||||
compose_ui.set_focus(opts_by_message_type);
|
compose_ui.set_focus(opts_by_message_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clear_textarea(): void {
|
export let clear_textarea = (): void => {
|
||||||
$("#compose").find("input[type=text], textarea").val("");
|
$("#compose").find("input[type=text], textarea").val("");
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_clear_textarea(value: typeof clear_textarea): void {
|
||||||
|
clear_textarea = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear_box(): void {
|
function clear_box(): void {
|
||||||
|
@ -135,7 +143,7 @@ function clear_box(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
let autosize_callback_opts: ComposeActionsStartOpts;
|
let autosize_callback_opts: ComposeActionsStartOpts;
|
||||||
export function autosize_message_content(opts: ComposeActionsStartOpts): void {
|
export let autosize_message_content = (opts: ComposeActionsStartOpts): void => {
|
||||||
if (!compose_ui.is_expanded()) {
|
if (!compose_ui.is_expanded()) {
|
||||||
autosize_callback_opts = opts;
|
autosize_callback_opts = opts;
|
||||||
let has_resized_once = false;
|
let has_resized_once = false;
|
||||||
|
@ -157,15 +165,23 @@ export function autosize_message_content(opts: ComposeActionsStartOpts): void {
|
||||||
});
|
});
|
||||||
autosize($("textarea#compose-textarea"));
|
autosize($("textarea#compose-textarea"));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_autosize_message_content(value: typeof autosize_message_content): void {
|
||||||
|
autosize_message_content = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function expand_compose_box(): void {
|
export let expand_compose_box = (): void => {
|
||||||
$("#compose_close").attr("data-tooltip-template-id", "compose_close_tooltip_template");
|
$("#compose_close").attr("data-tooltip-template-id", "compose_close_tooltip_template");
|
||||||
$("#compose_controls").hide();
|
$("#compose_controls").hide();
|
||||||
$(".message_comp").show();
|
$(".message_comp").show();
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_expand_compose_box(value: typeof expand_compose_box): void {
|
||||||
|
expand_compose_box = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function complete_starting_tasks(opts: ComposeActionsOpts): void {
|
export let complete_starting_tasks = (opts: ComposeActionsOpts): void => {
|
||||||
// This is sort of a kitchen sink function, and it's called only
|
// This is sort of a kitchen sink function, and it's called only
|
||||||
// by compose.start() for now. Having this as a separate function
|
// by compose.start() for now. Having this as a separate function
|
||||||
// makes testing a bit easier.
|
// makes testing a bit easier.
|
||||||
|
@ -182,6 +198,10 @@ export function complete_starting_tasks(opts: ComposeActionsOpts): void {
|
||||||
if (!narrow_state.narrowed_by_reply()) {
|
if (!narrow_state.narrowed_by_reply()) {
|
||||||
compose_notifications.maybe_show_one_time_interleaved_view_messages_fading_banner();
|
compose_notifications.maybe_show_one_time_interleaved_view_messages_fading_banner();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_complete_starting_tasks(value: typeof complete_starting_tasks): void {
|
||||||
|
complete_starting_tasks = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function maybe_scroll_up_selected_message(opts: ComposeActionsStartOpts): void {
|
export function maybe_scroll_up_selected_message(opts: ComposeActionsStartOpts): void {
|
||||||
|
@ -246,7 +266,7 @@ function same_recipient_as_before(opts: ComposeActionsOpts): boolean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function start(raw_opts: ComposeActionsStartOpts): void {
|
export let start = (raw_opts: ComposeActionsStartOpts): void => {
|
||||||
if (page_params.is_spectator) {
|
if (page_params.is_spectator) {
|
||||||
spectators.login_to_access();
|
spectators.login_to_access();
|
||||||
return;
|
return;
|
||||||
|
@ -390,9 +410,13 @@ export function start(raw_opts: ComposeActionsStartOpts): void {
|
||||||
resize.reset_compose_message_max_height();
|
resize.reset_compose_message_max_height();
|
||||||
|
|
||||||
complete_starting_tasks(opts);
|
complete_starting_tasks(opts);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_start(value: typeof start): void {
|
||||||
|
start = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cancel(): void {
|
export let cancel = (): void => {
|
||||||
// As user closes the compose box, restore the compose box max height
|
// As user closes the compose box, restore the compose box max height
|
||||||
if (compose_ui.is_expanded()) {
|
if (compose_ui.is_expanded()) {
|
||||||
compose_ui.make_compose_box_original_size();
|
compose_ui.make_compose_box_original_size();
|
||||||
|
@ -420,6 +444,10 @@ export function cancel(): void {
|
||||||
compose_state.set_message_type(undefined);
|
compose_state.set_message_type(undefined);
|
||||||
compose_pm_pill.clear();
|
compose_pm_pill.clear();
|
||||||
$(document).trigger("compose_canceled.zulip");
|
$(document).trigger("compose_canceled.zulip");
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_cancel(value: typeof cancel): void {
|
||||||
|
cancel = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function on_show_navigation_view(): void {
|
export function on_show_navigation_view(): void {
|
||||||
|
@ -440,7 +468,7 @@ export function on_show_navigation_view(): void {
|
||||||
cancel();
|
cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function on_topic_narrow(): void {
|
export let on_topic_narrow = (): void => {
|
||||||
if (!compose_state.composing()) {
|
if (!compose_state.composing()) {
|
||||||
// If our compose box is closed, then just
|
// If our compose box is closed, then just
|
||||||
// leave it closed, assuming that the user is
|
// leave it closed, assuming that the user is
|
||||||
|
@ -491,6 +519,10 @@ export function on_topic_narrow(): void {
|
||||||
compose_fade.update_message_list();
|
compose_fade.update_message_list();
|
||||||
drafts.update_compose_draft_count();
|
drafts.update_compose_draft_count();
|
||||||
$("textarea#compose-textarea").trigger("focus");
|
$("textarea#compose-textarea").trigger("focus");
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_on_topic_narrow(value: typeof on_topic_narrow): void {
|
||||||
|
on_topic_narrow = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO/typescript: Fill this in when converting narrow.js to typescripot.
|
// TODO/typescript: Fill this in when converting narrow.js to typescripot.
|
||||||
|
|
|
@ -91,10 +91,10 @@ export function update_or_append_banner(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clear_message_sent_banners(
|
export let clear_message_sent_banners = (
|
||||||
include_unmute_banner = true,
|
include_unmute_banner = true,
|
||||||
skip_automatic_new_visibility_policy_banner = false,
|
skip_automatic_new_visibility_policy_banner = false,
|
||||||
): void {
|
): void => {
|
||||||
for (const classname of Object.values(MESSAGE_SENT_CLASSNAMES)) {
|
for (const classname of Object.values(MESSAGE_SENT_CLASSNAMES)) {
|
||||||
if (
|
if (
|
||||||
skip_automatic_new_visibility_policy_banner &&
|
skip_automatic_new_visibility_policy_banner &&
|
||||||
|
@ -115,6 +115,10 @@ export function clear_message_sent_banners(
|
||||||
clear_unmute_topic_notifications();
|
clear_unmute_topic_notifications();
|
||||||
}
|
}
|
||||||
scroll_to_message_banner_message_id = null;
|
scroll_to_message_banner_message_id = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_clear_message_sent_banners(value: typeof clear_message_sent_banners): void {
|
||||||
|
clear_message_sent_banners = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Replace with compose_ui.hide_compose_spinner() when it is converted to ts.
|
// TODO: Replace with compose_ui.hide_compose_spinner() when it is converted to ts.
|
||||||
|
|
|
@ -61,7 +61,7 @@ export function get_recipient_label(message?: ComposeClosedMessage): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported for tests
|
// Exported for tests
|
||||||
export function update_reply_button_state(disable = false): void {
|
export let update_reply_button_state = (disable = false): void => {
|
||||||
$(".compose_reply_button").attr("disabled", disable ? "disabled" : null);
|
$(".compose_reply_button").attr("disabled", disable ? "disabled" : null);
|
||||||
if (disable) {
|
if (disable) {
|
||||||
$("#compose_buttons .compose-reply-button-wrapper").attr(
|
$("#compose_buttons .compose-reply-button-wrapper").attr(
|
||||||
|
@ -81,6 +81,10 @@ export function update_reply_button_state(disable = false): void {
|
||||||
"selected_conversation",
|
"selected_conversation",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_reply_button_state(value: typeof update_reply_button_state): void {
|
||||||
|
update_reply_button_state = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_buttons(disable_reply?: boolean): void {
|
function update_buttons(disable_reply?: boolean): void {
|
||||||
|
|
|
@ -63,10 +63,14 @@ export function set_from_typeahead(person: User): void {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set_from_emails(value: string): void {
|
export let set_from_emails = (value: string): void => {
|
||||||
// value is something like "alice@example.com,bob@example.com"
|
// value is something like "alice@example.com,bob@example.com"
|
||||||
clear();
|
clear();
|
||||||
widget.appendValue(value);
|
widget.appendValue(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_set_from_emails(value: typeof set_from_emails): void {
|
||||||
|
set_from_emails = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_user_ids(): number[] {
|
export function get_user_ids(): number[] {
|
||||||
|
@ -84,11 +88,15 @@ export function get_user_ids_string(): string {
|
||||||
return user_ids_string;
|
return user_ids_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_emails(): string {
|
export let get_emails = (): string => {
|
||||||
// return something like "alice@example.com,bob@example.com"
|
// return something like "alice@example.com,bob@example.com"
|
||||||
const user_ids = get_user_ids();
|
const user_ids = get_user_ids();
|
||||||
const emails = user_ids.map((id) => people.get_by_user_id(id).email).join(",");
|
const emails = user_ids.map((id) => people.get_by_user_id(id).email).join(",");
|
||||||
return emails;
|
return emails;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_emails(value: typeof get_emails): void {
|
||||||
|
get_emails = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filter_taken_users(persons: User[]): User[] {
|
export function filter_taken_users(persons: User[]): User[] {
|
||||||
|
|
|
@ -62,7 +62,7 @@ function composing_to_current_private_message_narrow(): boolean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_narrow_to_recipient_visibility(): void {
|
export let update_narrow_to_recipient_visibility = (): void => {
|
||||||
const message_type = compose_state.get_message_type();
|
const message_type = compose_state.get_message_type();
|
||||||
if (message_type === "stream") {
|
if (message_type === "stream") {
|
||||||
const stream_exists = Boolean(compose_state.stream_id());
|
const stream_exists = Boolean(compose_state.stream_id());
|
||||||
|
@ -87,6 +87,12 @@ export function update_narrow_to_recipient_visibility(): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(".conversation-arrow").toggleClass("narrow_to_compose_recipients", false);
|
$(".conversation-arrow").toggleClass("narrow_to_compose_recipients", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_narrow_to_recipient_visibility(
|
||||||
|
value: typeof update_narrow_to_recipient_visibility,
|
||||||
|
): void {
|
||||||
|
update_narrow_to_recipient_visibility = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_fade(): void {
|
function update_fade(): void {
|
||||||
|
@ -131,7 +137,7 @@ export function get_posting_policy_error_message(): string {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function check_posting_policy_for_compose_box(): void {
|
export let check_posting_policy_for_compose_box = (): void => {
|
||||||
const banner_text = get_posting_policy_error_message();
|
const banner_text = get_posting_policy_error_message();
|
||||||
if (banner_text === "") {
|
if (banner_text === "") {
|
||||||
compose_validate.set_recipient_disallowed(false);
|
compose_validate.set_recipient_disallowed(false);
|
||||||
|
@ -147,6 +153,12 @@ export function check_posting_policy_for_compose_box(): void {
|
||||||
} else {
|
} else {
|
||||||
compose_banner.show_error_message(banner_text, banner_classname, $("#compose_banners"));
|
compose_banner.show_error_message(banner_text, banner_classname, $("#compose_banners"));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_check_posting_policy_for_compose_box(
|
||||||
|
value: typeof check_posting_policy_for_compose_box,
|
||||||
|
): void {
|
||||||
|
check_posting_policy_for_compose_box = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function switch_message_type(message_type: MessageType): void {
|
function switch_message_type(message_type: MessageType): void {
|
||||||
|
@ -207,7 +219,7 @@ export function update_compose_for_message_type(opts: ComposeTriggeredOptions):
|
||||||
compose_banner.clear_uploads();
|
compose_banner.clear_uploads();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function on_compose_select_recipient_update(): void {
|
export let on_compose_select_recipient_update = (): void => {
|
||||||
const prev_message_type = compose_state.get_message_type();
|
const prev_message_type = compose_state.get_message_type();
|
||||||
|
|
||||||
let curr_message_type: MessageType = "stream";
|
let curr_message_type: MessageType = "stream";
|
||||||
|
@ -226,6 +238,12 @@ export function on_compose_select_recipient_update(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
update_on_recipient_change();
|
update_on_recipient_change();
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_on_compose_select_recipient_update(
|
||||||
|
value: typeof on_compose_select_recipient_update,
|
||||||
|
): void {
|
||||||
|
on_compose_select_recipient_update = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function possibly_update_stream_name_in_compose(stream_id: number): void {
|
export function possibly_update_stream_name_in_compose(stream_id: number): void {
|
||||||
|
@ -327,7 +345,7 @@ export function initialize(): void {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_placeholder_text(): void {
|
export let update_placeholder_text = (): void => {
|
||||||
const $textarea: JQuery<HTMLTextAreaElement> = $("textarea#compose-textarea");
|
const $textarea: JQuery<HTMLTextAreaElement> = $("textarea#compose-textarea");
|
||||||
// Change compose placeholder text only if compose box is open.
|
// Change compose placeholder text only if compose box is open.
|
||||||
if (!$textarea.is(":visible")) {
|
if (!$textarea.is(":visible")) {
|
||||||
|
@ -352,4 +370,8 @@ export function update_placeholder_text(): void {
|
||||||
|
|
||||||
$textarea.attr("placeholder", placeholder);
|
$textarea.attr("placeholder", placeholder);
|
||||||
compose_ui.autosize_textarea($textarea);
|
compose_ui.autosize_textarea($textarea);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_placeholder_text(value: typeof update_placeholder_text): void {
|
||||||
|
update_placeholder_text = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ import * as recent_view_util from "./recent_view_util";
|
||||||
import * as stream_data from "./stream_data";
|
import * as stream_data from "./stream_data";
|
||||||
import * as unread_ops from "./unread_ops";
|
import * as unread_ops from "./unread_ops";
|
||||||
|
|
||||||
export function respond_to_message(opts: {
|
export let respond_to_message = (opts: {
|
||||||
keep_composebox_empty?: boolean;
|
keep_composebox_empty?: boolean;
|
||||||
message_id?: number;
|
message_id?: number;
|
||||||
reply_type?: "personal";
|
reply_type?: "personal";
|
||||||
trigger?: string;
|
trigger?: string;
|
||||||
}): void {
|
}): void => {
|
||||||
let message;
|
let message;
|
||||||
let msg_type: "private" | "stream";
|
let msg_type: "private" | "stream";
|
||||||
if (recent_view_util.is_visible()) {
|
if (recent_view_util.is_visible()) {
|
||||||
|
@ -147,6 +147,10 @@ export function respond_to_message(opts: {
|
||||||
is_reply: true,
|
is_reply: true,
|
||||||
keep_composebox_empty: opts.keep_composebox_empty,
|
keep_composebox_empty: opts.keep_composebox_empty,
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_respond_to_message(value: typeof respond_to_message): void {
|
||||||
|
respond_to_message = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reply_with_mention(opts: {
|
export function reply_with_mention(opts: {
|
||||||
|
@ -166,7 +170,9 @@ export function reply_with_mention(opts: {
|
||||||
compose_ui.insert_syntax_and_focus(mention);
|
compose_ui.insert_syntax_and_focus(mention);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function selection_within_message_id(selection = window.getSelection()): number | undefined {
|
export let selection_within_message_id = (
|
||||||
|
selection = window.getSelection(),
|
||||||
|
): number | undefined => {
|
||||||
// Returns the message_id if the selection is entirely within a message,
|
// Returns the message_id if the selection is entirely within a message,
|
||||||
// otherwise returns undefined.
|
// otherwise returns undefined.
|
||||||
assert(selection !== null);
|
assert(selection !== null);
|
||||||
|
@ -178,6 +184,12 @@ export function selection_within_message_id(selection = window.getSelection()):
|
||||||
return start_id;
|
return start_id;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_selection_within_message_id(
|
||||||
|
value: typeof selection_within_message_id,
|
||||||
|
): void {
|
||||||
|
selection_within_message_id = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_quote_target(opts: {message_id?: number; quote_content?: string}): {
|
function get_quote_target(opts: {message_id?: number; quote_content?: string}): {
|
||||||
|
|
|
@ -106,12 +106,16 @@ export function stream_id(): number | undefined {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stream_name(): string {
|
export let stream_name = (): string => {
|
||||||
const stream_id = selected_recipient_id;
|
const stream_id = selected_recipient_id;
|
||||||
if (typeof stream_id === "number") {
|
if (typeof stream_id === "number") {
|
||||||
return sub_store.maybe_get_stream_name(stream_id) ?? "";
|
return sub_store.maybe_get_stream_name(stream_id) ?? "";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_stream_name(value: typeof stream_name): void {
|
||||||
|
stream_name = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set_stream_id(stream_id: number | ""): void {
|
export function set_stream_id(stream_id: number | ""): void {
|
||||||
|
|
|
@ -70,6 +70,11 @@ const message_render_response_schema = z.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export let compose_spinner_visible = false;
|
export let compose_spinner_visible = false;
|
||||||
|
|
||||||
|
export function rewire_compose_spinner_visible(value: typeof compose_spinner_visible): void {
|
||||||
|
compose_spinner_visible = value;
|
||||||
|
}
|
||||||
|
|
||||||
export let shift_pressed = false; // true or false
|
export let shift_pressed = false; // true or false
|
||||||
export let code_formatting_button_triggered = false; // true or false
|
export let code_formatting_button_triggered = false; // true or false
|
||||||
export let compose_textarea_typeahead: Typeahead<TypeaheadSuggestion> | undefined;
|
export let compose_textarea_typeahead: Typeahead<TypeaheadSuggestion> | undefined;
|
||||||
|
@ -102,20 +107,24 @@ export function is_full_size(): boolean {
|
||||||
return full_size_status;
|
return full_size_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function autosize_textarea($textarea: JQuery<HTMLTextAreaElement>): void {
|
export let autosize_textarea = ($textarea: JQuery<HTMLTextAreaElement>): void => {
|
||||||
// Since this supports both compose and file upload, one must pass
|
// Since this supports both compose and file upload, one must pass
|
||||||
// in the text area to autosize.
|
// in the text area to autosize.
|
||||||
if (!is_expanded()) {
|
if (!is_expanded()) {
|
||||||
autosize.update($textarea);
|
autosize.update($textarea);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_autosize_textarea(value: typeof autosize_textarea): void {
|
||||||
|
autosize_textarea = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function insert_and_scroll_into_view(
|
export let insert_and_scroll_into_view = (
|
||||||
content: string,
|
content: string,
|
||||||
$textarea: JQuery<HTMLTextAreaElement>,
|
$textarea: JQuery<HTMLTextAreaElement>,
|
||||||
replace_all = false,
|
replace_all = false,
|
||||||
replace_all_without_undo_support = false,
|
replace_all_without_undo_support = false,
|
||||||
): void {
|
): void => {
|
||||||
if (replace_all_without_undo_support) {
|
if (replace_all_without_undo_support) {
|
||||||
// setFieldText is very slow and noticeable when inserting 10k+
|
// setFieldText is very slow and noticeable when inserting 10k+
|
||||||
// characters of text like from a drafted response,
|
// characters of text like from a drafted response,
|
||||||
|
@ -132,6 +141,12 @@ export function insert_and_scroll_into_view(
|
||||||
$textarea.trigger("blur");
|
$textarea.trigger("blur");
|
||||||
$textarea.trigger("focus");
|
$textarea.trigger("focus");
|
||||||
autosize_textarea($textarea);
|
autosize_textarea($textarea);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_insert_and_scroll_into_view(
|
||||||
|
value: typeof insert_and_scroll_into_view,
|
||||||
|
): void {
|
||||||
|
insert_and_scroll_into_view = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_focus_area(opts: ComposeTriggeredOptions): string {
|
function get_focus_area(opts: ComposeTriggeredOptions): string {
|
||||||
|
@ -168,7 +183,7 @@ export function set_focus(opts: ComposeTriggeredOptions): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function smart_insert_inline($textarea: JQuery<HTMLTextAreaElement>, syntax: string): void {
|
export let smart_insert_inline = ($textarea: JQuery<HTMLTextAreaElement>, syntax: string): void => {
|
||||||
function is_space(c: string | undefined): boolean {
|
function is_space(c: string | undefined): boolean {
|
||||||
return c === " " || c === "\t" || c === "\n";
|
return c === " " || c === "\t" || c === "\n";
|
||||||
}
|
}
|
||||||
|
@ -200,6 +215,10 @@ export function smart_insert_inline($textarea: JQuery<HTMLTextAreaElement>, synt
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_and_scroll_into_view(syntax, $textarea);
|
insert_and_scroll_into_view(syntax, $textarea);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_smart_insert_inline(value: typeof smart_insert_inline): void {
|
||||||
|
smart_insert_inline = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function smart_insert_block(
|
export function smart_insert_block(
|
||||||
|
@ -252,12 +271,12 @@ export function smart_insert_block(
|
||||||
insert_and_scroll_into_view(syntax, $textarea);
|
insert_and_scroll_into_view(syntax, $textarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function insert_syntax_and_focus(
|
export let insert_syntax_and_focus = (
|
||||||
syntax: string,
|
syntax: string,
|
||||||
$textarea = $<HTMLTextAreaElement>("textarea#compose-textarea"),
|
$textarea = $<HTMLTextAreaElement>("textarea#compose-textarea"),
|
||||||
mode = "inline",
|
mode = "inline",
|
||||||
padding_newlines?: number,
|
padding_newlines?: number,
|
||||||
): void {
|
): void => {
|
||||||
// Generic helper for inserting syntax into the main compose box
|
// Generic helper for inserting syntax into the main compose box
|
||||||
// where the cursor was and focusing the area. Mostly a thin
|
// where the cursor was and focusing the area. Mostly a thin
|
||||||
// wrapper around smart_insert_inline and smart_inline_block.
|
// wrapper around smart_insert_inline and smart_inline_block.
|
||||||
|
@ -277,13 +296,17 @@ export function insert_syntax_and_focus(
|
||||||
} else if (mode === "block") {
|
} else if (mode === "block") {
|
||||||
smart_insert_block($textarea, syntax, padding_newlines);
|
smart_insert_block($textarea, syntax, padding_newlines);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_insert_syntax_and_focus(value: typeof insert_syntax_and_focus): void {
|
||||||
|
insert_syntax_and_focus = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function replace_syntax(
|
export let replace_syntax = (
|
||||||
old_syntax: string,
|
old_syntax: string,
|
||||||
new_syntax: string,
|
new_syntax: string,
|
||||||
$textarea = $<HTMLTextAreaElement>("textarea#compose-textarea"),
|
$textarea = $<HTMLTextAreaElement>("textarea#compose-textarea"),
|
||||||
): boolean {
|
): boolean => {
|
||||||
// The following couple lines are needed to later restore the initial
|
// The following couple lines are needed to later restore the initial
|
||||||
// logical position of the cursor after the replacement
|
// logical position of the cursor after the replacement
|
||||||
const prev_caret = $textarea.caret();
|
const prev_caret = $textarea.caret();
|
||||||
|
@ -322,6 +345,10 @@ export function replace_syntax(
|
||||||
|
|
||||||
// Return if anything was actually replaced.
|
// Return if anything was actually replaced.
|
||||||
return old_text !== new_text;
|
return old_text !== new_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_replace_syntax(value: typeof replace_syntax): void {
|
||||||
|
replace_syntax = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compute_placeholder_text(opts: ComposePlaceholderOptions): string {
|
export function compute_placeholder_text(opts: ComposePlaceholderOptions): string {
|
||||||
|
@ -374,7 +401,7 @@ export function compute_placeholder_text(opts: ComposePlaceholderOptions): strin
|
||||||
return DEFAULT_COMPOSE_PLACEHOLDER;
|
return DEFAULT_COMPOSE_PLACEHOLDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set_compose_box_top(set_top: boolean): void {
|
export let set_compose_box_top = (set_top: boolean): void => {
|
||||||
if (set_top) {
|
if (set_top) {
|
||||||
// As `#compose` has `position: fixed` property, we cannot
|
// As `#compose` has `position: fixed` property, we cannot
|
||||||
// make the compose-box to attain the correct height just by
|
// make the compose-box to attain the correct height just by
|
||||||
|
@ -386,6 +413,10 @@ export function set_compose_box_top(set_top: boolean): void {
|
||||||
} else {
|
} else {
|
||||||
$("#compose").css("top", "");
|
$("#compose").css("top", "");
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_set_compose_box_top(value: typeof set_compose_box_top): void {
|
||||||
|
set_compose_box_top = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function make_compose_box_full_size(): void {
|
export function make_compose_box_full_size(): void {
|
||||||
|
@ -504,11 +535,11 @@ export function position_inside_code_block(content: string, position: number): b
|
||||||
return [...code_blocks].some((code_block) => code_block?.textContent?.includes(unique_insert));
|
return [...code_blocks].some((code_block) => code_block?.textContent?.includes(unique_insert));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function format_text(
|
export let format_text = (
|
||||||
$textarea: JQuery<HTMLTextAreaElement>,
|
$textarea: JQuery<HTMLTextAreaElement>,
|
||||||
type: string,
|
type: string,
|
||||||
inserted_content = "",
|
inserted_content = "",
|
||||||
): void {
|
): void => {
|
||||||
const italic_syntax = "*";
|
const italic_syntax = "*";
|
||||||
const bold_syntax = "**";
|
const bold_syntax = "**";
|
||||||
const bold_and_italic_syntax = "***";
|
const bold_and_italic_syntax = "***";
|
||||||
|
@ -1156,6 +1187,10 @@ export function format_text(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_format_text(value: typeof format_text): void {
|
||||||
|
format_text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: This functions don't belong in this module, as they have
|
/* TODO: This functions don't belong in this module, as they have
|
||||||
|
|
|
@ -476,7 +476,7 @@ function is_recipient_large_topic(): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported for tests
|
// Exported for tests
|
||||||
export function wildcard_mention_policy_authorizes_user(): boolean {
|
export let wildcard_mention_policy_authorizes_user = (): boolean => {
|
||||||
if (
|
if (
|
||||||
realm.realm_wildcard_mention_policy ===
|
realm.realm_wildcard_mention_policy ===
|
||||||
settings_config.wildcard_mention_policy_values.by_everyone.code
|
settings_config.wildcard_mention_policy_values.by_everyone.code
|
||||||
|
@ -518,6 +518,12 @@ export function wildcard_mention_policy_authorizes_user(): boolean {
|
||||||
return days >= realm.realm_waiting_period_threshold && !current_user.is_guest;
|
return days >= realm.realm_waiting_period_threshold && !current_user.is_guest;
|
||||||
}
|
}
|
||||||
return !current_user.is_guest;
|
return !current_user.is_guest;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_wildcard_mention_policy_authorizes_user(
|
||||||
|
value: typeof wildcard_mention_policy_authorizes_user,
|
||||||
|
): void {
|
||||||
|
wildcard_mention_policy_authorizes_user = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stream_wildcard_mention_allowed(): boolean {
|
export function stream_wildcard_mention_allowed(): boolean {
|
||||||
|
|
|
@ -106,7 +106,11 @@ export type TypeaheadSuggestion =
|
||||||
| SlashCommandSuggestion;
|
| SlashCommandSuggestion;
|
||||||
|
|
||||||
// We export it to allow tests to mock it.
|
// We export it to allow tests to mock it.
|
||||||
export const max_num_items = MAX_ITEMS;
|
export let max_num_items = MAX_ITEMS;
|
||||||
|
|
||||||
|
export function rewire_max_num_items(value: typeof max_num_items): void {
|
||||||
|
max_num_items = value;
|
||||||
|
}
|
||||||
|
|
||||||
export let emoji_collection: Emoji[] = [];
|
export let emoji_collection: Emoji[] = [];
|
||||||
|
|
||||||
|
@ -389,9 +393,13 @@ function handle_keyup(e: JQuery.KeyUpEvent): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function split_at_cursor(query: string, $input: JQuery): [string, string] {
|
export let split_at_cursor = (query: string, $input: JQuery): [string, string] => {
|
||||||
const cursor = $input.caret();
|
const cursor = $input.caret();
|
||||||
return [query.slice(0, cursor), query.slice(cursor)];
|
return [query.slice(0, cursor), query.slice(cursor)];
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_split_at_cursor(value: typeof split_at_cursor): void {
|
||||||
|
split_at_cursor = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tokenize_compose_str(s: string): string {
|
export function tokenize_compose_str(s: string): string {
|
||||||
|
|
|
@ -22,9 +22,13 @@ import * as timerender from "./timerender";
|
||||||
import * as ui_util from "./ui_util";
|
import * as ui_util from "./ui_util";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
|
||||||
export function set_count(count: number): void {
|
export let set_count = (count: number): void => {
|
||||||
const $drafts_li = $(".top_left_drafts");
|
const $drafts_li = $(".top_left_drafts");
|
||||||
ui_util.update_unread_count_in_dom($drafts_li, count);
|
ui_util.update_unread_count_in_dom($drafts_li, count);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_set_count(value: typeof set_count): void {
|
||||||
|
set_count = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTimestamp(): number {
|
function getTimestamp(): number {
|
||||||
|
@ -219,7 +223,7 @@ export const draft_model = (function () {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export function update_compose_draft_count(): void {
|
export let update_compose_draft_count = (): void => {
|
||||||
const $count_container = $(".compose-drafts-count-container");
|
const $count_container = $(".compose-drafts-count-container");
|
||||||
const $count_ele = $count_container.find(".compose-drafts-count");
|
const $count_ele = $count_container.find(".compose-drafts-count");
|
||||||
if (!compose_state.has_full_recipient()) {
|
if (!compose_state.has_full_recipient()) {
|
||||||
|
@ -235,11 +239,19 @@ export function update_compose_draft_count(): void {
|
||||||
$count_ele.text("");
|
$count_ele.text("");
|
||||||
$count_container.hide();
|
$count_container.hide();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_compose_draft_count(value: typeof update_compose_draft_count): void {
|
||||||
|
update_compose_draft_count = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sync_count(): void {
|
export let sync_count = (): void => {
|
||||||
const drafts = draft_model.get();
|
const drafts = draft_model.get();
|
||||||
set_count(Object.keys(drafts).length);
|
set_count(Object.keys(drafts).length);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_sync_count(value: typeof sync_count): void {
|
||||||
|
sync_count = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function delete_all_drafts(): void {
|
export function delete_all_drafts(): void {
|
||||||
|
@ -396,7 +408,7 @@ type UpdateDraftOptions = {
|
||||||
is_sending_saving?: boolean;
|
is_sending_saving?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function update_draft(opts: UpdateDraftOptions = {}): string | undefined {
|
export let update_draft = (opts: UpdateDraftOptions = {}): string | undefined => {
|
||||||
const draft_id = compose_draft_id;
|
const draft_id = compose_draft_id;
|
||||||
const old_draft = draft_id === undefined ? undefined : draft_model.getDraft(draft_id);
|
const old_draft = draft_id === undefined ? undefined : draft_model.getDraft(draft_id);
|
||||||
|
|
||||||
|
@ -439,6 +451,10 @@ export function update_draft(opts: UpdateDraftOptions = {}): string | undefined
|
||||||
maybe_notify(no_notify);
|
maybe_notify(no_notify);
|
||||||
|
|
||||||
return new_draft_id;
|
return new_draft_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_draft(value: typeof update_draft): void {
|
||||||
|
update_draft = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DRAFT_LIFETIME = 30;
|
export const DRAFT_LIFETIME = 30;
|
||||||
|
|
|
@ -288,14 +288,14 @@ export function is_slash_command(content: string): boolean {
|
||||||
return !content.startsWith("/me") && content.startsWith("/");
|
return !content.startsWith("/me") && content.startsWith("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function try_deliver_locally(
|
export let try_deliver_locally = (
|
||||||
message_request: MessageRequest,
|
message_request: MessageRequest,
|
||||||
insert_new_messages: (
|
insert_new_messages: (
|
||||||
messages: LocalMessage[],
|
messages: LocalMessage[],
|
||||||
send_by_this_client: boolean,
|
send_by_this_client: boolean,
|
||||||
deliver_locally: boolean,
|
deliver_locally: boolean,
|
||||||
) => Message[],
|
) => Message[],
|
||||||
): Message | undefined {
|
): Message | undefined => {
|
||||||
// Checks if the message request can be locally echoed, and if so,
|
// Checks if the message request can be locally echoed, and if so,
|
||||||
// adds a local echoed copy of the message to appropriate message lists.
|
// adds a local echoed copy of the message to appropriate message lists.
|
||||||
//
|
//
|
||||||
|
@ -349,6 +349,10 @@ export function try_deliver_locally(
|
||||||
|
|
||||||
const message = insert_local_message(message_request, local_id_float, insert_new_messages);
|
const message = insert_local_message(message_request, local_id_float, insert_new_messages);
|
||||||
return message;
|
return message;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_try_deliver_locally(value: typeof try_deliver_locally): void {
|
||||||
|
try_deliver_locally = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function edit_locally(message: Message, request: LocalEditRequest): Message {
|
export function edit_locally(message: Message, request: LocalEditRequest): Message {
|
||||||
|
@ -432,7 +436,7 @@ export function edit_locally(message: Message, request: LocalEditRequest): Messa
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reify_message_id(local_id: string, server_id: number): void {
|
export let reify_message_id = (local_id: string, server_id: number): void => {
|
||||||
const message = echo_state.get_message_waiting_for_id(local_id);
|
const message = echo_state.get_message_waiting_for_id(local_id);
|
||||||
echo_state.remove_message_from_waiting_for_id(local_id);
|
echo_state.remove_message_from_waiting_for_id(local_id);
|
||||||
|
|
||||||
|
@ -463,6 +467,10 @@ export function reify_message_id(local_id: string, server_id: number): void {
|
||||||
message_id: message.id,
|
message_id: message.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_reify_message_id(value: typeof reify_message_id): void {
|
||||||
|
reify_message_id = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_message_lists({old_id, new_id}: {old_id: number; new_id: number}): void {
|
export function update_message_lists({old_id, new_id}: {old_id: number; new_id: number}): void {
|
||||||
|
@ -576,13 +584,17 @@ export function process_from_server(messages: ServerMessage[]): ServerMessage[]
|
||||||
return non_echo_messages;
|
return non_echo_messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function message_send_error(message_id: number, error_response: string): void {
|
export let message_send_error = (message_id: number, error_response: string): void => {
|
||||||
// Error sending message, show inline
|
// Error sending message, show inline
|
||||||
const message = message_store.get(message_id)!;
|
const message = message_store.get(message_id)!;
|
||||||
message.failed_request = true;
|
message.failed_request = true;
|
||||||
message.show_slow_send_spinner = false;
|
message.show_slow_send_spinner = false;
|
||||||
|
|
||||||
show_message_failed(message_id, error_response);
|
show_message_failed(message_id, error_response);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_message_send_error(value: typeof message_send_error): void {
|
||||||
|
message_send_error = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function abort_message(message: Message): void {
|
function abort_message(message: Message): void {
|
||||||
|
|
|
@ -250,7 +250,7 @@ export function get_keypress_hotkey(e) {
|
||||||
return keypress_mappings[e.which];
|
return keypress_mappings[e.which];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function processing_text() {
|
export let processing_text = () => {
|
||||||
const $focused_elt = $(":focus");
|
const $focused_elt = $(":focus");
|
||||||
return (
|
return (
|
||||||
$focused_elt.is("input") ||
|
$focused_elt.is("input") ||
|
||||||
|
@ -260,6 +260,10 @@ export function processing_text() {
|
||||||
$focused_elt.attr("id") === "compose-send-button" ||
|
$focused_elt.attr("id") === "compose-send-button" ||
|
||||||
$focused_elt.parents(".dropdown-list-container").length >= 1
|
$focused_elt.parents(".dropdown-list-container").length >= 1
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_processing_text(value) {
|
||||||
|
processing_text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function in_content_editable_widget(e) {
|
export function in_content_editable_widget(e) {
|
||||||
|
|
|
@ -103,11 +103,11 @@ export function update_current_view_for_topic_visibility() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_views_filtered_on_message_property(
|
export let update_views_filtered_on_message_property = (
|
||||||
message_ids,
|
message_ids,
|
||||||
property_term_type,
|
property_term_type,
|
||||||
property_value,
|
property_value,
|
||||||
) {
|
) => {
|
||||||
// NOTE: Call this function after updating the message property locally.
|
// NOTE: Call this function after updating the message property locally.
|
||||||
assert(!property_term_type.includes("not-"));
|
assert(!property_term_type.includes("not-"));
|
||||||
|
|
||||||
|
@ -212,6 +212,7 @@ export function update_views_filtered_on_message_property(
|
||||||
// can be used to update other message lists and
|
// can be used to update other message lists and
|
||||||
// cached message data structures as well.
|
// cached message data structures as well.
|
||||||
},
|
},
|
||||||
|
// eslint-disable-next-line no-loop-func
|
||||||
success(data) {
|
success(data) {
|
||||||
// `messages_to_fetch` might already be cached locally when
|
// `messages_to_fetch` might already be cached locally when
|
||||||
// we reach here but `message_helper.process_new_message`
|
// we reach here but `message_helper.process_new_message`
|
||||||
|
@ -258,6 +259,10 @@ export function update_views_filtered_on_message_property(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_views_filtered_on_message_property(value) {
|
||||||
|
update_views_filtered_on_message_property = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function insert_new_messages(messages, sent_by_this_client, deliver_locally) {
|
export function insert_new_messages(messages, sent_by_this_client, deliver_locally) {
|
||||||
|
|
|
@ -16,7 +16,11 @@ export function send_flag_update_for_messages(msg_ids: number[], flag: string, o
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
export const _unread_batch_size = 1000;
|
export let _unread_batch_size = 1000;
|
||||||
|
|
||||||
|
export function rewire__unread_batch_size(value: typeof _unread_batch_size): void {
|
||||||
|
_unread_batch_size = value;
|
||||||
|
}
|
||||||
|
|
||||||
export const send_read = (function () {
|
export const send_read = (function () {
|
||||||
let queue: Message[] = [];
|
let queue: Message[] = [];
|
||||||
|
|
|
@ -351,7 +351,7 @@ type ShowMessageViewOpts = {
|
||||||
show_more_topics?: boolean;
|
show_more_topics?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function show(raw_terms: NarrowTerm[], show_opts: ShowMessageViewOpts): void {
|
export let show = (raw_terms: NarrowTerm[], show_opts: ShowMessageViewOpts): void => {
|
||||||
/* Main entry point for switching to a new view / message list.
|
/* Main entry point for switching to a new view / message list.
|
||||||
|
|
||||||
Supported parameters:
|
Supported parameters:
|
||||||
|
@ -777,6 +777,10 @@ export function show(raw_terms: NarrowTerm[], show_opts: ShowMessageViewOpts): v
|
||||||
resize.resize_stream_filters_container();
|
resize.resize_stream_filters_container();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_show(value: typeof show): void {
|
||||||
|
show = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigate_to_anchor_message(opts: {
|
function navigate_to_anchor_message(opts: {
|
||||||
|
|
|
@ -114,7 +114,7 @@ export function set_compose_defaults(): {
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stream_id(current_filter: Filter | undefined = filter()): number | undefined {
|
export let stream_id = (current_filter: Filter | undefined = filter()): number | undefined => {
|
||||||
if (current_filter === undefined) {
|
if (current_filter === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,10 @@ export function stream_id(current_filter: Filter | undefined = filter()): number
|
||||||
return Number.parseInt(stream_operands[0], 10);
|
return Number.parseInt(stream_operands[0], 10);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_stream_id(value: typeof stream_id): void {
|
||||||
|
stream_id = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stream_name(current_filter: Filter | undefined = filter()): string | undefined {
|
export function stream_name(current_filter: Filter | undefined = filter()): string | undefined {
|
||||||
|
@ -148,7 +152,7 @@ export function stream_sub(
|
||||||
return stream_data.get_sub_by_id_string(stream_operands[0]);
|
return stream_data.get_sub_by_id_string(stream_operands[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function topic(current_filter: Filter | undefined = filter()): string | undefined {
|
export let topic = (current_filter: Filter | undefined = filter()): string | undefined => {
|
||||||
if (current_filter === undefined) {
|
if (current_filter === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +161,10 @@ export function topic(current_filter: Filter | undefined = filter()): string | u
|
||||||
return operands[0];
|
return operands[0];
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_topic(value: typeof topic): void {
|
||||||
|
topic = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pm_ids_string(filter?: Filter): string | undefined {
|
export function pm_ids_string(filter?: Filter): string | undefined {
|
||||||
|
@ -173,10 +181,14 @@ export function pm_ids_string(filter?: Filter): string | undefined {
|
||||||
return user_ids_string;
|
return user_ids_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pm_ids_set(filter?: Filter): Set<number> {
|
export let pm_ids_set = (filter?: Filter): Set<number> => {
|
||||||
const ids_string = pm_ids_string(filter);
|
const ids_string = pm_ids_string(filter);
|
||||||
const pm_ids_list = ids_string ? people.user_ids_string_to_ids_array(ids_string) : [];
|
const pm_ids_list = ids_string ? people.user_ids_string_to_ids_array(ids_string) : [];
|
||||||
return new Set(pm_ids_list);
|
return new Set(pm_ids_list);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_pm_ids_set(value: typeof pm_ids_set): void {
|
||||||
|
pm_ids_set = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pm_emails_string(
|
export function pm_emails_string(
|
||||||
|
@ -194,9 +206,9 @@ export function pm_emails_string(
|
||||||
return operands[0];
|
return operands[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_first_unread_info(
|
export let get_first_unread_info = (
|
||||||
current_filter: Filter | undefined = filter(),
|
current_filter: Filter | undefined = filter(),
|
||||||
): {flavor: "cannot_compute" | "not_found"} | {flavor: "found"; msg_id: number} {
|
): {flavor: "cannot_compute" | "not_found"} | {flavor: "found"; msg_id: number} => {
|
||||||
const cannot_compute_response: {flavor: "cannot_compute"} = {flavor: "cannot_compute"};
|
const cannot_compute_response: {flavor: "cannot_compute"} = {flavor: "cannot_compute"};
|
||||||
if (current_filter === undefined) {
|
if (current_filter === undefined) {
|
||||||
// we don't yet support the all-messages view
|
// we don't yet support the all-messages view
|
||||||
|
@ -231,11 +243,15 @@ export function get_first_unread_info(
|
||||||
flavor: "found",
|
flavor: "found",
|
||||||
msg_id,
|
msg_id,
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_first_unread_info(value: typeof get_first_unread_info): void {
|
||||||
|
get_first_unread_info = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _possible_unread_message_ids(
|
export let _possible_unread_message_ids = (
|
||||||
current_filter: Filter | undefined = filter(),
|
current_filter: Filter | undefined = filter(),
|
||||||
): number[] | undefined {
|
): number[] | undefined => {
|
||||||
// This function currently only returns valid results for
|
// This function currently only returns valid results for
|
||||||
// certain types of narrows, mostly left sidebar narrows.
|
// certain types of narrows, mostly left sidebar narrows.
|
||||||
// For more complicated narrows we may return undefined.
|
// For more complicated narrows we may return undefined.
|
||||||
|
@ -318,6 +334,12 @@ export function _possible_unread_message_ids(
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire__possible_unread_message_ids(
|
||||||
|
value: typeof _possible_unread_message_ids,
|
||||||
|
): void {
|
||||||
|
_possible_unread_message_ids = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we narrowed to direct messages: the direct message feed or a
|
// Are we narrowed to direct messages: the direct message feed or a
|
||||||
|
|
|
@ -69,7 +69,7 @@ export function potential_subscribers(stream_id: number): User[] {
|
||||||
return people.filter_all_users(is_potential_subscriber);
|
return people.filter_all_users(is_potential_subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_subscriber_count(stream_id: number, include_bots = true): number {
|
export let get_subscriber_count = (stream_id: number, include_bots = true): number => {
|
||||||
if (include_bots) {
|
if (include_bots) {
|
||||||
return get_user_set(stream_id).size;
|
return get_user_set(stream_id).size;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,10 @@ export function get_subscriber_count(stream_id: number, include_bots = true): nu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_subscriber_count(value: typeof get_subscriber_count): void {
|
||||||
|
get_subscriber_count = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_subscribers(stream_id: number): number[] {
|
export function get_subscribers(stream_id: number): number[] {
|
||||||
|
|
|
@ -89,10 +89,14 @@ export function get_users_from_ids(user_ids: number[]): User[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this function only when you are sure that user_id is valid.
|
// Use this function only when you are sure that user_id is valid.
|
||||||
export function get_by_user_id(user_id: number): User {
|
export let get_by_user_id = (user_id: number): User => {
|
||||||
const person = people_by_user_id_dict.get(user_id);
|
const person = people_by_user_id_dict.get(user_id);
|
||||||
assert(person, `Unknown user_id in get_by_user_id: ${user_id}`);
|
assert(person, `Unknown user_id in get_by_user_id: ${user_id}`);
|
||||||
return person;
|
return person;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_by_user_id(value: typeof get_by_user_id): void {
|
||||||
|
get_by_user_id = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is type unsafe version of get_by_user_id for the callers that expects undefined values.
|
// This is type unsafe version of get_by_user_id for the callers that expects undefined values.
|
||||||
|
@ -123,7 +127,7 @@ export function validate_user_ids(user_ids: number[]): number[] {
|
||||||
return good_ids;
|
return good_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_by_email(email: string): User | undefined {
|
export let get_by_email = (email: string): User | undefined => {
|
||||||
const person = people_dict.get(email);
|
const person = people_dict.get(email);
|
||||||
|
|
||||||
if (!person) {
|
if (!person) {
|
||||||
|
@ -137,6 +141,10 @@ export function get_by_email(email: string): User | undefined {
|
||||||
}
|
}
|
||||||
|
|
||||||
return person;
|
return person;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_by_email(value: typeof get_by_email): void {
|
||||||
|
get_by_email = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_bot_owner_user(user: User & {is_bot: true}): User | undefined {
|
export function get_bot_owner_user(user: User & {is_bot: true}): User | undefined {
|
||||||
|
@ -382,7 +390,7 @@ export function emails_strings_to_user_ids_string(emails_string: string): string
|
||||||
return email_list_to_user_ids_string(emails);
|
return email_list_to_user_ids_string(emails);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function email_list_to_user_ids_string(emails: string[]): string | undefined {
|
export let email_list_to_user_ids_string = (emails: string[]): string | undefined => {
|
||||||
let user_ids = util.try_parse_as_truthy(
|
let user_ids = util.try_parse_as_truthy(
|
||||||
emails.map((email) => {
|
emails.map((email) => {
|
||||||
const person = get_by_email(email);
|
const person = get_by_email(email);
|
||||||
|
@ -398,6 +406,12 @@ export function email_list_to_user_ids_string(emails: string[]): string | undefi
|
||||||
user_ids = sort_numerically(user_ids);
|
user_ids = sort_numerically(user_ids);
|
||||||
|
|
||||||
return user_ids.join(",");
|
return user_ids.join(",");
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_email_list_to_user_ids_string(
|
||||||
|
value: typeof email_list_to_user_ids_string,
|
||||||
|
): void {
|
||||||
|
email_list_to_user_ids_string = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_full_names_for_poll_option(user_ids: number[]): string {
|
export function get_full_names_for_poll_option(user_ids: number[]): string {
|
||||||
|
@ -1056,7 +1070,7 @@ export function get_bot_ids(): number[] {
|
||||||
return bot_ids;
|
return bot_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_active_human_count(): number {
|
export let get_active_human_count = (): number => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (const person of active_user_dict.values()) {
|
for (const person of active_user_dict.values()) {
|
||||||
if (!person.is_bot) {
|
if (!person.is_bot) {
|
||||||
|
@ -1064,6 +1078,10 @@ export function get_active_human_count(): number {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_active_human_count(value: typeof get_active_human_count): void {
|
||||||
|
get_active_human_count = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_active_user_ids(): number[] {
|
export function get_active_user_ids(): number[] {
|
||||||
|
|
|
@ -11,8 +11,12 @@ type PMConversation = {
|
||||||
|
|
||||||
const partners = new Set<number>();
|
const partners = new Set<number>();
|
||||||
|
|
||||||
export function set_partner(user_id: number): void {
|
export let set_partner = (user_id: number): void => {
|
||||||
partners.add(user_id);
|
partners.add(user_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_set_partner(value: typeof set_partner): void {
|
||||||
|
set_partner = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function is_partner(user_id: number): boolean {
|
export function is_partner(user_id: number): boolean {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import generated_pygments_data from "../generated/pygments_data.json";
|
import generated_pygments_data from "../generated/pygments_data.json";
|
||||||
|
|
||||||
type PygmentsLanguage = {priority: number; pretty_name: string};
|
type PygmentsLanguage = {priority: number; pretty_name: string};
|
||||||
const langs: Record<string, PygmentsLanguage | undefined> = generated_pygments_data.langs;
|
export let langs: Record<string, PygmentsLanguage | undefined> = generated_pygments_data.langs;
|
||||||
|
|
||||||
export {langs};
|
export function rewire_langs(value: typeof langs): void {
|
||||||
|
langs = value;
|
||||||
|
}
|
||||||
|
|
|
@ -249,10 +249,14 @@ export function get_reaction_sections(message_id: number): JQuery {
|
||||||
return $rows.find(".message_reactions");
|
return $rows.find(".message_reactions");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function find_reaction(message_id: number, local_id: string): JQuery {
|
export let find_reaction = (message_id: number, local_id: string): JQuery => {
|
||||||
const $reaction_section = get_reaction_sections(message_id);
|
const $reaction_section = get_reaction_sections(message_id);
|
||||||
const $reaction = $reaction_section.find(`[data-reaction-id='${CSS.escape(local_id)}']`);
|
const $reaction = $reaction_section.find(`[data-reaction-id='${CSS.escape(local_id)}']`);
|
||||||
return $reaction;
|
return $reaction;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_find_reaction(value: typeof find_reaction): void {
|
||||||
|
find_reaction = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_add_reaction_button(message_id: number): JQuery {
|
export function get_add_reaction_button(message_id: number): JQuery {
|
||||||
|
@ -261,12 +265,16 @@ export function get_add_reaction_button(message_id: number): JQuery {
|
||||||
return $add_button;
|
return $add_button;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set_reaction_vote_text($reaction: JQuery, vote_text: string): void {
|
export let set_reaction_vote_text = ($reaction: JQuery, vote_text: string): void => {
|
||||||
const $count_element = $reaction.find(".message_reaction_count");
|
const $count_element = $reaction.find(".message_reaction_count");
|
||||||
$count_element.text(vote_text);
|
$count_element.text(vote_text);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_set_reaction_vote_text(value: typeof set_reaction_vote_text): void {
|
||||||
|
set_reaction_vote_text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function add_reaction(event: ReactionEvent): void {
|
export let add_reaction = (event: ReactionEvent): void => {
|
||||||
const message_id = event.message_id;
|
const message_id = event.message_id;
|
||||||
const message = message_store.get(message_id);
|
const message = message_store.get(message_id);
|
||||||
|
|
||||||
|
@ -311,13 +319,17 @@ export function add_reaction(event: ReactionEvent): void {
|
||||||
message.clean_reactions.set(local_id, clean_reaction_object);
|
message.clean_reactions.set(local_id, clean_reaction_object);
|
||||||
insert_new_reaction(clean_reaction_object, message, user_id);
|
insert_new_reaction(clean_reaction_object, message, user_id);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_add_reaction(value: typeof add_reaction): void {
|
||||||
|
add_reaction = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_existing_reaction(
|
export let update_existing_reaction = (
|
||||||
clean_reaction_object: MessageCleanReaction,
|
clean_reaction_object: MessageCleanReaction,
|
||||||
message: Message,
|
message: Message,
|
||||||
acting_user_id: number,
|
acting_user_id: number,
|
||||||
): void {
|
): void => {
|
||||||
// Our caller ensures that this message already has a reaction
|
// Our caller ensures that this message already has a reaction
|
||||||
// for this emoji and sets up our user_list. This function
|
// for this emoji and sets up our user_list. This function
|
||||||
// simply updates the DOM.
|
// simply updates the DOM.
|
||||||
|
@ -335,13 +347,17 @@ export function update_existing_reaction(
|
||||||
}
|
}
|
||||||
|
|
||||||
update_vote_text_on_message(message);
|
update_vote_text_on_message(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_existing_reaction(value: typeof update_existing_reaction): void {
|
||||||
|
update_existing_reaction = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function insert_new_reaction(
|
export let insert_new_reaction = (
|
||||||
clean_reaction_object: MessageCleanReaction,
|
clean_reaction_object: MessageCleanReaction,
|
||||||
message: Message,
|
message: Message,
|
||||||
user_id: number,
|
user_id: number,
|
||||||
): void {
|
): void => {
|
||||||
// Our caller ensures we are the first user to react to this
|
// Our caller ensures we are the first user to react to this
|
||||||
// message with this emoji. We then render the emoji/title/count
|
// message with this emoji. We then render the emoji/title/count
|
||||||
// and insert it before the add button.
|
// and insert it before the add button.
|
||||||
|
@ -389,9 +405,13 @@ export function insert_new_reaction(
|
||||||
}
|
}
|
||||||
|
|
||||||
update_vote_text_on_message(message);
|
update_vote_text_on_message(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_insert_new_reaction(value: typeof insert_new_reaction): void {
|
||||||
|
insert_new_reaction = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function remove_reaction(event: ReactionEvent): void {
|
export let remove_reaction = (event: ReactionEvent): void => {
|
||||||
const message_id = event.message_id;
|
const message_id = event.message_id;
|
||||||
const user_id = event.user_id;
|
const user_id = event.user_id;
|
||||||
const message = message_store.get(message_id);
|
const message = message_store.get(message_id);
|
||||||
|
@ -426,13 +446,17 @@ export function remove_reaction(event: ReactionEvent): void {
|
||||||
update_user_fields(clean_reaction_object, should_display_reactors);
|
update_user_fields(clean_reaction_object, should_display_reactors);
|
||||||
|
|
||||||
remove_reaction_from_view(clean_reaction_object, message, user_id);
|
remove_reaction_from_view(clean_reaction_object, message, user_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_remove_reaction(value: typeof remove_reaction): void {
|
||||||
|
remove_reaction = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function remove_reaction_from_view(
|
export let remove_reaction_from_view = (
|
||||||
clean_reaction_object: MessageCleanReaction,
|
clean_reaction_object: MessageCleanReaction,
|
||||||
message: Message,
|
message: Message,
|
||||||
user_id: number,
|
user_id: number,
|
||||||
): void {
|
): void => {
|
||||||
const local_id = get_local_reaction_id(clean_reaction_object);
|
const local_id = get_local_reaction_id(clean_reaction_object);
|
||||||
const $reaction = find_reaction(message.id, local_id);
|
const $reaction = find_reaction(message.id, local_id);
|
||||||
const reaction_count = clean_reaction_object.user_ids.length;
|
const reaction_count = clean_reaction_object.user_ids.length;
|
||||||
|
@ -466,6 +490,10 @@ export function remove_reaction_from_view(
|
||||||
}
|
}
|
||||||
|
|
||||||
update_vote_text_on_message(message);
|
update_vote_text_on_message(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_remove_reaction_from_view(value: typeof remove_reaction_from_view): void {
|
||||||
|
remove_reaction_from_view = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_emojis_used_by_user_for_message_id(message_id: number): string[] {
|
export function get_emojis_used_by_user_for_message_id(message_id: number): string[] {
|
||||||
|
@ -687,7 +715,7 @@ function comma_separated_usernames(user_list: number[]): string {
|
||||||
return comma_separated_usernames;
|
return comma_separated_usernames;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_vote_text_on_message(message: Message): void {
|
export let update_vote_text_on_message = (message: Message): void => {
|
||||||
// Because whether we display a count or the names of reacting
|
// Because whether we display a count or the names of reacting
|
||||||
// users depends on total reactions on the message, we need to
|
// users depends on total reactions on the message, we need to
|
||||||
// recalculate this whenever adjusting reaction rendering on a
|
// recalculate this whenever adjusting reaction rendering on a
|
||||||
|
@ -703,4 +731,10 @@ export function update_vote_text_on_message(message: Message): void {
|
||||||
message_clean_reaction.vote_text = vote_text;
|
message_clean_reaction.vote_text = vote_text;
|
||||||
set_reaction_vote_text(reaction_elem, vote_text);
|
set_reaction_vote_text(reaction_elem, vote_text);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_vote_text_on_message(
|
||||||
|
value: typeof update_vote_text_on_message,
|
||||||
|
): void {
|
||||||
|
update_vote_text_on_message = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -930,7 +930,7 @@ export function bulk_inplace_rerender(row_keys: string[]): void {
|
||||||
setTimeout(revive_current_focus, 0);
|
setTimeout(revive_current_focus, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inplace_rerender(topic_key: string, is_bulk_rerender?: boolean): boolean {
|
export let inplace_rerender = (topic_key: string, is_bulk_rerender?: boolean): boolean => {
|
||||||
if (!recent_view_util.is_visible()) {
|
if (!recent_view_util.is_visible()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -990,6 +990,10 @@ export function inplace_rerender(topic_key: string, is_bulk_rerender?: boolean):
|
||||||
setTimeout(revive_current_focus, 0);
|
setTimeout(revive_current_focus, 0);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_inplace_rerender(value: typeof inplace_rerender): void {
|
||||||
|
inplace_rerender = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_topic_visibility_policy(stream_id: number, topic: string): boolean {
|
export function update_topic_visibility_policy(stream_id: number, topic: string): boolean {
|
||||||
|
|
|
@ -17,6 +17,11 @@ import * as util from "./util";
|
||||||
|
|
||||||
// Exported for unit testing
|
// Exported for unit testing
|
||||||
export let is_using_input_method = false;
|
export let is_using_input_method = false;
|
||||||
|
|
||||||
|
export function rewire_is_using_input_method(value: typeof is_using_input_method): void {
|
||||||
|
is_using_input_method = value;
|
||||||
|
}
|
||||||
|
|
||||||
export let search_pill_widget: SearchPillWidget | null = null;
|
export let search_pill_widget: SearchPillWidget | null = null;
|
||||||
let search_input_has_changed = false;
|
let search_input_has_changed = false;
|
||||||
|
|
||||||
|
@ -390,7 +395,7 @@ function reset_searchbox(clear = false): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported for tests
|
// Exported for tests
|
||||||
export function exit_search(opts: {keep_search_narrow_open: boolean}): void {
|
export let exit_search = (opts: {keep_search_narrow_open: boolean}): void => {
|
||||||
const filter = narrow_state.filter();
|
const filter = narrow_state.filter();
|
||||||
if (!filter || filter.is_common_narrow()) {
|
if (!filter || filter.is_common_narrow()) {
|
||||||
// for common narrows, we change the UI (and don't redirect)
|
// for common narrows, we change the UI (and don't redirect)
|
||||||
|
@ -404,13 +409,23 @@ export function exit_search(opts: {keep_search_narrow_open: boolean}): void {
|
||||||
}
|
}
|
||||||
$("#search_query").trigger("blur");
|
$("#search_query").trigger("blur");
|
||||||
$(".app").trigger("focus");
|
$(".app").trigger("focus");
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_exit_search(value: typeof exit_search): void {
|
||||||
|
exit_search = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function open_search_bar_and_close_narrow_description(clear = false): void {
|
export let open_search_bar_and_close_narrow_description = (clear = false): void => {
|
||||||
reset_searchbox(clear);
|
reset_searchbox(clear);
|
||||||
$(".navbar-search").addClass("expanded");
|
$(".navbar-search").addClass("expanded");
|
||||||
$("#message_view_header").addClass("hidden");
|
$("#message_view_header").addClass("hidden");
|
||||||
popovers.hide_all();
|
popovers.hide_all();
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_open_search_bar_and_close_narrow_description(
|
||||||
|
value: typeof open_search_bar_and_close_narrow_description,
|
||||||
|
): void {
|
||||||
|
open_search_bar_and_close_narrow_description = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function close_search_bar_and_open_narrow_description(): void {
|
export function close_search_bar_and_open_narrow_description(): void {
|
||||||
|
|
|
@ -631,10 +631,10 @@ export function get_input_type($input_elem: JQuery, input_type?: string): string
|
||||||
return input_type;
|
return input_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_input_element_value(
|
export let get_input_element_value = (
|
||||||
input_elem: HTMLElement,
|
input_elem: HTMLElement,
|
||||||
input_type?: string,
|
input_type?: string,
|
||||||
): boolean | number | string | null | undefined | GroupSettingValue {
|
): boolean | number | string | null | undefined | GroupSettingValue => {
|
||||||
const $input_elem = $(input_elem);
|
const $input_elem = $(input_elem);
|
||||||
input_type = get_input_type($input_elem, input_type);
|
input_type = get_input_type($input_elem, input_type);
|
||||||
let input_value;
|
let input_value;
|
||||||
|
@ -691,6 +691,10 @@ export function get_input_element_value(
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_input_element_value(value: typeof get_input_element_value): void {
|
||||||
|
get_input_element_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set_input_element_value(
|
export function set_input_element_value(
|
||||||
|
|
|
@ -899,7 +899,7 @@ export function set_up_dropdown_widget_for_realm_group_settings(): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function init_dropdown_widgets(): void {
|
export let init_dropdown_widgets = (): void => {
|
||||||
const notification_stream_options = (): dropdown_widget.Option[] => {
|
const notification_stream_options = (): dropdown_widget.Option[] => {
|
||||||
const streams = stream_settings_data.get_streams_for_settings_page();
|
const streams = stream_settings_data.get_streams_for_settings_page();
|
||||||
const options: dropdown_widget.Option[] = streams.map((stream) => ({
|
const options: dropdown_widget.Option[] = streams.map((stream) => ({
|
||||||
|
@ -956,6 +956,10 @@ export function init_dropdown_widgets(): void {
|
||||||
);
|
);
|
||||||
|
|
||||||
set_up_dropdown_widget_for_realm_group_settings();
|
set_up_dropdown_widget_for_realm_group_settings();
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_init_dropdown_widgets(value: typeof init_dropdown_widgets): void {
|
||||||
|
init_dropdown_widgets = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function register_save_discard_widget_handlers(
|
export function register_save_discard_widget_handlers(
|
||||||
|
@ -1055,7 +1059,7 @@ export function register_save_discard_widget_handlers(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported for tests
|
// Exported for tests
|
||||||
export function initialize_group_setting_widgets(): void {
|
export let initialize_group_setting_widgets = (): void => {
|
||||||
const realm_group_permission_settings = Object.entries(
|
const realm_group_permission_settings = Object.entries(
|
||||||
realm.server_supported_permission_settings.realm,
|
realm.server_supported_permission_settings.realm,
|
||||||
);
|
);
|
||||||
|
@ -1080,6 +1084,12 @@ export function initialize_group_setting_widgets(): void {
|
||||||
|
|
||||||
enable_or_disable_group_permission_settings();
|
enable_or_disable_group_permission_settings();
|
||||||
check_disable_direct_message_initiator_group_widget();
|
check_disable_direct_message_initiator_group_widget();
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_initialize_group_setting_widgets(
|
||||||
|
value: typeof initialize_group_setting_widgets,
|
||||||
|
): void {
|
||||||
|
initialize_group_setting_widgets = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function build_page(): void {
|
export function build_page(): void {
|
||||||
|
|
|
@ -217,7 +217,7 @@ export function get_stream_name_from_id(stream_id: number): string {
|
||||||
return get_sub_by_id(stream_id)?.name ?? "";
|
return get_sub_by_id(stream_id)?.name ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_sub_by_name(name: string): StreamSubscription | undefined {
|
export let get_sub_by_name = (name: string): StreamSubscription | undefined => {
|
||||||
// Note: Only use this function for situations where
|
// Note: Only use this function for situations where
|
||||||
// you are comfortable with a user dealing with an
|
// you are comfortable with a user dealing with an
|
||||||
// old name of a stream (from prior to a rename).
|
// old name of a stream (from prior to a rename).
|
||||||
|
@ -230,6 +230,10 @@ export function get_sub_by_name(name: string): StreamSubscription | undefined {
|
||||||
}
|
}
|
||||||
|
|
||||||
return sub_store.get(stream_id);
|
return sub_store.get(stream_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_sub_by_name(value: typeof get_sub_by_name): void {
|
||||||
|
get_sub_by_name = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function id_to_slug(stream_id: number): string {
|
export function id_to_slug(stream_id: number): string {
|
||||||
|
@ -449,7 +453,7 @@ export function canonicalized_name(stream_name: string): string {
|
||||||
return stream_name.toString().toLowerCase();
|
return stream_name.toString().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_color(stream_id: number | undefined): string {
|
export let get_color = (stream_id: number | undefined): string => {
|
||||||
if (stream_id === undefined) {
|
if (stream_id === undefined) {
|
||||||
return DEFAULT_COLOR;
|
return DEFAULT_COLOR;
|
||||||
}
|
}
|
||||||
|
@ -458,6 +462,10 @@ export function get_color(stream_id: number | undefined): string {
|
||||||
return DEFAULT_COLOR;
|
return DEFAULT_COLOR;
|
||||||
}
|
}
|
||||||
return sub.color;
|
return sub.color;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_color(value: typeof get_color): void {
|
||||||
|
get_color = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function is_muted(stream_id: number): boolean {
|
export function is_muted(stream_id: number): boolean {
|
||||||
|
@ -675,7 +683,7 @@ export function is_default_stream_id(stream_id: number): boolean {
|
||||||
return default_stream_ids.has(stream_id);
|
return default_stream_ids.has(stream_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function is_user_subscribed(stream_id: number, user_id: number): boolean {
|
export let is_user_subscribed = (stream_id: number, user_id: number): boolean => {
|
||||||
const sub = sub_store.get(stream_id);
|
const sub = sub_store.get(stream_id);
|
||||||
if (sub === undefined || !can_view_subscribers(sub)) {
|
if (sub === undefined || !can_view_subscribers(sub)) {
|
||||||
// If we don't know about the stream, or we ourselves cannot access subscriber list,
|
// If we don't know about the stream, or we ourselves cannot access subscriber list,
|
||||||
|
@ -691,6 +699,10 @@ export function is_user_subscribed(stream_id: number, user_id: number): boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
return peer_data.is_user_subscribed(stream_id, user_id);
|
return peer_data.is_user_subscribed(stream_id, user_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_is_user_subscribed(value: typeof is_user_subscribed): void {
|
||||||
|
is_user_subscribed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function create_streams(streams: Stream[]): void {
|
export function create_streams(streams: Stream[]): void {
|
||||||
|
|
|
@ -41,6 +41,10 @@ let zoomed_in = false;
|
||||||
|
|
||||||
export let stream_cursor: ListCursor<number>;
|
export let stream_cursor: ListCursor<number>;
|
||||||
|
|
||||||
|
export function rewire_stream_cursor(value: typeof stream_cursor): void {
|
||||||
|
stream_cursor = value;
|
||||||
|
}
|
||||||
|
|
||||||
let has_scrolled = false;
|
let has_scrolled = false;
|
||||||
|
|
||||||
export function is_zoomed_in(): boolean {
|
export function is_zoomed_in(): boolean {
|
||||||
|
@ -97,13 +101,13 @@ export function clear_topics(): void {
|
||||||
zoomed_in = false;
|
zoomed_in = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_count_in_dom(
|
export let update_count_in_dom = (
|
||||||
$stream_li: JQuery,
|
$stream_li: JQuery,
|
||||||
stream_counts: StreamCountInfo,
|
stream_counts: StreamCountInfo,
|
||||||
stream_has_any_unread_mention_messages: boolean,
|
stream_has_any_unread_mention_messages: boolean,
|
||||||
stream_has_any_unmuted_unread_mention: boolean,
|
stream_has_any_unmuted_unread_mention: boolean,
|
||||||
stream_has_only_muted_unread_mention: boolean,
|
stream_has_only_muted_unread_mention: boolean,
|
||||||
): void {
|
): void => {
|
||||||
// The subscription_block properly excludes the topic list,
|
// The subscription_block properly excludes the topic list,
|
||||||
// and it also has sensitive margins related to whether the
|
// and it also has sensitive margins related to whether the
|
||||||
// count is there or not.
|
// count is there or not.
|
||||||
|
@ -176,6 +180,10 @@ export function update_count_in_dom(
|
||||||
$subscription_block.removeClass("has-only-muted-unreads");
|
$subscription_block.removeClass("has-only-muted-unreads");
|
||||||
$subscription_block.removeClass("stream-with-count");
|
$subscription_block.removeClass("stream-with-count");
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_count_in_dom(value: typeof update_count_in_dom): void {
|
||||||
|
update_count_in_dom = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSidebar {
|
class StreamSidebar {
|
||||||
|
@ -567,7 +575,7 @@ function set_stream_unread_count(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_streams_sidebar(force_rerender = false): void {
|
export let update_streams_sidebar = (force_rerender = false): void => {
|
||||||
if (!force_rerender && is_zoomed_in()) {
|
if (!force_rerender && is_zoomed_in()) {
|
||||||
// We do our best to update topics that are displayed
|
// We do our best to update topics that are displayed
|
||||||
// in case user zoomed in. Streams list will be updated,
|
// in case user zoomed in. Streams list will be updated,
|
||||||
|
@ -591,6 +599,10 @@ export function update_streams_sidebar(force_rerender = false): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
update_stream_sidebar_for_narrow(filter);
|
update_stream_sidebar_for_narrow(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_update_streams_sidebar(value: typeof update_streams_sidebar): void {
|
||||||
|
update_streams_sidebar = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update_dom_with_unread_counts(counts: FullUnreadCountsData): void {
|
export function update_dom_with_unread_counts(counts: FullUnreadCountsData): void {
|
||||||
|
|
|
@ -58,7 +58,7 @@ export function is_filtering_inactives(): boolean {
|
||||||
return filter_out_inactives;
|
return filter_out_inactives;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function has_recent_activity(sub: StreamSubscription): boolean {
|
export let has_recent_activity = (sub: StreamSubscription): boolean => {
|
||||||
if (!filter_out_inactives || sub.pin_to_top) {
|
if (!filter_out_inactives || sub.pin_to_top) {
|
||||||
// If users don't want to filter inactive streams
|
// If users don't want to filter inactive streams
|
||||||
// to the bottom, we respect that setting and don't
|
// to the bottom, we respect that setting and don't
|
||||||
|
@ -70,6 +70,10 @@ export function has_recent_activity(sub: StreamSubscription): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return stream_topic_history.stream_has_topics(sub.stream_id) || sub.newly_subscribed;
|
return stream_topic_history.stream_has_topics(sub.stream_id) || sub.newly_subscribed;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_has_recent_activity(value: typeof has_recent_activity): void {
|
||||||
|
has_recent_activity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function has_recent_activity_but_muted(sub: StreamSubscription): boolean {
|
export function has_recent_activity_but_muted(sub: StreamSubscription): boolean {
|
||||||
|
|
|
@ -356,10 +356,14 @@ export function has_history_for(stream_id: number): boolean {
|
||||||
return fetched_stream_ids.has(stream_id);
|
return fetched_stream_ids.has(stream_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_recent_topic_names(stream_id: number): string[] {
|
export let get_recent_topic_names = (stream_id: number): string[] => {
|
||||||
const history = find_or_create(stream_id);
|
const history = find_or_create(stream_id);
|
||||||
|
|
||||||
return history.get_recent_topic_names();
|
return history.get_recent_topic_names();
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_get_recent_topic_names(value: typeof get_recent_topic_names): void {
|
||||||
|
get_recent_topic_names = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_max_message_id(stream_id: number): number {
|
export function get_max_message_id(stream_id: number): number {
|
||||||
|
|
|
@ -33,8 +33,11 @@ export type StreamSubscription = z.infer<typeof stream_subscription_schema>;
|
||||||
|
|
||||||
const subs_by_stream_id = new Map<number, StreamSubscription>();
|
const subs_by_stream_id = new Map<number, StreamSubscription>();
|
||||||
|
|
||||||
export function get(stream_id: number): StreamSubscription | undefined {
|
export let get = (stream_id: number): StreamSubscription | undefined =>
|
||||||
return subs_by_stream_id.get(stream_id);
|
subs_by_stream_id.get(stream_id);
|
||||||
|
|
||||||
|
export function rewire_get(value: typeof get): void {
|
||||||
|
get = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validate_stream_ids(stream_ids: number[]): number[] {
|
export function validate_stream_ids(stream_ids: number[]): number[] {
|
||||||
|
|
|
@ -175,7 +175,7 @@ export type TimeRender = {
|
||||||
needs_update: boolean;
|
needs_update: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function render_now(time: Date, today = new Date(), display_year?: boolean): TimeRender {
|
export let render_now = (time: Date, today = new Date(), display_year?: boolean): TimeRender => {
|
||||||
let time_str = "";
|
let time_str = "";
|
||||||
let needs_update = false;
|
let needs_update = false;
|
||||||
// render formal time to be used for tippy tooltip
|
// render formal time to be used for tippy tooltip
|
||||||
|
@ -210,6 +210,10 @@ export function render_now(time: Date, today = new Date(), display_year?: boolea
|
||||||
formal_time_str,
|
formal_time_str,
|
||||||
needs_update,
|
needs_update,
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_render_now(value: typeof render_now): void {
|
||||||
|
render_now = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relative time rendering for use in most screens like Recent conversations.
|
// Relative time rendering for use in most screens like Recent conversations.
|
||||||
|
|
|
@ -94,7 +94,7 @@ type StreamData = {
|
||||||
subscribed: boolean;
|
subscribed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function render_typeahead_item(args: {
|
export let render_typeahead_item = (args: {
|
||||||
primary?: string | undefined;
|
primary?: string | undefined;
|
||||||
is_person?: boolean;
|
is_person?: boolean;
|
||||||
img_src?: string;
|
img_src?: string;
|
||||||
|
@ -105,7 +105,7 @@ export function render_typeahead_item(args: {
|
||||||
is_user_group?: boolean;
|
is_user_group?: boolean;
|
||||||
stream?: StreamData;
|
stream?: StreamData;
|
||||||
emoji_code?: string | undefined;
|
emoji_code?: string | undefined;
|
||||||
}): string {
|
}): string => {
|
||||||
const has_image = args.img_src !== undefined;
|
const has_image = args.img_src !== undefined;
|
||||||
const has_status = args.status_emoji_info !== undefined;
|
const has_status = args.status_emoji_info !== undefined;
|
||||||
const has_secondary = args.secondary !== undefined;
|
const has_secondary = args.secondary !== undefined;
|
||||||
|
@ -119,9 +119,13 @@ export function render_typeahead_item(args: {
|
||||||
has_secondary_html,
|
has_secondary_html,
|
||||||
has_pronouns,
|
has_pronouns,
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_render_typeahead_item(value: typeof render_typeahead_item): void {
|
||||||
|
render_typeahead_item = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function render_person(person: UserPillData | UserOrMentionPillData): string {
|
export let render_person = (person: UserPillData | UserOrMentionPillData): string => {
|
||||||
if (person.type === "broadcast") {
|
if (person.type === "broadcast") {
|
||||||
return render_typeahead_item({
|
return render_typeahead_item({
|
||||||
primary: person.user.special_item_text,
|
primary: person.user.special_item_text,
|
||||||
|
@ -155,14 +159,21 @@ export function render_person(person: UserPillData | UserOrMentionPillData): str
|
||||||
};
|
};
|
||||||
|
|
||||||
return render_typeahead_item(typeahead_arguments);
|
return render_typeahead_item(typeahead_arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_render_person(value: typeof render_person): void {
|
||||||
|
render_person = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function render_user_group(user_group: {name: string; description: string}): string {
|
export let render_user_group = (user_group: {name: string; description: string}): string =>
|
||||||
return render_typeahead_item({
|
render_typeahead_item({
|
||||||
primary: user_groups.get_display_group_name(user_group.name),
|
primary: user_groups.get_display_group_name(user_group.name),
|
||||||
secondary: user_group.description,
|
secondary: user_group.description,
|
||||||
is_user_group: true,
|
is_user_group: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function rewire_render_user_group(value: typeof render_user_group): void {
|
||||||
|
render_user_group = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function render_person_or_user_group(
|
export function render_person_or_user_group(
|
||||||
|
@ -175,14 +186,17 @@ export function render_person_or_user_group(
|
||||||
return render_person(item);
|
return render_person(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function render_stream(stream: StreamData): string {
|
export let render_stream = (stream: StreamData): string =>
|
||||||
return render_typeahead_item({
|
render_typeahead_item({
|
||||||
secondary_html: stream.rendered_description,
|
secondary_html: stream.rendered_description,
|
||||||
stream,
|
stream,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function rewire_render_stream(value: typeof render_stream): void {
|
||||||
|
render_stream = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function render_emoji(item: EmojiSuggestion): string {
|
export let render_emoji = (item: EmojiSuggestion): string => {
|
||||||
const args = {
|
const args = {
|
||||||
is_emoji: true,
|
is_emoji: true,
|
||||||
primary: item.emoji_name.replaceAll("_", " "),
|
primary: item.emoji_name.replaceAll("_", " "),
|
||||||
|
@ -198,6 +212,10 @@ export function render_emoji(item: EmojiSuggestion): string {
|
||||||
...args,
|
...args,
|
||||||
emoji_code: item.emoji_code,
|
emoji_code: item.emoji_code,
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_render_emoji(value: typeof render_emoji): void {
|
||||||
|
render_emoji = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sorter<T>(query: string, objs: T[], get_item: (x: T) => string): T[] {
|
export function sorter<T>(query: string, objs: T[], get_item: (x: T) => string): T[] {
|
||||||
|
@ -415,7 +433,7 @@ export function sort_languages(matches: LanguageSuggestion[], query: string): La
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sort_recipients<UserType extends UserOrMentionPillData | UserPillData>({
|
export let sort_recipients = <UserType extends UserOrMentionPillData | UserPillData>({
|
||||||
users,
|
users,
|
||||||
query,
|
query,
|
||||||
current_stream_id,
|
current_stream_id,
|
||||||
|
@ -429,7 +447,7 @@ export function sort_recipients<UserType extends UserOrMentionPillData | UserPil
|
||||||
current_topic?: string | undefined;
|
current_topic?: string | undefined;
|
||||||
groups?: UserGroupPillData[];
|
groups?: UserGroupPillData[];
|
||||||
max_num_items?: number | undefined;
|
max_num_items?: number | undefined;
|
||||||
}): (UserType | UserGroupPillData)[] {
|
}): (UserType | UserGroupPillData)[] => {
|
||||||
function sort_relevance(items: UserType[]): UserType[] {
|
function sort_relevance(items: UserType[]): UserType[] {
|
||||||
return sort_people_for_relevance(items, current_stream_id, current_topic);
|
return sort_people_for_relevance(items, current_stream_id, current_topic);
|
||||||
}
|
}
|
||||||
|
@ -556,6 +574,10 @@ export function sort_recipients<UserType extends UserOrMentionPillData | UserPil
|
||||||
// FirstName, which we don't want to artificially prioritize over the
|
// FirstName, which we don't want to artificially prioritize over the
|
||||||
// the lone active user whose name is FirstName LastName.
|
// the lone active user whose name is FirstName LastName.
|
||||||
return recipients.slice(0, max_num_items);
|
return recipients.slice(0, max_num_items);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_sort_recipients(value: typeof sort_recipients): void {
|
||||||
|
sort_recipients = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compare_setting_options(
|
export function compare_setting_options(
|
||||||
|
@ -618,7 +640,7 @@ export function compare_setting_options(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sort_group_setting_options({
|
export let sort_group_setting_options = ({
|
||||||
users,
|
users,
|
||||||
query,
|
query,
|
||||||
groups,
|
groups,
|
||||||
|
@ -628,7 +650,7 @@ export function sort_group_setting_options({
|
||||||
query: string;
|
query: string;
|
||||||
groups: UserGroupPillData[];
|
groups: UserGroupPillData[];
|
||||||
target_group: UserGroup | undefined;
|
target_group: UserGroup | undefined;
|
||||||
}): (UserPillData | UserGroupPillData)[] {
|
}): (UserPillData | UserGroupPillData)[] => {
|
||||||
function sort_group_setting_items(
|
function sort_group_setting_items(
|
||||||
objs: (UserPillData | UserGroupPillData)[],
|
objs: (UserPillData | UserGroupPillData)[],
|
||||||
): (UserPillData | UserGroupPillData)[] {
|
): (UserPillData | UserGroupPillData)[] {
|
||||||
|
@ -703,6 +725,10 @@ export function sort_group_setting_options({
|
||||||
}
|
}
|
||||||
|
|
||||||
return setting_options.slice(0, MAX_ITEMS);
|
return setting_options.slice(0, MAX_ITEMS);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_sort_group_setting_options(value: typeof sort_group_setting_options): void {
|
||||||
|
sort_group_setting_options = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SlashCommand = {
|
type SlashCommand = {
|
||||||
|
@ -781,7 +807,7 @@ function compare_by_name(stream_a: StreamSubscription, stream_b: StreamSubscript
|
||||||
return util.strcmp(stream_a.name, stream_b.name);
|
return util.strcmp(stream_a.name, stream_b.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sort_streams(matches: StreamPillData[], query: string): StreamPillData[] {
|
export let sort_streams = (matches: StreamPillData[], query: string): StreamPillData[] => {
|
||||||
const name_results = typeahead.triage(query, matches, (x) => x.name, compare_by_activity);
|
const name_results = typeahead.triage(query, matches, (x) => x.name, compare_by_activity);
|
||||||
const desc_results = typeahead.triage(
|
const desc_results = typeahead.triage(
|
||||||
query,
|
query,
|
||||||
|
@ -791,11 +817,19 @@ export function sort_streams(matches: StreamPillData[], query: string): StreamPi
|
||||||
);
|
);
|
||||||
|
|
||||||
return [...name_results.matches, ...desc_results.matches, ...desc_results.rest];
|
return [...name_results.matches, ...desc_results.matches, ...desc_results.rest];
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_sort_streams(value: typeof sort_streams): void {
|
||||||
|
sort_streams = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sort_streams_by_name(matches: StreamPillData[], query: string): StreamPillData[] {
|
export let sort_streams_by_name = (matches: StreamPillData[], query: string): StreamPillData[] => {
|
||||||
const results = typeahead.triage(query, matches, (x) => x.name, compare_by_name);
|
const results = typeahead.triage(query, matches, (x) => x.name, compare_by_name);
|
||||||
return [...results.matches, ...results.rest];
|
return [...results.matches, ...results.rest];
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_sort_streams_by_name(value: typeof sort_streams_by_name): void {
|
||||||
|
sort_streams_by_name = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function query_matches_person(
|
export function query_matches_person(
|
||||||
|
|
|
@ -72,10 +72,15 @@ export function is_user_said_paragraph($element: JQuery): boolean {
|
||||||
return remaining_text.trim() === ":";
|
return remaining_text.trim() === ":";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_collapsible_status_array($elements: JQuery): boolean[] {
|
export let get_collapsible_status_array = ($elements: JQuery): boolean[] =>
|
||||||
return [...$elements].map(
|
[...$elements].map(
|
||||||
(element) => $(element).is("blockquote") || is_user_said_paragraph($(element)),
|
(element) => $(element).is("blockquote") || is_user_said_paragraph($(element)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export function rewire_get_collapsible_status_array(
|
||||||
|
value: typeof get_collapsible_status_array,
|
||||||
|
): void {
|
||||||
|
get_collapsible_status_array = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function potentially_collapse_quotes($element: JQuery): boolean {
|
export function potentially_collapse_quotes($element: JQuery): boolean {
|
||||||
|
|
|
@ -125,7 +125,7 @@ export function edit_config(row: number): Config {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide_upload_banner(uppy: Uppy, config: Config, file_id: string): void {
|
export let hide_upload_banner = (uppy: Uppy, config: Config, file_id: string): void => {
|
||||||
config.upload_banner(file_id).remove();
|
config.upload_banner(file_id).remove();
|
||||||
if (uppy.getFiles().length === 0) {
|
if (uppy.getFiles().length === 0) {
|
||||||
if (config.mode === "compose") {
|
if (config.mode === "compose") {
|
||||||
|
@ -134,6 +134,10 @@ export function hide_upload_banner(uppy: Uppy, config: Config, file_id: string):
|
||||||
config.send_button().prop("disabled", false);
|
config.send_button().prop("disabled", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_hide_upload_banner(value: typeof hide_upload_banner): void {
|
||||||
|
hide_upload_banner = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_upload_banner(
|
function add_upload_banner(
|
||||||
|
@ -172,7 +176,7 @@ export function show_error_message(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function upload_files(uppy: Uppy, config: Config, files: File[] | FileList): void {
|
export let upload_files = (uppy: Uppy, config: Config, files: File[] | FileList): void => {
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -230,6 +234,7 @@ export function upload_files(uppy: Uppy, config: Config, files: File[] | FileLis
|
||||||
file_id,
|
file_id,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
// eslint-disable-next-line no-loop-func
|
||||||
config.upload_banner_cancel_button(file_id).one("click", () => {
|
config.upload_banner_cancel_button(file_id).one("click", () => {
|
||||||
compose_ui.replace_syntax(get_translated_status(file), "", config.textarea());
|
compose_ui.replace_syntax(get_translated_status(file), "", config.textarea());
|
||||||
compose_ui.autosize_textarea(config.textarea());
|
compose_ui.autosize_textarea(config.textarea());
|
||||||
|
@ -238,10 +243,15 @@ export function upload_files(uppy: Uppy, config: Config, files: File[] | FileLis
|
||||||
uppy.removeFile(file_id);
|
uppy.removeFile(file_id);
|
||||||
hide_upload_banner(uppy, config, file_id);
|
hide_upload_banner(uppy, config, file_id);
|
||||||
});
|
});
|
||||||
|
// eslint-disable-next-line no-loop-func
|
||||||
config.upload_banner_hide_button(file_id).one("click", () => {
|
config.upload_banner_hide_button(file_id).one("click", () => {
|
||||||
hide_upload_banner(uppy, config, file_id);
|
hide_upload_banner(uppy, config, file_id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_upload_files(value: typeof upload_files): void {
|
||||||
|
upload_files = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setup_upload(config: Config): Uppy {
|
export function setup_upload(config: Config): Uppy {
|
||||||
|
|
|
@ -116,7 +116,7 @@ export function get_user_topics_for_visibility_policy(visibility_policy: number)
|
||||||
return topics;
|
return topics;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set_user_topic_visibility_policy(
|
export let set_user_topic_visibility_policy = (
|
||||||
stream_id: number,
|
stream_id: number,
|
||||||
topic: string,
|
topic: string,
|
||||||
visibility_policy: number,
|
visibility_policy: number,
|
||||||
|
@ -125,7 +125,7 @@ export function set_user_topic_visibility_policy(
|
||||||
$status_element?: JQuery,
|
$status_element?: JQuery,
|
||||||
success_cb?: () => void,
|
success_cb?: () => void,
|
||||||
error_cb?: () => void,
|
error_cb?: () => void,
|
||||||
): void {
|
): void => {
|
||||||
const data = {
|
const data = {
|
||||||
stream_id,
|
stream_id,
|
||||||
topic,
|
topic,
|
||||||
|
@ -203,6 +203,12 @@ export function set_user_topic_visibility_policy(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_set_user_topic_visibility_policy(
|
||||||
|
value: typeof set_user_topic_visibility_policy,
|
||||||
|
): void {
|
||||||
|
set_user_topic_visibility_policy = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set_visibility_policy_for_element($elt: JQuery, visibility_policy: number): void {
|
export function set_visibility_policy_for_element($elt: JQuery, visibility_policy: number): void {
|
||||||
|
|
|
@ -315,7 +315,7 @@ export function get_time_from_date_muted(date_muted: number | undefined): number
|
||||||
return date_muted * 1000;
|
return date_muted * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function call_function_periodically(callback: () => void, delay: number): void {
|
export let call_function_periodically = (callback: () => void, delay: number): void => {
|
||||||
// We previously used setInterval for this purpose, but
|
// We previously used setInterval for this purpose, but
|
||||||
// empirically observed that after unsuspend, Chrome can end
|
// empirically observed that after unsuspend, Chrome can end
|
||||||
// up trying to "catch up" by doing dozens of these requests
|
// up trying to "catch up" by doing dozens of these requests
|
||||||
|
@ -337,6 +337,10 @@ export function call_function_periodically(callback: () => void, delay: number):
|
||||||
// exception.
|
// exception.
|
||||||
callback();
|
callback();
|
||||||
}, delay);
|
}, delay);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rewire_call_function_periodically(value: typeof call_function_periodically): void {
|
||||||
|
call_function_periodically = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_string_diff(string1: string, string2: string): [number, number, number] {
|
export function get_string_diff(string1: string, string2: string): [number, number, number] {
|
||||||
|
|
Loading…
Reference in New Issue