stream-chat 9.49.0 → 9.50.1
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/cjs/index.browser.js +82 -27
- package/dist/cjs/index.browser.js.map +2 -2
- package/dist/cjs/index.node.js +82 -27
- package/dist/cjs/index.node.js.map +2 -2
- package/dist/esm/index.mjs +82 -27
- package/dist/esm/index.mjs.map +2 -2
- package/dist/types/channel.d.ts +12 -0
- package/dist/types/events.d.ts +1 -0
- package/dist/types/thread_manager.d.ts +7 -0
- package/dist/types/types.d.ts +6 -0
- package/dist/types/utils.d.ts +13 -0
- package/package.json +1 -1
- package/src/channel.ts +45 -4
- package/src/client.ts +1 -0
- package/src/events.ts +1 -0
- package/src/messageDelivery/MessageDeliveryReporter.ts +3 -1
- package/src/offline-support/offline_support_api.ts +53 -24
- package/src/thread_manager.ts +11 -3
- package/src/types.ts +6 -0
- package/src/utils.ts +22 -0
|
@@ -621,6 +621,12 @@ function isOwnUserBaseProperty(property) {
|
|
|
621
621
|
};
|
|
622
622
|
return ownUserBaseProperties[property];
|
|
623
623
|
}
|
|
624
|
+
var channelHasReadEvents = (channel) => {
|
|
625
|
+
const ownCapabilities = channel?.data?.own_capabilities;
|
|
626
|
+
return !(Array.isArray(ownCapabilities) && !ownCapabilities.includes("read-events"));
|
|
627
|
+
};
|
|
628
|
+
var channelTracksReadLocally = (channel) => !channelHasReadEvents(channel) && !!channel?.getClient().options.isLocalUnreadCountEnabled;
|
|
629
|
+
var userHasReadReceipts = (client) => client.user?.privacy_settings?.read_receipts?.enabled ?? true;
|
|
624
630
|
function addFileToFormData(uri, name, contentType) {
|
|
625
631
|
const data = new import_form_data.default();
|
|
626
632
|
if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {
|
|
@@ -8782,6 +8788,7 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
|
|
|
8782
8788
|
* @param options
|
|
8783
8789
|
*/
|
|
8784
8790
|
this.markRead = async (collection, options) => {
|
|
8791
|
+
if (!userHasReadReceipts(this.client)) return null;
|
|
8785
8792
|
let result = null;
|
|
8786
8793
|
if (isChannel(collection)) {
|
|
8787
8794
|
result = await collection.markAsReadRequest(options);
|
|
@@ -10126,6 +10133,33 @@ var Channel = class {
|
|
|
10126
10133
|
...data
|
|
10127
10134
|
});
|
|
10128
10135
|
}
|
|
10136
|
+
/**
|
|
10137
|
+
* markReadLocally - Resets this user's unread count locally, without any backend call. Intended for
|
|
10138
|
+
* channels that have read events disabled (e.g. livestreams) when the client is created with the
|
|
10139
|
+
* `isLocalUnreadCountEnabled` option. Dispatches a dedicated, client-only `message.read_locally` event
|
|
10140
|
+
* that runs through the same `_handleChannelEvent` read logic as a real `message.read` (minus the
|
|
10141
|
+
* delivery-report network sync), so the read-state update lives in one place. When offline support
|
|
10142
|
+
* is enabled, the offline DB persists the reset for read-events-disabled channels, so the local
|
|
10143
|
+
* count stays consistent across app restarts.
|
|
10144
|
+
*
|
|
10145
|
+
* @return {Event | undefined} The dispatched `message.read_locally` event, or `undefined` if there is no connected user.
|
|
10146
|
+
*/
|
|
10147
|
+
markReadLocally() {
|
|
10148
|
+
const client = this.getClient();
|
|
10149
|
+
if (!client.userID) return;
|
|
10150
|
+
const event = {
|
|
10151
|
+
channel_id: this.id,
|
|
10152
|
+
channel_type: this.type,
|
|
10153
|
+
cid: this.cid,
|
|
10154
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10155
|
+
last_read_message_id: this.lastMessage()?.id,
|
|
10156
|
+
team: this.data?.team,
|
|
10157
|
+
type: "message.read_locally",
|
|
10158
|
+
user: client.user
|
|
10159
|
+
};
|
|
10160
|
+
client.dispatchEvent(event);
|
|
10161
|
+
return event;
|
|
10162
|
+
}
|
|
10129
10163
|
/**
|
|
10130
10164
|
* clean - Cleans the channel state and fires stop typing if needed
|
|
10131
10165
|
*/
|
|
@@ -10281,7 +10315,7 @@ var Channel = class {
|
|
|
10281
10315
|
if (message.user?.id === this.getClient().userID) return false;
|
|
10282
10316
|
if (message.user?.id && this.getClient().userMuteStatus(message.user.id))
|
|
10283
10317
|
return false;
|
|
10284
|
-
if (
|
|
10318
|
+
if (!this.getClient().options.isLocalUnreadCountEnabled && !channelHasReadEvents(this)) {
|
|
10285
10319
|
return false;
|
|
10286
10320
|
}
|
|
10287
10321
|
if (this.getClient()._muteStatus(this.cid).muted) return false;
|
|
@@ -10692,6 +10726,11 @@ var Channel = class {
|
|
|
10692
10726
|
delete channelState.typing[event.user.id];
|
|
10693
10727
|
}
|
|
10694
10728
|
break;
|
|
10729
|
+
// `message.read_locally` is the client-only event dispatched by `markReadLocally()` when read
|
|
10730
|
+
// events are disabled (e.g. livestreams with `isLocalUnreadCountEnabled`). It reuses the exact
|
|
10731
|
+
// `message.read` state logic so the read-state update lives in one place — only the
|
|
10732
|
+
// delivery-report network sync below is skipped for it.
|
|
10733
|
+
case "message.read_locally":
|
|
10695
10734
|
case "message.read":
|
|
10696
10735
|
if (event.user?.id && event.created_at) {
|
|
10697
10736
|
const previousReadState = channelState.read[event.user.id];
|
|
@@ -10712,7 +10751,9 @@ var Channel = class {
|
|
|
10712
10751
|
const isOwnEvent = event.user?.id === client.user?.id;
|
|
10713
10752
|
if (isOwnEvent) {
|
|
10714
10753
|
channelState.unreadCount = 0;
|
|
10715
|
-
|
|
10754
|
+
if (event.type === "message.read") {
|
|
10755
|
+
client.syncDeliveredCandidates([this]);
|
|
10756
|
+
}
|
|
10716
10757
|
}
|
|
10717
10758
|
}
|
|
10718
10759
|
break;
|
|
@@ -12597,6 +12638,7 @@ var DEFAULT_CONNECTION_RECOVERY_THROTTLE_DURATION = 1e3;
|
|
|
12597
12638
|
var MAX_QUERY_THREADS_LIMIT = 25;
|
|
12598
12639
|
var THREAD_MANAGER_INITIAL_STATE = {
|
|
12599
12640
|
active: false,
|
|
12641
|
+
wasActivatedAtLeastOnce: false,
|
|
12600
12642
|
isThreadOrderStale: false,
|
|
12601
12643
|
threads: [],
|
|
12602
12644
|
unreadThreadCount: 0,
|
|
@@ -12619,7 +12661,7 @@ var ThreadManager = class extends WithSubscriptions {
|
|
|
12619
12661
|
this.state.next(THREAD_MANAGER_INITIAL_STATE);
|
|
12620
12662
|
};
|
|
12621
12663
|
this.activate = () => {
|
|
12622
|
-
this.state.partialNext({ active: true });
|
|
12664
|
+
this.state.partialNext({ active: true, wasActivatedAtLeastOnce: true });
|
|
12623
12665
|
};
|
|
12624
12666
|
this.deactivate = () => {
|
|
12625
12667
|
this.state.partialNext({ active: false });
|
|
@@ -12699,8 +12741,8 @@ var ThreadManager = class extends WithSubscriptions {
|
|
|
12699
12741
|
}).unsubscribe;
|
|
12700
12742
|
const throttledHandleConnectionRecovered = throttle(
|
|
12701
12743
|
() => {
|
|
12702
|
-
const { lastConnectionDropAt } = this.state.getLatestValue();
|
|
12703
|
-
if (!lastConnectionDropAt) return;
|
|
12744
|
+
const { lastConnectionDropAt, wasActivatedAtLeastOnce } = this.state.getLatestValue();
|
|
12745
|
+
if (!lastConnectionDropAt || !wasActivatedAtLeastOnce) return;
|
|
12704
12746
|
this.reload({ force: true });
|
|
12705
12747
|
},
|
|
12706
12748
|
DEFAULT_CONNECTION_RECOVERY_THROTTLE_DURATION,
|
|
@@ -14832,7 +14874,7 @@ var StreamChat = class _StreamChat {
|
|
|
14832
14874
|
return this.userAgent;
|
|
14833
14875
|
}
|
|
14834
14876
|
if (!this.cachedUserAgent) {
|
|
14835
|
-
const version = "9.
|
|
14877
|
+
const version = "9.50.1";
|
|
14836
14878
|
const { name: sdkName, version: sdkVersion } = this.sdkIdentifier ?? {};
|
|
14837
14879
|
const { name: appName, version: appVersion } = this.appIdentifier ?? {};
|
|
14838
14880
|
const { os, model: deviceModel } = this.deviceIdentifier ?? {};
|
|
@@ -14890,6 +14932,7 @@ var StreamChat = class _StreamChat {
|
|
|
14890
14932
|
warmUp: false,
|
|
14891
14933
|
recoverStateOnReconnect: true,
|
|
14892
14934
|
disableCache: false,
|
|
14935
|
+
isLocalUnreadCountEnabled: false,
|
|
14893
14936
|
wsUrlParams: new URLSearchParams({}),
|
|
14894
14937
|
...inputOptions
|
|
14895
14938
|
};
|
|
@@ -18243,6 +18286,7 @@ var EVENT_MAP = {
|
|
|
18243
18286
|
"ai_indicator.stop": true,
|
|
18244
18287
|
"ai_indicator.clear": true,
|
|
18245
18288
|
// local events
|
|
18289
|
+
"message.read_locally": true,
|
|
18246
18290
|
"channels.queried": true,
|
|
18247
18291
|
"offline_reactions.queried": true,
|
|
18248
18292
|
"connection.changed": true,
|
|
@@ -18626,7 +18670,8 @@ var AbstractOfflineDB = class {
|
|
|
18626
18670
|
if (cid && client.user && client.user.id !== user?.id) {
|
|
18627
18671
|
const userId = client.user.id;
|
|
18628
18672
|
const channel = client.activeChannels[cid];
|
|
18629
|
-
|
|
18673
|
+
const tracksReadLocally = channelTracksReadLocally(channel);
|
|
18674
|
+
if (channel && (channelHasReadEvents(channel) || tracksReadLocally)) {
|
|
18630
18675
|
const ownReads = channel.state.read[userId];
|
|
18631
18676
|
const unreadCount = channel.countUnread();
|
|
18632
18677
|
const upsertReadsQueries = await this.upsertReads({
|
|
@@ -18634,8 +18679,8 @@ var AbstractOfflineDB = class {
|
|
|
18634
18679
|
execute: false,
|
|
18635
18680
|
reads: [
|
|
18636
18681
|
{
|
|
18637
|
-
last_read: ownReads
|
|
18638
|
-
last_read_message_id: ownReads
|
|
18682
|
+
last_read: (ownReads?.last_read ?? /* @__PURE__ */ new Date(0)).toISOString(),
|
|
18683
|
+
last_read_message_id: ownReads?.last_read_message_id,
|
|
18639
18684
|
unread_messages: unreadCount,
|
|
18640
18685
|
user: client.user
|
|
18641
18686
|
}
|
|
@@ -18834,27 +18879,30 @@ var AbstractOfflineDB = class {
|
|
|
18834
18879
|
truncated_at,
|
|
18835
18880
|
execute: false
|
|
18836
18881
|
});
|
|
18882
|
+
let finalQueries = [...truncateQueries];
|
|
18837
18883
|
const userId = ownUser.id;
|
|
18838
18884
|
const activeChannel = this.client.activeChannels[cid];
|
|
18839
|
-
const
|
|
18840
|
-
|
|
18841
|
-
|
|
18842
|
-
|
|
18843
|
-
|
|
18885
|
+
const tracksReadLocally = channelTracksReadLocally(activeChannel);
|
|
18886
|
+
if (activeChannel && (channelHasReadEvents(activeChannel) || tracksReadLocally)) {
|
|
18887
|
+
const ownReads = activeChannel.state.read[userId];
|
|
18888
|
+
let unreadCount = 0;
|
|
18889
|
+
if (truncated_at) {
|
|
18890
|
+
unreadCount = activeChannel.countUnread(new Date(truncated_at));
|
|
18891
|
+
}
|
|
18892
|
+
const upsertReadQueries = await this.upsertReads({
|
|
18893
|
+
cid,
|
|
18894
|
+
execute: false,
|
|
18895
|
+
reads: [
|
|
18896
|
+
{
|
|
18897
|
+
last_read: (ownReads?.last_read ?? /* @__PURE__ */ new Date(0)).toString(),
|
|
18898
|
+
last_read_message_id: ownReads?.last_read_message_id,
|
|
18899
|
+
unread_messages: unreadCount,
|
|
18900
|
+
user: ownUser
|
|
18901
|
+
}
|
|
18902
|
+
]
|
|
18903
|
+
});
|
|
18904
|
+
finalQueries = [...finalQueries, ...upsertReadQueries];
|
|
18844
18905
|
}
|
|
18845
|
-
const upsertReadQueries = await this.upsertReads({
|
|
18846
|
-
cid,
|
|
18847
|
-
execute: false,
|
|
18848
|
-
reads: [
|
|
18849
|
-
{
|
|
18850
|
-
last_read: ownReads.last_read.toString(),
|
|
18851
|
-
last_read_message_id: ownReads.last_read_message_id,
|
|
18852
|
-
unread_messages: unreadCount,
|
|
18853
|
-
user: ownUser
|
|
18854
|
-
}
|
|
18855
|
-
]
|
|
18856
|
-
});
|
|
18857
|
-
const finalQueries = [...truncateQueries, ...upsertReadQueries];
|
|
18858
18906
|
if (execute) {
|
|
18859
18907
|
await this.executeSqlBatch(finalQueries);
|
|
18860
18908
|
}
|
|
@@ -18955,6 +19003,13 @@ var AbstractOfflineDB = class {
|
|
|
18955
19003
|
if (type === "message.read" || type === "notification.mark_read") {
|
|
18956
19004
|
return this.handleRead({ event, unreadMessages: 0, execute });
|
|
18957
19005
|
}
|
|
19006
|
+
if (type === "message.read_locally") {
|
|
19007
|
+
const localChannel = event.cid ? this.client.activeChannels[event.cid] : void 0;
|
|
19008
|
+
if (channelTracksReadLocally(localChannel)) {
|
|
19009
|
+
return this.handleRead({ event, unreadMessages: 0, execute });
|
|
19010
|
+
}
|
|
19011
|
+
return [];
|
|
19012
|
+
}
|
|
18958
19013
|
if (type === "notification.mark_unread") {
|
|
18959
19014
|
return this.handleRead({ event, execute });
|
|
18960
19015
|
}
|