@ermis-network/ermis-chat-sdk 1.0.6 → 1.0.8
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/index.browser.cjs +211 -52
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.full-bundle.min.js +2 -2
- package/dist/index.browser.full-bundle.min.js.map +1 -1
- package/dist/index.browser.mjs +211 -52
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.cjs +211 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +47 -16
- package/dist/index.d.ts +47 -16
- package/dist/index.mjs +211 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/channel.ts +65 -3
- package/src/client.ts +159 -50
- package/src/types.ts +14 -0
package/package.json
CHANGED
package/src/channel.ts
CHANGED
|
@@ -36,6 +36,8 @@ import {
|
|
|
36
36
|
PollMessage,
|
|
37
37
|
EditMessage,
|
|
38
38
|
ForwardMessage,
|
|
39
|
+
CreateTopicData,
|
|
40
|
+
EditTopicData,
|
|
39
41
|
} from './types';
|
|
40
42
|
/**
|
|
41
43
|
* Represents a Channel in the Ermis Network.
|
|
@@ -224,6 +226,48 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
|
|
|
224
226
|
);
|
|
225
227
|
}
|
|
226
228
|
|
|
229
|
+
async pin() {
|
|
230
|
+
if (this.data) this.data.is_pinned = true;
|
|
231
|
+
this.getClient().dispatchEvent({
|
|
232
|
+
type: 'channel.pinned',
|
|
233
|
+
cid: this.cid,
|
|
234
|
+
channel: this.data,
|
|
235
|
+
} as Event<ErmisChatGenerics>);
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
return await this.getClient().pinChannel(this.type, this.id as string);
|
|
239
|
+
} catch (e) {
|
|
240
|
+
if (this.data) this.data.is_pinned = false;
|
|
241
|
+
this.getClient().dispatchEvent({
|
|
242
|
+
type: 'channel.unpinned',
|
|
243
|
+
cid: this.cid,
|
|
244
|
+
channel: this.data,
|
|
245
|
+
} as Event<ErmisChatGenerics>);
|
|
246
|
+
throw e;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async unpin() {
|
|
251
|
+
if (this.data) this.data.is_pinned = false;
|
|
252
|
+
this.getClient().dispatchEvent({
|
|
253
|
+
type: 'channel.unpinned',
|
|
254
|
+
cid: this.cid,
|
|
255
|
+
channel: this.data,
|
|
256
|
+
} as Event<ErmisChatGenerics>);
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
return await this.getClient().unpinChannel(this.type, this.id as string);
|
|
260
|
+
} catch (e) {
|
|
261
|
+
if (this.data) this.data.is_pinned = true;
|
|
262
|
+
this.getClient().dispatchEvent({
|
|
263
|
+
type: 'channel.pinned',
|
|
264
|
+
cid: this.cid,
|
|
265
|
+
channel: this.data,
|
|
266
|
+
} as Event<ErmisChatGenerics>);
|
|
267
|
+
throw e;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
227
271
|
async editMessage(oldMessageID: string, message: EditMessage) {
|
|
228
272
|
return await this.getClient().post(this.getClient().baseURL + `/messages/${this.type}/${this.id}/${oldMessageID}`, {
|
|
229
273
|
message,
|
|
@@ -726,7 +770,7 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
|
|
|
726
770
|
}
|
|
727
771
|
};
|
|
728
772
|
|
|
729
|
-
async createTopic(data:
|
|
773
|
+
async createTopic(data: CreateTopicData) {
|
|
730
774
|
const project_id = this._client.projectId;
|
|
731
775
|
const uuid = randomId();
|
|
732
776
|
const topicID = `${project_id}:${uuid}`;
|
|
@@ -1079,7 +1123,7 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
|
|
|
1079
1123
|
});
|
|
1080
1124
|
}
|
|
1081
1125
|
|
|
1082
|
-
async editTopic(topicCID: string, data:
|
|
1126
|
+
async editTopic(topicCID: string, data: EditTopicData) {
|
|
1083
1127
|
const response: any = await this.getClient().post(
|
|
1084
1128
|
this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics`,
|
|
1085
1129
|
{
|
|
@@ -1390,6 +1434,18 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
|
|
|
1390
1434
|
delete channelState.members[event.user.id];
|
|
1391
1435
|
}
|
|
1392
1436
|
break;
|
|
1437
|
+
case 'channel.topic.enabled':
|
|
1438
|
+
if (channel.data) {
|
|
1439
|
+
channel.data.topics_enabled = true;
|
|
1440
|
+
}
|
|
1441
|
+
channelState.topics = channelState.topics || [];
|
|
1442
|
+
break;
|
|
1443
|
+
case 'channel.topic.disabled':
|
|
1444
|
+
if (channel.data) {
|
|
1445
|
+
channel.data.topics_enabled = false;
|
|
1446
|
+
}
|
|
1447
|
+
channelState.topics = [];
|
|
1448
|
+
break;
|
|
1393
1449
|
case 'channel.updated':
|
|
1394
1450
|
if (event.channel) {
|
|
1395
1451
|
channel.data = {
|
|
@@ -1545,7 +1601,13 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
|
|
|
1545
1601
|
const topic = this.getClient().channel(event.channel_type || '', event.channel_id || '');
|
|
1546
1602
|
topic.data = event.channel;
|
|
1547
1603
|
topic._initializeState(topicState, 'latest');
|
|
1548
|
-
|
|
1604
|
+
|
|
1605
|
+
if (!channelState.topics) {
|
|
1606
|
+
channelState.topics = [];
|
|
1607
|
+
}
|
|
1608
|
+
if (!channelState.topics.some((t) => t.cid === topic.cid)) {
|
|
1609
|
+
channelState.topics.push(topic);
|
|
1610
|
+
}
|
|
1549
1611
|
break;
|
|
1550
1612
|
case 'channel.topic.closed':
|
|
1551
1613
|
if (channel.data) {
|
package/src/client.ts
CHANGED
|
@@ -205,7 +205,6 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
205
205
|
params.avatar = user.avatar;
|
|
206
206
|
}
|
|
207
207
|
const url = this.userBaseURL + '/get_token/external_auth';
|
|
208
|
-
const query = new URLSearchParams(params).toString();
|
|
209
208
|
const headers: Record<string, string> = {
|
|
210
209
|
'Content-Type': 'application/json',
|
|
211
210
|
};
|
|
@@ -213,21 +212,21 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
213
212
|
const tokenStr = typeof token === 'string' && token.startsWith('Bearer ') ? token : `Bearer ${token}`;
|
|
214
213
|
headers['Authorization'] = tokenStr;
|
|
215
214
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
215
|
+
try {
|
|
216
|
+
const response = await this.axiosInstance.get(url, {
|
|
217
|
+
params,
|
|
218
|
+
headers,
|
|
219
|
+
});
|
|
220
|
+
return response.data;
|
|
221
|
+
} catch (error: any) {
|
|
222
|
+
let errorMsg = 'Failed to fetch external auth token';
|
|
223
|
+
if (error.response && error.response.data) {
|
|
224
|
+
errorMsg = error.response.data.message || JSON.stringify(error.response.data);
|
|
225
|
+
} else if (error.message) {
|
|
226
|
+
errorMsg = error.message;
|
|
227
227
|
}
|
|
228
228
|
throw new Error(errorMsg);
|
|
229
229
|
}
|
|
230
|
-
return await response.json();
|
|
231
230
|
}
|
|
232
231
|
|
|
233
232
|
/**
|
|
@@ -242,7 +241,7 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
242
241
|
connectUser = async (
|
|
243
242
|
user: UserResponse<ErmisChatGenerics>,
|
|
244
243
|
userTokenOrProvider: string | null,
|
|
245
|
-
|
|
244
|
+
external_auth?: boolean, // pass true if you are using external auth
|
|
246
245
|
) => {
|
|
247
246
|
this.logger('info', 'client:connectUser() - started', {
|
|
248
247
|
tags: ['connection', 'client'],
|
|
@@ -251,19 +250,25 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
251
250
|
throw new Error('The "id" field on the user is missing');
|
|
252
251
|
}
|
|
253
252
|
|
|
253
|
+
let connectionUser = user;
|
|
254
|
+
let connectionToken = userTokenOrProvider;
|
|
255
|
+
|
|
254
256
|
// If external auth is enabled, get the token from the server
|
|
255
|
-
if (
|
|
257
|
+
if (external_auth) {
|
|
256
258
|
const external_auth_token = await this.getExternalAuthToken(user, userTokenOrProvider);
|
|
257
259
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
connectionToken = external_auth_token.token;
|
|
261
|
+
connectionUser = {
|
|
262
|
+
...user,
|
|
263
|
+
id: external_auth_token.user_id,
|
|
264
|
+
};
|
|
260
265
|
}
|
|
261
266
|
|
|
262
267
|
/**
|
|
263
268
|
* Calling connectUser multiple times is potentially the result of a bad integration, however,
|
|
264
269
|
* If the user id remains the same we don't throw error
|
|
265
270
|
*/
|
|
266
|
-
if (this.userID ===
|
|
271
|
+
if (this.userID === connectionUser.id && this.setUserPromise) {
|
|
267
272
|
console.warn(
|
|
268
273
|
'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.',
|
|
269
274
|
);
|
|
@@ -283,11 +288,11 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
283
288
|
}
|
|
284
289
|
|
|
285
290
|
// we generate the client id client side
|
|
286
|
-
this.userID =
|
|
291
|
+
this.userID = connectionUser.id;
|
|
287
292
|
|
|
288
|
-
const setTokenPromise = this._setToken(
|
|
289
|
-
this._setUser(
|
|
290
|
-
this.state.updateUser({ id:
|
|
293
|
+
const setTokenPromise = this._setToken(connectionUser, connectionToken);
|
|
294
|
+
this._setUser(connectionUser);
|
|
295
|
+
this.state.updateUser({ id: connectionUser.id, name: connectionUser?.name || connectionUser.id, avatar: connectionUser?.avatar || '' });
|
|
291
296
|
|
|
292
297
|
const wsPromise = this.openConnection();
|
|
293
298
|
|
|
@@ -586,6 +591,21 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
586
591
|
});
|
|
587
592
|
}
|
|
588
593
|
|
|
594
|
+
/**
|
|
595
|
+
* Downloads a media file as a Blob via the SDK's configured axiosInstance.
|
|
596
|
+
* This avoids CORS issues that arise when using `fetch()` directly from the browser,
|
|
597
|
+
* because axios is routed through the SDK's authenticated transport layer.
|
|
598
|
+
*
|
|
599
|
+
* @param url - The full URL of the media file to download.
|
|
600
|
+
* @returns A Blob of the file content.
|
|
601
|
+
*/
|
|
602
|
+
async downloadMedia(url: string): Promise<Blob> {
|
|
603
|
+
const response = await this.axiosInstance.get(url, {
|
|
604
|
+
responseType: 'blob',
|
|
605
|
+
});
|
|
606
|
+
return response.data as Blob;
|
|
607
|
+
}
|
|
608
|
+
|
|
589
609
|
errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse> {
|
|
590
610
|
let err: ErrorFromResponse<APIErrorResponse>;
|
|
591
611
|
err = new ErrorFromResponse(`ErmisChat error HTTP code: ${response.status}`);
|
|
@@ -609,8 +629,8 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
609
629
|
dispatchEvent = (event: Event<ErmisChatGenerics>) => {
|
|
610
630
|
if (!event.received_at) event.received_at = new Date();
|
|
611
631
|
|
|
612
|
-
// If the event is channel.created, handle it asynchronously
|
|
613
|
-
if (event.type === 'channel.created') {
|
|
632
|
+
// If the event is channel.created or channel.topic.created, handle it asynchronously
|
|
633
|
+
if (event.type === 'channel.created' || event.type === 'channel.topic.created') {
|
|
614
634
|
this._handleChannelCreatedEvent(event).then(() => {
|
|
615
635
|
this._afterDispatchEvent(event);
|
|
616
636
|
});
|
|
@@ -789,6 +809,85 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
789
809
|
}
|
|
790
810
|
}
|
|
791
811
|
|
|
812
|
+
if (event.type === 'message.new' && event.channel_type === 'topic') {
|
|
813
|
+
postListenerCallbacks.push(() => {
|
|
814
|
+
const parentCid = event.parent_cid || event.channel?.parent_cid;
|
|
815
|
+
if (parentCid && this.activeChannels[parentCid]) {
|
|
816
|
+
const parentChannel = this.activeChannels[parentCid];
|
|
817
|
+
if (parentChannel.state.topics) {
|
|
818
|
+
parentChannel.state.topics.sort((a, b) => {
|
|
819
|
+
const aLatest = a.state?.latestMessages?.[a.state.latestMessages.length - 1]?.created_at;
|
|
820
|
+
const bLatest = b.state?.latestMessages?.[b.state.latestMessages.length - 1]?.created_at;
|
|
821
|
+
const aTime = aLatest ? new Date(aLatest).getTime() : 0;
|
|
822
|
+
const bTime = bLatest ? new Date(bLatest).getTime() : 0;
|
|
823
|
+
return bTime - aTime;
|
|
824
|
+
});
|
|
825
|
+
parentChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: parentChannel.data } as any);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
if (event.type === 'channel.topic.updated') {
|
|
831
|
+
postListenerCallbacks.push(() => {
|
|
832
|
+
const parentCid = event.parent_cid || event.channel?.parent_cid;
|
|
833
|
+
if (parentCid && this.activeChannels[parentCid]) {
|
|
834
|
+
const parentChannel = this.activeChannels[parentCid];
|
|
835
|
+
if (parentChannel.state?.topics && event.channel) {
|
|
836
|
+
const topicIndex = parentChannel.state.topics.findIndex((t: any) => t.cid === event.cid || t.channel?.cid === event.cid);
|
|
837
|
+
if (topicIndex !== -1) {
|
|
838
|
+
const t = parentChannel.state.topics[topicIndex] as any;
|
|
839
|
+
if (t.data) {
|
|
840
|
+
t.data = { ...t.data, ...event.channel };
|
|
841
|
+
} else if (t.channel) {
|
|
842
|
+
t.channel = { ...t.channel, ...event.channel };
|
|
843
|
+
} else {
|
|
844
|
+
Object.assign(t, event.channel);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
parentChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: parentChannel.data } as any);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
if (event.cid && this.activeChannels[event.cid]) {
|
|
852
|
+
const topicChannel = this.activeChannels[event.cid];
|
|
853
|
+
if (event.channel) {
|
|
854
|
+
topicChannel.data = { ...topicChannel.data, ...event.channel };
|
|
855
|
+
topicChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: topicChannel.data } as any);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
if (event.type === 'channel.topic.closed' || event.type === 'channel.topic.reopen') {
|
|
862
|
+
postListenerCallbacks.push(() => {
|
|
863
|
+
const isClosed = event.type === 'channel.topic.closed';
|
|
864
|
+
const parentCid = event.parent_cid;
|
|
865
|
+
if (parentCid && this.activeChannels[parentCid]) {
|
|
866
|
+
const parentChannel = this.activeChannels[parentCid];
|
|
867
|
+
if (parentChannel.state?.topics) {
|
|
868
|
+
const topicIndex = parentChannel.state.topics.findIndex((t: any) => t.cid === event.cid || t.channel?.cid === event.cid);
|
|
869
|
+
if (topicIndex !== -1) {
|
|
870
|
+
const t = parentChannel.state.topics[topicIndex] as any;
|
|
871
|
+
if (t.data) t.data.is_closed_topic = isClosed;
|
|
872
|
+
else if (t.channel) t.channel.is_closed_topic = isClosed;
|
|
873
|
+
else t.is_closed_topic = isClosed;
|
|
874
|
+
}
|
|
875
|
+
parentChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: parentChannel.data } as any);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (event.cid && this.activeChannels[event.cid]) {
|
|
880
|
+
const topicChannel = this.activeChannels[event.cid];
|
|
881
|
+
if (topicChannel.data) {
|
|
882
|
+
topicChannel.data.is_closed_topic = isClosed;
|
|
883
|
+
}
|
|
884
|
+
topicChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: topicChannel.data } as any);
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
|
|
792
891
|
if (event.type === 'connection.recovered') {
|
|
793
892
|
postListenerCallbacks.push(() => {
|
|
794
893
|
// Auto-resend offline failed messages
|
|
@@ -1086,7 +1185,14 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
1086
1185
|
this.projectId = project_id;
|
|
1087
1186
|
}
|
|
1088
1187
|
|
|
1089
|
-
|
|
1188
|
+
/**
|
|
1189
|
+
* Uploads a new avatar image for the current user.
|
|
1190
|
+
* The user's avatar URL is automatically updated in both the client and the local state.
|
|
1191
|
+
*
|
|
1192
|
+
* @param file - The image file to upload.
|
|
1193
|
+
* @returns The response containing the new avatar URL.
|
|
1194
|
+
*/
|
|
1195
|
+
async uploadAvatar(file: File) {
|
|
1090
1196
|
const formData = new FormData();
|
|
1091
1197
|
formData.append('avatar', file);
|
|
1092
1198
|
let response = await this.post<{ avatar: string }>(this.userBaseURL + '/users/upload', formData, {
|
|
@@ -1102,12 +1208,8 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
1102
1208
|
|
|
1103
1209
|
return response;
|
|
1104
1210
|
}
|
|
1105
|
-
async updateProfile(
|
|
1106
|
-
let
|
|
1107
|
-
name,
|
|
1108
|
-
about_me,
|
|
1109
|
-
};
|
|
1110
|
-
let response = await this.patch<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/update', body);
|
|
1211
|
+
async updateProfile(updates: Partial<UserResponse<ErmisChatGenerics>>) {
|
|
1212
|
+
let response = await this.patch<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/update', updates);
|
|
1111
1213
|
this.user = response;
|
|
1112
1214
|
this.state.updateUser(response);
|
|
1113
1215
|
return response;
|
|
@@ -1359,53 +1461,60 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
1359
1461
|
};
|
|
1360
1462
|
|
|
1361
1463
|
/**
|
|
1362
|
-
* Creates
|
|
1363
|
-
*
|
|
1464
|
+
* Creates a quick channel and immediately registers it on the server.
|
|
1465
|
+
* Quick channels are public group channels that anyone can join without an invitation.
|
|
1466
|
+
* The creator is added as the first member automatically.
|
|
1364
1467
|
*
|
|
1365
|
-
* @param name -
|
|
1468
|
+
* @param name - An optional display name for the channel.
|
|
1366
1469
|
* @returns A promise that resolves to the created `Channel` object.
|
|
1367
1470
|
*/
|
|
1368
|
-
async
|
|
1471
|
+
async createQuickChannel(name?: string): Promise<Channel<ErmisChatGenerics>> {
|
|
1369
1472
|
if (!this.userID) {
|
|
1370
1473
|
throw Error('Call connectUser before creating a channel');
|
|
1371
1474
|
}
|
|
1372
1475
|
|
|
1476
|
+
const now = new Date();
|
|
1477
|
+
const formattedDate = new Intl.DateTimeFormat('en-US', {
|
|
1478
|
+
month: 'short', day: '2-digit', year: 'numeric',
|
|
1479
|
+
hour: '2-digit', minute: '2-digit', hour12: false,
|
|
1480
|
+
}).format(now);
|
|
1481
|
+
|
|
1373
1482
|
const payload = {
|
|
1374
|
-
name: name || `
|
|
1483
|
+
name: name || `Quick Channel - ${formattedDate}`,
|
|
1375
1484
|
members: [this.userID],
|
|
1376
1485
|
public: true,
|
|
1377
1486
|
} as unknown as ChannelData<ErmisChatGenerics>;
|
|
1378
1487
|
|
|
1379
|
-
const
|
|
1380
|
-
await
|
|
1488
|
+
const quickChannel = this.channel('meeting', payload);
|
|
1489
|
+
await quickChannel.create();
|
|
1381
1490
|
|
|
1382
|
-
return
|
|
1491
|
+
return quickChannel;
|
|
1383
1492
|
}
|
|
1384
1493
|
|
|
1385
1494
|
/**
|
|
1386
|
-
* Joins a
|
|
1387
|
-
*
|
|
1388
|
-
* If not, it
|
|
1495
|
+
* Joins a quick channel by its ID.
|
|
1496
|
+
* Automatically checks whether the caller is already a member.
|
|
1497
|
+
* If not, it joins the channel and synchronizes state.
|
|
1389
1498
|
*
|
|
1390
|
-
* @param channelId - The ID of the
|
|
1499
|
+
* @param channelId - The ID of the quick channel to join.
|
|
1391
1500
|
* @returns A promise that resolves to the joined `Channel` object.
|
|
1392
1501
|
*/
|
|
1393
|
-
async
|
|
1502
|
+
async joinQuickChannel(channelId: string): Promise<Channel<ErmisChatGenerics>> {
|
|
1394
1503
|
if (!this.userID) {
|
|
1395
1504
|
throw Error('Call connectUser before joining a channel');
|
|
1396
1505
|
}
|
|
1397
1506
|
|
|
1398
|
-
const
|
|
1399
|
-
await
|
|
1507
|
+
const quickChannel = this.channel('meeting', channelId);
|
|
1508
|
+
await quickChannel.watch();
|
|
1400
1509
|
|
|
1401
|
-
const isMember =
|
|
1510
|
+
const isMember = quickChannel.state.members && quickChannel.state.members[this.userID];
|
|
1402
1511
|
|
|
1403
1512
|
if (!isMember) {
|
|
1404
|
-
await
|
|
1405
|
-
await
|
|
1513
|
+
await quickChannel.acceptInvite('join');
|
|
1514
|
+
await quickChannel.watch();
|
|
1406
1515
|
}
|
|
1407
1516
|
|
|
1408
|
-
return
|
|
1517
|
+
return quickChannel;
|
|
1409
1518
|
}
|
|
1410
1519
|
|
|
1411
1520
|
_normalizeExpiration(timeoutOrExpirationDate?: null | number | string | Date) {
|
package/src/types.ts
CHANGED
|
@@ -58,6 +58,7 @@ export type ChannelResponse<ErmisChatGenerics extends ExtendableGenerics = Defau
|
|
|
58
58
|
member_capabilities?: string[];
|
|
59
59
|
is_pinned?: boolean;
|
|
60
60
|
topics_enabled?: boolean;
|
|
61
|
+
parent_cid?: string;
|
|
61
62
|
is_closed_topic?: boolean;
|
|
62
63
|
};
|
|
63
64
|
|
|
@@ -265,6 +266,7 @@ export type Event<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics
|
|
|
265
266
|
message?: MessageResponse<ErmisChatGenerics>;
|
|
266
267
|
online?: boolean;
|
|
267
268
|
parent_id?: string;
|
|
269
|
+
parent_cid?: string;
|
|
268
270
|
reaction?: ReactionResponse<ErmisChatGenerics>;
|
|
269
271
|
received_at?: string | Date;
|
|
270
272
|
unread_messages?: number;
|
|
@@ -300,6 +302,18 @@ export type ChannelFilters = {
|
|
|
300
302
|
include_parent?: boolean;
|
|
301
303
|
};
|
|
302
304
|
|
|
305
|
+
export type CreateTopicData = {
|
|
306
|
+
name: string;
|
|
307
|
+
image?: string;
|
|
308
|
+
[key: string]: any;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
export type EditTopicData = {
|
|
312
|
+
name?: string;
|
|
313
|
+
image?: string;
|
|
314
|
+
description?: string;
|
|
315
|
+
};
|
|
316
|
+
|
|
303
317
|
export type ChannelSort = {
|
|
304
318
|
field: string;
|
|
305
319
|
direction: -1 | 1;
|