stream-chat 9.28.0 → 9.30.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.
@@ -0,0 +1,45 @@
1
+ import { StateStore } from './store';
2
+ import { WithSubscriptions } from './utils/WithSubscriptions';
3
+ import type { Channel } from './channel';
4
+ export type CooldownTimerState = {
5
+ /**
6
+ * Slow mode cooldown interval in seconds. Change reported via channel.updated WS event.
7
+ */
8
+ cooldownConfigSeconds: number;
9
+ /**
10
+ * Whether the current user can skip slow mode. Change is not reported via WS.
11
+ */
12
+ canSkipCooldown: boolean;
13
+ /**
14
+ * Latest message creation date authored by the current user in this channel. Change reported via message.new WS event.
15
+ */
16
+ ownLatestMessageDate?: Date;
17
+ /**
18
+ * Remaining cooldown in whole seconds (rounded).
19
+ */
20
+ cooldownRemaining: number;
21
+ };
22
+ export declare class CooldownTimer extends WithSubscriptions {
23
+ readonly state: StateStore<CooldownTimerState>;
24
+ private timeout;
25
+ private channel;
26
+ constructor({ channel }: {
27
+ channel: Channel;
28
+ });
29
+ get cooldownConfigSeconds(): number;
30
+ get cooldownRemaining(): number;
31
+ get canSkipCooldown(): boolean;
32
+ get ownLatestMessageDate(): Date | undefined;
33
+ registerSubscriptions: () => void;
34
+ setCooldownRemaining: (cooldownRemaining: number) => void;
35
+ clearTimeout: () => void;
36
+ refresh: () => void;
37
+ /**
38
+ * Updates the known latest own message date and recomputes remaining time.
39
+ * Prefer calling this when you already know the message date (e.g. from an event).
40
+ */
41
+ setOwnLatestMessageDate: (date: Date | undefined) => void;
42
+ private getOwnUserId;
43
+ private findOwnLatestMessageDate;
44
+ private recalculate;
45
+ }
@@ -1,8 +1,9 @@
1
1
  import { ChannelState } from './channel_state';
2
+ import { CooldownTimer } from './CooldownTimer';
2
3
  import { MessageComposer } from './messageComposer';
3
4
  import { MessageReceiptsTracker } from './messageDelivery';
4
5
  import type { StreamChat } from './client';
5
- import type { AIState, APIResponse, AscDesc, BanUserOptions, ChannelAPIResponse, ChannelData, ChannelMemberAPIResponse, ChannelMemberResponse, ChannelQueryOptions, ChannelResponse, ChannelUpdateOptions, CreateDraftResponse, DeleteChannelAPIResponse, DraftMessagePayload, Event, EventAPIResponse, EventHandler, EventTypes, GetDraftResponse, GetMultipleMessagesAPIResponse, GetReactionsAPIResponse, GetRepliesAPIResponse, LiveLocationPayload, LocalMessage, MarkReadOptions, MarkUnreadOptions, MemberFilters, MemberSort, Message, MessageFilters, MessageOptions, MessagePaginationOptions, MessageResponse, MessageSetType, MuteChannelAPIResponse, NewMemberPayload, PartialUpdateChannel, PartialUpdateChannelAPIResponse, PartialUpdateMember, PartialUpdateMemberAPIResponse, PinnedMessagePaginationOptions, PinnedMessagesSort, PollVoteData, PushPreference, QueryChannelAPIResponse, QueryMembersOptions, Reaction, ReactionAPIResponse, SearchAPIResponse, SearchOptions, SendMessageAPIResponse, SendMessageOptions, SendReactionOptions, StaticLocationPayload, TruncateChannelAPIResponse, TruncateOptions, UpdateChannelAPIResponse, UpdateChannelOptions, UpdateLocationPayload, UserResponse } from './types';
6
+ import type { AIState, APIResponse, AscDesc, BanUserOptions, ChannelAPIResponse, ChannelData, ChannelMemberAPIResponse, ChannelMemberResponse, ChannelQueryOptions, ChannelResponse, ChannelUpdateOptions, CreateDraftResponse, DeleteChannelAPIResponse, DraftMessagePayload, Event, EventAPIResponse, EventHandler, EventTypes, GetDraftResponse, GetMultipleMessagesAPIResponse, GetReactionsAPIResponse, GetRepliesAPIResponse, LiveLocationPayload, LocalMessage, MarkReadOptions, MarkUnreadOptions, MemberFilters, MemberSort, Message, MessageFilters, MessageOptions, MessagePaginationOptions, MessageResponse, MessageSetType, MuteChannelAPIResponse, NewMemberPayload, PartialUpdateChannel, PartialUpdateChannelAPIResponse, PartialUpdateMember, PartialUpdateMemberAPIResponse, PinnedMessagePaginationOptions, PinnedMessagesSort, PollVoteData, PushPreference, QueryChannelAPIResponse, QueryMembersOptions, Reaction, ReactionAPIResponse, SearchAPIResponse, SearchOptions, SendMessageAPIResponse, SendMessageOptions, SendReactionOptions, StaticLocationPayload, TruncateChannelAPIResponse, TruncateOptions, UnBanUserOptions, UpdateChannelAPIResponse, UpdateChannelOptions, UpdateLocationPayload, UserResponse } from './types';
6
7
  import type { Role } from './permissions';
7
8
  /**
8
9
  * Channel - The Channel class manages it's own state.
@@ -41,6 +42,7 @@ export declare class Channel {
41
42
  push_preferences?: PushPreference;
42
43
  readonly messageComposer: MessageComposer;
43
44
  readonly messageReceiptsTracker: MessageReceiptsTracker;
45
+ readonly cooldownTimer: CooldownTimer;
44
46
  /**
45
47
  * constructor - Create a channel
46
48
  *
@@ -610,9 +612,10 @@ export declare class Channel {
610
612
  * unbanUser - Removes the bans for a user on a channel
611
613
  *
612
614
  * @param {string} targetUserID
615
+ * @param {UnBanUserOptions} options
613
616
  * @returns {Promise<APIResponse>}
614
617
  */
615
- unbanUser(targetUserID: string): Promise<APIResponse>;
618
+ unbanUser(targetUserID: string, options?: UnBanUserOptions): Promise<APIResponse>;
616
619
  /**
617
620
  * shadowBan - Shadow bans a user from a channel
618
621
  *
@@ -109,7 +109,7 @@ export declare class ChannelState {
109
109
  *
110
110
  */
111
111
  removePinnedMessage(message: MessageResponse): void;
112
- addReaction(reaction: ReactionResponse, message?: MessageResponse, enforce_unique?: boolean): MessageResponse | LocalMessage | undefined;
112
+ addReaction(reaction: ReactionResponse, message?: MessageResponse, enforce_unique?: boolean): LocalMessage | MessageResponse | undefined;
113
113
  _addReactionToState(messageFromState: LocalMessage, reaction: ReactionResponse, enforce_unique?: boolean): LocalMessage;
114
114
  _addOwnReactionToMessage(ownReactions: ReactionResponse[] | null | undefined, reaction: ReactionResponse, enforce_unique?: boolean): ReactionResponse[];
115
115
  _removeOwnReactionFromMessage(ownReactions: ReactionResponse[] | null | undefined, reaction: ReactionResponse): ReactionResponse[] | null | undefined;
@@ -8,7 +8,7 @@ import { WSConnectionFallback } from './connection_fallback';
8
8
  import { Campaign } from './campaign';
9
9
  import { ChannelBatchUpdater } from './channel_batch_updater';
10
10
  import { Segment } from './segment';
11
- import type { ActiveLiveLocationsAPIResponse, APIErrorResponse, APIResponse, AppSettings, AppSettingsAPIResponse, BannedUsersFilters, BannedUsersPaginationOptions, BannedUsersResponse, BannedUsersSort, BanUserOptions, BaseDeviceFields, BlockList, BlockListResponse, BlockUserAPIResponse, CampaignData, CampaignFilters, CampaignQueryOptions, CampaignResponse, CampaignSort, CastVoteAPIResponse, ChannelAPIResponse, ChannelData, ChannelFilters, ChannelMute, ChannelOptions, ChannelResponse, ChannelSort, ChannelStateOptions, CheckPushResponse, CheckSNSResponse, CheckSQSResponse, Configs, ConnectAPIResponse, CreateChannelOptions, CreateChannelResponse, CreateCommandOptions, CreateCommandResponse, CreateImportOptions, CreateImportResponse, CreateImportURLResponse, CreatePollAPIResponse, CreatePollData, CreatePollOptionAPIResponse, CreateReminderOptions, CustomPermissionOptions, DeactivateUsersOptions, DeleteCommandResponse, DeleteMessageOptions, DeleteUserOptions, Device, DeviceIdentifier, DraftFilters, DraftSort, EndpointName, Event, EventAPIResponse, EventHandler, ExportChannelOptions, ExportChannelRequest, ExportChannelResponse, ExportChannelStatusResponse, ExportUsersRequest, ExportUsersResponse, FlagMessageResponse, FlagReportsFilters, FlagReportsPaginationOptions, FlagReportsResponse, FlagsFilters, FlagsPaginationOptions, FlagsResponse, FlagUserResponse, GetBlockedUsersAPIResponse, GetCampaignOptions, GetChannelTypeResponse, GetCommandResponse, GetHookEventsResponse, GetImportResponse, GetMessageOptions, GetPollAPIResponse, GetRateLimitsResponse, GetThreadAPIResponse, GetThreadOptions, GetUnreadCountAPIResponse, GetUnreadCountBatchAPIResponse, ListChannelResponse, ListCommandsResponse, ListImportsPaginationOptions, ListImportsResponse, LocalMessage, Logger, MarkChannelsReadOptions, MarkDeliveredOptions, MessageFilters, MessageFlagsFilters, MessageFlagsPaginationOptions, MessageFlagsResponse, MessageResponse, Mute, MuteUserOptions, MuteUserResponse, OGAttachment, OwnUserResponse, Pager, PartialMessageUpdate, PartialPollUpdate, PartialThreadUpdate, PartialUserUpdate, PermissionAPIResponse, PermissionsAPIResponse, PollAnswersAPIResponse, PollData, PollOptionData, PollSort, PollVote, PollVoteData, PollVotesAPIResponse, Product, PushPreference, PushProvider, PushProviderConfig, PushProviderID, PushProviderListResponse, PushProviderUpsertResponse, QueryDraftsResponse, QueryMessageHistoryFilters, QueryMessageHistoryOptions, QueryMessageHistoryResponse, QueryMessageHistorySort, QueryPollsFilters, QueryPollsOptions, QueryPollsResponse, QueryReactionsAPIResponse, QueryReactionsOptions, QueryRemindersOptions, QueryRemindersResponse, QuerySegmentsOptions, QuerySegmentTargetsFilter, QueryThreadsOptions, QueryVotesFilters, QueryVotesOptions, ReactionFilters, ReactionResponse, ReactionSort, ReactivateUserOptions, ReactivateUsersOptions, ReminderAPIResponse, ReviewFlagReportOptions, ReviewFlagReportResponse, SdkIdentifier, SearchAPIResponse, SearchOptions, SegmentData, SegmentResponse, SegmentTargetsResponse, SegmentType, SendFileAPIResponse, SharedLocationResponse, SortParam, StreamChatOptions, SyncOptions, SyncResponse, TaskResponse, TaskStatus, TestPushDataInput, TestSNSDataInput, TestSQSDataInput, TokenOrProvider, TranslateResponse, UnBanUserOptions, UpdateChannelsBatchOptions, UpdateChannelTypeRequest, UpdateChannelTypeResponse, UpdateCommandOptions, UpdateCommandResponse, UpdateLocationPayload, UpdateMessageAPIResponse, UpdateMessageOptions, UpdatePollAPIResponse, UpdateReminderOptions, UpdateSegmentData, UpdateUsersAPIResponse, UpsertPushPreferencesResponse, UserCustomEvent, UserFilters, UserOptions, UserResponse, UserSort, VoteSort } from './types';
11
+ import type { ActiveLiveLocationsAPIResponse, APIErrorResponse, APIResponse, AppSettings, AppSettingsAPIResponse, BannedUsersFilters, BannedUsersPaginationOptions, BannedUsersResponse, BannedUsersSort, BanUserOptions, BaseDeviceFields, BlockList, BlockListResponse, BlockUserAPIResponse, CampaignData, CampaignFilters, CampaignQueryOptions, CampaignResponse, CampaignSort, CastVoteAPIResponse, ChannelAPIResponse, ChannelData, ChannelFilters, ChannelMute, ChannelOptions, ChannelResponse, ChannelSort, ChannelStateOptions, CheckPushResponse, CheckSNSResponse, CheckSQSResponse, Configs, ConnectAPIResponse, CreateChannelOptions, CreateChannelResponse, CreateCommandOptions, CreateCommandResponse, CreateImportOptions, CreateImportResponse, CreateImportURLResponse, CreatePollAPIResponse, CreatePollData, CreatePollOptionAPIResponse, CreatePredefinedFilterOptions, CreateReminderOptions, CustomPermissionOptions, DeactivateUsersOptions, DeleteCommandResponse, DeleteMessageOptions, DeleteUserOptions, Device, DeviceIdentifier, DraftFilters, DraftSort, EndpointName, Event, EventAPIResponse, EventHandler, ExportChannelOptions, ExportChannelRequest, ExportChannelResponse, ExportChannelStatusResponse, ExportUsersRequest, ExportUsersResponse, FlagMessageResponse, FlagReportsFilters, FlagReportsPaginationOptions, FlagReportsResponse, FlagsFilters, FlagsPaginationOptions, FlagsResponse, FlagUserResponse, FutureChannelBansResponse, GetBlockedUsersAPIResponse, GetCampaignOptions, GetChannelTypeResponse, GetCommandResponse, GetHookEventsResponse, GetImportResponse, GetMessageOptions, GetPollAPIResponse, GetRateLimitsResponse, GetThreadAPIResponse, GetThreadOptions, GetUnreadCountAPIResponse, GetUnreadCountBatchAPIResponse, ListChannelResponse, ListCommandsResponse, ListImportsPaginationOptions, ListImportsResponse, ListPredefinedFiltersOptions, ListPredefinedFiltersResponse, LocalMessage, Logger, MarkChannelsReadOptions, MarkDeliveredOptions, MessageFilters, MessageFlagsFilters, MessageFlagsPaginationOptions, MessageFlagsResponse, MessageResponse, Mute, MuteUserOptions, MuteUserResponse, OGAttachment, OwnUserResponse, Pager, PartialMessageUpdate, PartialPollUpdate, PartialThreadUpdate, PartialUserUpdate, PermissionAPIResponse, PermissionsAPIResponse, PollAnswersAPIResponse, PollData, PollOptionData, PollSort, PollVote, PollVoteData, PollVotesAPIResponse, PredefinedFilterResponse, Product, PushPreference, PushProvider, PushProviderConfig, PushProviderID, PushProviderListResponse, PushProviderUpsertResponse, QueryDraftsResponse, QueryFutureChannelBansOptions, QueryMessageHistoryFilters, QueryMessageHistoryOptions, QueryMessageHistoryResponse, QueryMessageHistorySort, QueryPollsFilters, QueryPollsOptions, QueryPollsResponse, QueryReactionsAPIResponse, QueryReactionsOptions, QueryRemindersOptions, QueryRemindersResponse, QuerySegmentsOptions, QuerySegmentTargetsFilter, QueryThreadsOptions, QueryVotesFilters, QueryVotesOptions, ReactionFilters, ReactionResponse, ReactionSort, ReactivateUserOptions, ReactivateUsersOptions, ReminderAPIResponse, ReviewFlagReportOptions, ReviewFlagReportResponse, SdkIdentifier, SearchAPIResponse, SearchOptions, SegmentData, SegmentResponse, SegmentTargetsResponse, SegmentType, SendFileAPIResponse, SharedLocationResponse, SortParam, StreamChatOptions, SyncOptions, SyncResponse, TaskResponse, TaskStatus, TestPushDataInput, TestSNSDataInput, TestSQSDataInput, TokenOrProvider, TranslateResponse, UnBanUserOptions, UpdateChannelsBatchOptions, UpdateChannelTypeRequest, UpdateChannelTypeResponse, UpdateCommandOptions, UpdateCommandResponse, UpdateLocationPayload, UpdateMessageAPIResponse, UpdateMessageOptions, UpdatePollAPIResponse, UpdatePredefinedFilterOptions, UpdateReminderOptions, UpdateSegmentData, UpdateUsersAPIResponse, UpsertPushPreferencesResponse, UserCustomEvent, UserFilters, UserOptions, UserResponse, UserSort, VoteSort } from './types';
12
12
  import { ErrorFromResponse } from './types';
13
13
  import { InsightMetrics } from './insights';
14
14
  import { Thread } from './thread';
@@ -484,6 +484,13 @@ export declare class StreamChat {
484
484
  * @return {Promise<BannedUsersResponse>} Ban Query Response
485
485
  */
486
486
  queryBannedUsers(filterConditions?: BannedUsersFilters, sort?: BannedUsersSort, options?: BannedUsersPaginationOptions): Promise<BannedUsersResponse>;
487
+ /**
488
+ * queryFutureChannelBans - Query future channel bans created by a user
489
+ *
490
+ * @param {QueryFutureChannelBansOptions} options Option object with user_id, exclude_expired_bans, limit, offset
491
+ * @returns {Promise<FutureChannelBansResponse>} Future Channel Bans Response
492
+ */
493
+ queryFutureChannelBans(options?: QueryFutureChannelBansOptions): Promise<FutureChannelBansResponse>;
487
494
  /**
488
495
  * queryMessageFlags - Query message flags
489
496
  *
@@ -496,10 +503,10 @@ export declare class StreamChat {
496
503
  /**
497
504
  * queryChannelsRequest - Queries channels and returns the raw response
498
505
  *
499
- * @param {ChannelFilters} filterConditions object MongoDB style filters
506
+ * @param {ChannelFilters} filterConditions object MongoDB style filters. Can be empty object when using predefined_filter in options.
500
507
  * @param {ChannelSort} [sort] Sort options, for instance {created_at: -1}.
501
508
  * When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{last_updated: -1}, {created_at: 1}]
502
- * @param {ChannelOptions} [options] Options object
509
+ * @param {ChannelOptions} [options] Options object. Can include predefined_filter, filter_values, and sort_values for using predefined filters.
503
510
  *
504
511
  * @return {Promise<Array<ChannelAPIResponse>>} search channels response
505
512
  */
@@ -1986,5 +1993,46 @@ export declare class StreamChat {
1986
1993
  updateChannelsBatch(payload: UpdateChannelsBatchOptions): Promise<APIResponse & {
1987
1994
  result: Record<string, string>;
1988
1995
  } & Partial<TaskResponse>>;
1996
+ /**
1997
+ * createPredefinedFilter - Creates a new predefined filter (server-side only)
1998
+ *
1999
+ * @param {CreatePredefinedFilterOptions} options Predefined filter options
2000
+ *
2001
+ * @return {Promise<PredefinedFilterResponse>} The created predefined filter
2002
+ */
2003
+ createPredefinedFilter(options: CreatePredefinedFilterOptions): Promise<PredefinedFilterResponse>;
2004
+ /**
2005
+ * getPredefinedFilter - Gets a predefined filter by name (server-side only)
2006
+ *
2007
+ * @param {string} name Predefined filter name
2008
+ *
2009
+ * @return {Promise<PredefinedFilterResponse>} The predefined filter
2010
+ */
2011
+ getPredefinedFilter(name: string): Promise<PredefinedFilterResponse>;
2012
+ /**
2013
+ * updatePredefinedFilter - Updates a predefined filter (server-side only)
2014
+ *
2015
+ * @param {string} name Predefined filter name
2016
+ * @param {UpdatePredefinedFilterOptions} options Predefined filter options
2017
+ *
2018
+ * @return {Promise<PredefinedFilterResponse>} The updated predefined filter
2019
+ */
2020
+ updatePredefinedFilter(name: string, options: UpdatePredefinedFilterOptions): Promise<PredefinedFilterResponse>;
2021
+ /**
2022
+ * deletePredefinedFilter - Deletes a predefined filter (server-side only)
2023
+ *
2024
+ * @param {string} name Predefined filter name
2025
+ *
2026
+ * @return {Promise<APIResponse>} The server response
2027
+ */
2028
+ deletePredefinedFilter(name: string): Promise<APIResponse>;
2029
+ /**
2030
+ * listPredefinedFilters - Lists all predefined filters (server-side only)
2031
+ *
2032
+ * @param {ListPredefinedFiltersOptions} options Query options
2033
+ *
2034
+ * @return {Promise<ListPredefinedFiltersResponse>} The list of predefined filters
2035
+ */
2036
+ listPredefinedFilters(options?: ListPredefinedFiltersOptions): Promise<ListPredefinedFiltersResponse>;
1989
2037
  }
1990
2038
  export {};
@@ -6,6 +6,7 @@ export * from './client_state';
6
6
  export * from './channel';
7
7
  export * from './channel_state';
8
8
  export * from './connection';
9
+ export { type CooldownTimerState } from './CooldownTimer';
9
10
  export * from './events';
10
11
  export * from './insights';
11
12
  export * from './messageComposer';
@@ -16,7 +16,7 @@ export declare class InsightMetrics {
16
16
  */
17
17
  export declare const postInsights: (insightType: InsightTypes, insights: Record<string, unknown>) => Promise<void>;
18
18
  export declare function buildWsFatalInsight(connection: StableWSConnection, event: Record<string, unknown>): {
19
- ready_state: 0 | 1 | 2 | 3 | undefined;
19
+ ready_state: 0 | 2 | 1 | 3 | undefined;
20
20
  url: string;
21
21
  api_key: string;
22
22
  start_ts: number | null;
@@ -36,7 +36,7 @@ export declare function buildWsFatalInsight(connection: StableWSConnection, even
36
36
  instance_client_id: string;
37
37
  };
38
38
  export declare function buildWsSuccessAfterFailureInsight(connection: StableWSConnection): {
39
- ready_state: 0 | 1 | 2 | 3 | undefined;
39
+ ready_state: 0 | 2 | 1 | 3 | undefined;
40
40
  url: string;
41
41
  api_key: string;
42
42
  start_ts: number | null;
@@ -13,5 +13,5 @@ export declare const getExtensionFromMimeType: (mimeType: string) => string | un
13
13
  export declare const readFileAsArrayBuffer: (file: File) => Promise<ArrayBuffer>;
14
14
  export declare const generateFileName: (mimeType: string) => string;
15
15
  export declare const isImageFile: (fileLike: FileReference | FileLike) => boolean;
16
- export declare const getAttachmentTypeFromMimeType: (mimeType: string) => "file" | "video" | "audio" | "image";
16
+ export declare const getAttachmentTypeFromMimeType: (mimeType: string) => "file" | "audio" | "video" | "image";
17
17
  export declare const ensureIsLocalAttachment: (attachment: Attachment | LocalAttachment) => LocalAttachment | null;
@@ -57,12 +57,12 @@ export declare class MessageComposer extends WithSubscriptions {
57
57
  locationComposer: LocationComposer;
58
58
  customDataManager: CustomDataManager;
59
59
  constructor({ composition, config, compositionContext, client, }: MessageComposerOptions);
60
- static evaluateContextType(compositionContext: CompositionContext): "message" | "channel" | "thread" | "legacy_thread";
60
+ static evaluateContextType(compositionContext: CompositionContext): "channel" | "message" | "thread" | "legacy_thread";
61
61
  static constructTag(compositionContext: CompositionContext): `${ReturnType<typeof MessageComposer.evaluateContextType>}_${string}`;
62
62
  static generateId: typeof generateUUIDv4;
63
63
  get config(): MessageComposerConfig;
64
- get contextType(): "message" | "channel" | "thread" | "legacy_thread";
65
- get tag(): `message_${string}` | `channel_${string}` | `thread_${string}` | `legacy_thread_${string}`;
64
+ get contextType(): "channel" | "message" | "thread" | "legacy_thread";
65
+ get tag(): `channel_${string}` | `message_${string}` | `thread_${string}` | `legacy_thread_${string}`;
66
66
  get threadId(): string | null;
67
67
  get client(): StreamChat;
68
68
  get id(): string;
@@ -21,12 +21,12 @@ export declare class CommandSearchSource extends BaseSearchSourceSync<CommandSug
21
21
  };
22
22
  query(searchQuery: string): {
23
23
  items: {
24
- id: "all" | "ban" | "fun_set" | "giphy" | "moderation_set" | "mute" | "unban" | "unmute";
24
+ id: "all" | "mute" | "unmute" | "giphy" | "ban" | "fun_set" | "moderation_set" | "unban";
25
25
  created_at?: string | undefined;
26
26
  updated_at?: string | undefined;
27
27
  args?: string;
28
28
  description?: string;
29
- name: "all" | "ban" | "fun_set" | "giphy" | "moderation_set" | "mute" | "unban" | "unmute";
29
+ name: "all" | "mute" | "unmute" | "giphy" | "ban" | "fun_set" | "moderation_set" | "unban";
30
30
  set?: import("../../..").CommandVariants;
31
31
  }[];
32
32
  next: null;
@@ -55,10 +55,18 @@ export type BaseLocalAttachmentMetadata = {
55
55
  };
56
56
  export type LocalAttachmentUploadMetadata = {
57
57
  file: File | FileReference;
58
+ /**
59
+ * Local preview URI, typically a Blob URL from `URL.createObjectURL(file)`
60
+ * or (for React Native `FileReference`) the provided `uri`.
61
+ */
62
+ previewUri?: string;
58
63
  uploadState: AttachmentLoadingState;
59
64
  uploadPermissionCheck?: UploadPermissionCheckResult;
60
65
  };
61
66
  export type LocalImageAttachmentUploadMetadata = LocalAttachmentUploadMetadata & {
67
+ /**
68
+ * @deprecated `previewUri` is now available on `LocalAttachmentUploadMetadata`.
69
+ */
62
70
  previewUri?: string;
63
71
  };
64
72
  export type LocalNotImageAttachment = LocalFileAttachment | LocalAudioAttachment | LocalVideoAttachment | LocalVoiceRecordingAttachment;
@@ -234,6 +234,23 @@ export type BannedUsersResponse = APIResponse & {
234
234
  timeout?: number;
235
235
  }>;
236
236
  };
237
+ export type FutureChannelBan = {
238
+ user: UserResponse;
239
+ expires?: string;
240
+ reason?: string;
241
+ shadow?: boolean;
242
+ created_at: string;
243
+ };
244
+ export type FutureChannelBansResponse = APIResponse & {
245
+ bans: FutureChannelBan[];
246
+ };
247
+ export type QueryFutureChannelBansOptions = {
248
+ user_id?: string;
249
+ target_user_id?: string;
250
+ exclude_expired_bans?: boolean;
251
+ limit?: number;
252
+ offset?: number;
253
+ };
237
254
  export type BlockListResponse = BlockList & {
238
255
  created_at?: string;
239
256
  type?: string;
@@ -847,6 +864,7 @@ export type BannedUsersPaginationOptions = Omit<PaginationOptions, 'id_gt' | 'id
847
864
  exclude_expired_bans?: boolean;
848
865
  };
849
866
  export type BanUserOptions = UnBanUserOptions & {
867
+ ban_from_future_channels?: boolean;
850
868
  banned_by?: UserResponse;
851
869
  banned_by_id?: string;
852
870
  ip_ban?: boolean;
@@ -863,6 +881,21 @@ export type ChannelOptions = {
863
881
  state?: boolean;
864
882
  user_id?: string;
865
883
  watch?: boolean;
884
+ /**
885
+ * Name of a predefined filter to use instead of filter_conditions.
886
+ * When provided, filter_conditions and sort parameters are ignored.
887
+ */
888
+ predefined_filter?: string;
889
+ /**
890
+ * Values to interpolate into the predefined filter template placeholders.
891
+ * Only used when predefined_filter is provided.
892
+ */
893
+ filter_values?: Record<string, unknown>;
894
+ /**
895
+ * Values to interpolate into the predefined filter sort template placeholders.
896
+ * Only used when predefined_filter is provided.
897
+ */
898
+ sort_values?: Record<string, unknown>;
866
899
  };
867
900
  export type ChannelQueryOptions = {
868
901
  client_id?: string;
@@ -1287,6 +1320,7 @@ export type UnBanUserOptions = {
1287
1320
  client_id?: string;
1288
1321
  connection_id?: string;
1289
1322
  id?: string;
1323
+ remove_future_channels_ban?: boolean;
1290
1324
  shadow?: boolean;
1291
1325
  target_user_id?: string;
1292
1326
  type?: string;
@@ -3326,4 +3360,43 @@ export type UpdateChannelsBatchFilters = QueryFilters<{
3326
3360
  export type UpdateChannelsBatchResponse = {
3327
3361
  result: Record<string, string>;
3328
3362
  } & Partial<TaskResponse>;
3363
+ /**
3364
+ * Predefined Filter Types
3365
+ */
3366
+ export type PredefinedFilterOperation = 'QueryChannels';
3367
+ export type PredefinedFilterSortParam = {
3368
+ field: string;
3369
+ direction?: AscDesc;
3370
+ type?: string;
3371
+ };
3372
+ export type PredefinedFilter = {
3373
+ name: string;
3374
+ operation: PredefinedFilterOperation;
3375
+ filter: Record<string, unknown>;
3376
+ created_at: string;
3377
+ updated_at: string;
3378
+ description?: string;
3379
+ sort?: PredefinedFilterSortParam[];
3380
+ query_id?: number;
3381
+ };
3382
+ export type CreatePredefinedFilterOptions = {
3383
+ name: string;
3384
+ operation: PredefinedFilterOperation;
3385
+ filter: Record<string, unknown>;
3386
+ description?: string;
3387
+ sort?: PredefinedFilterSortParam[];
3388
+ };
3389
+ export type UpdatePredefinedFilterOptions = Omit<CreatePredefinedFilterOptions, 'name'>;
3390
+ export type PredefinedFilterResponse = APIResponse & {
3391
+ predefined_filter: PredefinedFilter;
3392
+ };
3393
+ export type ListPredefinedFiltersResponse = APIResponse & {
3394
+ predefined_filters: PredefinedFilter[];
3395
+ next?: string;
3396
+ prev?: string;
3397
+ };
3398
+ export type PredefinedFilterSort = SortParam[];
3399
+ export type ListPredefinedFiltersOptions = Pager & {
3400
+ sort?: PredefinedFilterSort;
3401
+ };
3329
3402
  export {};
@@ -87,6 +87,10 @@ export declare const toDeletedMessage: ({ message, deletedAt, hardDelete, }: {
87
87
  attachments: never[];
88
88
  type: string;
89
89
  deleted_at: Date | null;
90
+ text?: string | undefined;
91
+ user_id?: string | undefined;
92
+ user?: (UserResponse | null) | undefined;
93
+ channel?: import("./types").ChannelResponse | undefined;
90
94
  command?: string | undefined;
91
95
  mentioned_users?: UserResponse[] | undefined;
92
96
  latest_reactions?: import("./types").ReactionResponse[] | undefined;
@@ -99,10 +103,9 @@ export declare const toDeletedMessage: ({ message, deletedAt, hardDelete, }: {
99
103
  language: import("./types").TranslationLanguages;
100
104
  }) | undefined;
101
105
  html?: string | undefined;
102
- user?: (UserResponse | null) | undefined;
106
+ parent_id?: string | undefined;
103
107
  id: string;
104
108
  mml?: string | undefined;
105
- parent_id?: string | undefined;
106
109
  pin_expires?: string | null | undefined;
107
110
  pinned?: boolean | undefined;
108
111
  poll_id?: string | undefined;
@@ -110,11 +113,8 @@ export declare const toDeletedMessage: ({ message, deletedAt, hardDelete, }: {
110
113
  restricted_visibility?: string[] | undefined;
111
114
  show_in_channel?: boolean | undefined;
112
115
  silent?: boolean | undefined;
113
- text?: string | undefined;
114
- user_id?: string | undefined;
115
116
  args?: string | undefined;
116
117
  before_message_send_failed?: boolean | undefined;
117
- channel?: import("./types").ChannelResponse | undefined;
118
118
  cid?: string | undefined;
119
119
  command_info?: {
120
120
  name?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stream-chat",
3
- "version": "9.28.0",
3
+ "version": "9.30.0",
4
4
  "description": "JS SDK for the Stream Chat API",
5
5
  "homepage": "https://getstream.io/chat/",
6
6
  "author": {
@@ -0,0 +1,196 @@
1
+ import { StateStore } from './store';
2
+ import type { ChannelResponse, LocalMessage } from './types';
3
+ import { WithSubscriptions } from './utils/WithSubscriptions';
4
+ import type { Channel } from './channel';
5
+
6
+ export type CooldownTimerState = {
7
+ /**
8
+ * Slow mode cooldown interval in seconds. Change reported via channel.updated WS event.
9
+ */
10
+ cooldownConfigSeconds: number;
11
+ /**
12
+ * Whether the current user can skip slow mode. Change is not reported via WS.
13
+ */
14
+ canSkipCooldown: boolean;
15
+ /**
16
+ * Latest message creation date authored by the current user in this channel. Change reported via message.new WS event.
17
+ */
18
+ ownLatestMessageDate?: Date;
19
+ /**
20
+ * Remaining cooldown in whole seconds (rounded).
21
+ */
22
+ cooldownRemaining: number;
23
+ };
24
+
25
+ const toDateOrUndefined = (value: unknown): Date | undefined => {
26
+ if (value instanceof Date) return value;
27
+ if (typeof value === 'string' || typeof value === 'number') {
28
+ const parsed = new Date(value);
29
+ if (!Number.isNaN(parsed.getTime())) return parsed;
30
+ }
31
+ return undefined;
32
+ };
33
+
34
+ export class CooldownTimer extends WithSubscriptions {
35
+ public readonly state: StateStore<CooldownTimerState>;
36
+ private timeout: ReturnType<typeof setTimeout> | null = null;
37
+ private channel: Channel;
38
+
39
+ constructor({ channel }: { channel: Channel }) {
40
+ super();
41
+ this.channel = channel;
42
+ this.state = new StateStore<CooldownTimerState>({
43
+ cooldownConfigSeconds: 0,
44
+ cooldownRemaining: 0,
45
+ ownLatestMessageDate: undefined,
46
+ canSkipCooldown: false,
47
+ });
48
+ this.refresh();
49
+ }
50
+
51
+ get cooldownConfigSeconds() {
52
+ return this.state.getLatestValue().cooldownConfigSeconds;
53
+ }
54
+
55
+ get cooldownRemaining() {
56
+ return this.state.getLatestValue().cooldownRemaining;
57
+ }
58
+
59
+ get canSkipCooldown() {
60
+ return this.state.getLatestValue().canSkipCooldown;
61
+ }
62
+
63
+ get ownLatestMessageDate() {
64
+ return this.state.getLatestValue().ownLatestMessageDate;
65
+ }
66
+
67
+ public registerSubscriptions = () => {
68
+ this.incrementRefCount();
69
+ if (this.hasSubscriptions) return;
70
+
71
+ this.addUnsubscribeFunction(
72
+ this.channel.on('message.new', (event) => {
73
+ const isOwnMessage =
74
+ event.message?.user?.id && event.message.user.id === this.getOwnUserId();
75
+ if (!isOwnMessage) return;
76
+ this.setOwnLatestMessageDate(toDateOrUndefined(event.message?.created_at));
77
+ }).unsubscribe,
78
+ );
79
+
80
+ this.addUnsubscribeFunction(
81
+ this.channel.on('channel.updated', (event) => {
82
+ const cooldownChanged = event.channel?.cooldown !== this.cooldownConfigSeconds;
83
+ if (!cooldownChanged) return;
84
+ this.refresh();
85
+ }).unsubscribe,
86
+ );
87
+ };
88
+
89
+ public setCooldownRemaining = (cooldownRemaining: number) => {
90
+ this.state.partialNext({ cooldownRemaining });
91
+ };
92
+
93
+ public clearTimeout = () => {
94
+ if (!this.timeout) return;
95
+ clearTimeout(this.timeout);
96
+ this.timeout = null;
97
+ };
98
+
99
+ public refresh = () => {
100
+ const { cooldown: cooldownConfigSeconds = 0, own_capabilities } = (this.channel
101
+ .data ?? {}) as Partial<ChannelResponse>;
102
+ const canSkipCooldown = (own_capabilities ?? []).includes('skip-slow-mode');
103
+
104
+ const ownLatestMessageDate = this.findOwnLatestMessageDate({
105
+ messages: this.channel.state.latestMessages,
106
+ });
107
+
108
+ if (
109
+ cooldownConfigSeconds !== this.cooldownConfigSeconds ||
110
+ ownLatestMessageDate?.getTime() !== this.ownLatestMessageDate?.getTime() ||
111
+ canSkipCooldown !== this.canSkipCooldown
112
+ ) {
113
+ this.state.partialNext({
114
+ cooldownConfigSeconds,
115
+ ownLatestMessageDate,
116
+ canSkipCooldown,
117
+ });
118
+ }
119
+
120
+ if (this.canSkipCooldown || this.cooldownConfigSeconds === 0) {
121
+ this.clearTimeout();
122
+ if (this.cooldownRemaining !== 0) {
123
+ this.setCooldownRemaining(0);
124
+ }
125
+ return;
126
+ }
127
+
128
+ this.recalculate();
129
+ };
130
+
131
+ /**
132
+ * Updates the known latest own message date and recomputes remaining time.
133
+ * Prefer calling this when you already know the message date (e.g. from an event).
134
+ */
135
+ public setOwnLatestMessageDate = (date: Date | undefined) => {
136
+ this.state.partialNext({ ownLatestMessageDate: date });
137
+ this.recalculate();
138
+ };
139
+
140
+ private getOwnUserId() {
141
+ const client = this.channel.getClient();
142
+ return client.userID ?? client.user?.id;
143
+ }
144
+
145
+ private findOwnLatestMessageDate({
146
+ messages,
147
+ }: {
148
+ messages: LocalMessage[];
149
+ }): Date | undefined {
150
+ const ownUserId = this.getOwnUserId();
151
+ if (!ownUserId) return undefined;
152
+
153
+ let latest: Date | undefined;
154
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
155
+ const message = messages[i];
156
+ if (message.user?.id !== ownUserId) continue;
157
+ const createdAt = toDateOrUndefined(message.created_at);
158
+ if (!createdAt) continue;
159
+ if (!latest || createdAt.getTime() > latest.getTime()) {
160
+ latest = createdAt;
161
+ }
162
+ if (latest.getTime() > createdAt.getTime()) break;
163
+ }
164
+ return latest;
165
+ }
166
+
167
+ private recalculate = () => {
168
+ this.clearTimeout();
169
+
170
+ const { cooldownConfigSeconds, ownLatestMessageDate, canSkipCooldown } =
171
+ this.state.getLatestValue();
172
+
173
+ const timeSinceOwnLastMessage =
174
+ ownLatestMessageDate != null
175
+ ? // prevent negative values
176
+ Math.max(0, (Date.now() - ownLatestMessageDate.getTime()) / 1000)
177
+ : undefined;
178
+
179
+ const remaining =
180
+ !canSkipCooldown &&
181
+ typeof timeSinceOwnLastMessage !== 'undefined' &&
182
+ cooldownConfigSeconds > timeSinceOwnLastMessage
183
+ ? Math.round(cooldownConfigSeconds - timeSinceOwnLastMessage)
184
+ : 0;
185
+
186
+ if (remaining !== this.cooldownRemaining) {
187
+ this.setCooldownRemaining(remaining);
188
+ }
189
+
190
+ if (remaining <= 0) return;
191
+
192
+ this.timeout = setTimeout(() => {
193
+ this.recalculate();
194
+ }, 1000);
195
+ };
196
+ }