Skip to content

Commit

Permalink
Merge branch 'master' into threads
Browse files Browse the repository at this point in the history
  • Loading branch information
tbarbugli authored Feb 1, 2024
2 parents e584fe8 + de84d40 commit e72f3b8
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 84 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [8.15.0](https://github.com/GetStream/stream-chat-js/compare/v8.14.5...v8.15.0) (2024-02-01)


### Features

* add batch unread endpoint ([#1212](https://github.com/GetStream/stream-chat-js/issues/1212)) ([5ea11db](https://github.com/GetStream/stream-chat-js/commit/5ea11dbaef4683ad0b2e58716190973180965294))
* add moderation types ([#1213](https://github.com/GetStream/stream-chat-js/issues/1213)) ([2a13b05](https://github.com/GetStream/stream-chat-js/commit/2a13b053c7006fd64f7187160ca5ea22e486d3a5))
* handle notification.mark_unread ([#1208](https://github.com/GetStream/stream-chat-js/issues/1208)) ([4d73838](https://github.com/GetStream/stream-chat-js/commit/4d73838c7e9aa174b1367d334a011d579b67573f))
* segments API v2 ([#1205](https://github.com/GetStream/stream-chat-js/issues/1205)) ([d2bf603](https://github.com/GetStream/stream-chat-js/commit/d2bf603673400bdcb57b75989825eb3cb638eee9))


### Bug Fixes

* missing types for datadog_info and blocklist type ([33f09b9](https://github.com/GetStream/stream-chat-js/commit/33f09b9fdfb9388312a6e715eba6fff0e5c956f6))
* prevent channel unread count reset to 0 when sending message and on new own or thread messages ([#1210](https://github.com/GetStream/stream-chat-js/issues/1210)) ([9cedf6f](https://github.com/GetStream/stream-chat-js/commit/9cedf6ff14e9cc039722371ada3b7e0a5a2fab05))

### [8.14.5](https://github.com/GetStream/stream-chat-js/compare/v8.14.4...v8.14.5) (2024-01-09)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stream-chat",
"version": "8.14.5",
"version": "8.15.0",
"description": "JS SDK for the Stream Chat API",
"author": "GetStream",
"homepage": "https://getstream.io/chat/",
Expand Down
32 changes: 15 additions & 17 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,10 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
* @return {Promise<SendMessageAPIResponse<StreamChatGenerics>>} The Server Response
*/
async sendMessage(message: Message<StreamChatGenerics>, options?: SendMessageOptions) {
const sendMessageResponse = await this.getClient().post<SendMessageAPIResponse<StreamChatGenerics>>(
this._channelURL() + '/message',
{
message,
...options,
},
);

// Reset unreadCount to 0.
this.state.unreadCount = 0;

return sendMessageResponse;
return await this.getClient().post<SendMessageAPIResponse<StreamChatGenerics>>(this._channelURL() + '/message', {
message,
...options,
});
}

sendFile(
Expand Down Expand Up @@ -1289,6 +1281,12 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
channelState.addPinnedMessage(event.message);
}

// do not increase the unread count - the back-end does not increase the count neither in the following cases:
// 1. the message is mine
// 2. the message is a thread reply from any user
const preventUnreadCountUpdate = ownMessage || isThreadMessage;
if (preventUnreadCountUpdate) break;

if (event.user?.id) {
for (const userId in channelState.read) {
if (userId === event.user.id) {
Expand All @@ -1303,9 +1301,7 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
}
}

if (ownMessage) {
channelState.unreadCount = 0;
} else if (this._countMessageAsUnread(event.message)) {
if (this._countMessageAsUnread(event.message)) {
channelState.unreadCount = channelState.unreadCount + 1;
}
}
Expand Down Expand Up @@ -1363,15 +1359,17 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
const ownMessage = event.user?.id === this.getClient().user?.id;
if (!(ownMessage && event.user)) break;

const unreadCount = event.unread_messages ?? 0;

channelState.read[event.user.id] = {
first_unread_message_id: event.first_unread_message_id,
last_read: new Date(event.last_read_at as string),
last_read_message_id: event.last_read_message_id,
user: event.user,
unread_messages: event.unread_messages ?? 0,
unread_messages: unreadCount,
};

channelState.unreadCount = event.unread_messages ?? 0;
channelState.unreadCount = unreadCount;
break;
}
case 'channel.updated':
Expand Down
158 changes: 115 additions & 43 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import {
GetRateLimitsResponse,
QueryThreadsAPIResponse,
GetUnreadCountAPIResponse,
GetUnreadCountBatchAPIResponse,
ListChannelResponse,
ListCommandsResponse,
ListImportsPaginationOptions,
Expand Down Expand Up @@ -124,12 +125,10 @@ import {
PushProviderListResponse,
PushProviderUpsertResponse,
QueryChannelsAPIResponse,
QuerySegmentsOptions,
ReactionResponse,
ReactivateUserOptions,
ReactivateUsersOptions,
Recipient,
RecipientFilters,
RecipientQueryOptions,
ReservedMessageFields,
ReviewFlagReportOptions,
ReviewFlagReportResponse,
Expand All @@ -139,8 +138,7 @@ import {
SearchPayload,
Segment,
SegmentData,
SegmentFilters,
SegmentQueryOptions,
SegmentType,
SendFileAPIResponse,
StreamChatOptions,
SyncOptions,
Expand All @@ -160,6 +158,7 @@ import {
UpdatedMessage,
UpdateMessageAPIResponse,
UpdateMessageOptions,
UpdateSegmentData,
UserCustomEvent,
UserFilters,
UserOptions,
Expand Down Expand Up @@ -1692,10 +1691,28 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
);
}

/**
* getUnreadCount - Returns unread counts for a single user
*
* @param {string} [userID] User ID.
*
* @return {<GetUnreadCountAPIResponse>}
*/
async getUnreadCount(userID?: string) {
return await this.get<GetUnreadCountAPIResponse>(this.baseURL + '/unread', userID ? { user_id: userID } : {});
}

/**
* getUnreadCountBatch - Returns unread counts for multiple users at once. Only works server side.
*
* @param {string[]} [userIDs] List of user IDs to fetch unread counts for.
*
* @return {<GetUnreadCountBatchAPIResponse>}
*/
async getUnreadCountBatch(userIDs: string[]) {
return await this.post<GetUnreadCountBatchAPIResponse>(this.baseURL + '/unread_batch', { user_ids: userIDs });
}

/**
* removeDevice - Removes the device with the given id. Clientside users can only delete their own devices
*
Expand Down Expand Up @@ -2907,56 +2924,132 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
}

/**
* createSegment - Creates a Campaign Segment
* createSegment - Creates a segment
*
* @private
* @param {SegmentType} type Segment type
* @param {string} id Segment ID (valid UUID)
* @param {string} name Segment name (valid UUID)
* @param {SegmentData} params Segment data
*
* @return {Segment} The Created Segment
* @return {Segment} The created Segment
*/
private async createSegment(type: SegmentType, id: string, name: string, data?: SegmentData): Promise<Segment> {
const body = {
id,
type,
name,
data,
};
const { segment } = await this.post<{ segment: Segment }>(this.baseURL + `/segments`, body);
return segment;
}

/**
* createUserSegment - Creates a user segment
*
* @param {string} id Segment ID (valid UUID)
* @param {string} name Segment name
* @param {SegmentData} data Segment data
*
* @return {Segment} The created Segment
*/
async createUserSegment(id: string, name: string, data?: SegmentData): Promise<Segment> {
return await this.createSegment('user', id, name, data);
}

/**
* createChannelSegment - Creates a channel segment
*
* @param {string} id Segment ID (valid UUID)
* @param {string} name Segment name
* @param {SegmentData} data Segment data
*
* @return {Segment} The created Segment
*/
async createChannelSegment(id: string, name: string, data?: SegmentData): Promise<Segment> {
return await this.createSegment('channel', id, name, data);
}

/**
* updateSegment - Update a segment
*
* @param {string} id Segment ID
* @param {Partial<UpdateSegmentData>} data Data to update
*
* @return {Segment} Updated Segment
*/
async createSegment(params: SegmentData) {
const { segment } = await this.post<{ segment: Segment }>(this.baseURL + `/segments`, { segment: params });
async updateSegment(id: string, data: Partial<UpdateSegmentData>) {
const { segment } = await this.put<{ segment: Segment }>(this.baseURL + `/segments/${id}`, data);
return segment;
}

/**
* querySegments - Query Campaign Segments
* addSegmentTargets - Add targets to a segment
*
* @param {string} id Segment ID
* @param {string[]} targets Targets to add to the segment
*
* @return {APIResponse} API response
*/
async addSegmentTargets(id: string, targets: string[]) {
const body = { targets };
return await this.post<APIResponse>(this.baseURL + `/segments/${id}/addtargets`, body);
}

/**
* deleteSegmentTargets - Delete targets from a segment
*
* @param {string} id Segment ID
* @param {string[]} targets Targets to add to the segment
*
* @return {APIResponse} API response
*/
async deleteSegmentTargets(id: string, targets: string[]) {
const body = { targets };
return await this.post<APIResponse>(this.baseURL + `/segments/${id}/deletetargets`, body);
}

/**
* querySegments - Query Segments
*
* @param {filter} filter MongoDB style filter conditions
* @param {QuerySegmentsOptions} options Options for sorting/paginating the results
*
* @return {Segment[]} Segments
*/
async querySegments(filters: SegmentFilters, options: SegmentQueryOptions = {}) {
async querySegments(filter: {}, options: QuerySegmentsOptions = {}) {
return await this.get<{
segments: Segment[];
}>(this.baseURL + `/segments`, {
payload: {
filter_conditions: filters,
filter,
...options,
},
});
}

/**
* updateSegment - Update a Campaign Segment
* deleteSegment - Delete a Campaign Segment
*
* @param {string} id Segment ID
* @param {Partial<SegmentData>} params Segment data
*
* @return {Segment} Updated Segment
* @return {Promise<APIResponse>} The Server Response
*/
async updateSegment(id: string, params: Partial<SegmentData>) {
const { segment } = await this.put<{ segment: Segment }>(this.baseURL + `/segments/${id}`, { segment: params });
return segment;
async deleteSegment(id: string) {
return await this.delete<APIResponse>(this.baseURL + `/segments/${id}`);
}

/**
* deleteSegment - Delete a Campaign Segment
* segmentTargetExists - Check if a target exists in a segment
*
* @param {string} id Segment ID
* @param {string} segmentId Segment ID
* @param {string} targetId Target ID
*
* @return {Promise<APIResponse>} The Server Response
*/
async deleteSegment(id: string) {
return this.delete<APIResponse>(this.baseURL + `/segments/${id}`);
async segmentTargetExists(segmentId: string, targetId: string) {
return await this.get<APIResponse>(this.baseURL + `/segments/${segmentId}/target/${targetId}`);
}

/**
Expand Down Expand Up @@ -3070,27 +3163,6 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
return await this.post<APIResponse & TestCampaignResponse>(this.baseURL + `/campaigns/${id}/test`, { users });
}

/**
* queryRecipients - Query Campaign Recipient Results
*
*
* @return {Recipient[]} Recipients
*/
async queryRecipients(filters: RecipientFilters, options: RecipientQueryOptions = {}) {
return await this.get<{
campaigns: Record<string, Campaign>;
recipients: Recipient[];
segments: Record<string, Segment>;
channels?: Record<string, ChannelResponse<StreamChatGenerics>>;
users?: Record<string, UserResponse<StreamChatGenerics>>;
}>(this.baseURL + `/recipients`, {
payload: {
filter_conditions: filters,
...options,
},
});
}

/**
* enrichURL - Get OpenGraph data of the given link
*
Expand Down
Loading

0 comments on commit e72f3b8

Please sign in to comment.