mirror of https://github.com/zulip/zulip.git
135 lines
4.2 KiB
JavaScript
135 lines
4.2 KiB
JavaScript
import $ from "jquery";
|
|
|
|
import * as typing_status from "../shared/src/typing_status";
|
|
|
|
import * as blueslip from "./blueslip";
|
|
import * as channel from "./channel";
|
|
import * as compose_pm_pill from "./compose_pm_pill";
|
|
import * as compose_state from "./compose_state";
|
|
import {page_params} from "./page_params";
|
|
import * as people from "./people";
|
|
import * as stream_data from "./stream_data";
|
|
import {user_settings} from "./user_settings";
|
|
|
|
// This module handles the outbound side of typing indicators.
|
|
// We detect changes in the compose box and notify the server
|
|
// when we are typing. For the inbound side see typing_events.js.
|
|
// See docs/subsystems/typing-indicators.md for more details.
|
|
|
|
// How frequently 'start' notifications are sent to extend
|
|
// the expiry of active typing indicators.
|
|
const typing_started_wait_period = page_params.server_typing_started_wait_period_milliseconds;
|
|
// How long after someone stops editing in the compose box
|
|
// do we send a 'stop' notification.
|
|
const typing_stopped_wait_period = page_params.server_typing_stopped_wait_period_milliseconds;
|
|
|
|
function send_typing_notification_ajax(data) {
|
|
channel.post({
|
|
url: "/json/typing",
|
|
data,
|
|
success() {},
|
|
error(xhr) {
|
|
if (xhr.readyState !== 0) {
|
|
blueslip.warn("Failed to send typing event: " + xhr.responseText);
|
|
}
|
|
},
|
|
});
|
|
}
|
|
|
|
function send_direct_message_typing_notification(user_ids_array, operation) {
|
|
const data = {
|
|
to: JSON.stringify(user_ids_array),
|
|
op: operation,
|
|
};
|
|
send_typing_notification_ajax(data);
|
|
}
|
|
|
|
function send_stream_typing_notification(stream_id, topic, operation) {
|
|
const data = {
|
|
type: "stream",
|
|
to: JSON.stringify(stream_id),
|
|
topic,
|
|
op: operation,
|
|
};
|
|
send_typing_notification_ajax(data);
|
|
}
|
|
|
|
function send_typing_notification_based_on_message_type(to, operation) {
|
|
const message_type = to.stream_id ? "stream" : "direct";
|
|
if (message_type === "direct" && user_settings.send_private_typing_notifications) {
|
|
send_direct_message_typing_notification(to, operation);
|
|
} else if (message_type === "stream" && user_settings.send_stream_typing_notifications) {
|
|
send_stream_typing_notification(to.stream_id, to.topic, operation);
|
|
}
|
|
}
|
|
|
|
function get_user_ids_array() {
|
|
const user_ids_string = compose_pm_pill.get_user_ids_string();
|
|
if (user_ids_string === "") {
|
|
return null;
|
|
}
|
|
|
|
return people.user_ids_string_to_ids_array(user_ids_string);
|
|
}
|
|
|
|
function is_valid_conversation() {
|
|
const compose_empty = !compose_state.has_message_content();
|
|
if (compose_empty) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function get_current_time() {
|
|
return Date.now();
|
|
}
|
|
|
|
function notify_server_start(to) {
|
|
send_typing_notification_based_on_message_type(to, "start");
|
|
}
|
|
|
|
function notify_server_stop(to) {
|
|
send_typing_notification_based_on_message_type(to, "stop");
|
|
}
|
|
|
|
export function get_recipient() {
|
|
const message_type = compose_state.get_message_type();
|
|
if (message_type === "private") {
|
|
return get_user_ids_array();
|
|
}
|
|
if (message_type === "stream") {
|
|
const stream_name = compose_state.stream_name();
|
|
const stream_id = stream_data.get_stream_id(stream_name);
|
|
const topic = compose_state.topic();
|
|
return {stream_id, topic};
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function initialize() {
|
|
const worker = {
|
|
get_current_time,
|
|
notify_server_start,
|
|
notify_server_stop,
|
|
};
|
|
|
|
$(document).on("input", "#compose-textarea", () => {
|
|
// If our previous state was no typing notification, send a
|
|
// start-typing notice immediately.
|
|
const new_recipient = is_valid_conversation() ? get_recipient() : null;
|
|
typing_status.update(
|
|
worker,
|
|
new_recipient,
|
|
typing_started_wait_period,
|
|
typing_stopped_wait_period,
|
|
);
|
|
});
|
|
|
|
// We send a stop-typing notification immediately when compose is
|
|
// closed/cancelled
|
|
$(document).on("compose_canceled.zulip compose_finished.zulip", () => {
|
|
typing_status.update(worker, null, typing_started_wait_period, typing_stopped_wait_period);
|
|
});
|
|
}
|