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
|
@@ -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);
|
|
@@ -5061,10 +5068,15 @@ var DEFAULT_TEXT_COMPOSER_CONFIG = {
|
|
|
5061
5068
|
enabled: true,
|
|
5062
5069
|
publishTypingEvents: true
|
|
5063
5070
|
};
|
|
5071
|
+
var DEFAULT_LOCATION_COMPOSER_CONFIG = {
|
|
5072
|
+
enabled: true,
|
|
5073
|
+
getDeviceId: () => generateUUIDv4()
|
|
5074
|
+
};
|
|
5064
5075
|
var DEFAULT_COMPOSER_CONFIG = {
|
|
5065
5076
|
attachments: DEFAULT_ATTACHMENT_MANAGER_CONFIG,
|
|
5066
5077
|
drafts: { enabled: false },
|
|
5067
5078
|
linkPreviews: DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
5079
|
+
location: DEFAULT_LOCATION_COMPOSER_CONFIG,
|
|
5068
5080
|
text: DEFAULT_TEXT_COMPOSER_CONFIG
|
|
5069
5081
|
};
|
|
5070
5082
|
|
|
@@ -5320,6 +5332,54 @@ _LinkPreviewsManager.getPreviewData = (preview) => {
|
|
|
5320
5332
|
};
|
|
5321
5333
|
var LinkPreviewsManager = _LinkPreviewsManager;
|
|
5322
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
|
+
|
|
5323
5383
|
// src/utils/concurrency.ts
|
|
5324
5384
|
var withoutConcurrency = createRunner(wrapWithContinuationTracking);
|
|
5325
5385
|
var withCancellation = createRunner(wrapWithCancellation);
|
|
@@ -6003,9 +6063,8 @@ var createCompositionValidationMiddleware = (composer) => ({
|
|
|
6003
6063
|
}) => {
|
|
6004
6064
|
const { maxLengthOnSend } = composer.config.text ?? {};
|
|
6005
6065
|
const inputText = state.message.text ?? "";
|
|
6006
|
-
const isEmptyMessage = textIsEmpty(inputText) && !state.message.attachments?.length && !state.message.poll_id;
|
|
6007
6066
|
const hasExceededMaxLength = typeof maxLengthOnSend === "number" && inputText.length > maxLengthOnSend;
|
|
6008
|
-
if (
|
|
6067
|
+
if (composer.compositionIsEmpty || hasExceededMaxLength) {
|
|
6009
6068
|
return await discard();
|
|
6010
6069
|
}
|
|
6011
6070
|
return await forward();
|
|
@@ -6285,6 +6344,40 @@ var createPollOnlyCompositionMiddleware = (composer) => ({
|
|
|
6285
6344
|
}
|
|
6286
6345
|
});
|
|
6287
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
|
+
|
|
6288
6381
|
// src/messageComposer/middleware/messageComposer/MessageComposerMiddlewareExecutor.ts
|
|
6289
6382
|
var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
6290
6383
|
constructor({ composer }) {
|
|
@@ -6295,6 +6388,7 @@ var MessageComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
6295
6388
|
createTextComposerCompositionMiddleware(composer),
|
|
6296
6389
|
createAttachmentsCompositionMiddleware(composer),
|
|
6297
6390
|
createLinkPreviewsCompositionMiddleware(composer),
|
|
6391
|
+
createSharedLocationCompositionMiddleware(composer),
|
|
6298
6392
|
createMessageComposerStateCompositionMiddleware(composer),
|
|
6299
6393
|
createCustomDataCompositionMiddleware(composer),
|
|
6300
6394
|
createCompositionValidationMiddleware(composer),
|
|
@@ -7336,7 +7430,7 @@ var textIsEmpty = (text) => {
|
|
|
7336
7430
|
const trimmedText = text.trim();
|
|
7337
7431
|
return trimmedText === "" || trimmedText === ">" || trimmedText === "``````" || trimmedText === "``" || trimmedText === "**" || trimmedText === "____" || trimmedText === "__" || trimmedText === "****";
|
|
7338
7432
|
};
|
|
7339
|
-
var
|
|
7433
|
+
var initState5 = ({
|
|
7340
7434
|
composer,
|
|
7341
7435
|
message
|
|
7342
7436
|
}) => {
|
|
@@ -7361,7 +7455,7 @@ var initState4 = ({
|
|
|
7361
7455
|
var TextComposer = class {
|
|
7362
7456
|
constructor({ composer, message }) {
|
|
7363
7457
|
this.initState = ({ message } = {}) => {
|
|
7364
|
-
this.state.next(
|
|
7458
|
+
this.state.next(initState5({ composer: this.composer, message }));
|
|
7365
7459
|
};
|
|
7366
7460
|
this.upsertMentionedUser = (user) => {
|
|
7367
7461
|
const mentionedUsers = [...this.mentionedUsers];
|
|
@@ -7489,7 +7583,7 @@ var TextComposer = class {
|
|
|
7489
7583
|
this.state.next(output.state);
|
|
7490
7584
|
};
|
|
7491
7585
|
this.composer = composer;
|
|
7492
|
-
this.state = new StateStore(
|
|
7586
|
+
this.state = new StateStore(initState5({ composer, message }));
|
|
7493
7587
|
this.middlewareExecutor = new TextComposerMiddlewareExecutor({ composer });
|
|
7494
7588
|
}
|
|
7495
7589
|
get channel() {
|
|
@@ -8062,7 +8156,7 @@ var initEditingAuditState = (composition) => {
|
|
|
8062
8156
|
}
|
|
8063
8157
|
};
|
|
8064
8158
|
};
|
|
8065
|
-
var
|
|
8159
|
+
var initState6 = (composition) => {
|
|
8066
8160
|
if (!composition) {
|
|
8067
8161
|
return {
|
|
8068
8162
|
draftId: null,
|
|
@@ -8100,6 +8194,9 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8100
8194
|
client
|
|
8101
8195
|
}) {
|
|
8102
8196
|
super();
|
|
8197
|
+
this.refreshId = () => {
|
|
8198
|
+
this.state.partialNext({ id: _MessageComposer.generateId() });
|
|
8199
|
+
};
|
|
8103
8200
|
this.initState = ({
|
|
8104
8201
|
composition
|
|
8105
8202
|
} = {}) => {
|
|
@@ -8107,10 +8204,11 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8107
8204
|
const message = typeof composition === "undefined" ? composition : compositionIsDraftResponse(composition) ? composition.message : formatMessage(composition);
|
|
8108
8205
|
this.attachmentManager.initState({ message });
|
|
8109
8206
|
this.linkPreviewsManager.initState({ message });
|
|
8207
|
+
this.locationComposer.initState({ message });
|
|
8110
8208
|
this.textComposer.initState({ message });
|
|
8111
8209
|
this.pollComposer.initState();
|
|
8112
8210
|
this.customDataManager.initState({ message });
|
|
8113
|
-
this.state.next(
|
|
8211
|
+
this.state.next(initState6(composition));
|
|
8114
8212
|
if (composition && !compositionIsDraftResponse(composition) && message && isLocalMessage(message)) {
|
|
8115
8213
|
this.editedMessage = message;
|
|
8116
8214
|
}
|
|
@@ -8150,6 +8248,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8150
8248
|
this.addUnsubscribeFunction(this.subscribeTextComposerStateChanged());
|
|
8151
8249
|
this.addUnsubscribeFunction(this.subscribeAttachmentManagerStateChanged());
|
|
8152
8250
|
this.addUnsubscribeFunction(this.subscribeLinkPreviewsManagerStateChanged());
|
|
8251
|
+
this.addUnsubscribeFunction(this.subscribeLocationComposerStateChanged());
|
|
8153
8252
|
this.addUnsubscribeFunction(this.subscribePollComposerStateChanged());
|
|
8154
8253
|
this.addUnsubscribeFunction(this.subscribeCustomDataManagerStateChanged());
|
|
8155
8254
|
this.addUnsubscribeFunction(this.subscribeMessageComposerStateChanged());
|
|
@@ -8246,6 +8345,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8246
8345
|
return;
|
|
8247
8346
|
}
|
|
8248
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
|
+
});
|
|
8249
8356
|
this.subscribeLinkPreviewsManagerStateChanged = () => this.linkPreviewsManager.state.subscribe((_, previousValue) => {
|
|
8250
8357
|
if (typeof previousValue === "undefined") return;
|
|
8251
8358
|
this.logStateUpdateTimestamp();
|
|
@@ -8466,10 +8573,32 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8466
8573
|
throw error;
|
|
8467
8574
|
}
|
|
8468
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
|
+
};
|
|
8469
8601
|
this.compositionContext = compositionContext;
|
|
8470
|
-
this.configState = new StateStore(
|
|
8471
|
-
mergeWith(DEFAULT_COMPOSER_CONFIG, config ?? {})
|
|
8472
|
-
);
|
|
8473
8602
|
if (compositionContext instanceof Channel) {
|
|
8474
8603
|
this.channel = compositionContext;
|
|
8475
8604
|
} else if (compositionContext instanceof Thread) {
|
|
@@ -8482,6 +8611,21 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8482
8611
|
"MessageComposer requires composition context pointing to channel (channel or context.cid)"
|
|
8483
8612
|
);
|
|
8484
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
|
+
);
|
|
8485
8629
|
let message = void 0;
|
|
8486
8630
|
if (compositionIsDraftResponse(composition)) {
|
|
8487
8631
|
message = composition.message;
|
|
@@ -8491,13 +8635,14 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8491
8635
|
}
|
|
8492
8636
|
this.attachmentManager = new AttachmentManager({ composer: this, message });
|
|
8493
8637
|
this.linkPreviewsManager = new LinkPreviewsManager({ composer: this, message });
|
|
8638
|
+
this.locationComposer = new LocationComposer({ composer: this, message });
|
|
8494
8639
|
this.textComposer = new TextComposer({ composer: this, message });
|
|
8495
8640
|
this.pollComposer = new PollComposer({ composer: this });
|
|
8496
8641
|
this.customDataManager = new CustomDataManager({ composer: this, message });
|
|
8497
8642
|
this.editingAuditState = new StateStore(
|
|
8498
8643
|
this.initEditingAuditState(composition)
|
|
8499
8644
|
);
|
|
8500
|
-
this.state = new StateStore(
|
|
8645
|
+
this.state = new StateStore(initState6(composition));
|
|
8501
8646
|
this.compositionMiddlewareExecutor = new MessageComposerMiddlewareExecutor({
|
|
8502
8647
|
composer: this
|
|
8503
8648
|
});
|
|
@@ -8572,10 +8717,10 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8572
8717
|
if (this.client.offlineDb) {
|
|
8573
8718
|
return !this.compositionIsEmpty;
|
|
8574
8719
|
}
|
|
8575
|
-
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);
|
|
8576
8721
|
}
|
|
8577
8722
|
get compositionIsEmpty() {
|
|
8578
|
-
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;
|
|
8579
8724
|
}
|
|
8580
8725
|
get lastChangeOriginIsLocal() {
|
|
8581
8726
|
const initiatedWithoutDraft = this.lastChange.draftUpdate === null;
|
|
@@ -9102,6 +9247,30 @@ var Channel = class {
|
|
|
9102
9247
|
this.data = data.channel;
|
|
9103
9248
|
return data;
|
|
9104
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
|
+
}
|
|
9105
9274
|
/**
|
|
9106
9275
|
* delete - Delete the channel. Messages are permanently removed.
|
|
9107
9276
|
*
|
|
@@ -12348,7 +12517,8 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12348
12517
|
constructor({
|
|
12349
12518
|
client,
|
|
12350
12519
|
eventHandlerOverrides = {},
|
|
12351
|
-
options = {}
|
|
12520
|
+
options = {},
|
|
12521
|
+
queryChannelsOverride
|
|
12352
12522
|
}) {
|
|
12353
12523
|
super();
|
|
12354
12524
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -12388,6 +12558,9 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12388
12558
|
Object.entries(truthyEventHandlerOverrides)
|
|
12389
12559
|
);
|
|
12390
12560
|
};
|
|
12561
|
+
this.setQueryChannelsRequest = (queryChannelsRequest) => {
|
|
12562
|
+
this.queryChannelsRequest = queryChannelsRequest;
|
|
12563
|
+
};
|
|
12391
12564
|
this.setOptions = (options = {}) => {
|
|
12392
12565
|
this.options = { ...DEFAULT_CHANNEL_MANAGER_OPTIONS, ...options };
|
|
12393
12566
|
};
|
|
@@ -12398,7 +12571,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12398
12571
|
...options
|
|
12399
12572
|
};
|
|
12400
12573
|
try {
|
|
12401
|
-
const channels = await this.
|
|
12574
|
+
const channels = await this.queryChannelsRequest(
|
|
12402
12575
|
filters,
|
|
12403
12576
|
sort,
|
|
12404
12577
|
options,
|
|
@@ -12514,7 +12687,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12514
12687
|
this.state.partialNext({
|
|
12515
12688
|
pagination: { ...pagination, isLoading: false, isLoadingNext: true }
|
|
12516
12689
|
});
|
|
12517
|
-
const nextChannels = await this.
|
|
12690
|
+
const nextChannels = await this.queryChannelsRequest(
|
|
12518
12691
|
filters,
|
|
12519
12692
|
sort,
|
|
12520
12693
|
options,
|
|
@@ -12757,6 +12930,7 @@ var ChannelManager = class extends WithSubscriptions {
|
|
|
12757
12930
|
});
|
|
12758
12931
|
this.setEventHandlerOverrides(eventHandlerOverrides);
|
|
12759
12932
|
this.setOptions(options);
|
|
12933
|
+
this.queryChannelsRequest = queryChannelsOverride ?? ((...params) => this.client.queryChannels(...params));
|
|
12760
12934
|
this.eventHandlers = new Map(
|
|
12761
12935
|
Object.entries({
|
|
12762
12936
|
channelDeletedHandler: this.channelDeletedHandler,
|
|
@@ -13458,8 +13632,14 @@ var StreamChat = class _StreamChat {
|
|
|
13458
13632
|
*/
|
|
13459
13633
|
this.createChannelManager = ({
|
|
13460
13634
|
eventHandlerOverrides = {},
|
|
13461
|
-
options = {}
|
|
13462
|
-
|
|
13635
|
+
options = {},
|
|
13636
|
+
queryChannelsOverride
|
|
13637
|
+
}) => new ChannelManager({
|
|
13638
|
+
client: this,
|
|
13639
|
+
eventHandlerOverrides,
|
|
13640
|
+
options,
|
|
13641
|
+
queryChannelsOverride
|
|
13642
|
+
});
|
|
13463
13643
|
/**
|
|
13464
13644
|
* Creates a new WebSocket connection with the current user. Returns empty promise, if there is an active connection
|
|
13465
13645
|
*/
|
|
@@ -15563,7 +15743,7 @@ var StreamChat = class _StreamChat {
|
|
|
15563
15743
|
if (this.userAgent) {
|
|
15564
15744
|
return this.userAgent;
|
|
15565
15745
|
}
|
|
15566
|
-
const version = "9.
|
|
15746
|
+
const version = "9.12.0";
|
|
15567
15747
|
const clientBundle = "browser-cjs";
|
|
15568
15748
|
let userAgentString = "";
|
|
15569
15749
|
if (this.sdkIdentifier) {
|
|
@@ -16655,9 +16835,9 @@ var StreamChat = class _StreamChat {
|
|
|
16655
16835
|
/**
|
|
16656
16836
|
* updateLocation - Updates a location
|
|
16657
16837
|
*
|
|
16658
|
-
* @param location
|
|
16838
|
+
* @param location SharedLocationRequest the location data to update
|
|
16659
16839
|
*
|
|
16660
|
-
* @returns {Promise<
|
|
16840
|
+
* @returns {Promise<SharedLocationResponse>} The server response
|
|
16661
16841
|
*/
|
|
16662
16842
|
async updateLocation(location) {
|
|
16663
16843
|
return await this.put(
|
|
@@ -16778,6 +16958,8 @@ var EVENT_MAP = {
|
|
|
16778
16958
|
"connection.recovered": true,
|
|
16779
16959
|
"transport.changed": true,
|
|
16780
16960
|
"capabilities.changed": true,
|
|
16961
|
+
"live_location_sharing.started": true,
|
|
16962
|
+
"live_location_sharing.stopped": true,
|
|
16781
16963
|
// Reminder events
|
|
16782
16964
|
"reminder.created": true,
|
|
16783
16965
|
"reminder.updated": true,
|
|
@@ -17633,6 +17815,200 @@ var AbstractOfflineDB = class {
|
|
|
17633
17815
|
}
|
|
17634
17816
|
};
|
|
17635
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
|
+
|
|
17636
18012
|
// src/utils/FixedSizeQueueCache.ts
|
|
17637
18013
|
var FixedSizeQueueCache = class {
|
|
17638
18014
|
constructor(size, options) {
|