mirror of https://github.com/zulip/zulip.git
typing: Add typing constants to the post register api response.
Adds typing notification constants to the response given by `POST /register`. Until now, these were hardcoded by clients based on the documentation for implementing typing notifications in the main endpoint description for `api/set-typing-status`. This change also reflects updating the web-app frontend code to use the new constants from the register response. Co-authored-by: Samuel Kabuya <samuel.mwangikabuya@kibo.school> Co-authored-by: Wilhelmina Asante <wilhelmina.asante@kibo.school>
This commit is contained in:
parent
d26a94a0db
commit
3ce7b77092
|
@ -20,6 +20,15 @@ format used by the Zulip server that they are interacting with.
|
||||||
|
|
||||||
## Changes in Zulip 8.0
|
## Changes in Zulip 8.0
|
||||||
|
|
||||||
|
**Feature level 204**
|
||||||
|
|
||||||
|
* [`POST /register`](/api/register-queue): Added
|
||||||
|
`server_typing_started_wait_period_milliseconds`,
|
||||||
|
`server_typing_stopped_wait_period_milliseconds`, and
|
||||||
|
`server_typing_started_expiry_period_milliseconds` fields
|
||||||
|
for clients to use when implementing [typing
|
||||||
|
notifications](/api/set-typing-status) protocol.
|
||||||
|
|
||||||
**Feature level 203**
|
**Feature level 203**
|
||||||
|
|
||||||
* [`POST /register`](/api/register-queue): Add
|
* [`POST /register`](/api/register-queue): Add
|
||||||
|
|
|
@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.9.3"
|
||||||
# Changes should be accompanied by documentation explaining what the
|
# Changes should be accompanied by documentation explaining what the
|
||||||
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
||||||
# entries in the endpoint's documentation in `zulip.yaml`.
|
# entries in the endpoint's documentation in `zulip.yaml`.
|
||||||
API_FEATURE_LEVEL = 203
|
API_FEATURE_LEVEL = 204
|
||||||
|
|
||||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||||
# only when going from an old version of the code to a newer version. Bump
|
# only when going from an old version of the code to a newer version. Bump
|
||||||
|
|
|
@ -13,18 +13,6 @@ type TypingStatusState = {
|
||||||
idle_timer: ReturnType<typeof setTimeout>;
|
idle_timer: ReturnType<typeof setTimeout>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following constants are tuned to work with
|
|
||||||
// TYPING_STARTED_EXPIRY_PERIOD, which is what the other
|
|
||||||
// users will use to time out our messages. (Or us,
|
|
||||||
// depending on your perspective.) See typing_events.js.
|
|
||||||
|
|
||||||
// How frequently 'still typing' notifications are sent
|
|
||||||
// to extend the expiry
|
|
||||||
const TYPING_STARTED_WAIT_PERIOD = 10000; // 10s
|
|
||||||
// How long after someone stops editing in the compose box
|
|
||||||
// do we send a 'stopped typing' notification
|
|
||||||
const TYPING_STOPPED_WAIT_PERIOD = 5000; // 5s
|
|
||||||
|
|
||||||
/** Exported only for tests. */
|
/** Exported only for tests. */
|
||||||
export let state: TypingStatusState | null = null;
|
export let state: TypingStatusState | null = null;
|
||||||
|
|
||||||
|
@ -39,6 +27,7 @@ export function stop_last_notification(worker: TypingStatusWorker): void {
|
||||||
/** Exported only for tests. */
|
/** Exported only for tests. */
|
||||||
export function start_or_extend_idle_timer(
|
export function start_or_extend_idle_timer(
|
||||||
worker: TypingStatusWorker,
|
worker: TypingStatusWorker,
|
||||||
|
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
|
||||||
|
@ -51,29 +40,34 @@ export function start_or_extend_idle_timer(
|
||||||
if (state?.idle_timer) {
|
if (state?.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_next_start_time(current_time: number): void {
|
function set_next_start_time(current_time: number, typing_started_wait_period: number): void {
|
||||||
assert(state !== null, "State object should not be null here.");
|
assert(state !== null, "State object should not be null here.");
|
||||||
state.next_send_start_time = current_time + TYPING_STARTED_WAIT_PERIOD;
|
state.next_send_start_time = current_time + typing_started_wait_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
function actually_ping_server(
|
function actually_ping_server(
|
||||||
worker: TypingStatusWorker,
|
worker: TypingStatusWorker,
|
||||||
recipient_ids: number[],
|
recipient_ids: number[],
|
||||||
current_time: number,
|
current_time: number,
|
||||||
|
typing_started_wait_period: number,
|
||||||
): void {
|
): void {
|
||||||
worker.notify_server_start(recipient_ids);
|
worker.notify_server_start(recipient_ids);
|
||||||
set_next_start_time(current_time);
|
set_next_start_time(current_time, typing_started_wait_period);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Exported only for tests. */
|
/** Exported only for tests. */
|
||||||
export function maybe_ping_server(worker: TypingStatusWorker, recipient_ids: number[]): void {
|
export function maybe_ping_server(
|
||||||
|
worker: TypingStatusWorker,
|
||||||
|
recipient_ids: number[],
|
||||||
|
typing_started_wait_period: number,
|
||||||
|
): 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_ids, current_time);
|
actually_ping_server(worker, recipient_ids, current_time, typing_started_wait_period);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,17 +97,22 @@ export function maybe_ping_server(worker: TypingStatusWorker, recipient_ids: num
|
||||||
* addressed to, as a sorted array of user IDs; or `null` if no direct message
|
* addressed to, as a sorted array of user IDs; or `null` if no direct message
|
||||||
* is being composed anymore.
|
* is being composed anymore.
|
||||||
*/
|
*/
|
||||||
export function update(worker: TypingStatusWorker, new_recipient_ids: number[] | null): void {
|
export function update(
|
||||||
|
worker: TypingStatusWorker,
|
||||||
|
new_recipient_ids: number[] | null,
|
||||||
|
typing_started_wait_period: number,
|
||||||
|
typing_stopped_wait_period: number,
|
||||||
|
): void {
|
||||||
if (state !== null) {
|
if (state !== null) {
|
||||||
// We need to use _.isEqual for comparisons; === doesn't work
|
// We need to use _.isEqual for comparisons; === doesn't work
|
||||||
// on arrays.
|
// on arrays.
|
||||||
if (_.isEqual(new_recipient_ids, state.current_recipient_ids)) {
|
if (_.isEqual(new_recipient_ids, state.current_recipient_ids)) {
|
||||||
// Nothing has really changed, except we may need
|
// Nothing has really changed, except we may need
|
||||||
// to send a ping to the server.
|
// to send a ping to the server.
|
||||||
maybe_ping_server(worker, new_recipient_ids!);
|
maybe_ping_server(worker, new_recipient_ids!, typing_started_wait_period);
|
||||||
|
|
||||||
// We can also extend out our idle time.
|
// We can also extend out our idle time.
|
||||||
state.idle_timer = start_or_extend_idle_timer(worker);
|
state.idle_timer = start_or_extend_idle_timer(worker, typing_stopped_wait_period);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -135,8 +134,8 @@ export function update(worker: TypingStatusWorker, new_recipient_ids: number[] |
|
||||||
state = {
|
state = {
|
||||||
current_recipient_ids: new_recipient_ids,
|
current_recipient_ids: new_recipient_ids,
|
||||||
next_send_start_time: 0,
|
next_send_start_time: 0,
|
||||||
idle_timer: start_or_extend_idle_timer(worker),
|
idle_timer: start_or_extend_idle_timer(worker, typing_stopped_wait_period),
|
||||||
};
|
};
|
||||||
const current_time = worker.get_current_time();
|
const current_time = worker.get_current_time();
|
||||||
actually_ping_server(worker, new_recipient_ids, current_time);
|
actually_ping_server(worker, new_recipient_ids, current_time, typing_started_wait_period);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,21 @@ import * as blueslip from "./blueslip";
|
||||||
import * as channel from "./channel";
|
import * as channel from "./channel";
|
||||||
import * as compose_pm_pill from "./compose_pm_pill";
|
import * as compose_pm_pill from "./compose_pm_pill";
|
||||||
import * as compose_state from "./compose_state";
|
import * as compose_state from "./compose_state";
|
||||||
|
import {page_params} from "./page_params";
|
||||||
import * as people from "./people";
|
import * as people from "./people";
|
||||||
import {user_settings} from "./user_settings";
|
import {user_settings} from "./user_settings";
|
||||||
|
|
||||||
// This module handles the outbound side of typing indicators.
|
// This module handles the outbound side of typing indicators.
|
||||||
// We detect changes in the compose box and notify the server
|
// We detect changes in the compose box and notify the server
|
||||||
// when we are typing. For the inbound side see typing_events.js.
|
// when we are typing. For the inbound side see typing_events.js.
|
||||||
//
|
// See docs/subsystems/typing-indicators.md for more details.
|
||||||
// See docs/subsystems/typing-indicators.md for details on typing indicators.
|
|
||||||
|
// 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(user_ids_array, operation) {
|
function send_typing_notification_ajax(user_ids_array, operation) {
|
||||||
channel.post({
|
channel.post({
|
||||||
|
@ -78,12 +85,17 @@ export function initialize() {
|
||||||
// If our previous state was no typing notification, send a
|
// If our previous state was no typing notification, send a
|
||||||
// start-typing notice immediately.
|
// start-typing notice immediately.
|
||||||
const new_recipient = is_valid_conversation() ? get_recipient() : null;
|
const new_recipient = is_valid_conversation() ? get_recipient() : null;
|
||||||
typing_status.update(worker, new_recipient);
|
typing_status.update(
|
||||||
|
worker,
|
||||||
|
new_recipient,
|
||||||
|
typing_started_wait_period,
|
||||||
|
typing_stopped_wait_period,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// We send a stop-typing notification immediately when compose is
|
// We send a stop-typing notification immediately when compose is
|
||||||
// closed/cancelled
|
// closed/cancelled
|
||||||
$(document).on("compose_canceled.zulip compose_finished.zulip", () => {
|
$(document).on("compose_canceled.zulip compose_finished.zulip", () => {
|
||||||
typing_status.update(worker, null);
|
typing_status.update(worker, null, typing_started_wait_period, typing_stopped_wait_period);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,10 @@ import * as typing_data from "./typing_data";
|
||||||
//
|
//
|
||||||
// We also handle the local event of re-narrowing.
|
// We also handle the local event of re-narrowing.
|
||||||
// (For the outbound code, see typing.js.)
|
// (For the outbound code, see typing.js.)
|
||||||
|
//
|
||||||
// How long before we assume a client has gone away
|
// How long before we assume a client has gone away
|
||||||
// and expire its typing status
|
// and expire the active typing indicator.
|
||||||
const TYPING_STARTED_EXPIRY_PERIOD = 15000; // 15s
|
const typing_started_expiry_period = page_params.server_typing_started_expiry_period_milliseconds;
|
||||||
|
|
||||||
// If number of users typing exceed this,
|
// If number of users typing exceed this,
|
||||||
// we render "Several people are typing..."
|
// we render "Several people are typing..."
|
||||||
|
@ -93,7 +93,7 @@ export function display_notification(event) {
|
||||||
|
|
||||||
render_notifications_for_narrow();
|
render_notifications_for_narrow();
|
||||||
|
|
||||||
typing_data.kickstart_inbound_timer(recipients, TYPING_STARTED_EXPIRY_PERIOD, () => {
|
typing_data.kickstart_inbound_timer(recipients, typing_started_expiry_period, () => {
|
||||||
hide_notification(event);
|
hide_notification(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,9 @@ const compose_pm_pill = mock_esm("../src/compose_pm_pill");
|
||||||
const typing = zrequire("typing");
|
const typing = zrequire("typing");
|
||||||
const typing_status = zrequire("../shared/src/typing_status");
|
const typing_status = zrequire("../shared/src/typing_status");
|
||||||
|
|
||||||
|
const TYPING_STARTED_WAIT_PERIOD = 10000;
|
||||||
|
const TYPING_STOPPED_WAIT_PERIOD = 5000;
|
||||||
|
|
||||||
function make_time(secs) {
|
function make_time(secs) {
|
||||||
// make times semi-realistic
|
// make times semi-realistic
|
||||||
return 1000000 + 1000 * secs;
|
return 1000000 + 1000 * secs;
|
||||||
|
@ -26,7 +29,7 @@ run_test("basics", ({override, override_rewire}) => {
|
||||||
|
|
||||||
// invalid conversation basically does nothing
|
// invalid conversation basically does nothing
|
||||||
let worker = {};
|
let worker = {};
|
||||||
typing_status.update(worker, null);
|
typing_status.update(worker, null, TYPING_STARTED_WAIT_PERIOD, TYPING_STOPPED_WAIT_PERIOD);
|
||||||
|
|
||||||
// Start setting up more testing state.
|
// Start setting up more testing state.
|
||||||
const events = {};
|
const events = {};
|
||||||
|
@ -63,7 +66,12 @@ run_test("basics", ({override, override_rewire}) => {
|
||||||
|
|
||||||
function call_handler(new_recipient) {
|
function call_handler(new_recipient) {
|
||||||
clear_events();
|
clear_events();
|
||||||
typing_status.update(worker, new_recipient);
|
typing_status.update(
|
||||||
|
worker,
|
||||||
|
new_recipient,
|
||||||
|
TYPING_STARTED_WAIT_PERIOD,
|
||||||
|
TYPING_STOPPED_WAIT_PERIOD,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
worker = {
|
worker = {
|
||||||
|
@ -263,12 +271,22 @@ run_test("basics", ({override, override_rewire}) => {
|
||||||
|
|
||||||
// User ids of people in compose narrow doesn't change and is same as stat.current_recipient_ids
|
// User ids of people in compose narrow doesn't change and is same as stat.current_recipient_ids
|
||||||
// so counts of function should increase except stop_last_notification
|
// so counts of function should increase except stop_last_notification
|
||||||
typing_status.update(worker, typing.get_recipient());
|
typing_status.update(
|
||||||
|
worker,
|
||||||
|
typing.get_recipient(),
|
||||||
|
TYPING_STARTED_WAIT_PERIOD,
|
||||||
|
TYPING_STOPPED_WAIT_PERIOD,
|
||||||
|
);
|
||||||
assert.deepEqual(call_count.maybe_ping_server, 1);
|
assert.deepEqual(call_count.maybe_ping_server, 1);
|
||||||
assert.deepEqual(call_count.start_or_extend_idle_timer, 1);
|
assert.deepEqual(call_count.start_or_extend_idle_timer, 1);
|
||||||
assert.deepEqual(call_count.stop_last_notification, 0);
|
assert.deepEqual(call_count.stop_last_notification, 0);
|
||||||
|
|
||||||
typing_status.update(worker, typing.get_recipient());
|
typing_status.update(
|
||||||
|
worker,
|
||||||
|
typing.get_recipient(),
|
||||||
|
TYPING_STARTED_WAIT_PERIOD,
|
||||||
|
TYPING_STOPPED_WAIT_PERIOD,
|
||||||
|
);
|
||||||
assert.deepEqual(call_count.maybe_ping_server, 2);
|
assert.deepEqual(call_count.maybe_ping_server, 2);
|
||||||
assert.deepEqual(call_count.start_or_extend_idle_timer, 2);
|
assert.deepEqual(call_count.start_or_extend_idle_timer, 2);
|
||||||
assert.deepEqual(call_count.stop_last_notification, 0);
|
assert.deepEqual(call_count.stop_last_notification, 0);
|
||||||
|
@ -276,14 +294,24 @@ run_test("basics", ({override, override_rewire}) => {
|
||||||
// change in recipient and new_recipient should make us
|
// change in recipient and new_recipient should make us
|
||||||
// call typing_status.stop_last_notification
|
// call typing_status.stop_last_notification
|
||||||
override(compose_pm_pill, "get_user_ids_string", () => "2,3,4");
|
override(compose_pm_pill, "get_user_ids_string", () => "2,3,4");
|
||||||
typing_status.update(worker, typing.get_recipient());
|
typing_status.update(
|
||||||
|
worker,
|
||||||
|
typing.get_recipient(),
|
||||||
|
TYPING_STARTED_WAIT_PERIOD,
|
||||||
|
TYPING_STOPPED_WAIT_PERIOD,
|
||||||
|
);
|
||||||
assert.deepEqual(call_count.maybe_ping_server, 2);
|
assert.deepEqual(call_count.maybe_ping_server, 2);
|
||||||
assert.deepEqual(call_count.start_or_extend_idle_timer, 3);
|
assert.deepEqual(call_count.start_or_extend_idle_timer, 3);
|
||||||
assert.deepEqual(call_count.stop_last_notification, 1);
|
assert.deepEqual(call_count.stop_last_notification, 1);
|
||||||
|
|
||||||
// Stream messages are represented as get_user_ids_string being empty
|
// Stream messages are represented as get_user_ids_string being empty
|
||||||
override(compose_pm_pill, "get_user_ids_string", () => "");
|
override(compose_pm_pill, "get_user_ids_string", () => "");
|
||||||
typing_status.update(worker, typing.get_recipient());
|
typing_status.update(
|
||||||
|
worker,
|
||||||
|
typing.get_recipient(),
|
||||||
|
TYPING_STARTED_WAIT_PERIOD,
|
||||||
|
TYPING_STOPPED_WAIT_PERIOD,
|
||||||
|
);
|
||||||
assert.deepEqual(call_count.maybe_ping_server, 2);
|
assert.deepEqual(call_count.maybe_ping_server, 2);
|
||||||
assert.deepEqual(call_count.start_or_extend_idle_timer, 3);
|
assert.deepEqual(call_count.start_or_extend_idle_timer, 3);
|
||||||
assert.deepEqual(call_count.stop_last_notification, 2);
|
assert.deepEqual(call_count.stop_last_notification, 2);
|
||||||
|
|
|
@ -364,7 +364,16 @@ def fetch_initial_state_data(
|
||||||
# Presence system parameters for client behavior.
|
# Presence system parameters for client behavior.
|
||||||
state["server_presence_ping_interval_seconds"] = settings.PRESENCE_PING_INTERVAL_SECS
|
state["server_presence_ping_interval_seconds"] = settings.PRESENCE_PING_INTERVAL_SECS
|
||||||
state["server_presence_offline_threshold_seconds"] = settings.OFFLINE_THRESHOLD_SECS
|
state["server_presence_offline_threshold_seconds"] = settings.OFFLINE_THRESHOLD_SECS
|
||||||
|
# Typing notifications protocol parameters for client behavior.
|
||||||
|
state[
|
||||||
|
"server_typing_started_expiry_period_milliseconds"
|
||||||
|
] = settings.TYPING_STARTED_EXPIRY_PERIOD_MILLISECONDS
|
||||||
|
state[
|
||||||
|
"server_typing_stopped_wait_period_milliseconds"
|
||||||
|
] = settings.TYPING_STOPPED_WAIT_PERIOD_MILLISECONDS
|
||||||
|
state[
|
||||||
|
"server_typing_started_wait_period_milliseconds"
|
||||||
|
] = settings.TYPING_STARTED_WAIT_PERIOD_MILLISECONDS
|
||||||
if want("realm_user_settings_defaults"):
|
if want("realm_user_settings_defaults"):
|
||||||
realm_user_default = RealmUserDefault.objects.get(realm=realm)
|
realm_user_default = RealmUserDefault.objects.get(realm=realm)
|
||||||
state["realm_user_settings_defaults"] = {}
|
state["realm_user_settings_defaults"] = {}
|
||||||
|
|
|
@ -11240,7 +11240,7 @@ paths:
|
||||||
|
|
||||||
**Changes**: New in Zulip 7.0 (feature level 164). Clients should use 60
|
**Changes**: New in Zulip 7.0 (feature level 164). Clients should use 60
|
||||||
for older Zulip servers, since that's the value that was hardcoded in the
|
for older Zulip servers, since that's the value that was hardcoded in the
|
||||||
the Zulip mobile apps prior to this parameter being introduced.
|
Zulip mobile apps prior to this parameter being introduced.
|
||||||
server_presence_offline_threshold_seconds:
|
server_presence_offline_threshold_seconds:
|
||||||
type: integer
|
type: integer
|
||||||
description: |
|
description: |
|
||||||
|
@ -11251,6 +11251,39 @@ paths:
|
||||||
**Changes**: New in Zulip 7.0 (feature level 164). Clients should use 140
|
**Changes**: New in Zulip 7.0 (feature level 164). Clients should use 140
|
||||||
for older Zulip servers, since that's the value that was hardcoded in the
|
for older Zulip servers, since that's the value that was hardcoded in the
|
||||||
Zulip client apps prior to this parameter being introduced.
|
Zulip client apps prior to this parameter being introduced.
|
||||||
|
server_typing_started_expiry_period_milliseconds:
|
||||||
|
type: integer
|
||||||
|
description: |
|
||||||
|
For clients implementing [typing notifications](/api/set-typing-status)
|
||||||
|
protocol, the time interval in milliseconds that the client should wait
|
||||||
|
for additional [typing start](/api/get-events#typing-start) events from
|
||||||
|
the server before removing an active typing indicator.
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 8.0 (feature level 204). Clients should use 15000
|
||||||
|
for older Zulip servers, since that's the value that was hardcoded in the
|
||||||
|
Zulip apps prior to this parameter being introduced.
|
||||||
|
server_typing_stopped_wait_period_milliseconds:
|
||||||
|
type: integer
|
||||||
|
description: |
|
||||||
|
For clients implementing [typing notifications](/api/set-typing-status)
|
||||||
|
protocol, the time interval in milliseconds that the client should wait
|
||||||
|
when a user stops interacting with the compose UI before sending a stop
|
||||||
|
notification to the server.
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 8.0 (feature level 204). Clients should use 5000
|
||||||
|
for older Zulip servers, since that's the value that was hardcoded in the
|
||||||
|
Zulip apps prior to this parameter being introduced.
|
||||||
|
server_typing_started_wait_period_milliseconds:
|
||||||
|
type: integer
|
||||||
|
description: |
|
||||||
|
For clients implementing [typing notifications](/api/set-typing-status)
|
||||||
|
protocol, the time interval in milliseconds that the client should use
|
||||||
|
to send regular start notifications to the server to indicate that the
|
||||||
|
user is still actively interacting with the compose UI.
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 8.0 (feature level 204). Clients should use 10000
|
||||||
|
for older Zulip servers, since that's the value that was hardcoded in the
|
||||||
|
Zulip apps prior to this parameter being introduced.
|
||||||
scheduled_messages:
|
scheduled_messages:
|
||||||
type: array
|
type: array
|
||||||
description: |
|
description: |
|
||||||
|
|
|
@ -199,6 +199,9 @@ class HomeTest(ZulipTestCase):
|
||||||
"server_presence_ping_interval_seconds",
|
"server_presence_ping_interval_seconds",
|
||||||
"server_sentry_dsn",
|
"server_sentry_dsn",
|
||||||
"server_timestamp",
|
"server_timestamp",
|
||||||
|
"server_typing_started_expiry_period_milliseconds",
|
||||||
|
"server_typing_started_wait_period_milliseconds",
|
||||||
|
"server_typing_stopped_wait_period_milliseconds",
|
||||||
"server_web_public_streams_enabled",
|
"server_web_public_streams_enabled",
|
||||||
"settings_send_digest_emails",
|
"settings_send_digest_emails",
|
||||||
"show_billing",
|
"show_billing",
|
||||||
|
|
|
@ -574,3 +574,16 @@ MAX_MESSAGE_LENGTH = 10000
|
||||||
# More drafts, should they exist for some crazy reason, could be
|
# More drafts, should they exist for some crazy reason, could be
|
||||||
# fetched in a separate request.
|
# fetched in a separate request.
|
||||||
MAX_DRAFTS_IN_REGISTER_RESPONSE = 1000
|
MAX_DRAFTS_IN_REGISTER_RESPONSE = 1000
|
||||||
|
|
||||||
|
# How long before a client should assume that another client sending
|
||||||
|
# typing notifications has gone away and expire the active typing
|
||||||
|
# indicator.
|
||||||
|
TYPING_STARTED_EXPIRY_PERIOD_MILLISECONDS = 15000
|
||||||
|
|
||||||
|
# How long after a user has stopped interacting with the compose UI
|
||||||
|
# that a client should send a stop notification to the server.
|
||||||
|
TYPING_STOPPED_WAIT_PERIOD_MILLISECONDS = 5000
|
||||||
|
|
||||||
|
# How often a client should send start notifications to the server to
|
||||||
|
# indicate that the user is still interacting with the compose UI.
|
||||||
|
TYPING_STARTED_WAIT_PERIOD_MILLISECONDS = 10000
|
||||||
|
|
Loading…
Reference in New Issue