typing_status: Use TypeScript unions for 'Recipient' type.

Typing 'Recipient' as union of 'stream' and 'direct' message type will help with upcoming type inference.
This commit is contained in:
Varun Singh 2024-01-24 00:16:07 +05:30 committed by Tim Abbott
parent b64a9d6ae0
commit 391e2a8e01
4 changed files with 61 additions and 41 deletions

View File

@ -4,16 +4,23 @@
"use strict";
type RecipientUserIds<UserId: number> = $ReadOnlyArray<UserId>;
type StreamTopicObject = {|stream_id: number, topic: string|};
type DirectMessageObject<UserId: number> = {|
message_type: string,
ids: $ReadOnlyArray<UserId>,
|};
type StreamObject = {|
message_type: string,
stream_id: number,
topic: string,
|};
type Worker<UserId> = {|
get_current_time: () => number, // as ms since epoch
notify_server_start: (RecipientUserIds<UserId> | StreamTopicObject) => void,
notify_server_stop: (RecipientUserIds<UserId> | StreamTopicObject) => void,
notify_server_start: (DirectMessageObject<UserId> | StreamObject) => void,
notify_server_stop: (DirectMessageObject<UserId> | StreamObject) => void,
|};
declare export function update<UserId>(
worker: Worker<UserId>,
new_recipient: RecipientUserIds<UserId> | StreamTopicObject | null,
new_recipient: DirectMessageObject<UserId> | StreamObject | null,
): void;

View File

@ -5,7 +5,14 @@ type StreamTopic = {
stream_id: number;
topic: string;
};
type Recipient = number[] | StreamTopic;
export type Recipient =
| {
message_type: "direct";
ids: number[];
}
| (StreamTopic & {
message_type: "stream";
});
type TypingStatusWorker = {
get_current_time: () => number;
notify_server_start: (recipient: Recipient) => void;
@ -32,10 +39,10 @@ function same_recipient(a: Recipient | null, b: Recipient | null): boolean {
return false;
}
if (Array.isArray(a) && Array.isArray(b)) {
if (a.message_type === "direct" && b.message_type === "direct") {
// direct message recipients
return _.isEqual(a, b);
} else if (!Array.isArray(a) && !Array.isArray(b)) {
return _.isEqual(a.ids, b.ids);
} else if (a.message_type === "stream" && b.message_type === "stream") {
// stream recipients
return same_stream_and_topic(a, b);
}
@ -120,9 +127,9 @@ export function maybe_ping_server(
* @param {*} worker Callbacks for reaching the real world. See typing.js
* for implementations.
* @param {*} new_recipient Depends on type of message being composed. If
* * Direct message: The users the DM being composed is addressed to,
* as a sorted array of user IDs
* * Stream message: An Object containing the stream_id and topic
* * Direct message: An Object containing id of users the DM being composed is addressed to
* and a message_type="direct" property.
* * Stream message: An Object containing stream_id, topic and message_type="stream".
* * No message is being composed: `null`
*/
export function update(

View File

@ -48,10 +48,9 @@ function send_stream_typing_notification(stream_id, topic, operation) {
}
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) {
if (to.message_type === "direct" && user_settings.send_private_typing_notifications) {
send_direct_message_typing_notification(to.ids, operation);
} else if (to.message_type === "stream" && user_settings.send_stream_typing_notifications) {
send_stream_typing_notification(to.stream_id, to.topic, operation);
}
}
@ -89,13 +88,20 @@ function notify_server_stop(to) {
export function get_recipient() {
const message_type = compose_state.get_message_type();
if (message_type === "private") {
return get_user_ids_array();
return {
message_type: "direct",
ids: 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 {
message_type: "stream",
stream_id,
topic,
};
}
return null;
}

View File

@ -50,12 +50,12 @@ run_test("basics", ({override, override_rewire}) => {
set_global("clearTimeout", clear_timeout);
function notify_server_start(recipient) {
assert.deepStrictEqual(recipient, [1, 2]);
assert.deepStrictEqual(recipient, {message_type: "direct", ids: [1, 2]});
events.started = true;
}
function notify_server_stop(recipient) {
assert.deepStrictEqual(recipient, [1, 2]);
assert.deepStrictEqual(recipient, {message_type: "direct", ids: [1, 2]});
events.stopped = true;
}
@ -83,11 +83,11 @@ run_test("basics", ({override, override_rewire}) => {
};
// Start talking to users having ids - 1, 2.
call_handler([1, 2]);
call_handler({message_type: "direct", ids: [1, 2]});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(5 + 10),
idle_timer: "idle_timer_stub",
current_recipient: [1, 2],
current_recipient: {message_type: "direct", ids: [1, 2]},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -99,11 +99,11 @@ run_test("basics", ({override, override_rewire}) => {
// type again 3 seconds later
worker.get_current_time = returns_time(8);
call_handler([1, 2]);
call_handler({message_type: "direct", ids: [1, 2]});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(5 + 10),
idle_timer: "idle_timer_stub",
current_recipient: [1, 2],
current_recipient: {message_type: "direct", ids: [1, 2]},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -116,11 +116,11 @@ run_test("basics", ({override, override_rewire}) => {
// type after 15 secs, so that we can notify the server
// again
worker.get_current_time = returns_time(18);
call_handler([1, 2]);
call_handler({message_type: "direct", ids: [1, 2]});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(18 + 10),
idle_timer: "idle_timer_stub",
current_recipient: [1, 2],
current_recipient: {message_type: "direct", ids: [1, 2]},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -153,11 +153,11 @@ run_test("basics", ({override, override_rewire}) => {
// Start talking to users again.
worker.get_current_time = returns_time(50);
call_handler([1, 2]);
call_handler({message_type: "direct", ids: [1, 2]});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(50 + 10),
idle_timer: "idle_timer_stub",
current_recipient: [1, 2],
current_recipient: {message_type: "direct", ids: [1, 2]},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -179,11 +179,11 @@ run_test("basics", ({override, override_rewire}) => {
// Start talking to users again.
worker.get_current_time = returns_time(80);
call_handler([1, 2]);
call_handler({message_type: "direct", ids: [1, 2]});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(80 + 10),
idle_timer: "idle_timer_stub",
current_recipient: [1, 2],
current_recipient: {message_type: "direct", ids: [1, 2]},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -215,11 +215,11 @@ run_test("basics", ({override, override_rewire}) => {
// Start talking to users again.
worker.get_current_time = returns_time(170);
call_handler([1, 2]);
call_handler({message_type: "direct", ids: [1, 2]});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(170 + 10),
idle_timer: "idle_timer_stub",
current_recipient: [1, 2],
current_recipient: {message_type: "direct", ids: [1, 2]},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -233,15 +233,15 @@ run_test("basics", ({override, override_rewire}) => {
worker.get_current_time = returns_time(171);
worker.notify_server_start = (recipient) => {
assert.deepStrictEqual(recipient, [3, 4]);
assert.deepStrictEqual(recipient, {message_type: "direct", ids: [3, 4]});
events.started = true;
};
call_handler([3, 4]);
call_handler({message_type: "direct", ids: [3, 4]});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(171 + 10),
idle_timer: "idle_timer_stub",
current_recipient: [3, 4],
current_recipient: {message_type: "direct", ids: [3, 4]},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -343,12 +343,12 @@ run_test("stream_messages", ({override_rewire}) => {
set_global("clearTimeout", clear_timeout);
function notify_server_start(recipient) {
assert.deepStrictEqual(recipient, {stream_id: 3, topic: "test"});
assert.deepStrictEqual(recipient, {message_type: "stream", stream_id: 3, topic: "test"});
events.started = true;
}
function notify_server_stop(recipient) {
assert.deepStrictEqual(recipient, {stream_id: 3, topic: "test"});
assert.deepStrictEqual(recipient, {message_type: "stream", stream_id: 3, topic: "test"});
events.stopped = true;
}
@ -376,11 +376,11 @@ run_test("stream_messages", ({override_rewire}) => {
};
// Start typing stream message
call_handler({stream_id: 3, topic: "test"});
call_handler({message_type: "stream", stream_id: 3, topic: "test"});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(5 + 10),
idle_timer: "idle_timer_stub",
current_recipient: {stream_id: 3, topic: "test"},
current_recipient: {message_type: "stream", stream_id: 3, topic: "test"},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,
@ -392,11 +392,11 @@ run_test("stream_messages", ({override_rewire}) => {
// type again 3 seconds later. Covers 'same_stream_and_topic' codepath.
worker.get_current_time = returns_time(8);
call_handler({stream_id: 3, topic: "test"});
call_handler({message_type: "stream", stream_id: 3, topic: "test"});
assert.deepEqual(typing_status.state, {
next_send_start_time: make_time(5 + 10),
idle_timer: "idle_timer_stub",
current_recipient: {stream_id: 3, topic: "test"},
current_recipient: {message_type: "stream", stream_id: 3, topic: "test"},
});
assert.deepEqual(events, {
idle_callback: events.idle_callback,