stream-chat 9.10.1 → 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 +400 -21
- package/dist/cjs/index.browser.cjs.map +4 -4
- package/dist/cjs/index.node.cjs +413 -28
- package/dist/cjs/index.node.cjs.map +4 -4
- package/dist/esm/index.js +400 -21
- package/dist/esm/index.js.map +4 -4
- package/dist/types/LiveLocationManager.d.ts +54 -0
- package/dist/types/channel.d.ts +5 -9
- 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 +52 -5
- package/package.json +1 -1
- package/src/LiveLocationManager.ts +297 -0
- package/src/channel.ts +37 -2
- 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/attachmentManager.ts +4 -0
- 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 +55 -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);
|
|
@@ -4642,6 +4643,9 @@ var AttachmentManager = class {
|
|
|
4642
4643
|
if (isFileReference(fileLike) && fileLike.thumb_url) {
|
|
4643
4644
|
localAttachment.thumb_url = fileLike.thumb_url;
|
|
4644
4645
|
}
|
|
4646
|
+
if (isFileReference(fileLike) && fileLike.duration) {
|
|
4647
|
+
localAttachment.duration = fileLike.duration;
|
|
4648
|
+
}
|
|
4645
4649
|
return localAttachment;
|
|
4646
4650
|
};
|
|
4647
4651
|
this.ensureLocalUploadAttachment = async (attachment) => {
|
|
@@ -6022,10 +6026,15 @@ var DEFAULT_TEXT_COMPOSER_CONFIG = {
|
|
|
6022
6026
|
enabled: true,
|
|
6023
6027
|
publishTypingEvents: true
|
|
6024
6028
|
};
|
|
6029
|
+
var DEFAULT_LOCATION_COMPOSER_CONFIG = {
|
|
6030
|
+
enabled: true,
|
|
6031
|
+
getDeviceId: () => generateUUIDv4()
|
|
6032
|
+
};
|
|
6025
6033
|
var DEFAULT_COMPOSER_CONFIG = {
|
|
6026
6034
|
attachments: DEFAULT_ATTACHMENT_MANAGER_CONFIG,
|
|
6027
6035
|
drafts: { enabled: false },
|
|
6028
6036
|
linkPreviews: DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
6037
|
+
location: DEFAULT_LOCATION_COMPOSER_CONFIG,
|
|
6029
6038
|
text: DEFAULT_TEXT_COMPOSER_CONFIG
|
|
6030
6039
|
};
|
|
6031
6040
|
|
|
@@ -6281,6 +6290,54 @@ _LinkPreviewsManager.getPreviewData = (preview) => {
|
|
|
6281
6290
|
};
|
|
6282
6291
|
var LinkPreviewsManager = _LinkPreviewsManager;
|
|
6283
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
|
+
|
|
6284
6341
|
// src/utils/concurrency.ts
|
|
6285
6342
|
var withoutConcurrency = createRunner(wrapWithContinuationTracking);
|
|
6286
6343
|
var withCancellation = createRunner(wrapWithCancellation);
|
|
@@ -6964,9 +7021,8 @@ var createCompositionValidationMiddleware = (composer) => ({
|
|
|
6964
7021
|
}) => {
|
|
6965
7022
|
const { maxLengthOnSend } = composer.config.text ?? {};
|
|
6966
7023
|
const inputText = state.message.text ?? "";
|
|
6967
|
-
const isEmptyMessage = textIsEmpty(inputText) && !state.message.attachments?.length && !state.message.poll_id;
|
|
6968
7024
|
const hasExceededMaxLength = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend;
|
|
6969
|
-
if (
|
|
7025
|
+
if (composer.compositionIsEmpty || hasExceededMaxLength) {
|
|
6970
7026
|
return await discard();
|
|
6971
7027
|
}
|
|
6972
7028
|
return await forward();
|
|
@@ -7246,6 +7302,40 @@ var createPollOnlyCompositionMiddleware = (composer) => ({
|
|
|
7246
7302
|
}
|
|
7247
7303
|
});
|
|
7248
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
|
+
|
|
7249
7339
|
// src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts
|
|
7250
7340
|
var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
7251
7341
|
constructor({ composer }) {
|
|
@@ -7256,6 +7346,7 @@ var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
7256
7346
|
createTextComposerCompositionMiddleware(composer),
|
|
7257
7347
|
createAttachmentsCompositionMiddleware(composer),
|
|
7258
7348
|
createLinkPreviewsCompositionMiddleware(composer),
|
|
7349
|
+
createSharedLocationCompositionMiddleware(composer),
|
|
7259
7350
|
createMessageComposerStateCompositionMiddleware(composer),
|
|
7260
7351
|
createCustomDataCompositionMiddleware(composer),
|
|
7261
7352
|
createCompositionValidationMiddleware(composer),
|
|
@@ -8297,7 +8388,7 @@ var textIsEmpty = (text) => {
|
|
|
8297
8388
|
const trimmedText = text.trim();
|
|
8298
8389
|
return trimmedText === "" || trimmedText === ">" || trimmedText === "``````" || trimmedText === "``" || trimmedText === "**" || trimmedText === "____" || trimmedText === "__" || trimmedText === "****";
|
|
8299
8390
|
};
|
|
8300
|
-
var
|
|
8391
|
+
var initState5 = ({
|
|
8301
8392
|
composer,
|
|
8302
8393
|
message
|
|
8303
8394
|
}) => {
|
|
@@ -8322,7 +8413,7 @@ var initState4 = ({
|
|
|
8322
8413
|
var TextComposer = class {
|
|
8323
8414
|
constructor({ composer, message }) {
|
|
8324
8415
|
this.initState = ({ message } = {}) => {
|
|
8325
|
-
this.state.next(
|
|
8416
|
+
this.state.next(initState5({ composer: this.composer, message }));
|
|
8326
8417
|
};
|
|
8327
8418
|
this.upsertMentionedUser = (user) => {
|
|
8328
8419
|
const mentionedUsers = [...this.mentionedUsers];
|
|
@@ -8450,7 +8541,7 @@ var TextComposer = class {
|
|
|
8450
8541
|
this.state.next(output.state);
|
|
8451
8542
|
};
|
|
8452
8543
|
this.composer = composer;
|
|
8453
|
-
this.state = new StateStore(
|
|
8544
|
+
this.state = new StateStore(initState5({ composer, message }));
|
|
8454
8545
|
this.middlewareExecutor = new TextComposerMiddlewareExecutor({ composer });
|
|
8455
8546
|
}
|
|
8456
8547
|
get channel() {
|
|
@@ -9023,7 +9114,7 @@ var initEditingAuditState = (composition) => {
|
|
|
9023
9114
|
}
|
|
9024
9115
|
};
|
|
9025
9116
|
};
|
|
9026
|
-
var
|
|
9117
|
+
var initState6 = (composition) => {
|
|
9027
9118
|
if (!composition) {
|
|
9028
9119
|
return {
|
|
9029
9120
|
draftId: null,
|
|
@@ -9061,6 +9152,9 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9061
9152
|
client
|
|
9062
9153
|
}) {
|
|
9063
9154
|
super();
|
|
9155
|
+
this.refreshId = () => {
|
|
9156
|
+
this.state.partialNext({ id: _MessageComposer.generateId() });
|
|
9157
|
+
};
|
|
9064
9158
|
this.initState = ({
|
|
9065
9159
|
composition
|
|
9066
9160
|
} = {}) => {
|
|
@@ -9068,10 +9162,11 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9068
9162
|
const message = typeof composition === "undefined" ? composition : compositionIsDraftResponse(composition) ? composition.message : formatMessage(composition);
|
|
9069
9163
|
this.attachmentManager.initState({ message });
|
|
9070
9164
|
this.linkPreviewsManager.initState({ message });
|
|
9165
|
+
this.locationComposer.initState({ message });
|
|
9071
9166
|
this.textComposer.initState({ message });
|
|
9072
9167
|
this.pollComposer.initState();
|
|
9073
9168
|
this.customDataManager.initState({ message });
|
|
9074
|
-
this.state.next(
|
|
9169
|
+
this.state.next(initState6(composition));
|
|
9075
9170
|
if (composition && !compositionIsDraftResponse(composition) && message && isLocalMessage(message)) {
|
|
9076
9171
|
this.editedMessage = message;
|
|
9077
9172
|
}
|
|
@@ -9111,6 +9206,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9111
9206
|
this.addUnsubscribeFunction(this.subscribeTextComposerStateChanged());
|
|
9112
9207
|
this.addUnsubscribeFunction(this.subscribeAttachmentManagerStateChanged());
|
|
9113
9208
|
this.addUnsubscribeFunction(this.subscribeLinkPreviewsManagerStateChanged());
|
|
9209
|
+
this.addUnsubscribeFunction(this.subscribeLocationComposerStateChanged());
|
|
9114
9210
|
this.addUnsubscribeFunction(this.subscribePollComposerStateChanged());
|
|
9115
9211
|
this.addUnsubscribeFunction(this.subscribeCustomDataManagerStateChanged());
|
|
9116
9212
|
this.addUnsubscribeFunction(this.subscribeMessageComposerStateChanged());
|
|
@@ -9207,6 +9303,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9207
9303
|
return;
|
|
9208
9304
|
}
|
|
9209
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
|
+
});
|
|
9210
9314
|
this.subscribeLinkPreviewsManagerStateChanged = () => this.linkPreviewsManager.state.subscribe((_, previousValue) => {
|
|
9211
9315
|
if (typeof previousValue === "undefined") return;
|
|
9212
9316
|
this.logStateUpdateTimestamp();
|
|
@@ -9427,10 +9531,32 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9427
9531
|
throw error;
|
|
9428
9532
|
}
|
|
9429
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
|
+
};
|
|
9430
9559
|
this.compositionContext = compositionContext;
|
|
9431
|
-
this.configState = new StateStore(
|
|
9432
|
-
mergeWith(DEFAULT_COMPOSER_CONFIG, config ?? {})
|
|
9433
|
-
);
|
|
9434
9560
|
if (compositionContext instanceof Channel) {
|
|
9435
9561
|
this.channel = compositionContext;
|
|
9436
9562
|
} else if (compositionContext instanceof Thread) {
|
|
@@ -9443,6 +9569,21 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9443
9569
|
"MessageComposer requires composition context pointing to channel (channel or context.cid)"
|
|
9444
9570
|
);
|
|
9445
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
|
+
);
|
|
9446
9587
|
let message = void 0;
|
|
9447
9588
|
if (compositionIsDraftResponse(composition)) {
|
|
9448
9589
|
message = composition.message;
|
|
@@ -9452,13 +9593,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9452
9593
|
}
|
|
9453
9594
|
this.attachmentManager = new AttachmentManager({ composer: this, message });
|
|
9454
9595
|
this.linkPreviewsManager = new LinkPreviewsManager({ composer: this, message });
|
|
9596
|
+
this.locationComposer = new LocationComposer({ composer: this, message });
|
|
9455
9597
|
this.textComposer = new TextComposer({ composer: this, message });
|
|
9456
9598
|
this.pollComposer = new PollComposer({ composer: this });
|
|
9457
9599
|
this.customDataManager = new CustomDataManager({ composer: this, message });
|
|
9458
9600
|
this.editingAuditState = new StateStore(
|
|
9459
9601
|
this.initEditingAuditState(composition)
|
|
9460
9602
|
);
|
|
9461
|
-
this.state = new StateStore(
|
|
9603
|
+
this.state = new StateStore(initState6(composition));
|
|
9462
9604
|
this.compositionMiddlewareExecutor = new MessageComposerMiddlewareExecutor({
|
|
9463
9605
|
composer: this
|
|
9464
9606
|
});
|
|
@@ -9533,10 +9675,10 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
9533
9675
|
if (this.client.offlineDb) {
|
|
9534
9676
|
return !this.compositionIsEmpty;
|
|
9535
9677
|
}
|
|
9536
|
-
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);
|
|
9537
9679
|
}
|
|
9538
9680
|
get compositionIsEmpty() {
|
|
9539
|
-
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;
|
|
9540
9682
|
}
|
|
9541
9683
|
get lastChangeOriginIsLocal() {
|
|
9542
9684
|
const initiatedWithoutDraft = this.lastChange.draftUpdate === null;
|
|
@@ -10063,6 +10205,30 @@ var Channel = class {
|
|
|
10063
10205
|
this.data = data.channel;
|
|
10064
10206
|
return data;
|
|
10065
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
|
+
}
|
|
10066
10232
|
/**
|
|
10067
10233
|
* delete - Delete the channel. Messages are permanently removed.
|
|
10068
10234
|
*
|
|
@@ -13309,7 +13475,8 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13309
13475
|
constructor({
|
|
13310
13476
|
client,
|
|
13311
13477
|
eventHandlerOverrides = {},
|
|
13312
|
-
options = {}
|
|
13478
|
+
options = {},
|
|
13479
|
+
queryChannelsOverride
|
|
13313
13480
|
}) {
|
|
13314
13481
|
super();
|
|
13315
13482
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -13349,6 +13516,9 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13349
13516
|
Object.entries(truthyEventHandlerOverrides)
|
|
13350
13517
|
);
|
|
13351
13518
|
};
|
|
13519
|
+
this.setQueryChannelsRequest = (queryChannelsRequest) => {
|
|
13520
|
+
this.queryChannelsRequest = queryChannelsRequest;
|
|
13521
|
+
};
|
|
13352
13522
|
this.setOptions = (options = {}) => {
|
|
13353
13523
|
this.options = { ...DEFAULT_CHANNEL_MANAGER_OPTIONS, ...options };
|
|
13354
13524
|
};
|
|
@@ -13359,7 +13529,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13359
13529
|
...options
|
|
13360
13530
|
};
|
|
13361
13531
|
try {
|
|
13362
|
-
const channels = await this.
|
|
13532
|
+
const channels = await this.queryChannelsRequest(
|
|
13363
13533
|
filters,
|
|
13364
13534
|
sort,
|
|
13365
13535
|
options,
|
|
@@ -13475,7 +13645,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13475
13645
|
this.state.partialNext({
|
|
13476
13646
|
pagination: { ...pagination, isLoading: false, isLoadingNext: true }
|
|
13477
13647
|
});
|
|
13478
|
-
const nextChannels = await this.
|
|
13648
|
+
const nextChannels = await this.queryChannelsRequest(
|
|
13479
13649
|
filters,
|
|
13480
13650
|
sort,
|
|
13481
13651
|
options,
|
|
@@ -13718,6 +13888,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
13718
13888
|
});
|
|
13719
13889
|
this.setEventHandlerOverrides(eventHandlerOverrides);
|
|
13720
13890
|
this.setOptions(options);
|
|
13891
|
+
this.queryChannelsRequest = queryChannelsOverride ?? ((...params) => this.client.queryChannels(...params));
|
|
13721
13892
|
this.eventHandlers = new Map(
|
|
13722
13893
|
Object.entries({
|
|
13723
13894
|
channelDeletedHandler: this.channelDeletedHandler,
|
|
@@ -14419,8 +14590,14 @@ var StreamChat = class _StreamChat {
|
|
|
14419
14590
|
*/
|
|
14420
14591
|
this.createChannelManager = ({
|
|
14421
14592
|
eventHandlerOverrides = {},
|
|
14422
|
-
options = {}
|
|
14423
|
-
|
|
14593
|
+
options = {},
|
|
14594
|
+
queryChannelsOverride
|
|
14595
|
+
}) => new ChannelManager({
|
|
14596
|
+
client: this,
|
|
14597
|
+
eventHandlerOverrides,
|
|
14598
|
+
options,
|
|
14599
|
+
queryChannelsOverride
|
|
14600
|
+
});
|
|
14424
14601
|
/**
|
|
14425
14602
|
* Creates a new WebSocket connection with the current user. Returns empty promise, if there is an active connection
|
|
14426
14603
|
*/
|
|
@@ -16524,7 +16701,7 @@ var StreamChat = class _StreamChat {
|
|
|
16524
16701
|
if (this.userAgent) {
|
|
16525
16702
|
return this.userAgent;
|
|
16526
16703
|
}
|
|
16527
|
-
const version = "9.
|
|
16704
|
+
const version = "9.12.0";
|
|
16528
16705
|
const clientBundle = "browser-esm";
|
|
16529
16706
|
let userAgentString = "";
|
|
16530
16707
|
if (this.sdkIdentifier) {
|
|
@@ -17616,9 +17793,9 @@ var StreamChat = class _StreamChat {
|
|
|
17616
17793
|
/**
|
|
17617
17794
|
* updateLocation - Updates a location
|
|
17618
17795
|
*
|
|
17619
|
-
* @param location
|
|
17796
|
+
* @param location SharedLocationRequest the location data to update
|
|
17620
17797
|
*
|
|
17621
|
-
* @returns {Promise<
|
|
17798
|
+
* @returns {Promise<SharedLocationResponse>} The server response
|
|
17622
17799
|
*/
|
|
17623
17800
|
async updateLocation(location) {
|
|
17624
17801
|
return await this.put(
|
|
@@ -17739,6 +17916,8 @@ var EVENT_MAP = {
|
|
|
17739
17916
|
"connection.recovered": true,
|
|
17740
17917
|
"transport.changed": true,
|
|
17741
17918
|
"capabilities.changed": true,
|
|
17919
|
+
"live_location_sharing.started": true,
|
|
17920
|
+
"live_location_sharing.stopped": true,
|
|
17742
17921
|
// Reminder events
|
|
17743
17922
|
"reminder.created": true,
|
|
17744
17923
|
"reminder.updated": true,
|
|
@@ -18594,6 +18773,200 @@ var AbstractOfflineDB = class {
|
|
|
18594
18773
|
}
|
|
18595
18774
|
};
|
|
18596
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
|
+
|
|
18597
18970
|
// src/utils/FixedSizeQueueCache.ts
|
|
18598
18971
|
var FixedSizeQueueCache = class {
|
|
18599
18972
|
constructor(size, options) {
|
|
@@ -18672,6 +19045,7 @@ export {
|
|
|
18672
19045
|
DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
18673
19046
|
DEFAULT_COMPOSER_CONFIG,
|
|
18674
19047
|
DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
19048
|
+
DEFAULT_LOCATION_COMPOSER_CONFIG,
|
|
18675
19049
|
DEFAULT_PAGINATION_OPTIONS,
|
|
18676
19050
|
DEFAULT_REMINDER_MANAGER_CONFIG,
|
|
18677
19051
|
DEFAULT_STOP_REFRESH_BOUNDARY_MS,
|
|
@@ -18687,6 +19061,8 @@ export {
|
|
|
18687
19061
|
JWTUserToken,
|
|
18688
19062
|
LinkPreviewStatus,
|
|
18689
19063
|
LinkPreviewsManager,
|
|
19064
|
+
LiveLocationManager,
|
|
19065
|
+
LocationComposer,
|
|
18690
19066
|
MAX_POLL_OPTIONS,
|
|
18691
19067
|
MODERATION_ENTITY_TYPES,
|
|
18692
19068
|
MaxPriority,
|
|
@@ -18723,6 +19099,7 @@ export {
|
|
|
18723
19099
|
Thread,
|
|
18724
19100
|
ThreadManager,
|
|
18725
19101
|
TokenManager,
|
|
19102
|
+
UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT,
|
|
18726
19103
|
UserFromToken,
|
|
18727
19104
|
UserSearchSource,
|
|
18728
19105
|
VALID_MAX_VOTES_VALUE_REGEX,
|
|
@@ -18753,6 +19130,7 @@ export {
|
|
|
18753
19130
|
createMentionsMiddleware,
|
|
18754
19131
|
createMessageComposerStateCompositionMiddleware,
|
|
18755
19132
|
createPollComposerStateMiddleware,
|
|
19133
|
+
createSharedLocationCompositionMiddleware,
|
|
18756
19134
|
createTextComposerCompositionMiddleware,
|
|
18757
19135
|
createTextComposerPreValidationMiddleware,
|
|
18758
19136
|
decodeBase64,
|
|
@@ -18789,6 +19167,7 @@ export {
|
|
|
18789
19167
|
isOwnUser,
|
|
18790
19168
|
isPatch,
|
|
18791
19169
|
isScrapedContent,
|
|
19170
|
+
isSharedLocationResponse,
|
|
18792
19171
|
isTargetedOptionTextUpdate,
|
|
18793
19172
|
isUploadedAttachment,
|
|
18794
19173
|
isVideoAttachment,
|