Skip to content

Commit dcfe970

Browse files
committed
typing api: Use recipients format based on server version.
Zulip server versions >= 2.0.0-rc1 (zulip/zulip@2f634f8c0) require user ID arrays in the 'to' argument for the typing endpoint, whereas we currently send email arrays. Check the Zulip version and use the appropriate format of the argument, i.e., for versions >= 2.0.0-rc1 or when the Zulip server version is undetermined [1], use user ID arrays, otherwise, use email arrays. [1] The server started providing its version as early as zulip/zulip@d9b10727fa (released in 1.6.0, in 2017-06). It's more likely that we failed to parse a new, exotic version-string format than that someone's actually trying to connect to a Zulip server that doesn't provide one. Fixes #3732.
1 parent 5631e43 commit dcfe970

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed

src/users/usersActions.js

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/* @flow strict-local */
22
import * as typing_status from '@zulip/shared/js/typing_status';
33

4-
import type { Dispatch, GetState, Narrow } from '../types';
4+
import type { Auth, Account, Dispatch, GetState, GlobalState, Narrow } from '../types';
55
import * as api from '../api';
66
import { PRESENCE_RESPONSE } from '../actionConstants';
7-
import { getAuth, tryGetAuth } from '../selectors';
7+
import { getAuth, tryGetAuth, getActiveAccount, getServerVersion } from '../selectors';
88
import { isPrivateOrGroupNarrow, caseNarrowPartial } from '../utils/narrow';
9-
import { getAllUsersByEmail } from './userSelectors';
9+
import { getAllUsersByEmail, getUserForId } from './userSelectors';
10+
import { ZulipVersion } from '../utils/zulipVersion';
1011

1112
export const reportPresence = (isActive: boolean = true, newUserInput: boolean = false) => async (
1213
dispatch: Dispatch,
@@ -25,17 +26,40 @@ export const reportPresence = (isActive: boolean = true, newUserInput: boolean =
2526
});
2627
};
2728

28-
const typingWorker = auth => ({
29-
get_current_time: () => new Date().getTime(),
29+
const typingWorker = (state: GlobalState) => {
30+
const auth: Auth = getAuth(state);
31+
const serverVersion: ZulipVersion | void = getServerVersion(state);
3032

31-
notify_server_start: (user_ids_array: number[]) => {
32-
api.typing(auth, JSON.stringify(user_ids_array), 'start');
33-
},
33+
// User ID arrays are only supported in server versions >= 2.0.0-rc1
34+
// (zulip/zulip@2f634f8c0). For versions before this, email arrays
35+
// are used. If current server version is undetermined, user ID
36+
// arrays are optimistically used.
37+
let useEmailArrays: boolean;
38+
if (serverVersion === undefined) {
39+
useEmailArrays = false;
40+
} else {
41+
useEmailArrays = !serverVersion.isAtLeast(new ZulipVersion('2.0.0-rc1'));
42+
}
43+
44+
const getRecipients = user_ids_array => {
45+
if (useEmailArrays) {
46+
return JSON.stringify(user_ids_array.map(userId => getUserForId(state, userId).email));
47+
}
48+
return JSON.stringify(user_ids_array);
49+
};
50+
51+
return {
52+
get_current_time: () => new Date().getTime(),
3453

35-
notify_server_stop: (user_ids_array: number[]) => {
36-
api.typing(auth, JSON.stringify(user_ids_array), 'stop');
37-
},
38-
});
54+
notify_server_start: (user_ids_array: number[]) => {
55+
api.typing(auth, getRecipients(user_ids_array), 'start');
56+
},
57+
58+
notify_server_stop: (user_ids_array: number[]) => {
59+
api.typing(auth, getRecipients(user_ids_array), 'stop');
60+
},
61+
};
62+
};
3963

4064
export const sendTypingStart = (narrow: Narrow) => async (
4165
dispatch: Dispatch,
@@ -56,9 +80,7 @@ export const sendTypingStart = (narrow: Narrow) => async (
5680
}
5781
return user.user_id;
5882
});
59-
60-
const auth = getAuth(getState());
61-
typing_status.update(typingWorker(auth), recipientIds);
83+
typing_status.update(typingWorker(getState()), recipientIds);
6284
};
6385

6486
// TODO call this on more than send: blur, navigate away,
@@ -71,6 +93,5 @@ export const sendTypingStop = (narrow: Narrow) => async (
7193
return;
7294
}
7395

74-
const auth = getAuth(getState());
75-
typing_status.update(typingWorker(auth), null);
96+
typing_status.update(typingWorker(getState()), null);
7697
};

0 commit comments

Comments
 (0)