stream-chat 8.50.0 → 8.51.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/src/thread.ts CHANGED
@@ -11,6 +11,7 @@ import type {
11
11
  MessageResponse,
12
12
  ReadResponse,
13
13
  ThreadResponse,
14
+ ThreadResponseCustomData,
14
15
  UserResponse,
15
16
  } from './types';
16
17
  import { addToMessageList, findIndexInSortedArray, formatMessage, throttle } from './utils';
@@ -27,6 +28,7 @@ export type ThreadState<SCG extends ExtendableGenerics = DefaultGenerics> = {
27
28
  active: boolean;
28
29
  channel: Channel<SCG>;
29
30
  createdAt: Date;
31
+ custom: ThreadResponseCustomData;
30
32
  deletedAt: Date | null;
31
33
  isLoading: boolean;
32
34
  isStateStale: boolean;
@@ -40,6 +42,7 @@ export type ThreadState<SCG extends ExtendableGenerics = DefaultGenerics> = {
40
42
  read: ThreadReadState;
41
43
  replies: Array<FormatMessageResponse<SCG>>;
42
44
  replyCount: number;
45
+ title: string;
43
46
  updatedAt: Date | null;
44
47
  };
45
48
 
@@ -65,6 +68,43 @@ export type ThreadReadState<SCG extends ExtendableGenerics = DefaultGenerics> =
65
68
  const DEFAULT_PAGE_LIMIT = 50;
66
69
  const DEFAULT_SORT: { created_at: AscDesc }[] = [{ created_at: -1 }];
67
70
  const MARK_AS_READ_THROTTLE_TIMEOUT = 1000;
71
+ // TODO: remove this once we move to API v2
72
+ export const THREAD_RESPONSE_RESERVED_KEYS: Record<keyof ThreadResponse, true> = {
73
+ channel: true,
74
+ channel_cid: true,
75
+ created_at: true,
76
+ created_by_user_id: true,
77
+ parent_message_id: true,
78
+ title: true,
79
+ updated_at: true,
80
+ latest_replies: true,
81
+ active_participant_count: true,
82
+ deleted_at: true,
83
+ last_message_at: true,
84
+ participant_count: true,
85
+ reply_count: true,
86
+ read: true,
87
+ thread_participants: true,
88
+ created_by: true,
89
+ parent_message: true,
90
+ };
91
+
92
+ // TODO: remove this once we move to API v2
93
+ const constructCustomDataObject = <T extends ThreadResponse>(threadData: T) => {
94
+ const custom: ThreadResponseCustomData = {};
95
+
96
+ for (const key in threadData) {
97
+ if (THREAD_RESPONSE_RESERVED_KEYS[key as keyof ThreadResponse]) {
98
+ continue;
99
+ }
100
+
101
+ const customKey = key as keyof ThreadResponseCustomData;
102
+
103
+ custom[customKey] = threadData[customKey];
104
+ }
105
+
106
+ return custom;
107
+ };
68
108
 
69
109
  export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
70
110
  public readonly state: StateStore<ThreadState<SCG>>;
@@ -87,12 +127,15 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
87
127
  : [];
88
128
 
89
129
  this.state = new StateStore<ThreadState<SCG>>({
130
+ // local only
90
131
  active: false,
132
+ isLoading: false,
133
+ isStateStale: false,
134
+ // 99.9% should never change
91
135
  channel,
92
136
  createdAt: new Date(threadData.created_at),
137
+ // rest
93
138
  deletedAt: threadData.deleted_at ? new Date(threadData.deleted_at) : null,
94
- isLoading: false,
95
- isStateStale: false,
96
139
  pagination: repliesPaginationFromInitialThread(threadData),
97
140
  parentMessage: formatMessage(threadData.parent_message),
98
141
  participants: threadData.thread_participants,
@@ -102,6 +145,8 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
102
145
  replies: threadData.latest_replies.map(formatMessage),
103
146
  replyCount: threadData.reply_count ?? 0,
104
147
  updatedAt: threadData.updated_at ? new Date(threadData.updated_at) : null,
148
+ title: threadData.title,
149
+ custom: constructCustomDataObject(threadData),
105
150
  });
106
151
 
107
152
  this.id = threadData.parent_message_id;
@@ -186,6 +231,7 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
186
231
  return;
187
232
  }
188
233
 
234
+ this.unsubscribeFunctions.add(this.subscribeThreadUpdated());
189
235
  this.unsubscribeFunctions.add(this.subscribeMarkActiveThreadRead());
190
236
  this.unsubscribeFunctions.add(this.subscribeReloadActiveStaleThread());
191
237
  this.unsubscribeFunctions.add(this.subscribeMarkThreadStale());
@@ -195,6 +241,24 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
195
241
  this.unsubscribeFunctions.add(this.subscribeMessageUpdated());
196
242
  };
197
243
 
244
+ private subscribeThreadUpdated = () => {
245
+ return this.client.on('thread.updated', (event) => {
246
+ if (!event.thread || event.thread.parent_message_id !== this.id) {
247
+ return;
248
+ }
249
+
250
+ const threadData = event.thread;
251
+
252
+ this.state.partialNext({
253
+ title: threadData.title,
254
+ updatedAt: new Date(threadData.updated_at),
255
+ deletedAt: threadData.deleted_at ? new Date(threadData.deleted_at) : null,
256
+ // TODO: use threadData.custom once we move to API v2
257
+ custom: constructCustomDataObject(threadData),
258
+ });
259
+ }).unsubscribe;
260
+ };
261
+
198
262
  private subscribeMarkActiveThreadRead = () => {
199
263
  return this.state.subscribeWithSelector(
200
264
  (nextValue) => ({
package/src/types.ts CHANGED
@@ -520,7 +520,10 @@ export type GetMessageAPIResponse<
520
520
  StreamChatGenerics extends ExtendableGenerics = DefaultGenerics
521
521
  > = SendMessageAPIResponse<StreamChatGenerics>;
522
522
 
523
- export interface ThreadResponse<SCG extends ExtendableGenerics = DefaultGenerics> {
523
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
524
+ export interface ThreadResponseCustomData {}
525
+
526
+ export interface ThreadResponse<SCG extends ExtendableGenerics = DefaultGenerics> extends ThreadResponseCustomData {
524
527
  // FIXME: according to OpenAPI, `channel` could be undefined but since cid is provided I'll asume that it's wrong
525
528
  channel: ChannelResponse<SCG>;
526
529
  channel_cid: string;
@@ -531,6 +534,7 @@ export interface ThreadResponse<SCG extends ExtendableGenerics = DefaultGenerics
531
534
  parent_message_id: string;
532
535
  title: string;
533
536
  updated_at: string;
537
+ active_participant_count?: number;
534
538
  created_by?: UserResponse<SCG>;
535
539
  deleted_at?: string;
536
540
  last_message_at?: string;
@@ -547,6 +551,8 @@ export interface ThreadResponse<SCG extends ExtendableGenerics = DefaultGenerics
547
551
  user?: UserResponse<SCG>;
548
552
  user_id?: string;
549
553
  }>;
554
+ // TODO: when moving to API v2 we should do this instead
555
+ // custom: ThreadResponseCustomData;
550
556
  }
551
557
 
552
558
  // TODO: Figure out a way to strongly type set and unset.