stream-chat 8.15.0 → 8.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.es.js +1018 -668
- package/dist/browser.es.js.map +1 -1
- package/dist/browser.full-bundle.min.js +1 -1
- package/dist/browser.full-bundle.min.js.map +1 -1
- package/dist/browser.js +1019 -667
- package/dist/browser.js.map +1 -1
- package/dist/index.es.js +1018 -668
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1019 -667
- package/dist/index.js.map +1 -1
- package/dist/types/channel.d.ts +6 -2
- package/dist/types/channel.d.ts.map +1 -1
- package/dist/types/channel_state.d.ts.map +1 -1
- package/dist/types/client.d.ts +40 -27
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/events.d.ts +1 -0
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/thread.d.ts +28 -0
- package/dist/types/thread.d.ts.map +1 -0
- package/dist/types/types.d.ts +54 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils.d.ts +10 -1
- package/dist/types/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/channel.ts +4 -2
- package/src/channel_state.ts +2 -58
- package/src/client.ts +103 -0
- package/src/events.ts +1 -0
- package/src/index.ts +2 -1
- package/src/thread.ts +116 -0
- package/src/types.ts +61 -0
- package/src/utils.ts +101 -1
package/src/thread.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { StreamChat } from './client';
|
|
2
|
+
import {
|
|
3
|
+
DefaultGenerics,
|
|
4
|
+
ExtendableGenerics,
|
|
5
|
+
MessageResponse,
|
|
6
|
+
ThreadResponse,
|
|
7
|
+
ChannelResponse,
|
|
8
|
+
FormatMessageResponse,
|
|
9
|
+
ReactionResponse,
|
|
10
|
+
UserResponse,
|
|
11
|
+
} from './types';
|
|
12
|
+
import { addToMessageList, formatMessage } from './utils';
|
|
13
|
+
|
|
14
|
+
type ThreadReadStatus<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<
|
|
15
|
+
string,
|
|
16
|
+
{
|
|
17
|
+
last_read: Date;
|
|
18
|
+
last_read_message_id: string;
|
|
19
|
+
unread_messages: number;
|
|
20
|
+
user: UserResponse<StreamChatGenerics>;
|
|
21
|
+
}
|
|
22
|
+
>;
|
|
23
|
+
|
|
24
|
+
export class Thread<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
25
|
+
id: string;
|
|
26
|
+
latestReplies: FormatMessageResponse<StreamChatGenerics>[] = [];
|
|
27
|
+
participants: ThreadResponse['thread_participants'] = [];
|
|
28
|
+
message: FormatMessageResponse<StreamChatGenerics>;
|
|
29
|
+
channel: ChannelResponse<StreamChatGenerics>;
|
|
30
|
+
_channel: ReturnType<StreamChat<StreamChatGenerics>['channel']>;
|
|
31
|
+
replyCount = 0;
|
|
32
|
+
_client: StreamChat<StreamChatGenerics>;
|
|
33
|
+
read: ThreadReadStatus<StreamChatGenerics> = {};
|
|
34
|
+
|
|
35
|
+
constructor(client: StreamChat<StreamChatGenerics>, t: ThreadResponse<StreamChatGenerics>) {
|
|
36
|
+
this.id = t.parent_message.id;
|
|
37
|
+
this.message = formatMessage(t.parent_message);
|
|
38
|
+
this.latestReplies = t.latest_replies.map(formatMessage);
|
|
39
|
+
this.participants = t.thread_participants;
|
|
40
|
+
this.replyCount = t.reply_count;
|
|
41
|
+
this.channel = t.channel;
|
|
42
|
+
this._channel = client.channel(t.channel.type, t.channel.id);
|
|
43
|
+
this._client = client;
|
|
44
|
+
for (const r of t.read) {
|
|
45
|
+
this.read[r.user.id] = {
|
|
46
|
+
...r,
|
|
47
|
+
last_read: new Date(r.last_read),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getClient(): StreamChat<StreamChatGenerics> {
|
|
53
|
+
return this._client;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
addReply(message: MessageResponse<StreamChatGenerics>) {
|
|
57
|
+
this.latestReplies = addToMessageList(this.latestReplies, formatMessage(message));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
updateReply(message: MessageResponse<StreamChatGenerics>) {
|
|
61
|
+
this.latestReplies = this.latestReplies.map((m) => {
|
|
62
|
+
if (m.id === message.id) {
|
|
63
|
+
return formatMessage(message);
|
|
64
|
+
}
|
|
65
|
+
return m;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
updateMessageOrReplyIfExists(message: MessageResponse<StreamChatGenerics>) {
|
|
70
|
+
if (!message.parent_id && message.id !== this.message.id) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (message.parent_id && message.parent_id !== this.message.id) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (message.parent_id && message.parent_id === this.message.id) {
|
|
79
|
+
this.updateReply(message);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!message.parent_id && message.id === this.message.id) {
|
|
83
|
+
this.message = formatMessage(message);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
addReaction(
|
|
88
|
+
reaction: ReactionResponse<StreamChatGenerics>,
|
|
89
|
+
message?: MessageResponse<StreamChatGenerics>,
|
|
90
|
+
enforce_unique?: boolean,
|
|
91
|
+
) {
|
|
92
|
+
if (!message) return;
|
|
93
|
+
|
|
94
|
+
this.latestReplies = this.latestReplies.map((m) => {
|
|
95
|
+
if (m.id === message.id) {
|
|
96
|
+
return formatMessage(
|
|
97
|
+
this._channel.state.addReaction(reaction, message, enforce_unique) as MessageResponse<StreamChatGenerics>,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return m;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
removeReaction(reaction: ReactionResponse<StreamChatGenerics>, message?: MessageResponse<StreamChatGenerics>) {
|
|
105
|
+
if (!message) return;
|
|
106
|
+
|
|
107
|
+
this.latestReplies = this.latestReplies.map((m) => {
|
|
108
|
+
if (m.id === message.id) {
|
|
109
|
+
return formatMessage(
|
|
110
|
+
this._channel.state.removeReaction(reaction, message) as MessageResponse<StreamChatGenerics>,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return m;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -478,6 +478,58 @@ export type GetMessageAPIResponse<
|
|
|
478
478
|
StreamChatGenerics extends ExtendableGenerics = DefaultGenerics
|
|
479
479
|
> = SendMessageAPIResponse<StreamChatGenerics>;
|
|
480
480
|
|
|
481
|
+
export type ThreadResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
482
|
+
channel: ChannelResponse<StreamChatGenerics>;
|
|
483
|
+
channel_cid: string;
|
|
484
|
+
created_at: string;
|
|
485
|
+
deleted_at: string;
|
|
486
|
+
latest_replies: MessageResponse<StreamChatGenerics>[];
|
|
487
|
+
parent_message: MessageResponse<StreamChatGenerics>;
|
|
488
|
+
parent_message_id: string;
|
|
489
|
+
read: {
|
|
490
|
+
last_read: string;
|
|
491
|
+
last_read_message_id: string;
|
|
492
|
+
unread_messages: number;
|
|
493
|
+
user: UserResponse<StreamChatGenerics>;
|
|
494
|
+
}[];
|
|
495
|
+
reply_count: number;
|
|
496
|
+
thread_participants: {
|
|
497
|
+
created_at: string;
|
|
498
|
+
user: UserResponse<StreamChatGenerics>;
|
|
499
|
+
}[];
|
|
500
|
+
title: string;
|
|
501
|
+
updated_at: string;
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// TODO: Figure out a way to strongly type set and unset.
|
|
505
|
+
export type PartialThreadUpdate = {
|
|
506
|
+
set?: Partial<Record<string, unknown>>;
|
|
507
|
+
unset?: Partial<Record<string, unknown>>;
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
export type QueryThreadsOptions = {
|
|
511
|
+
limit?: number;
|
|
512
|
+
next?: string;
|
|
513
|
+
participant_limit?: number;
|
|
514
|
+
reply_limit?: number;
|
|
515
|
+
watch?: boolean;
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
export type QueryThreadsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
519
|
+
threads: ThreadResponse<StreamChatGenerics>[];
|
|
520
|
+
next?: string;
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
export type GetThreadOptions = {
|
|
524
|
+
participant_limit?: number;
|
|
525
|
+
reply_limit?: number;
|
|
526
|
+
watch?: boolean;
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
export type GetThreadAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
530
|
+
thread: ThreadResponse<StreamChatGenerics>;
|
|
531
|
+
};
|
|
532
|
+
|
|
481
533
|
export type GetMultipleMessagesAPIResponse<
|
|
482
534
|
StreamChatGenerics extends ExtendableGenerics = DefaultGenerics
|
|
483
535
|
> = APIResponse & {
|
|
@@ -510,7 +562,14 @@ export type GetUnreadCountAPIResponse = APIResponse & {
|
|
|
510
562
|
last_read: string;
|
|
511
563
|
unread_count: number;
|
|
512
564
|
}[];
|
|
565
|
+
threads: {
|
|
566
|
+
last_read: string;
|
|
567
|
+
last_read_message_id: string;
|
|
568
|
+
parent_message_id: string;
|
|
569
|
+
unread_count: number;
|
|
570
|
+
}[];
|
|
513
571
|
total_unread_count: number;
|
|
572
|
+
total_unread_threads_count: number;
|
|
514
573
|
};
|
|
515
574
|
|
|
516
575
|
export type GetUnreadCountBatchAPIResponse = APIResponse & {
|
|
@@ -893,6 +952,7 @@ export type MarkChannelsReadOptions<StreamChatGenerics extends ExtendableGeneric
|
|
|
893
952
|
export type MarkReadOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
894
953
|
client_id?: string;
|
|
895
954
|
connection_id?: string;
|
|
955
|
+
thread_id?: string;
|
|
896
956
|
user?: UserResponse<StreamChatGenerics>;
|
|
897
957
|
user_id?: string;
|
|
898
958
|
};
|
|
@@ -1099,6 +1159,7 @@ export type Event<StreamChatGenerics extends ExtendableGenerics = DefaultGeneric
|
|
|
1099
1159
|
reaction?: ReactionResponse<StreamChatGenerics>;
|
|
1100
1160
|
received_at?: string | Date;
|
|
1101
1161
|
team?: string;
|
|
1162
|
+
thread?: ThreadResponse<StreamChatGenerics>;
|
|
1102
1163
|
// @deprecated number of all unread messages across all current user's unread channels, equals unread_count
|
|
1103
1164
|
total_unread_count?: number;
|
|
1104
1165
|
// number of all current user's channels with at least one unread message including the channel in this event
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import FormData from 'form-data';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AscDesc,
|
|
4
|
+
ExtendableGenerics,
|
|
5
|
+
DefaultGenerics,
|
|
6
|
+
OwnUserBase,
|
|
7
|
+
OwnUserResponse,
|
|
8
|
+
UserResponse,
|
|
9
|
+
MessageResponse,
|
|
10
|
+
FormatMessageResponse,
|
|
11
|
+
} from './types';
|
|
3
12
|
import { AxiosRequestConfig } from 'axios';
|
|
4
13
|
|
|
5
14
|
/**
|
|
@@ -263,3 +272,94 @@ export const axiosParamsSerializer: AxiosRequestConfig['paramsSerializer'] = (pa
|
|
|
263
272
|
|
|
264
273
|
return newParams.join('&');
|
|
265
274
|
};
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* formatMessage - Takes the message object. Parses the dates, sets __html
|
|
278
|
+
* and sets the status to received if missing. Returns a message object
|
|
279
|
+
*
|
|
280
|
+
* @param {MessageResponse<StreamChatGenerics>} message a message object
|
|
281
|
+
*
|
|
282
|
+
*/
|
|
283
|
+
export function formatMessage<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(
|
|
284
|
+
message: MessageResponse<StreamChatGenerics>,
|
|
285
|
+
): FormatMessageResponse<StreamChatGenerics> {
|
|
286
|
+
return {
|
|
287
|
+
...message,
|
|
288
|
+
/**
|
|
289
|
+
* @deprecated please use `html`
|
|
290
|
+
*/
|
|
291
|
+
__html: message.html,
|
|
292
|
+
// parse the date..
|
|
293
|
+
pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,
|
|
294
|
+
created_at: message.created_at ? new Date(message.created_at) : new Date(),
|
|
295
|
+
updated_at: message.updated_at ? new Date(message.updated_at) : new Date(),
|
|
296
|
+
status: message.status || 'received',
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function addToMessageList<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(
|
|
301
|
+
messages: Array<FormatMessageResponse<StreamChatGenerics>>,
|
|
302
|
+
message: FormatMessageResponse<StreamChatGenerics>,
|
|
303
|
+
timestampChanged = false,
|
|
304
|
+
sortBy: 'pinned_at' | 'created_at' = 'created_at',
|
|
305
|
+
addIfDoesNotExist = true,
|
|
306
|
+
) {
|
|
307
|
+
const addMessageToList = addIfDoesNotExist || timestampChanged;
|
|
308
|
+
let messageArr = messages;
|
|
309
|
+
|
|
310
|
+
// if created_at has changed, message should be filtered and re-inserted in correct order
|
|
311
|
+
// slow op but usually this only happens for a message inserted to state before actual response with correct timestamp
|
|
312
|
+
if (timestampChanged) {
|
|
313
|
+
messageArr = messageArr.filter((msg) => !(msg.id && message.id === msg.id));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Get array length after filtering
|
|
317
|
+
const messageArrayLength = messageArr.length;
|
|
318
|
+
|
|
319
|
+
// for empty list just concat and return unless it's an update or deletion
|
|
320
|
+
if (messageArrayLength === 0 && addMessageToList) {
|
|
321
|
+
return messageArr.concat(message);
|
|
322
|
+
} else if (messageArrayLength === 0) {
|
|
323
|
+
return [...messageArr];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const messageTime = (message[sortBy] as Date).getTime();
|
|
327
|
+
const messageIsNewest = (messageArr[messageArrayLength - 1][sortBy] as Date).getTime() < messageTime;
|
|
328
|
+
|
|
329
|
+
// if message is newer than last item in the list concat and return unless it's an update or deletion
|
|
330
|
+
if (messageIsNewest && addMessageToList) {
|
|
331
|
+
return messageArr.concat(message);
|
|
332
|
+
} else if (messageIsNewest) {
|
|
333
|
+
return [...messageArr];
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// find the closest index to push the new message
|
|
337
|
+
let left = 0;
|
|
338
|
+
let middle = 0;
|
|
339
|
+
let right = messageArrayLength - 1;
|
|
340
|
+
while (left <= right) {
|
|
341
|
+
middle = Math.floor((right + left) / 2);
|
|
342
|
+
if ((messageArr[middle][sortBy] as Date).getTime() <= messageTime) left = middle + 1;
|
|
343
|
+
else right = middle - 1;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// message already exists and not filtered due to timestampChanged, update and return
|
|
347
|
+
if (!timestampChanged && message.id) {
|
|
348
|
+
if (messageArr[left] && message.id === messageArr[left].id) {
|
|
349
|
+
messageArr[left] = message;
|
|
350
|
+
return [...messageArr];
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (messageArr[left - 1] && message.id === messageArr[left - 1].id) {
|
|
354
|
+
messageArr[left - 1] = message;
|
|
355
|
+
return [...messageArr];
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Do not add updated or deleted messages to the list if they do not already exist
|
|
360
|
+
// or have a timestamp change.
|
|
361
|
+
if (addMessageToList) {
|
|
362
|
+
messageArr.splice(left, 0, message);
|
|
363
|
+
}
|
|
364
|
+
return [...messageArr];
|
|
365
|
+
}
|