stream-chat 9.11.0 → 9.12.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/dist/cjs/index.browser.cjs +397 -21
- package/dist/cjs/index.browser.cjs.map +4 -4
- package/dist/cjs/index.node.cjs +410 -28
- package/dist/cjs/index.node.cjs.map +4 -4
- package/dist/esm/index.js +397 -21
- package/dist/esm/index.js.map +4 -4
- package/dist/types/LiveLocationManager.d.ts +54 -0
- package/dist/types/channel.d.ts +3 -1
- package/dist/types/channel_manager.d.ts +5 -1
- package/dist/types/client.d.ts +7 -6
- package/dist/types/events.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/messageComposer/LocationComposer.d.ts +34 -0
- package/dist/types/messageComposer/attachmentIdentity.d.ts +2 -1
- package/dist/types/messageComposer/configuration/configuration.d.ts +2 -1
- package/dist/types/messageComposer/configuration/types.d.ts +11 -0
- package/dist/types/messageComposer/index.d.ts +1 -0
- package/dist/types/messageComposer/messageComposer.d.ts +7 -2
- package/dist/types/messageComposer/middleware/messageComposer/index.d.ts +1 -0
- package/dist/types/messageComposer/middleware/messageComposer/sharedLocation.d.ts +3 -0
- package/dist/types/types.d.ts +44 -5
- package/package.json +1 -1
- package/src/LiveLocationManager.ts +297 -0
- package/src/channel.ts +34 -0
- package/src/channel_manager.ts +15 -2
- package/src/client.ts +14 -5
- package/src/events.ts +2 -0
- package/src/index.ts +1 -0
- package/src/messageComposer/LocationComposer.ts +94 -0
- package/src/messageComposer/attachmentIdentity.ts +8 -1
- package/src/messageComposer/configuration/configuration.ts +8 -0
- package/src/messageComposer/configuration/types.ts +14 -0
- package/src/messageComposer/index.ts +1 -0
- package/src/messageComposer/messageComposer.ts +81 -9
- package/src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts +2 -0
- package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +1 -5
- package/src/messageComposer/middleware/messageComposer/index.ts +1 -0
- package/src/messageComposer/middleware/messageComposer/sharedLocation.ts +42 -0
- package/src/types.ts +46 -5
package/dist/esm/index.js
CHANGED
|
@@ -3854,6 +3854,7 @@ var isLocalVoiceRecordingAttachment = (attachment) => isVoiceRecordingAttachment
|
|
|
3854
3854
|
var isVideoAttachment = (attachment, supportedVideoFormat = []) => attachment.type === "video" || !!(attachment.mime_type && supportedVideoFormat.indexOf(attachment.mime_type) !== -1);
|
|
3855
3855
|
var isLocalVideoAttachment = (attachment) => isVideoAttachment(attachment) && isLocalAttachment(attachment);
|
|
3856
3856
|
var isUploadedAttachment = (attachment) => isAudioAttachment(attachment) || isFileAttachment(attachment) || isImageAttachment(attachment) || isVideoAttachment(attachment) || isVoiceRecordingAttachment(attachment);
|
|
3857
|
+
var isSharedLocationResponse = (location) => !!location.latitude && !!location.longitude && !!location.channel_cid;
|
|
3857
3858
|
|
|
3858
3859
|
// src/messageComposer/fileUtils.ts
|
|
3859
3860
|
var isFile2 = (fileLike) => !!fileLike.lastModified && !("uri" in fileLike);
|
|
@@ -6025,10 +6026,15 @@ var DEFAULT_TEXT_COMPOSER_CONFIG = {
|
|
|
6025
6026
|
enabled: true,
|
|
6026
6027
|
publishTypingEvents: true
|
|
6027
6028
|
};
|
|
6029
|
+
var DEFAULT_LOCATION_COMPOSER_CONFIG = {
|
|
6030
|
+
enabled: true,
|
|
6031
|
+
getDeviceId: () => generateUUIDv4()
|
|
6032
|
+
};
|
|
6028
6033
|
var DEFAULT_COMPOSER_CONFIG = {
|
|
6029
6034
|
attachments: DEFAULT_ATTACHMENT_MANAGER_CONFIG,
|
|
6030
6035
|
drafts: { enabled: false },
|
|
6031
6036
|
linkPreviews: DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
6037
|
+
location: DEFAULT_LOCATION_COMPOSER_CONFIG,
|
|
6032
6038
|
text: DEFAULT_TEXT_COMPOSER_CONFIG
|
|
6033
6039
|
};
|
|
6034
6040
|
|
|
@@ -6284,6 +6290,54 @@ _LinkPreviewsManager.getPreviewData = (preview) => {
|
|
|
6284
6290
|
};
|
|
6285
6291
|
var LinkPreviewsManager = _LinkPreviewsManager;
|
|
6286
6292
|
|
|
6293
|
+
// src/messageComposer/LocationComposer.ts
|
|
6294
|
+
var MIN_LIVE_LOCATION_SHARE_DURATION = 60 * 1e3;
|
|
6295
|
+
var initState4 = ({
|
|
6296
|
+
message
|
|
6297
|
+
}) => ({
|
|
6298
|
+
location: message?.shared_location ?? null
|
|
6299
|
+
});
|
|
6300
|
+
var LocationComposer = class {
|
|
6301
|
+
constructor({ composer, message }) {
|
|
6302
|
+
this.initState = ({ message } = {}) => {
|
|
6303
|
+
this.state.next(initState4({ message }));
|
|
6304
|
+
};
|
|
6305
|
+
this.setData = (data) => {
|
|
6306
|
+
if (!this.config.enabled) return;
|
|
6307
|
+
if (!data.latitude || !data.longitude) return;
|
|
6308
|
+
this.state.partialNext({
|
|
6309
|
+
location: {
|
|
6310
|
+
...data,
|
|
6311
|
+
message_id: this.composer.id,
|
|
6312
|
+
created_by_device_id: this.deviceId
|
|
6313
|
+
}
|
|
6314
|
+
});
|
|
6315
|
+
};
|
|
6316
|
+
this.composer = composer;
|
|
6317
|
+
this.state = new StateStore(initState4({ message }));
|
|
6318
|
+
this._deviceId = this.config.getDeviceId();
|
|
6319
|
+
}
|
|
6320
|
+
get config() {
|
|
6321
|
+
return this.composer.config.location;
|
|
6322
|
+
}
|
|
6323
|
+
get deviceId() {
|
|
6324
|
+
return this._deviceId;
|
|
6325
|
+
}
|
|
6326
|
+
get location() {
|
|
6327
|
+
return this.state.getLatestValue().location;
|
|
6328
|
+
}
|
|
6329
|
+
get validLocation() {
|
|
6330
|
+
const { durationMs, ...location } = this.location ?? {};
|
|
6331
|
+
if (!!location?.created_by_device_id && location.message_id && location.latitude && location.longitude && (typeof durationMs === "undefined" || durationMs >= MIN_LIVE_LOCATION_SHARE_DURATION)) {
|
|
6332
|
+
return {
|
|
6333
|
+
...location,
|
|
6334
|
+
end_at: durationMs && new Date(Date.now() + durationMs).toISOString()
|
|
6335
|
+
};
|
|
6336
|
+
}
|
|
6337
|
+
return null;
|
|
6338
|
+
}
|
|
6339
|
+
};
|
|
6340
|
+
|
|
6287
6341
|
// src/utils/concurrency.ts
|
|
6288
6342
|
var withoutConcurrency = createRunner(wrapWithContinuationTracking);
|
|
6289
6343
|
var withCancellation = createRunner(wrapWithCancellation);
|
|
@@ -6967,9 +7021,8 @@ var createCompositionValidationMiddleware = (composer) => ({
|
|
|
6967
7021
|
}) => {
|
|
6968
7022
|
const { maxLengthOnSend } = composer.config.text ?? {};
|
|
6969
7023
|
const inputText = state.message.text ?? "";
|
|
6970
|
-
const isEmptyMessage = textIsEmpty(inputText) && !state.message.attachments?.length && !state.message.poll_id;
|
|
6971
7024
|
const hasExceededMaxLength = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend;
|
|
6972
|
-
if (
|
|
7025
|
+
if (composer.compositionIsEmpty || hasExceededMaxLength) {
|
|
6973
7026
|
return await discard();
|
|
6974
7027
|
}
|
|
6975
7028
|
return await forward();
|
|
@@ -7249,6 +7302,40 @@ var createPollOnlyCompositionMiddleware = (composer) => ({
|
|
|
7249
7302
|
}
|
|
7250
7303
|
});
|
|
7251
7304
|
|
|
7305
|
+
// src/messageComposer/middleware/messageComposer/sharedLocation.ts
|
|
7306
|
+
var createSharedLocationCompositionMiddleware = (composer) => ({
|
|
7307
|
+
id: "stream-io/message-composer-middleware/shared-location",
|
|
7308
|
+
handlers: {
|
|
7309
|
+
compose: ({
|
|
7310
|
+
state,
|
|
7311
|
+
next,
|
|
7312
|
+
forward
|
|
7313
|
+
}) => {
|
|
7314
|
+
const { locationComposer } = composer;
|
|
7315
|
+
const location = locationComposer.validLocation;
|
|
7316
|
+
if (!locationComposer || !location || !composer.client.user) return forward();
|
|
7317
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
7318
|
+
return next({
|
|
7319
|
+
...state,
|
|
7320
|
+
localMessage: {
|
|
7321
|
+
...state.localMessage,
|
|
7322
|
+
shared_location: {
|
|
7323
|
+
...location,
|
|
7324
|
+
channel_cid: composer.channel.cid,
|
|
7325
|
+
created_at: timestamp,
|
|
7326
|
+
updated_at: timestamp,
|
|
7327
|
+
user_id: composer.client.user.id
|
|
7328
|
+
}
|
|
7329
|
+
},
|
|
7330
|
+
message: {
|
|
7331
|
+
...state.message,
|
|
7332
|
+
shared_location: location
|
|
7333
|
+
}
|
|
7334
|
+
});
|
|
7335
|
+
}
|
|
7336
|
+
}
|
|
7337
|
+
});
|
|
7338
|
+
|
|
7252
7339
|
// src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts
|
|
7253
7340
|
var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
7254
7341
|
constructor({ composer }) {
|
|
@@ -7259,6 +7346,7 @@ var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
7259
7346
|
createTextComposerCompositionMiddleware(composer),
|
|
7260
7347
|
createAttachmentsCompositionMiddleware(composer),
|
|
7261
7348
|
createLinkPreviewsCompositionMiddleware(composer),
|
|
7349
|
+
createSharedLocationCompositionMiddleware(composer),
|
|
7262
7350
|
createMessageComposerStateCompositionMiddleware(composer),
|
|
7263
7351
|
createCustomDataCompositionMiddleware(composer),
|
|
7264
7352
|
createCompositionValidationMiddleware(composer),
|
|
@@ -8300,7 +8388,7 @@ var textIsEmpty = (text) => {
|
|
|
8300
8388
|
const trimmedText = text.trim();
|
|
8301
8389
|
return trimmedText === "" || trimmedText === ">" || trimmedText === "``````" || trimmedText === "``" || trimmedText === "**" || trimmedText === "____" || trimmedText === "__" || trimmedText === "****";
|
|
8302
8390
|
};
|
|
8303
|
-
var
|
|
8391
|
+
var initState5 = ({
|
|
8304
8392
|
composer,
|
|
8305
8393
|
message
|
|
8306
8394
|
}) => {
|
|
@@ -8325,7 +8413,7 @@ var initState4 = ({
|
|
|
8325
8413
|
var TextComposer = class {
|
|
8326
8414
|
constructor({ composer, message }) {
|
|
8327
8415
|
this.initState = ({ message } = {}) => {
|
|
8328
|
-
this.state.next(
|
|
8416
|
+
this.state.next(initState5({ composer: this.composer, message }));
|
|
8329
8417
|
};
|
|
8330
8418
|
this.upsertMentionedUser = (user) => {
|
|
8331
8419
|
const mentionedUsers = [...this.mentionedUsers];
|
|
@@ -8453,7 +8541,7 @@ var TextComposer = class {
|
|
|
8453
8541
|
this.state.next(output.state);
|
|
8454
8542
|
};
|
|
8455
8543
|
this.composer = composer;
|
|
8456
|
-
this.state = new StateStore(
|
|
8544
|
+
this.state = new StateStore(initState5({ composer, message }));
|
|
8457
8545
|
this.middlewareExecutor = new TextComposerMiddlewareExecutor({ composer });
|
|
8458
8546
|
}
|
|
8459
8547
|
get channel() {
|
|
@@ -9026,7 +9114,7 @@ var initEditingAuditState = (composition) => {
|
|
|
9026
9114
|
}
|
|
9027
9115
|
};
|
|
9028
9116
|
};
|
|
9029
|
-
var
|
|
9117
|
+
var initState6 = (composition) => {
|
|
9030
9118
|
if (!composition) {
|
|
9031
9119
|
return {
|
|
9032
9120
|
draftId: null,
|
|
@@ -9064,6 +9152,9 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9064
9152
|
client
|
|
9065
9153
|
}) {
|
|
9066
9154
|
super();
|
|
9155
|
+
this.refreshId = () => {
|
|
9156
|
+
this.state.partialNext({ id: _MessageComposer.generateId() });
|
|
9157
|
+
};
|
|
9067
9158
|
this.initState = ({
|
|
9068
9159
|
composition
|
|
9069
9160
|
} = {}) => {
|
|
@@ -9071,10 +9162,11 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9071
9162
|
const message = typeof composition === "undefined" ? composition : compositionIsDraftResponse(composition) ? composition.message : formatMessage(composition);
|
|
9072
9163
|
this.attachmentManager.initState({ message });
|
|
9073
9164
|
this.linkPreviewsManager.initState({ message });
|
|
9165
|
+
this.locationComposer.initState({ message });
|
|
9074
9166
|
this.textComposer.initState({ message });
|
|
9075
9167
|
this.pollComposer.initState();
|
|
9076
9168
|
this.customDataManager.initState({ message });
|
|
9077
|
-
this.state.next(
|
|
9169
|
+
this.state.next(initState6(composition));
|
|
9078
9170
|
if (composition && !compositionIsDraftResponse(composition) && message && isLocalMessage(message)) {
|
|
9079
9171
|
this.editedMessage = message;
|
|
9080
9172
|
}
|
|
@@ -9114,6 +9206,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9114
9206
|
this.addUnsubscribeFunction(this.subscribeTextComposerStateChanged());
|
|
9115
9207
|
this.addUnsubscribeFunction(this.subscribeAttachmentManagerStateChanged());
|
|
9116
9208
|
this.addUnsubscribeFunction(this.subscribeLinkPreviewsManagerStateChanged());
|
|
9209
|
+
this.addUnsubscribeFunction(this.subscribeLocationComposerStateChanged());
|
|
9117
9210
|
this.addUnsubscribeFunction(this.subscribePollComposerStateChanged());
|
|
9118
9211
|
this.addUnsubscribeFunction(this.subscribeCustomDataManagerStateChanged());
|
|
9119
9212
|
this.addUnsubscribeFunction(this.subscribeMessageComposerStateChanged());
|
|
@@ -9210,6 +9303,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9210
9303
|
return;
|
|
9211
9304
|
}
|
|
9212
9305
|
});
|
|
9306
|
+
this.subscribeLocationComposerStateChanged = () => this.locationComposer.state.subscribe((_, previousValue) => {
|
|
9307
|
+
if (typeof previousValue === "undefined") return;
|
|
9308
|
+
this.logStateUpdateTimestamp();
|
|
9309
|
+
if (this.compositionIsEmpty) {
|
|
9310
|
+
this.deleteDraft();
|
|
9311
|
+
return;
|
|
9312
|
+
}
|
|
9313
|
+
});
|
|
9213
9314
|
this.subscribeLinkPreviewsManagerStateChanged = () => this.linkPreviewsManager.state.subscribe((_, previousValue) => {
|
|
9214
9315
|
if (typeof previousValue === "undefined") return;
|
|
9215
9316
|
this.logStateUpdateTimestamp();
|
|
@@ -9430,10 +9531,32 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9430
9531
|
throw error;
|
|
9431
9532
|
}
|
|
9432
9533
|
};
|
|
9534
|
+
this.sendLocation = async () => {
|
|
9535
|
+
const location = this.locationComposer.validLocation;
|
|
9536
|
+
if (this.threadId || !location) return;
|
|
9537
|
+
try {
|
|
9538
|
+
await this.channel.sendSharedLocation(location);
|
|
9539
|
+
this.refreshId();
|
|
9540
|
+
this.locationComposer.initState();
|
|
9541
|
+
} catch (error) {
|
|
9542
|
+
this.client.notifications.addError({
|
|
9543
|
+
message: "Failed to share the location",
|
|
9544
|
+
origin: {
|
|
9545
|
+
emitter: "MessageComposer",
|
|
9546
|
+
context: { composer: this }
|
|
9547
|
+
},
|
|
9548
|
+
options: {
|
|
9549
|
+
type: "api:location:create:failed",
|
|
9550
|
+
metadata: {
|
|
9551
|
+
reason: error.message
|
|
9552
|
+
},
|
|
9553
|
+
originalError: error instanceof Error ? error : void 0
|
|
9554
|
+
}
|
|
9555
|
+
});
|
|
9556
|
+
throw error;
|
|
9557
|
+
}
|
|
9558
|
+
};
|
|
9433
9559
|
this.compositionContext = compositionContext;
|
|
9434
|
-
this.configState = new StateStore(
|
|
9435
|
-
mergeWith(DEFAULT_COMPOSER_CONFIG, config ?? {})
|
|
9436
|
-
);
|
|
9437
9560
|
if (compositionContext instanceof Channel) {
|
|
9438
9561
|
this.channel = compositionContext;
|
|
9439
9562
|
} else if (compositionContext instanceof Thread) {
|
|
@@ -9446,6 +9569,21 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9446
9569
|
"MessageComposer requires composition context pointing to channel (channel or context.cid)"
|
|
9447
9570
|
);
|
|
9448
9571
|
}
|
|
9572
|
+
const mergeChannelConfigCustomizer = (originalVal, channelConfigVal, key) => typeof originalVal === "object" ? void 0 : originalVal === false && key === "enabled" ? false : ["string", "number", "bigint", "boolean", "symbol"].includes(
|
|
9573
|
+
// prevent enabling features that are disabled server-side
|
|
9574
|
+
typeof channelConfigVal
|
|
9575
|
+
) ? channelConfigVal : originalVal;
|
|
9576
|
+
this.configState = new StateStore(
|
|
9577
|
+
mergeWith(
|
|
9578
|
+
mergeWith(DEFAULT_COMPOSER_CONFIG, config ?? {}),
|
|
9579
|
+
{
|
|
9580
|
+
location: {
|
|
9581
|
+
enabled: this.channel.getConfig()?.shared_locations
|
|
9582
|
+
}
|
|
9583
|
+
},
|
|
9584
|
+
mergeChannelConfigCustomizer
|
|
9585
|
+
)
|
|
9586
|
+
);
|
|
9449
9587
|
let message = void 0;
|
|
9450
9588
|
if (compositionIsDraftResponse(composition)) {
|
|
9451
9589
|
message = composition.message;
|
|
@@ -9455,13 +9593,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9455
9593
|
}
|
|
9456
9594
|
this.attachmentManager = new AttachmentManager({ composer: this, message });
|
|
9457
9595
|
this.linkPreviewsManager = new LinkPreviewsManager({ composer: this, message });
|
|
9596
|
+
this.locationComposer = new LocationComposer({ composer: this, message });
|
|
9458
9597
|
this.textComposer = new TextComposer({ composer: this, message });
|
|
9459
9598
|
this.pollComposer = new PollComposer({ composer: this });
|
|
9460
9599
|
this.customDataManager = new CustomDataManager({ composer: this, message });
|
|
9461
9600
|
this.editingAuditState = new StateStore(
|
|
9462
9601
|
this.initEditingAuditState(composition)
|
|
9463
9602
|
);
|
|
9464
|
-
this.state = new StateStore(
|
|
9603
|
+
this.state = new StateStore(initState6(composition));
|
|
9465
9604
|
this.compositionMiddlewareExecutor = new MessageComposerMiddlewareExecutor({
|
|
9466
9605
|
composer: this
|
|
9467
9606
|
});
|
|
@@ -9536,10 +9675,10 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9536
9675
|
if (this.client.offlineDb) {
|
|
9537
9676
|
return !this.compositionIsEmpty;
|
|
9538
9677
|
}
|
|
9539
|
-
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId);
|
|
9678
|
+
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId || !!this.locationComposer.validLocation);
|
|
9540
9679
|
}
|
|
9541
9680
|
get compositionIsEmpty() {
|
|
9542
|
-
return !this.quotedMessage && this.textComposer.textIsEmpty && !this.attachmentManager.attachments.length && !this.pollId;
|
|
9681
|
+
return !this.quotedMessage && this.textComposer.textIsEmpty && !this.attachmentManager.attachments.length && !this.pollId && !this.locationComposer.validLocation;
|
|
9543
9682
|
}
|
|
9544
9683
|
get lastChangeOriginIsLocal() {
|
|
9545
9684
|
const initiatedWithoutDraft = this.lastChange.draftUpdate === null;
|
|
@@ -10066,6 +10205,30 @@ var Channel = class {
|
|
|
10066
10205
|
this.data = data.channel;
|
|
10067
10206
|
return data;
|
|
10068
10207
|
}
|
|
10208
|
+
async sendSharedLocation(location, userId) {
|
|
10209
|
+
const result = await this.sendMessage({
|
|
10210
|
+
id: location.message_id,
|
|
10211
|
+
shared_location: location,
|
|
10212
|
+
user: userId ? { id: userId } : void 0
|
|
10213
|
+
});
|
|
10214
|
+
if (location.end_at) {
|
|
10215
|
+
this.getClient().dispatchEvent({
|
|
10216
|
+
message: result.message,
|
|
10217
|
+
type: "live_location_sharing.started"
|
|
10218
|
+
});
|
|
10219
|
+
}
|
|
10220
|
+
return result;
|
|
10221
|
+
}
|
|
10222
|
+
async stopLiveLocationSharing(payload) {
|
|
10223
|
+
const location = await this.getClient().updateLocation({
|
|
10224
|
+
...payload,
|
|
10225
|
+
end_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
10226
|
+
});
|
|
10227
|
+
this.getClient().dispatchEvent({
|
|
10228
|
+
live_location: location,
|
|
10229
|
+
type: "live_location_sharing.stopped"
|
|
10230
|
+
});
|
|
10231
|
+
}
|
|
10069
10232
|
/**
|
|
10070
10233
|
* delete - Delete the channel. Messages are permanently removed.
|
|
10071
10234
|
*
|
|
@@ -13312,7 +13475,8 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13312
13475
|
constructor({
|
|
13313
13476
|
client,
|
|
13314
13477
|
eventHandlerOverrides = {},
|
|
13315
|
-
options = {}
|
|
13478
|
+
options = {},
|
|
13479
|
+
queryChannelsOverride
|
|
13316
13480
|
}) {
|
|
13317
13481
|
super();
|
|
13318
13482
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -13352,6 +13516,9 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13352
13516
|
Object.entries(truthyEventHandlerOverrides)
|
|
13353
13517
|
);
|
|
13354
13518
|
};
|
|
13519
|
+
this.setQueryChannelsRequest = (queryChannelsRequest) => {
|
|
13520
|
+
this.queryChannelsRequest = queryChannelsRequest;
|
|
13521
|
+
};
|
|
13355
13522
|
this.setOptions = (options = {}) => {
|
|
13356
13523
|
this.options = { ...DEFAULT_CHANNEL_MANAGER_OPTIONS, ...options };
|
|
13357
13524
|
};
|
|
@@ -13362,7 +13529,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13362
13529
|
...options
|
|
13363
13530
|
};
|
|
13364
13531
|
try {
|
|
13365
|
-
const channels = await this.
|
|
13532
|
+
const channels = await this.queryChannelsRequest(
|
|
13366
13533
|
filters,
|
|
13367
13534
|
sort,
|
|
13368
13535
|
options,
|
|
@@ -13478,7 +13645,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13478
13645
|
this.state.partialNext({
|
|
13479
13646
|
pagination: { ...pagination, isLoading: false, isLoadingNext: true }
|
|
13480
13647
|
});
|
|
13481
|
-
const nextChannels = await this.
|
|
13648
|
+
const nextChannels = await this.queryChannelsRequest(
|
|
13482
13649
|
filters,
|
|
13483
13650
|
sort,
|
|
13484
13651
|
options,
|
|
@@ -13721,6 +13888,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13721
13888
|
});
|
|
13722
13889
|
this.setEventHandlerOverrides(eventHandlerOverrides);
|
|
13723
13890
|
this.setOptions(options);
|
|
13891
|
+
this.queryChannelsRequest = queryChannelsOverride ?? ((...params) => this.client.queryChannels(...params));
|
|
13724
13892
|
this.eventHandlers = new Map(
|
|
13725
13893
|
Object.entries({
|
|
13726
13894
|
channelDeletedHandler: this.channelDeletedHandler,
|
|
@@ -14422,8 +14590,14 @@ var StreamChat = class _StreamChat {
|
|
|
14422
14590
|
*/
|
|
14423
14591
|
this.createChannelManager = ({
|
|
14424
14592
|
eventHandlerOverrides = {},
|
|
14425
|
-
options = {}
|
|
14426
|
-
|
|
14593
|
+
options = {},
|
|
14594
|
+
queryChannelsOverride
|
|
14595
|
+
}) => new ChannelManager({
|
|
14596
|
+
client: this,
|
|
14597
|
+
eventHandlerOverrides,
|
|
14598
|
+
options,
|
|
14599
|
+
queryChannelsOverride
|
|
14600
|
+
});
|
|
14427
14601
|
/**
|
|
14428
14602
|
* Creates a new WebSocket connection with the current user. Returns empty promise, if there is an active connection
|
|
14429
14603
|
*/
|
|
@@ -16527,7 +16701,7 @@ var StreamChat = class _StreamChat {
|
|
|
16527
16701
|
if (this.userAgent) {
|
|
16528
16702
|
return this.userAgent;
|
|
16529
16703
|
}
|
|
16530
|
-
const version = "9.
|
|
16704
|
+
const version = "9.12.0";
|
|
16531
16705
|
const clientBundle = "browser-esm";
|
|
16532
16706
|
let userAgentString = "";
|
|
16533
16707
|
if (this.sdkIdentifier) {
|
|
@@ -17619,9 +17793,9 @@ var StreamChat = class _StreamChat {
|
|
|
17619
17793
|
/**
|
|
17620
17794
|
* updateLocation - Updates a location
|
|
17621
17795
|
*
|
|
17622
|
-
* @param location
|
|
17796
|
+
* @param location SharedLocationRequest the location data to update
|
|
17623
17797
|
*
|
|
17624
|
-
* @returns {Promise<
|
|
17798
|
+
* @returns {Promise<SharedLocationResponse>} The server response
|
|
17625
17799
|
*/
|
|
17626
17800
|
async updateLocation(location) {
|
|
17627
17801
|
return await this.put(
|
|
@@ -17742,6 +17916,8 @@ var EVENT_MAP = {
|
|
|
17742
17916
|
"connection.recovered": true,
|
|
17743
17917
|
"transport.changed": true,
|
|
17744
17918
|
"capabilities.changed": true,
|
|
17919
|
+
"live_location_sharing.started": true,
|
|
17920
|
+
"live_location_sharing.stopped": true,
|
|
17745
17921
|
// Reminder events
|
|
17746
17922
|
"reminder.created": true,
|
|
17747
17923
|
"reminder.updated": true,
|
|
@@ -18597,6 +18773,200 @@ var AbstractOfflineDB = class {
|
|
|
18597
18773
|
}
|
|
18598
18774
|
};
|
|
18599
18775
|
|
|
18776
|
+
// src/LiveLocationManager.ts
|
|
18777
|
+
var isExpiredLocation = (location) => {
|
|
18778
|
+
const endTimeTimestamp = new Date(location.end_at).getTime();
|
|
18779
|
+
return endTimeTimestamp < Date.now();
|
|
18780
|
+
};
|
|
18781
|
+
function isValidLiveLocationMessage(message) {
|
|
18782
|
+
if (!message || message.type === "deleted" || !message.shared_location?.end_at)
|
|
18783
|
+
return false;
|
|
18784
|
+
return !isExpiredLocation(message.shared_location);
|
|
18785
|
+
}
|
|
18786
|
+
var UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT = 3e3;
|
|
18787
|
+
var _LiveLocationManager = class _LiveLocationManager extends WithSubscriptions {
|
|
18788
|
+
constructor({
|
|
18789
|
+
client,
|
|
18790
|
+
getDeviceId,
|
|
18791
|
+
watchLocation
|
|
18792
|
+
}) {
|
|
18793
|
+
if (!client.userID) {
|
|
18794
|
+
throw new Error("Live-location sharing is reserved for client-side use only");
|
|
18795
|
+
}
|
|
18796
|
+
super();
|
|
18797
|
+
this.registerSubscriptions = () => {
|
|
18798
|
+
this.incrementRefCount();
|
|
18799
|
+
if (this.hasSubscriptions) return;
|
|
18800
|
+
this.addUnsubscribeFunction(this.subscribeLiveLocationSharingUpdates());
|
|
18801
|
+
this.addUnsubscribeFunction(this.subscribeTargetMessagesChange());
|
|
18802
|
+
};
|
|
18803
|
+
this.unregisterSubscriptions = () => super.unregisterSubscriptions();
|
|
18804
|
+
this.client = client;
|
|
18805
|
+
this.state = new StateStore({
|
|
18806
|
+
messages: /* @__PURE__ */ new Map(),
|
|
18807
|
+
ready: false
|
|
18808
|
+
});
|
|
18809
|
+
this._deviceId = getDeviceId();
|
|
18810
|
+
this.getDeviceId = getDeviceId;
|
|
18811
|
+
this.watchLocation = watchLocation;
|
|
18812
|
+
}
|
|
18813
|
+
async init() {
|
|
18814
|
+
await this.assureStateInit();
|
|
18815
|
+
this.registerSubscriptions();
|
|
18816
|
+
}
|
|
18817
|
+
get messages() {
|
|
18818
|
+
return this.state.getLatestValue().messages;
|
|
18819
|
+
}
|
|
18820
|
+
get stateIsReady() {
|
|
18821
|
+
return this.state.getLatestValue().ready;
|
|
18822
|
+
}
|
|
18823
|
+
get deviceId() {
|
|
18824
|
+
if (!this._deviceId) {
|
|
18825
|
+
this._deviceId = this.getDeviceId();
|
|
18826
|
+
}
|
|
18827
|
+
return this._deviceId;
|
|
18828
|
+
}
|
|
18829
|
+
async assureStateInit() {
|
|
18830
|
+
if (this.stateIsReady) return;
|
|
18831
|
+
const { active_live_locations } = await this.client.getSharedLocations();
|
|
18832
|
+
this.state.next({
|
|
18833
|
+
messages: new Map(
|
|
18834
|
+
active_live_locations.filter((location) => !isExpiredLocation(location)).map((location) => [
|
|
18835
|
+
location.message_id,
|
|
18836
|
+
{
|
|
18837
|
+
...location,
|
|
18838
|
+
stopSharingTimeout: setTimeout(
|
|
18839
|
+
() => {
|
|
18840
|
+
this.unregisterMessages([location.message_id]);
|
|
18841
|
+
},
|
|
18842
|
+
new Date(location.end_at).getTime() - Date.now()
|
|
18843
|
+
)
|
|
18844
|
+
}
|
|
18845
|
+
])
|
|
18846
|
+
),
|
|
18847
|
+
ready: true
|
|
18848
|
+
});
|
|
18849
|
+
}
|
|
18850
|
+
subscribeTargetMessagesChange() {
|
|
18851
|
+
let unsubscribeWatchLocation = null;
|
|
18852
|
+
const unsubscribe = this.state.subscribeWithSelector(
|
|
18853
|
+
({ messages }) => ({ messages }),
|
|
18854
|
+
({ messages }) => {
|
|
18855
|
+
if (!messages.size) {
|
|
18856
|
+
unsubscribeWatchLocation?.();
|
|
18857
|
+
unsubscribeWatchLocation = null;
|
|
18858
|
+
} else if (messages.size && !unsubscribeWatchLocation) {
|
|
18859
|
+
unsubscribeWatchLocation = this.subscribeWatchLocation();
|
|
18860
|
+
}
|
|
18861
|
+
}
|
|
18862
|
+
);
|
|
18863
|
+
return () => {
|
|
18864
|
+
unsubscribe();
|
|
18865
|
+
unsubscribeWatchLocation?.();
|
|
18866
|
+
};
|
|
18867
|
+
}
|
|
18868
|
+
subscribeWatchLocation() {
|
|
18869
|
+
let nextAllowedUpdateCallTimestamp = Date.now();
|
|
18870
|
+
const unsubscribe = this.watchLocation(({ latitude, longitude }) => {
|
|
18871
|
+
if (Date.now() < nextAllowedUpdateCallTimestamp) return;
|
|
18872
|
+
nextAllowedUpdateCallTimestamp = Date.now() + UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT;
|
|
18873
|
+
withCancellation(_LiveLocationManager.symbol, async () => {
|
|
18874
|
+
const promises = [];
|
|
18875
|
+
await this.assureStateInit();
|
|
18876
|
+
const expiredLocations = [];
|
|
18877
|
+
for (const [messageId, location] of this.messages) {
|
|
18878
|
+
if (isExpiredLocation(location)) {
|
|
18879
|
+
expiredLocations.push(location.message_id);
|
|
18880
|
+
continue;
|
|
18881
|
+
}
|
|
18882
|
+
if (location.latitude === latitude && location.longitude === longitude)
|
|
18883
|
+
continue;
|
|
18884
|
+
const promise = this.client.updateLocation({
|
|
18885
|
+
created_by_device_id: location.created_by_device_id,
|
|
18886
|
+
message_id: messageId,
|
|
18887
|
+
latitude,
|
|
18888
|
+
longitude
|
|
18889
|
+
});
|
|
18890
|
+
promises.push(promise);
|
|
18891
|
+
}
|
|
18892
|
+
this.unregisterMessages(expiredLocations);
|
|
18893
|
+
if (promises.length > 0) {
|
|
18894
|
+
await Promise.allSettled(promises);
|
|
18895
|
+
}
|
|
18896
|
+
});
|
|
18897
|
+
});
|
|
18898
|
+
return unsubscribe;
|
|
18899
|
+
}
|
|
18900
|
+
subscribeLiveLocationSharingUpdates() {
|
|
18901
|
+
const subscriptions = [
|
|
18902
|
+
...[
|
|
18903
|
+
"live_location_sharing.started",
|
|
18904
|
+
"message.updated",
|
|
18905
|
+
"message.deleted"
|
|
18906
|
+
].map(
|
|
18907
|
+
(eventType) => this.client.on(eventType, (event) => {
|
|
18908
|
+
if (!event.message) return;
|
|
18909
|
+
if (event.type === "live_location_sharing.started") {
|
|
18910
|
+
this.registerMessage(event.message);
|
|
18911
|
+
} else if (event.type === "message.updated") {
|
|
18912
|
+
const isRegistered = this.messages.has(event.message.id);
|
|
18913
|
+
if (isRegistered && !isValidLiveLocationMessage(event.message)) {
|
|
18914
|
+
this.unregisterMessages([event.message.id]);
|
|
18915
|
+
}
|
|
18916
|
+
this.registerMessage(event.message);
|
|
18917
|
+
} else {
|
|
18918
|
+
this.unregisterMessages([event.message.id]);
|
|
18919
|
+
}
|
|
18920
|
+
})
|
|
18921
|
+
),
|
|
18922
|
+
this.client.on("live_location_sharing.stopped", (event) => {
|
|
18923
|
+
if (!event.live_location) return;
|
|
18924
|
+
this.unregisterMessages([event.live_location?.message_id]);
|
|
18925
|
+
})
|
|
18926
|
+
];
|
|
18927
|
+
return () => subscriptions.forEach((subscription) => subscription.unsubscribe());
|
|
18928
|
+
}
|
|
18929
|
+
registerMessage(message) {
|
|
18930
|
+
if (!this.client.userID || message?.user?.id !== this.client.userID || !isValidLiveLocationMessage(message))
|
|
18931
|
+
return;
|
|
18932
|
+
this.state.next((currentValue) => {
|
|
18933
|
+
const messages = new Map(currentValue.messages);
|
|
18934
|
+
messages.set(message.id, {
|
|
18935
|
+
...message.shared_location,
|
|
18936
|
+
stopSharingTimeout: setTimeout(
|
|
18937
|
+
() => {
|
|
18938
|
+
this.unregisterMessages([message.id]);
|
|
18939
|
+
},
|
|
18940
|
+
new Date(message.shared_location.end_at).getTime() - Date.now()
|
|
18941
|
+
)
|
|
18942
|
+
});
|
|
18943
|
+
return {
|
|
18944
|
+
...currentValue,
|
|
18945
|
+
messages
|
|
18946
|
+
};
|
|
18947
|
+
});
|
|
18948
|
+
}
|
|
18949
|
+
unregisterMessages(messageIds) {
|
|
18950
|
+
const messages = this.messages;
|
|
18951
|
+
const removedMessages = new Set(messageIds);
|
|
18952
|
+
const newMessages = new Map(
|
|
18953
|
+
Array.from(messages).filter(([messageId, location]) => {
|
|
18954
|
+
if (removedMessages.has(messageId) && location.stopSharingTimeout) {
|
|
18955
|
+
clearTimeout(location.stopSharingTimeout);
|
|
18956
|
+
location.stopSharingTimeout = null;
|
|
18957
|
+
}
|
|
18958
|
+
return !removedMessages.has(messageId);
|
|
18959
|
+
})
|
|
18960
|
+
);
|
|
18961
|
+
if (newMessages.size === messages.size) return;
|
|
18962
|
+
this.state.partialNext({
|
|
18963
|
+
messages: newMessages
|
|
18964
|
+
});
|
|
18965
|
+
}
|
|
18966
|
+
};
|
|
18967
|
+
_LiveLocationManager.symbol = Symbol(_LiveLocationManager.name);
|
|
18968
|
+
var LiveLocationManager = _LiveLocationManager;
|
|
18969
|
+
|
|
18600
18970
|
// src/utils/FixedSizeQueueCache.ts
|
|
18601
18971
|
var FixedSizeQueueCache = class {
|
|
18602
18972
|
constructor(size, options) {
|
|
@@ -18675,6 +19045,7 @@ export {
|
|
|
18675
19045
|
DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
18676
19046
|
DEFAULT_COMPOSER_CONFIG,
|
|
18677
19047
|
DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
19048
|
+
DEFAULT_LOCATION_COMPOSER_CONFIG,
|
|
18678
19049
|
DEFAULT_PAGINATION_OPTIONS,
|
|
18679
19050
|
DEFAULT_REMINDER_MANAGER_CONFIG,
|
|
18680
19051
|
DEFAULT_STOP_REFRESH_BOUNDARY_MS,
|
|
@@ -18690,6 +19061,8 @@ export {
|
|
|
18690
19061
|
JWTUserToken,
|
|
18691
19062
|
LinkPreviewStatus,
|
|
18692
19063
|
LinkPreviewsManager,
|
|
19064
|
+
LiveLocationManager,
|
|
19065
|
+
LocationComposer,
|
|
18693
19066
|
MAX_POLL_OPTIONS,
|
|
18694
19067
|
MODERATION_ENTITY_TYPES,
|
|
18695
19068
|
MaxPriority,
|
|
@@ -18726,6 +19099,7 @@ export {
|
|
|
18726
19099
|
Thread,
|
|
18727
19100
|
ThreadManager,
|
|
18728
19101
|
TokenManager,
|
|
19102
|
+
UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT,
|
|
18729
19103
|
UserFromToken,
|
|
18730
19104
|
UserSearchSource,
|
|
18731
19105
|
VALID_MAX_VOTES_VALUE_REGEX,
|
|
@@ -18756,6 +19130,7 @@ export {
|
|
|
18756
19130
|
createMentionsMiddleware,
|
|
18757
19131
|
createMessageComposerStateCompositionMiddleware,
|
|
18758
19132
|
createPollComposerStateMiddleware,
|
|
19133
|
+
createSharedLocationCompositionMiddleware,
|
|
18759
19134
|
createTextComposerCompositionMiddleware,
|
|
18760
19135
|
createTextComposerPreValidationMiddleware,
|
|
18761
19136
|
decodeBase64,
|
|
@@ -18792,6 +19167,7 @@ export {
|
|
|
18792
19167
|
isOwnUser,
|
|
18793
19168
|
isPatch,
|
|
18794
19169
|
isScrapedContent,
|
|
19170
|
+
isSharedLocationResponse,
|
|
18795
19171
|
isTargetedOptionTextUpdate,
|
|
18796
19172
|
isUploadedAttachment,
|
|
18797
19173
|
isVideoAttachment,
|