stream-chat 8.49.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.
@@ -1943,8 +1949,7 @@ export type ReactionSortBase<StreamChatGenerics extends ExtendableGenerics = Def
1943
1949
 
1944
1950
  export type ChannelSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =
1945
1951
  | ChannelSortBase<StreamChatGenerics>
1946
- | Array<ChannelSortBase<StreamChatGenerics>>
1947
- | { pinned_at: AscDesc };
1952
+ | Array<ChannelSortBase<StreamChatGenerics>>;
1948
1953
 
1949
1954
  export type ChannelSortBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Sort<
1950
1955
  StreamChatGenerics['channelType']
@@ -1954,6 +1959,7 @@ export type ChannelSortBase<StreamChatGenerics extends ExtendableGenerics = Defa
1954
1959
  last_message_at?: AscDesc;
1955
1960
  last_updated?: AscDesc;
1956
1961
  member_count?: AscDesc;
1962
+ pinned_at?: AscDesc;
1957
1963
  unread_count?: AscDesc;
1958
1964
  updated_at?: AscDesc;
1959
1965
  };
@@ -2990,6 +2996,7 @@ export type CampaignData = {
2990
2996
  name?: string;
2991
2997
  segment_ids?: string[];
2992
2998
  sender_id?: string;
2999
+ sender_mode?: 'exclude' | 'include' | null;
2993
3000
  skip_push?: boolean;
2994
3001
  skip_webhook?: boolean;
2995
3002
  user_ids?: string[];