zulip/web/src/typing_events.js

120 lines
3.9 KiB
JavaScript
Raw Normal View History

import $ from "jquery";
import render_typing_notifications from "../templates/typing_notifications.hbs";
import * as narrow_state from "./narrow_state";
import {page_params} from "./page_params";
import * as people from "./people";
import * as typing_data from "./typing_data";
2020-08-20 21:24:06 +02:00
// See docs/subsystems/typing-indicators.md for details on typing indicators.
2017-09-25 20:33:29 +02:00
2017-03-22 15:11:41 +01:00
// This code handles the inbound side of typing notifications.
// When another user is typing, we process the events here.
//
// We also handle the local event of re-narrowing.
// (For the outbound code, see typing.js.)
// If number of users typing exceed this,
// we render "Several people are typing..."
const MAX_USERS_TO_DISPLAY_NAME = 3;
2017-03-22 15:11:41 +01:00
// Note!: There are also timing constants in typing_status.js
// that make typing indicators work.
function get_users_typing_for_narrow() {
if (narrow_state.narrowed_by_topic_reply()) {
const current_stream_id = narrow_state.stream_id();
const current_topic = narrow_state.topic();
return typing_data.get_topic_typists(current_stream_id, current_topic);
}
if (!narrow_state.narrowed_to_pms()) {
// Narrow is neither "dm:" nor "is:dm" nor topic.
2017-03-22 15:11:41 +01:00
return [];
}
const terms = narrow_state.search_terms();
if (terms.length === 0) {
return [];
}
const first_term = terms[0];
if (first_term.operator === "dm") {
2017-03-22 15:11:41 +01:00
// Get list of users typing in this conversation
const narrow_emails_string = first_term.operand;
2017-03-22 15:11:41 +01:00
// TODO: Create people.emails_strings_to_user_ids.
const narrow_user_ids_string = people.reply_to_to_user_ids_string(narrow_emails_string);
if (!narrow_user_ids_string) {
return [];
}
const narrow_user_ids = narrow_user_ids_string
.split(",")
.map((user_id_string) => Number.parseInt(user_id_string, 10));
const group = [...narrow_user_ids, page_params.user_id];
2017-03-22 15:11:41 +01:00
return typing_data.get_group_typists(group);
}
// Get all users typing (in all direct message conversations with current user)
return typing_data.get_all_direct_message_typists();
2017-03-22 15:11:41 +01:00
}
export function render_notifications_for_narrow() {
const user_ids = get_users_typing_for_narrow();
const users_typing = user_ids
.map((user_id) => people.get_user_by_id_assert_valid(user_id))
.filter((person) => !person.is_inaccessible_user);
const num_of_users_typing = users_typing.length;
if (num_of_users_typing === 0) {
$("#typing_notifications").hide();
2017-03-22 15:11:41 +01:00
} else {
$("#typing_notifications").html(
render_typing_notifications({
users: users_typing,
several_users: num_of_users_typing > MAX_USERS_TO_DISPLAY_NAME,
}),
);
$("#typing_notifications").show();
2017-03-22 15:11:41 +01:00
}
}
2017-03-22 15:11:41 +01:00
function get_key(event) {
if (event.message_type === "stream") {
return typing_data.get_topic_key(event.stream_id, event.topic);
}
if (event.message_type === "direct") {
const recipients = event.recipients.map((user) => user.user_id);
recipients.sort();
return typing_data.get_direct_message_conversation_key(recipients);
}
throw new Error("Invalid typing notification type", event);
}
2017-03-22 15:11:41 +01:00
export function hide_notification(event) {
const key = get_key(event);
typing_data.clear_inbound_timer(key);
2017-03-22 15:11:41 +01:00
const removed = typing_data.remove_typist(key, event.sender.user_id);
2017-03-22 15:11:41 +01:00
if (removed) {
render_notifications_for_narrow();
2017-03-22 15:11:41 +01:00
}
}
2017-03-22 15:11:41 +01:00
export function display_notification(event) {
const sender_id = event.sender.user_id;
2017-03-22 15:11:41 +01:00
const key = get_key(event);
typing_data.add_typist(key, sender_id);
2017-03-22 15:11:41 +01:00
render_notifications_for_narrow();
typing_data.kickstart_inbound_timer(
key,
page_params.server_typing_started_expiry_period_milliseconds,
() => {
hide_notification(event);
},
);
}