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
|
@@ -178,6 +178,7 @@ __export(index_exports, {
|
|
|
178
178
|
DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS: () => DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
179
179
|
DEFAULT_COMPOSER_CONFIG: () => DEFAULT_COMPOSER_CONFIG,
|
|
180
180
|
DEFAULT_LINK_PREVIEW_MANAGER_CONFIG: () => DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
181
|
+
DEFAULT_LOCATION_COMPOSER_CONFIG: () => DEFAULT_LOCATION_COMPOSER_CONFIG,
|
|
181
182
|
DEFAULT_PAGINATION_OPTIONS: () => DEFAULT_PAGINATION_OPTIONS,
|
|
182
183
|
DEFAULT_REMINDER_MANAGER_CONFIG: () => DEFAULT_REMINDER_MANAGER_CONFIG,
|
|
183
184
|
DEFAULT_STOP_REFRESH_BOUNDARY_MS: () => DEFAULT_STOP_REFRESH_BOUNDARY_MS,
|
|
@@ -193,6 +194,8 @@ __export(index_exports, {
|
|
|
193
194
|
JWTUserToken: () => JWTUserToken,
|
|
194
195
|
LinkPreviewStatus: () => LinkPreviewStatus,
|
|
195
196
|
LinkPreviewsManager: () => LinkPreviewsManager,
|
|
197
|
+
LiveLocationManager: () => LiveLocationManager,
|
|
198
|
+
LocationComposer: () => LocationComposer,
|
|
196
199
|
MAX_POLL_OPTIONS: () => MAX_POLL_OPTIONS,
|
|
197
200
|
MODERATION_ENTITY_TYPES: () => MODERATION_ENTITY_TYPES,
|
|
198
201
|
MaxPriority: () => MaxPriority,
|
|
@@ -229,6 +232,7 @@ __export(index_exports, {
|
|
|
229
232
|
Thread: () => Thread,
|
|
230
233
|
ThreadManager: () => ThreadManager,
|
|
231
234
|
TokenManager: () => TokenManager,
|
|
235
|
+
UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT: () => UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT,
|
|
232
236
|
UserFromToken: () => UserFromToken,
|
|
233
237
|
UserSearchSource: () => UserSearchSource,
|
|
234
238
|
VALID_MAX_VOTES_VALUE_REGEX: () => VALID_MAX_VOTES_VALUE_REGEX,
|
|
@@ -259,6 +263,7 @@ __export(index_exports, {
|
|
|
259
263
|
createMentionsMiddleware: () => createMentionsMiddleware,
|
|
260
264
|
createMessageComposerStateCompositionMiddleware: () => createMessageComposerStateCompositionMiddleware,
|
|
261
265
|
createPollComposerStateMiddleware: () => createPollComposerStateMiddleware,
|
|
266
|
+
createSharedLocationCompositionMiddleware: () => createSharedLocationCompositionMiddleware,
|
|
262
267
|
createTextComposerCompositionMiddleware: () => createTextComposerCompositionMiddleware,
|
|
263
268
|
createTextComposerPreValidationMiddleware: () => createTextComposerPreValidationMiddleware,
|
|
264
269
|
decodeBase64: () => decodeBase64,
|
|
@@ -295,6 +300,7 @@ __export(index_exports, {
|
|
|
295
300
|
isOwnUser: () => isOwnUser,
|
|
296
301
|
isPatch: () => isPatch,
|
|
297
302
|
isScrapedContent: () => isScrapedContent,
|
|
303
|
+
isSharedLocationResponse: () => isSharedLocationResponse,
|
|
298
304
|
isTargetedOptionTextUpdate: () => isTargetedOptionTextUpdate,
|
|
299
305
|
isUploadedAttachment: () => isUploadedAttachment,
|
|
300
306
|
isVideoAttachment: () => isVideoAttachment,
|
|
@@ -4019,6 +4025,7 @@ var isLocalVoiceRecordingAttachment = (attachment) => isVoiceRecordingAttachment
|
|
|
4019
4025
|
var isVideoAttachment = (attachment, supportedVideoFormat = []) => attachment.type === "video" || !!(attachment.mime_type && supportedVideoFormat.indexOf(attachment.mime_type) !== -1);
|
|
4020
4026
|
var isLocalVideoAttachment = (attachment) => isVideoAttachment(attachment) && isLocalAttachment(attachment);
|
|
4021
4027
|
var isUploadedAttachment = (attachment) => isAudioAttachment(attachment) || isFileAttachment(attachment) || isImageAttachment(attachment) || isVideoAttachment(attachment) || isVoiceRecordingAttachment(attachment);
|
|
4028
|
+
var isSharedLocationResponse = (location) => !!location.latitude && !!location.longitude && !!location.channel_cid;
|
|
4022
4029
|
|
|
4023
4030
|
// src/messageComposer/fileUtils.ts
|
|
4024
4031
|
var isFile2 = (fileLike) => !!fileLike.lastModified && !("uri" in fileLike);
|
|
@@ -4807,6 +4814,9 @@ var AttachmentManager = class {
|
|
|
4807
4814
|
if (isFileReference(fileLike) && fileLike.thumb_url) {
|
|
4808
4815
|
localAttachment.thumb_url = fileLike.thumb_url;
|
|
4809
4816
|
}
|
|
4817
|
+
if (isFileReference(fileLike) && fileLike.duration) {
|
|
4818
|
+
localAttachment.duration = fileLike.duration;
|
|
4819
|
+
}
|
|
4810
4820
|
return localAttachment;
|
|
4811
4821
|
};
|
|
4812
4822
|
this.ensureLocalUploadAttachment = async (attachment) => {
|
|
@@ -5058,10 +5068,15 @@ var DEFAULT_TEXT_COMPOSER_CONFIG = {
|
|
|
5058
5068
|
enabled: true,
|
|
5059
5069
|
publishTypingEvents: true
|
|
5060
5070
|
};
|
|
5071
|
+
var DEFAULT_LOCATION_COMPOSER_CONFIG = {
|
|
5072
|
+
enabled: true,
|
|
5073
|
+
getDeviceId: () => generateUUIDv4()
|
|
5074
|
+
};
|
|
5061
5075
|
var DEFAULT_COMPOSER_CONFIG = {
|
|
5062
5076
|
attachments: DEFAULT_ATTACHMENT_MANAGER_CONFIG,
|
|
5063
5077
|
drafts: { enabled: false },
|
|
5064
5078
|
linkPreviews: DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
5079
|
+
location: DEFAULT_LOCATION_COMPOSER_CONFIG,
|
|
5065
5080
|
text: DEFAULT_TEXT_COMPOSER_CONFIG
|
|
5066
5081
|
};
|
|
5067
5082
|
|
|
@@ -5317,6 +5332,54 @@ _LinkPreviewsManager.getPreviewData = (preview) => {
|
|
|
5317
5332
|
};
|
|
5318
5333
|
var LinkPreviewsManager = _LinkPreviewsManager;
|
|
5319
5334
|
|
|
5335
|
+
// src/messageComposer/LocationComposer.ts
|
|
5336
|
+
var MIN_LIVE_LOCATION_SHARE_DURATION = 60 * 1e3;
|
|
5337
|
+
var initState4 = ({
|
|
5338
|
+
message
|
|
5339
|
+
}) => ({
|
|
5340
|
+
location: message?.shared_location ?? null
|
|
5341
|
+
});
|
|
5342
|
+
var LocationComposer = class {
|
|
5343
|
+
constructor({ composer, message }) {
|
|
5344
|
+
this.initState = ({ message } = {}) => {
|
|
5345
|
+
this.state.next(initState4({ message }));
|
|
5346
|
+
};
|
|
5347
|
+
this.setData = (data) => {
|
|
5348
|
+
if (!this.config.enabled) return;
|
|
5349
|
+
if (!data.latitude || !data.longitude) return;
|
|
5350
|
+
this.state.partialNext({
|
|
5351
|
+
location: {
|
|
5352
|
+
...data,
|
|
5353
|
+
message_id: this.composer.id,
|
|
5354
|
+
created_by_device_id: this.deviceId
|
|
5355
|
+
}
|
|
5356
|
+
});
|
|
5357
|
+
};
|
|
5358
|
+
this.composer = composer;
|
|
5359
|
+
this.state = new StateStore(initState4({ message }));
|
|
5360
|
+
this._deviceId = this.config.getDeviceId();
|
|
5361
|
+
}
|
|
5362
|
+
get config() {
|
|
5363
|
+
return this.composer.config.location;
|
|
5364
|
+
}
|
|
5365
|
+
get deviceId() {
|
|
5366
|
+
return this._deviceId;
|
|
5367
|
+
}
|
|
5368
|
+
get location() {
|
|
5369
|
+
return this.state.getLatestValue().location;
|
|
5370
|
+
}
|
|
5371
|
+
get validLocation() {
|
|
5372
|
+
const { durationMs, ...location } = this.location ?? {};
|
|
5373
|
+
if (!!location?.created_by_device_id && location.message_id && location.latitude && location.longitude && (typeof durationMs === "undefined" || durationMs >= MIN_LIVE_LOCATION_SHARE_DURATION)) {
|
|
5374
|
+
return {
|
|
5375
|
+
...location,
|
|
5376
|
+
end_at: durationMs && new Date(Date.now() + durationMs).toISOString()
|
|
5377
|
+
};
|
|
5378
|
+
}
|
|
5379
|
+
return null;
|
|
5380
|
+
}
|
|
5381
|
+
};
|
|
5382
|
+
|
|
5320
5383
|
// src/utils/concurrency.ts
|
|
5321
5384
|
var withoutConcurrency = createRunner(wrapWithContinuationTracking);
|
|
5322
5385
|
var withCancellation = createRunner(wrapWithCancellation);
|
|
@@ -6000,9 +6063,8 @@ var createCompositionValidationMiddleware = (composer) => ({
|
|
|
6000
6063
|
}) => {
|
|
6001
6064
|
const { maxLengthOnSend } = composer.config.text ?? {};
|
|
6002
6065
|
const inputText = state.message.text ?? "";
|
|
6003
|
-
const isEmptyMessage = textIsEmpty(inputText) && !state.message.attachments?.length && !state.message.poll_id;
|
|
6004
6066
|
const hasExceededMaxLength = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend;
|
|
6005
|
-
if (
|
|
6067
|
+
if (composer.compositionIsEmpty || hasExceededMaxLength) {
|
|
6006
6068
|
return await discard();
|
|
6007
6069
|
}
|
|
6008
6070
|
return await forward();
|
|
@@ -6282,6 +6344,40 @@ var createPollOnlyCompositionMiddleware = (composer) => ({
|
|
|
6282
6344
|
}
|
|
6283
6345
|
});
|
|
6284
6346
|
|
|
6347
|
+
// src/messageComposer/middleware/messageComposer/sharedLocation.ts
|
|
6348
|
+
var createSharedLocationCompositionMiddleware = (composer) => ({
|
|
6349
|
+
id: "stream-io/message-composer-middleware/shared-location",
|
|
6350
|
+
handlers: {
|
|
6351
|
+
compose: ({
|
|
6352
|
+
state,
|
|
6353
|
+
next,
|
|
6354
|
+
forward
|
|
6355
|
+
}) => {
|
|
6356
|
+
const { locationComposer } = composer;
|
|
6357
|
+
const location = locationComposer.validLocation;
|
|
6358
|
+
if (!locationComposer || !location || !composer.client.user) return forward();
|
|
6359
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
6360
|
+
return next({
|
|
6361
|
+
...state,
|
|
6362
|
+
localMessage: {
|
|
6363
|
+
...state.localMessage,
|
|
6364
|
+
shared_location: {
|
|
6365
|
+
...location,
|
|
6366
|
+
channel_cid: composer.channel.cid,
|
|
6367
|
+
created_at: timestamp,
|
|
6368
|
+
updated_at: timestamp,
|
|
6369
|
+
user_id: composer.client.user.id
|
|
6370
|
+
}
|
|
6371
|
+
},
|
|
6372
|
+
message: {
|
|
6373
|
+
...state.message,
|
|
6374
|
+
shared_location: location
|
|
6375
|
+
}
|
|
6376
|
+
});
|
|
6377
|
+
}
|
|
6378
|
+
}
|
|
6379
|
+
});
|
|
6380
|
+
|
|
6285
6381
|
// src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts
|
|
6286
6382
|
var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
6287
6383
|
constructor({ composer }) {
|
|
@@ -6292,6 +6388,7 @@ var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
6292
6388
|
createTextComposerCompositionMiddleware(composer),
|
|
6293
6389
|
createAttachmentsCompositionMiddleware(composer),
|
|
6294
6390
|
createLinkPreviewsCompositionMiddleware(composer),
|
|
6391
|
+
createSharedLocationCompositionMiddleware(composer),
|
|
6295
6392
|
createMessageComposerStateCompositionMiddleware(composer),
|
|
6296
6393
|
createCustomDataCompositionMiddleware(composer),
|
|
6297
6394
|
createCompositionValidationMiddleware(composer),
|
|
@@ -7333,7 +7430,7 @@ var textIsEmpty = (text) => {
|
|
|
7333
7430
|
const trimmedText = text.trim();
|
|
7334
7431
|
return trimmedText === "" || trimmedText === ">" || trimmedText === "``````" || trimmedText === "``" || trimmedText === "**" || trimmedText === "____" || trimmedText === "__" || trimmedText === "****";
|
|
7335
7432
|
};
|
|
7336
|
-
var
|
|
7433
|
+
var initState5 = ({
|
|
7337
7434
|
composer,
|
|
7338
7435
|
message
|
|
7339
7436
|
}) => {
|
|
@@ -7358,7 +7455,7 @@ var initState4 = ({
|
|
|
7358
7455
|
var TextComposer = class {
|
|
7359
7456
|
constructor({ composer, message }) {
|
|
7360
7457
|
this.initState = ({ message } = {}) => {
|
|
7361
|
-
this.state.next(
|
|
7458
|
+
this.state.next(initState5({ composer: this.composer, message }));
|
|
7362
7459
|
};
|
|
7363
7460
|
this.upsertMentionedUser = (user) => {
|
|
7364
7461
|
const mentionedUsers = [...this.mentionedUsers];
|
|
@@ -7486,7 +7583,7 @@ var TextComposer = class {
|
|
|
7486
7583
|
this.state.next(output.state);
|
|
7487
7584
|
};
|
|
7488
7585
|
this.composer = composer;
|
|
7489
|
-
this.state = new StateStore(
|
|
7586
|
+
this.state = new StateStore(initState5({ composer, message }));
|
|
7490
7587
|
this.middlewareExecutor = new TextComposerMiddlewareExecutor({ composer });
|
|
7491
7588
|
}
|
|
7492
7589
|
get channel() {
|
|
@@ -8059,7 +8156,7 @@ var initEditingAuditState = (composition) => {
|
|
|
8059
8156
|
}
|
|
8060
8157
|
};
|
|
8061
8158
|
};
|
|
8062
|
-
var
|
|
8159
|
+
var initState6 = (composition) => {
|
|
8063
8160
|
if (!composition) {
|
|
8064
8161
|
return {
|
|
8065
8162
|
draftId: null,
|
|
@@ -8097,6 +8194,9 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8097
8194
|
client
|
|
8098
8195
|
}) {
|
|
8099
8196
|
super();
|
|
8197
|
+
this.refreshId = () => {
|
|
8198
|
+
this.state.partialNext({ id: _MessageComposer.generateId() });
|
|
8199
|
+
};
|
|
8100
8200
|
this.initState = ({
|
|
8101
8201
|
composition
|
|
8102
8202
|
} = {}) => {
|
|
@@ -8104,10 +8204,11 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8104
8204
|
const message = typeof composition === "undefined" ? composition : compositionIsDraftResponse(composition) ? composition.message : formatMessage(composition);
|
|
8105
8205
|
this.attachmentManager.initState({ message });
|
|
8106
8206
|
this.linkPreviewsManager.initState({ message });
|
|
8207
|
+
this.locationComposer.initState({ message });
|
|
8107
8208
|
this.textComposer.initState({ message });
|
|
8108
8209
|
this.pollComposer.initState();
|
|
8109
8210
|
this.customDataManager.initState({ message });
|
|
8110
|
-
this.state.next(
|
|
8211
|
+
this.state.next(initState6(composition));
|
|
8111
8212
|
if (composition && !compositionIsDraftResponse(composition) && message && isLocalMessage(message)) {
|
|
8112
8213
|
this.editedMessage = message;
|
|
8113
8214
|
}
|
|
@@ -8147,6 +8248,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8147
8248
|
this.addUnsubscribeFunction(this.subscribeTextComposerStateChanged());
|
|
8148
8249
|
this.addUnsubscribeFunction(this.subscribeAttachmentManagerStateChanged());
|
|
8149
8250
|
this.addUnsubscribeFunction(this.subscribeLinkPreviewsManagerStateChanged());
|
|
8251
|
+
this.addUnsubscribeFunction(this.subscribeLocationComposerStateChanged());
|
|
8150
8252
|
this.addUnsubscribeFunction(this.subscribePollComposerStateChanged());
|
|
8151
8253
|
this.addUnsubscribeFunction(this.subscribeCustomDataManagerStateChanged());
|
|
8152
8254
|
this.addUnsubscribeFunction(this.subscribeMessageComposerStateChanged());
|
|
@@ -8243,6 +8345,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8243
8345
|
return;
|
|
8244
8346
|
}
|
|
8245
8347
|
});
|
|
8348
|
+
this.subscribeLocationComposerStateChanged = () => this.locationComposer.state.subscribe((_, previousValue) => {
|
|
8349
|
+
if (typeof previousValue === "undefined") return;
|
|
8350
|
+
this.logStateUpdateTimestamp();
|
|
8351
|
+
if (this.compositionIsEmpty) {
|
|
8352
|
+
this.deleteDraft();
|
|
8353
|
+
return;
|
|
8354
|
+
}
|
|
8355
|
+
});
|
|
8246
8356
|
this.subscribeLinkPreviewsManagerStateChanged = () => this.linkPreviewsManager.state.subscribe((_, previousValue) => {
|
|
8247
8357
|
if (typeof previousValue === "undefined") return;
|
|
8248
8358
|
this.logStateUpdateTimestamp();
|
|
@@ -8463,10 +8573,32 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8463
8573
|
throw error;
|
|
8464
8574
|
}
|
|
8465
8575
|
};
|
|
8576
|
+
this.sendLocation = async () => {
|
|
8577
|
+
const location = this.locationComposer.validLocation;
|
|
8578
|
+
if (this.threadId || !location) return;
|
|
8579
|
+
try {
|
|
8580
|
+
await this.channel.sendSharedLocation(location);
|
|
8581
|
+
this.refreshId();
|
|
8582
|
+
this.locationComposer.initState();
|
|
8583
|
+
} catch (error) {
|
|
8584
|
+
this.client.notifications.addError({
|
|
8585
|
+
message: "Failed to share the location",
|
|
8586
|
+
origin: {
|
|
8587
|
+
emitter: "MessageComposer",
|
|
8588
|
+
context: { composer: this }
|
|
8589
|
+
},
|
|
8590
|
+
options: {
|
|
8591
|
+
type: "api:location:create:failed",
|
|
8592
|
+
metadata: {
|
|
8593
|
+
reason: error.message
|
|
8594
|
+
},
|
|
8595
|
+
originalError: error instanceof Error ? error : void 0
|
|
8596
|
+
}
|
|
8597
|
+
});
|
|
8598
|
+
throw error;
|
|
8599
|
+
}
|
|
8600
|
+
};
|
|
8466
8601
|
this.compositionContext = compositionContext;
|
|
8467
|
-
this.configState = new StateStore(
|
|
8468
|
-
mergeWith(DEFAULT_COMPOSER_CONFIG, config ?? {})
|
|
8469
|
-
);
|
|
8470
8602
|
if (compositionContext instanceof Channel) {
|
|
8471
8603
|
this.channel = compositionContext;
|
|
8472
8604
|
} else if (compositionContext instanceof Thread) {
|
|
@@ -8479,6 +8611,21 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8479
8611
|
"MessageComposer requires composition context pointing to channel (channel or context.cid)"
|
|
8480
8612
|
);
|
|
8481
8613
|
}
|
|
8614
|
+
const mergeChannelConfigCustomizer = (originalVal, channelConfigVal, key) => typeof originalVal === "object" ? void 0 : originalVal === false && key === "enabled" ? false : ["string", "number", "bigint", "boolean", "symbol"].includes(
|
|
8615
|
+
// prevent enabling features that are disabled server-side
|
|
8616
|
+
typeof channelConfigVal
|
|
8617
|
+
) ? channelConfigVal : originalVal;
|
|
8618
|
+
this.configState = new StateStore(
|
|
8619
|
+
mergeWith(
|
|
8620
|
+
mergeWith(DEFAULT_COMPOSER_CONFIG, config ?? {}),
|
|
8621
|
+
{
|
|
8622
|
+
location: {
|
|
8623
|
+
enabled: this.channel.getConfig()?.shared_locations
|
|
8624
|
+
}
|
|
8625
|
+
},
|
|
8626
|
+
mergeChannelConfigCustomizer
|
|
8627
|
+
)
|
|
8628
|
+
);
|
|
8482
8629
|
let message = void 0;
|
|
8483
8630
|
if (compositionIsDraftResponse(composition)) {
|
|
8484
8631
|
message = composition.message;
|
|
@@ -8488,13 +8635,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8488
8635
|
}
|
|
8489
8636
|
this.attachmentManager = new AttachmentManager({ composer: this, message });
|
|
8490
8637
|
this.linkPreviewsManager = new LinkPreviewsManager({ composer: this, message });
|
|
8638
|
+
this.locationComposer = new LocationComposer({ composer: this, message });
|
|
8491
8639
|
this.textComposer = new TextComposer({ composer: this, message });
|
|
8492
8640
|
this.pollComposer = new PollComposer({ composer: this });
|
|
8493
8641
|
this.customDataManager = new CustomDataManager({ composer: this, message });
|
|
8494
8642
|
this.editingAuditState = new StateStore(
|
|
8495
8643
|
this.initEditingAuditState(composition)
|
|
8496
8644
|
);
|
|
8497
|
-
this.state = new StateStore(
|
|
8645
|
+
this.state = new StateStore(initState6(composition));
|
|
8498
8646
|
this.compositionMiddlewareExecutor = new MessageComposerMiddlewareExecutor({
|
|
8499
8647
|
composer: this
|
|
8500
8648
|
});
|
|
@@ -8569,10 +8717,10 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8569
8717
|
if (this.client.offlineDb) {
|
|
8570
8718
|
return !this.compositionIsEmpty;
|
|
8571
8719
|
}
|
|
8572
|
-
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId);
|
|
8720
|
+
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId || !!this.locationComposer.validLocation);
|
|
8573
8721
|
}
|
|
8574
8722
|
get compositionIsEmpty() {
|
|
8575
|
-
return !this.quotedMessage && this.textComposer.textIsEmpty && !this.attachmentManager.attachments.length && !this.pollId;
|
|
8723
|
+
return !this.quotedMessage && this.textComposer.textIsEmpty && !this.attachmentManager.attachments.length && !this.pollId && !this.locationComposer.validLocation;
|
|
8576
8724
|
}
|
|
8577
8725
|
get lastChangeOriginIsLocal() {
|
|
8578
8726
|
const initiatedWithoutDraft = this.lastChange.draftUpdate === null;
|
|
@@ -9099,6 +9247,30 @@ var Channel = class {
|
|
|
9099
9247
|
this.data = data.channel;
|
|
9100
9248
|
return data;
|
|
9101
9249
|
}
|
|
9250
|
+
async sendSharedLocation(location, userId) {
|
|
9251
|
+
const result = await this.sendMessage({
|
|
9252
|
+
id: location.message_id,
|
|
9253
|
+
shared_location: location,
|
|
9254
|
+
user: userId ? { id: userId } : void 0
|
|
9255
|
+
});
|
|
9256
|
+
if (location.end_at) {
|
|
9257
|
+
this.getClient().dispatchEvent({
|
|
9258
|
+
message: result.message,
|
|
9259
|
+
type: "live_location_sharing.started"
|
|
9260
|
+
});
|
|
9261
|
+
}
|
|
9262
|
+
return result;
|
|
9263
|
+
}
|
|
9264
|
+
async stopLiveLocationSharing(payload) {
|
|
9265
|
+
const location = await this.getClient().updateLocation({
|
|
9266
|
+
...payload,
|
|
9267
|
+
end_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
9268
|
+
});
|
|
9269
|
+
this.getClient().dispatchEvent({
|
|
9270
|
+
live_location: location,
|
|
9271
|
+
type: "live_location_sharing.stopped"
|
|
9272
|
+
});
|
|
9273
|
+
}
|
|
9102
9274
|
/**
|
|
9103
9275
|
* delete - Delete the channel. Messages are permanently removed.
|
|
9104
9276
|
*
|
|
@@ -12345,7 +12517,8 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12345
12517
|
constructor({
|
|
12346
12518
|
client,
|
|
12347
12519
|
eventHandlerOverrides = {},
|
|
12348
|
-
options = {}
|
|
12520
|
+
options = {},
|
|
12521
|
+
queryChannelsOverride
|
|
12349
12522
|
}) {
|
|
12350
12523
|
super();
|
|
12351
12524
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -12385,6 +12558,9 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12385
12558
|
Object.entries(truthyEventHandlerOverrides)
|
|
12386
12559
|
);
|
|
12387
12560
|
};
|
|
12561
|
+
this.setQueryChannelsRequest = (queryChannelsRequest) => {
|
|
12562
|
+
this.queryChannelsRequest = queryChannelsRequest;
|
|
12563
|
+
};
|
|
12388
12564
|
this.setOptions = (options = {}) => {
|
|
12389
12565
|
this.options = { ...DEFAULT_CHANNEL_MANAGER_OPTIONS, ...options };
|
|
12390
12566
|
};
|
|
@@ -12395,7 +12571,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12395
12571
|
...options
|
|
12396
12572
|
};
|
|
12397
12573
|
try {
|
|
12398
|
-
const channels = await this.
|
|
12574
|
+
const channels = await this.queryChannelsRequest(
|
|
12399
12575
|
filters,
|
|
12400
12576
|
sort,
|
|
12401
12577
|
options,
|
|
@@ -12511,7 +12687,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12511
12687
|
this.state.partialNext({
|
|
12512
12688
|
pagination: { ...pagination, isLoading: false, isLoadingNext: true }
|
|
12513
12689
|
});
|
|
12514
|
-
const nextChannels = await this.
|
|
12690
|
+
const nextChannels = await this.queryChannelsRequest(
|
|
12515
12691
|
filters,
|
|
12516
12692
|
sort,
|
|
12517
12693
|
options,
|
|
@@ -12754,6 +12930,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12754
12930
|
});
|
|
12755
12931
|
this.setEventHandlerOverrides(eventHandlerOverrides);
|
|
12756
12932
|
this.setOptions(options);
|
|
12933
|
+
this.queryChannelsRequest = queryChannelsOverride ?? ((...params) => this.client.queryChannels(...params));
|
|
12757
12934
|
this.eventHandlers = new Map(
|
|
12758
12935
|
Object.entries({
|
|
12759
12936
|
channelDeletedHandler: this.channelDeletedHandler,
|
|
@@ -13455,8 +13632,14 @@ var StreamChat = class _StreamChat {
|
|
|
13455
13632
|
*/
|
|
13456
13633
|
this.createChannelManager = ({
|
|
13457
13634
|
eventHandlerOverrides = {},
|
|
13458
|
-
options = {}
|
|
13459
|
-
|
|
13635
|
+
options = {},
|
|
13636
|
+
queryChannelsOverride
|
|
13637
|
+
}) => new ChannelManager({
|
|
13638
|
+
client: this,
|
|
13639
|
+
eventHandlerOverrides,
|
|
13640
|
+
options,
|
|
13641
|
+
queryChannelsOverride
|
|
13642
|
+
});
|
|
13460
13643
|
/**
|
|
13461
13644
|
* Creates a new WebSocket connection with the current user. Returns empty promise, if there is an active connection
|
|
13462
13645
|
*/
|
|
@@ -15560,7 +15743,7 @@ var StreamChat = class _StreamChat {
|
|
|
15560
15743
|
if (this.userAgent) {
|
|
15561
15744
|
return this.userAgent;
|
|
15562
15745
|
}
|
|
15563
|
-
const version = "9.
|
|
15746
|
+
const version = "9.12.0";
|
|
15564
15747
|
const clientBundle = "browser-cjs";
|
|
15565
15748
|
let userAgentString = "";
|
|
15566
15749
|
if (this.sdkIdentifier) {
|
|
@@ -16652,9 +16835,9 @@ var StreamChat = class _StreamChat {
|
|
|
16652
16835
|
/**
|
|
16653
16836
|
* updateLocation - Updates a location
|
|
16654
16837
|
*
|
|
16655
|
-
* @param location
|
|
16838
|
+
* @param location SharedLocationRequest the location data to update
|
|
16656
16839
|
*
|
|
16657
|
-
* @returns {Promise<
|
|
16840
|
+
* @returns {Promise<SharedLocationResponse>} The server response
|
|
16658
16841
|
*/
|
|
16659
16842
|
async updateLocation(location) {
|
|
16660
16843
|
return await this.put(
|
|
@@ -16775,6 +16958,8 @@ var EVENT_MAP = {
|
|
|
16775
16958
|
"connection.recovered": true,
|
|
16776
16959
|
"transport.changed": true,
|
|
16777
16960
|
"capabilities.changed": true,
|
|
16961
|
+
"live_location_sharing.started": true,
|
|
16962
|
+
"live_location_sharing.stopped": true,
|
|
16778
16963
|
// Reminder events
|
|
16779
16964
|
"reminder.created": true,
|
|
16780
16965
|
"reminder.updated": true,
|
|
@@ -17630,6 +17815,200 @@ var AbstractOfflineDB = class {
|
|
|
17630
17815
|
}
|
|
17631
17816
|
};
|
|
17632
17817
|
|
|
17818
|
+
// src/LiveLocationManager.ts
|
|
17819
|
+
var isExpiredLocation = (location) => {
|
|
17820
|
+
const endTimeTimestamp = new Date(location.end_at).getTime();
|
|
17821
|
+
return endTimeTimestamp < Date.now();
|
|
17822
|
+
};
|
|
17823
|
+
function isValidLiveLocationMessage(message) {
|
|
17824
|
+
if (!message || message.type === "deleted" || !message.shared_location?.end_at)
|
|
17825
|
+
return false;
|
|
17826
|
+
return !isExpiredLocation(message.shared_location);
|
|
17827
|
+
}
|
|
17828
|
+
var UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT = 3e3;
|
|
17829
|
+
var _LiveLocationManager = class _LiveLocationManager extends WithSubscriptions {
|
|
17830
|
+
constructor({
|
|
17831
|
+
client,
|
|
17832
|
+
getDeviceId,
|
|
17833
|
+
watchLocation
|
|
17834
|
+
}) {
|
|
17835
|
+
if (!client.userID) {
|
|
17836
|
+
throw new Error("Live-location sharing is reserved for client-side use only");
|
|
17837
|
+
}
|
|
17838
|
+
super();
|
|
17839
|
+
this.registerSubscriptions = () => {
|
|
17840
|
+
this.incrementRefCount();
|
|
17841
|
+
if (this.hasSubscriptions) return;
|
|
17842
|
+
this.addUnsubscribeFunction(this.subscribeLiveLocationSharingUpdates());
|
|
17843
|
+
this.addUnsubscribeFunction(this.subscribeTargetMessagesChange());
|
|
17844
|
+
};
|
|
17845
|
+
this.unregisterSubscriptions = () => super.unregisterSubscriptions();
|
|
17846
|
+
this.client = client;
|
|
17847
|
+
this.state = new StateStore({
|
|
17848
|
+
messages: /* @__PURE__ */ new Map(),
|
|
17849
|
+
ready: false
|
|
17850
|
+
});
|
|
17851
|
+
this._deviceId = getDeviceId();
|
|
17852
|
+
this.getDeviceId = getDeviceId;
|
|
17853
|
+
this.watchLocation = watchLocation;
|
|
17854
|
+
}
|
|
17855
|
+
async init() {
|
|
17856
|
+
await this.assureStateInit();
|
|
17857
|
+
this.registerSubscriptions();
|
|
17858
|
+
}
|
|
17859
|
+
get messages() {
|
|
17860
|
+
return this.state.getLatestValue().messages;
|
|
17861
|
+
}
|
|
17862
|
+
get stateIsReady() {
|
|
17863
|
+
return this.state.getLatestValue().ready;
|
|
17864
|
+
}
|
|
17865
|
+
get deviceId() {
|
|
17866
|
+
if (!this._deviceId) {
|
|
17867
|
+
this._deviceId = this.getDeviceId();
|
|
17868
|
+
}
|
|
17869
|
+
return this._deviceId;
|
|
17870
|
+
}
|
|
17871
|
+
async assureStateInit() {
|
|
17872
|
+
if (this.stateIsReady) return;
|
|
17873
|
+
const { active_live_locations } = await this.client.getSharedLocations();
|
|
17874
|
+
this.state.next({
|
|
17875
|
+
messages: new Map(
|
|
17876
|
+
active_live_locations.filter((location) => !isExpiredLocation(location)).map((location) => [
|
|
17877
|
+
location.message_id,
|
|
17878
|
+
{
|
|
17879
|
+
...location,
|
|
17880
|
+
stopSharingTimeout: setTimeout(
|
|
17881
|
+
() => {
|
|
17882
|
+
this.unregisterMessages([location.message_id]);
|
|
17883
|
+
},
|
|
17884
|
+
new Date(location.end_at).getTime() - Date.now()
|
|
17885
|
+
)
|
|
17886
|
+
}
|
|
17887
|
+
])
|
|
17888
|
+
),
|
|
17889
|
+
ready: true
|
|
17890
|
+
});
|
|
17891
|
+
}
|
|
17892
|
+
subscribeTargetMessagesChange() {
|
|
17893
|
+
let unsubscribeWatchLocation = null;
|
|
17894
|
+
const unsubscribe = this.state.subscribeWithSelector(
|
|
17895
|
+
({ messages }) => ({ messages }),
|
|
17896
|
+
({ messages }) => {
|
|
17897
|
+
if (!messages.size) {
|
|
17898
|
+
unsubscribeWatchLocation?.();
|
|
17899
|
+
unsubscribeWatchLocation = null;
|
|
17900
|
+
} else if (messages.size && !unsubscribeWatchLocation) {
|
|
17901
|
+
unsubscribeWatchLocation = this.subscribeWatchLocation();
|
|
17902
|
+
}
|
|
17903
|
+
}
|
|
17904
|
+
);
|
|
17905
|
+
return () => {
|
|
17906
|
+
unsubscribe();
|
|
17907
|
+
unsubscribeWatchLocation?.();
|
|
17908
|
+
};
|
|
17909
|
+
}
|
|
17910
|
+
subscribeWatchLocation() {
|
|
17911
|
+
let nextAllowedUpdateCallTimestamp = Date.now();
|
|
17912
|
+
const unsubscribe = this.watchLocation(({ latitude, longitude }) => {
|
|
17913
|
+
if (Date.now() < nextAllowedUpdateCallTimestamp) return;
|
|
17914
|
+
nextAllowedUpdateCallTimestamp = Date.now() + UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT;
|
|
17915
|
+
withCancellation(_LiveLocationManager.symbol, async () => {
|
|
17916
|
+
const promises = [];
|
|
17917
|
+
await this.assureStateInit();
|
|
17918
|
+
const expiredLocations = [];
|
|
17919
|
+
for (const [messageId, location] of this.messages) {
|
|
17920
|
+
if (isExpiredLocation(location)) {
|
|
17921
|
+
expiredLocations.push(location.message_id);
|
|
17922
|
+
continue;
|
|
17923
|
+
}
|
|
17924
|
+
if (location.latitude === latitude && location.longitude === longitude)
|
|
17925
|
+
continue;
|
|
17926
|
+
const promise = this.client.updateLocation({
|
|
17927
|
+
created_by_device_id: location.created_by_device_id,
|
|
17928
|
+
message_id: messageId,
|
|
17929
|
+
latitude,
|
|
17930
|
+
longitude
|
|
17931
|
+
});
|
|
17932
|
+
promises.push(promise);
|
|
17933
|
+
}
|
|
17934
|
+
this.unregisterMessages(expiredLocations);
|
|
17935
|
+
if (promises.length > 0) {
|
|
17936
|
+
await Promise.allSettled(promises);
|
|
17937
|
+
}
|
|
17938
|
+
});
|
|
17939
|
+
});
|
|
17940
|
+
return unsubscribe;
|
|
17941
|
+
}
|
|
17942
|
+
subscribeLiveLocationSharingUpdates() {
|
|
17943
|
+
const subscriptions = [
|
|
17944
|
+
...[
|
|
17945
|
+
"live_location_sharing.started",
|
|
17946
|
+
"message.updated",
|
|
17947
|
+
"message.deleted"
|
|
17948
|
+
].map(
|
|
17949
|
+
(eventType) => this.client.on(eventType, (event) => {
|
|
17950
|
+
if (!event.message) return;
|
|
17951
|
+
if (event.type === "live_location_sharing.started") {
|
|
17952
|
+
this.registerMessage(event.message);
|
|
17953
|
+
} else if (event.type === "message.updated") {
|
|
17954
|
+
const isRegistered = this.messages.has(event.message.id);
|
|
17955
|
+
if (isRegistered && !isValidLiveLocationMessage(event.message)) {
|
|
17956
|
+
this.unregisterMessages([event.message.id]);
|
|
17957
|
+
}
|
|
17958
|
+
this.registerMessage(event.message);
|
|
17959
|
+
} else {
|
|
17960
|
+
this.unregisterMessages([event.message.id]);
|
|
17961
|
+
}
|
|
17962
|
+
})
|
|
17963
|
+
),
|
|
17964
|
+
this.client.on("live_location_sharing.stopped", (event) => {
|
|
17965
|
+
if (!event.live_location) return;
|
|
17966
|
+
this.unregisterMessages([event.live_location?.message_id]);
|
|
17967
|
+
})
|
|
17968
|
+
];
|
|
17969
|
+
return () => subscriptions.forEach((subscription) => subscription.unsubscribe());
|
|
17970
|
+
}
|
|
17971
|
+
registerMessage(message) {
|
|
17972
|
+
if (!this.client.userID || message?.user?.id !== this.client.userID || !isValidLiveLocationMessage(message))
|
|
17973
|
+
return;
|
|
17974
|
+
this.state.next((currentValue) => {
|
|
17975
|
+
const messages = new Map(currentValue.messages);
|
|
17976
|
+
messages.set(message.id, {
|
|
17977
|
+
...message.shared_location,
|
|
17978
|
+
stopSharingTimeout: setTimeout(
|
|
17979
|
+
() => {
|
|
17980
|
+
this.unregisterMessages([message.id]);
|
|
17981
|
+
},
|
|
17982
|
+
new Date(message.shared_location.end_at).getTime() - Date.now()
|
|
17983
|
+
)
|
|
17984
|
+
});
|
|
17985
|
+
return {
|
|
17986
|
+
...currentValue,
|
|
17987
|
+
messages
|
|
17988
|
+
};
|
|
17989
|
+
});
|
|
17990
|
+
}
|
|
17991
|
+
unregisterMessages(messageIds) {
|
|
17992
|
+
const messages = this.messages;
|
|
17993
|
+
const removedMessages = new Set(messageIds);
|
|
17994
|
+
const newMessages = new Map(
|
|
17995
|
+
Array.from(messages).filter(([messageId, location]) => {
|
|
17996
|
+
if (removedMessages.has(messageId) && location.stopSharingTimeout) {
|
|
17997
|
+
clearTimeout(location.stopSharingTimeout);
|
|
17998
|
+
location.stopSharingTimeout = null;
|
|
17999
|
+
}
|
|
18000
|
+
return !removedMessages.has(messageId);
|
|
18001
|
+
})
|
|
18002
|
+
);
|
|
18003
|
+
if (newMessages.size === messages.size) return;
|
|
18004
|
+
this.state.partialNext({
|
|
18005
|
+
messages: newMessages
|
|
18006
|
+
});
|
|
18007
|
+
}
|
|
18008
|
+
};
|
|
18009
|
+
_LiveLocationManager.symbol = Symbol(_LiveLocationManager.name);
|
|
18010
|
+
var LiveLocationManager = _LiveLocationManager;
|
|
18011
|
+
|
|
17633
18012
|
// src/utils/FixedSizeQueueCache.ts
|
|
17634
18013
|
var FixedSizeQueueCache = class {
|
|
17635
18014
|
constructor(size, options) {
|