@ermis-network/ermis-chat-sdk 1.0.6 → 1.0.7
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 +197 -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 +197 -52
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.cjs +197 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +38 -16
- package/dist/index.d.ts +38 -16
- package/dist/index.mjs +197 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/channel.ts +65 -3
- package/src/client.ts +144 -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
|
|
|
@@ -609,8 +614,8 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
609
614
|
dispatchEvent = (event: Event<ErmisChatGenerics>) => {
|
|
610
615
|
if (!event.received_at) event.received_at = new Date();
|
|
611
616
|
|
|
612
|
-
// If the event is channel.created, handle it asynchronously
|
|
613
|
-
if (event.type === 'channel.created') {
|
|
617
|
+
// If the event is channel.created or channel.topic.created, handle it asynchronously
|
|
618
|
+
if (event.type === 'channel.created' || event.type === 'channel.topic.created') {
|
|
614
619
|
this._handleChannelCreatedEvent(event).then(() => {
|
|
615
620
|
this._afterDispatchEvent(event);
|
|
616
621
|
});
|
|
@@ -789,6 +794,85 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
789
794
|
}
|
|
790
795
|
}
|
|
791
796
|
|
|
797
|
+
if (event.type === 'message.new' && event.channel_type === 'topic') {
|
|
798
|
+
postListenerCallbacks.push(() => {
|
|
799
|
+
const parentCid = event.parent_cid || event.channel?.parent_cid;
|
|
800
|
+
if (parentCid && this.activeChannels[parentCid]) {
|
|
801
|
+
const parentChannel = this.activeChannels[parentCid];
|
|
802
|
+
if (parentChannel.state.topics) {
|
|
803
|
+
parentChannel.state.topics.sort((a, b) => {
|
|
804
|
+
const aLatest = a.state?.latestMessages?.[a.state.latestMessages.length - 1]?.created_at;
|
|
805
|
+
const bLatest = b.state?.latestMessages?.[b.state.latestMessages.length - 1]?.created_at;
|
|
806
|
+
const aTime = aLatest ? new Date(aLatest).getTime() : 0;
|
|
807
|
+
const bTime = bLatest ? new Date(bLatest).getTime() : 0;
|
|
808
|
+
return bTime - aTime;
|
|
809
|
+
});
|
|
810
|
+
parentChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: parentChannel.data } as any);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
if (event.type === 'channel.topic.updated') {
|
|
816
|
+
postListenerCallbacks.push(() => {
|
|
817
|
+
const parentCid = event.parent_cid || event.channel?.parent_cid;
|
|
818
|
+
if (parentCid && this.activeChannels[parentCid]) {
|
|
819
|
+
const parentChannel = this.activeChannels[parentCid];
|
|
820
|
+
if (parentChannel.state?.topics && event.channel) {
|
|
821
|
+
const topicIndex = parentChannel.state.topics.findIndex((t: any) => t.cid === event.cid || t.channel?.cid === event.cid);
|
|
822
|
+
if (topicIndex !== -1) {
|
|
823
|
+
const t = parentChannel.state.topics[topicIndex] as any;
|
|
824
|
+
if (t.data) {
|
|
825
|
+
t.data = { ...t.data, ...event.channel };
|
|
826
|
+
} else if (t.channel) {
|
|
827
|
+
t.channel = { ...t.channel, ...event.channel };
|
|
828
|
+
} else {
|
|
829
|
+
Object.assign(t, event.channel);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
parentChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: parentChannel.data } as any);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
if (event.cid && this.activeChannels[event.cid]) {
|
|
837
|
+
const topicChannel = this.activeChannels[event.cid];
|
|
838
|
+
if (event.channel) {
|
|
839
|
+
topicChannel.data = { ...topicChannel.data, ...event.channel };
|
|
840
|
+
topicChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: topicChannel.data } as any);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
if (event.type === 'channel.topic.closed' || event.type === 'channel.topic.reopen') {
|
|
847
|
+
postListenerCallbacks.push(() => {
|
|
848
|
+
const isClosed = event.type === 'channel.topic.closed';
|
|
849
|
+
const parentCid = event.parent_cid;
|
|
850
|
+
if (parentCid && this.activeChannels[parentCid]) {
|
|
851
|
+
const parentChannel = this.activeChannels[parentCid];
|
|
852
|
+
if (parentChannel.state?.topics) {
|
|
853
|
+
const topicIndex = parentChannel.state.topics.findIndex((t: any) => t.cid === event.cid || t.channel?.cid === event.cid);
|
|
854
|
+
if (topicIndex !== -1) {
|
|
855
|
+
const t = parentChannel.state.topics[topicIndex] as any;
|
|
856
|
+
if (t.data) t.data.is_closed_topic = isClosed;
|
|
857
|
+
else if (t.channel) t.channel.is_closed_topic = isClosed;
|
|
858
|
+
else t.is_closed_topic = isClosed;
|
|
859
|
+
}
|
|
860
|
+
parentChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: parentChannel.data } as any);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (event.cid && this.activeChannels[event.cid]) {
|
|
865
|
+
const topicChannel = this.activeChannels[event.cid];
|
|
866
|
+
if (topicChannel.data) {
|
|
867
|
+
topicChannel.data.is_closed_topic = isClosed;
|
|
868
|
+
}
|
|
869
|
+
topicChannel._callChannelListeners({ ...event, type: 'channel.updated', channel: topicChannel.data } as any);
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
|
|
792
876
|
if (event.type === 'connection.recovered') {
|
|
793
877
|
postListenerCallbacks.push(() => {
|
|
794
878
|
// Auto-resend offline failed messages
|
|
@@ -1086,7 +1170,14 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
1086
1170
|
this.projectId = project_id;
|
|
1087
1171
|
}
|
|
1088
1172
|
|
|
1089
|
-
|
|
1173
|
+
/**
|
|
1174
|
+
* Uploads a new avatar image for the current user.
|
|
1175
|
+
* The user's avatar URL is automatically updated in both the client and the local state.
|
|
1176
|
+
*
|
|
1177
|
+
* @param file - The image file to upload.
|
|
1178
|
+
* @returns The response containing the new avatar URL.
|
|
1179
|
+
*/
|
|
1180
|
+
async uploadAvatar(file: File) {
|
|
1090
1181
|
const formData = new FormData();
|
|
1091
1182
|
formData.append('avatar', file);
|
|
1092
1183
|
let response = await this.post<{ avatar: string }>(this.userBaseURL + '/users/upload', formData, {
|
|
@@ -1102,12 +1193,8 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
1102
1193
|
|
|
1103
1194
|
return response;
|
|
1104
1195
|
}
|
|
1105
|
-
async updateProfile(
|
|
1106
|
-
let
|
|
1107
|
-
name,
|
|
1108
|
-
about_me,
|
|
1109
|
-
};
|
|
1110
|
-
let response = await this.patch<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/update', body);
|
|
1196
|
+
async updateProfile(updates: Partial<UserResponse<ErmisChatGenerics>>) {
|
|
1197
|
+
let response = await this.patch<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/update', updates);
|
|
1111
1198
|
this.user = response;
|
|
1112
1199
|
this.state.updateUser(response);
|
|
1113
1200
|
return response;
|
|
@@ -1359,53 +1446,60 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
|
|
|
1359
1446
|
};
|
|
1360
1447
|
|
|
1361
1448
|
/**
|
|
1362
|
-
* Creates
|
|
1363
|
-
*
|
|
1449
|
+
* Creates a quick channel and immediately registers it on the server.
|
|
1450
|
+
* Quick channels are public group channels that anyone can join without an invitation.
|
|
1451
|
+
* The creator is added as the first member automatically.
|
|
1364
1452
|
*
|
|
1365
|
-
* @param name -
|
|
1453
|
+
* @param name - An optional display name for the channel.
|
|
1366
1454
|
* @returns A promise that resolves to the created `Channel` object.
|
|
1367
1455
|
*/
|
|
1368
|
-
async
|
|
1456
|
+
async createQuickChannel(name?: string): Promise<Channel<ErmisChatGenerics>> {
|
|
1369
1457
|
if (!this.userID) {
|
|
1370
1458
|
throw Error('Call connectUser before creating a channel');
|
|
1371
1459
|
}
|
|
1372
1460
|
|
|
1461
|
+
const now = new Date();
|
|
1462
|
+
const formattedDate = new Intl.DateTimeFormat('en-US', {
|
|
1463
|
+
month: 'short', day: '2-digit', year: 'numeric',
|
|
1464
|
+
hour: '2-digit', minute: '2-digit', hour12: false,
|
|
1465
|
+
}).format(now);
|
|
1466
|
+
|
|
1373
1467
|
const payload = {
|
|
1374
|
-
name: name || `
|
|
1468
|
+
name: name || `Quick Channel - ${formattedDate}`,
|
|
1375
1469
|
members: [this.userID],
|
|
1376
1470
|
public: true,
|
|
1377
1471
|
} as unknown as ChannelData<ErmisChatGenerics>;
|
|
1378
1472
|
|
|
1379
|
-
const
|
|
1380
|
-
await
|
|
1473
|
+
const quickChannel = this.channel('meeting', payload);
|
|
1474
|
+
await quickChannel.create();
|
|
1381
1475
|
|
|
1382
|
-
return
|
|
1476
|
+
return quickChannel;
|
|
1383
1477
|
}
|
|
1384
1478
|
|
|
1385
1479
|
/**
|
|
1386
|
-
* Joins a
|
|
1387
|
-
*
|
|
1388
|
-
* If not, it
|
|
1480
|
+
* Joins a quick channel by its ID.
|
|
1481
|
+
* Automatically checks whether the caller is already a member.
|
|
1482
|
+
* If not, it joins the channel and synchronizes state.
|
|
1389
1483
|
*
|
|
1390
|
-
* @param channelId - The ID of the
|
|
1484
|
+
* @param channelId - The ID of the quick channel to join.
|
|
1391
1485
|
* @returns A promise that resolves to the joined `Channel` object.
|
|
1392
1486
|
*/
|
|
1393
|
-
async
|
|
1487
|
+
async joinQuickChannel(channelId: string): Promise<Channel<ErmisChatGenerics>> {
|
|
1394
1488
|
if (!this.userID) {
|
|
1395
1489
|
throw Error('Call connectUser before joining a channel');
|
|
1396
1490
|
}
|
|
1397
1491
|
|
|
1398
|
-
const
|
|
1399
|
-
await
|
|
1492
|
+
const quickChannel = this.channel('meeting', channelId);
|
|
1493
|
+
await quickChannel.watch();
|
|
1400
1494
|
|
|
1401
|
-
const isMember =
|
|
1495
|
+
const isMember = quickChannel.state.members && quickChannel.state.members[this.userID];
|
|
1402
1496
|
|
|
1403
1497
|
if (!isMember) {
|
|
1404
|
-
await
|
|
1405
|
-
await
|
|
1498
|
+
await quickChannel.acceptInvite('join');
|
|
1499
|
+
await quickChannel.watch();
|
|
1406
1500
|
}
|
|
1407
1501
|
|
|
1408
|
-
return
|
|
1502
|
+
return quickChannel;
|
|
1409
1503
|
}
|
|
1410
1504
|
|
|
1411
1505
|
_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;
|