quickblox-react-ui-kit 0.5.2-alpha.1 → 0.5.3-beta.1

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.
Files changed (29) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/dist/Data/dto/dialog/LocalDialogDTO.d.ts +1 -0
  3. package/dist/Data/dto/dialog/LocalDialogDTO.d.ts.map +1 -1
  4. package/dist/Data/mapper/DialogLocalDTOMapper.d.ts.map +1 -1
  5. package/dist/Data/mapper/DialogRemoteDTOMapper.d.ts.map +1 -1
  6. package/dist/Data/source/remote/Mapper/DialogDTOMapper.d.ts.map +1 -1
  7. package/dist/Data/source/remote/RemoteDataSource.d.ts +16 -0
  8. package/dist/Data/source/remote/RemoteDataSource.d.ts.map +1 -1
  9. package/dist/Domain/entity/DialogEntity.d.ts +1 -0
  10. package/dist/Domain/entity/DialogEntity.d.ts.map +1 -1
  11. package/dist/Domain/entity/GroupDialogEntity.d.ts +1 -0
  12. package/dist/Domain/entity/GroupDialogEntity.d.ts.map +1 -1
  13. package/dist/index-ui.js +23819 -23439
  14. package/package.json +2 -2
  15. package/src/Data/dto/dialog/LocalDialogDTO.ts +4 -0
  16. package/src/Data/mapper/DialogLocalDTOMapper.ts +5 -0
  17. package/src/Data/mapper/DialogRemoteDTOMapper.ts +6 -0
  18. package/src/Data/source/remote/Mapper/DialogDTOMapper.ts +2 -0
  19. package/src/Data/source/remote/RemoteDataSource.ts +58 -3
  20. package/src/Domain/entity/DialogEntity.ts +2 -0
  21. package/src/Domain/entity/GroupDialogEntity.ts +3 -0
  22. package/storybook-static/363.e762d8b6.iframe.bundle.js +2 -0
  23. package/storybook-static/Presentation-ui-components-MessageInput-MessageInput-stories.fe9298d3.iframe.bundle.js +1 -0
  24. package/storybook-static/iframe.html +1 -1
  25. package/storybook-static/project.json +1 -1
  26. package/storybook-static/{runtime~main.b1ec3380.iframe.bundle.js → runtime~main.92144959.iframe.bundle.js} +1 -1
  27. package/storybook-static/363.fe646024.iframe.bundle.js +0 -2
  28. package/storybook-static/Presentation-ui-components-MessageInput-MessageInput-stories.d72f098b.iframe.bundle.js +0 -1
  29. /package/storybook-static/{363.fe646024.iframe.bundle.js.LICENSE.txt → 363.e762d8b6.iframe.bundle.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quickblox-react-ui-kit",
3
- "version": "0.5.2-alpha.1",
3
+ "version": "0.5.3-beta.1",
4
4
  "main": "dist/index-ui.js",
5
5
  "types": "dist/index-ui.d.ts",
6
6
  "license": "MIT",
@@ -13,7 +13,7 @@
13
13
  "qb-ai-core": "^0.1.3",
14
14
  "qb-ai-rephrase": "^0.1.2",
15
15
  "qb-ai-translate": "^0.1.2",
16
- "quickblox": "2.22.0-alpha.1",
16
+ "quickblox": "2.23.1",
17
17
  "react": "^19.0.0",
18
18
  "react-dom": "^19.0.0",
19
19
  "react-router-dom": "^6.11.1",
@@ -25,6 +25,9 @@ export class LocalDialogDTO {
25
25
 
26
26
  public photo: string;
27
27
 
28
+ // CSAMPLES-4138: persisted join flag (0 = skip join, 1/undefined/null = join).
29
+ public isJoinRequired?: number | null;
30
+
28
31
  constructor() {
29
32
  this.id = '';
30
33
  this.type = 0;
@@ -38,5 +41,6 @@ export class LocalDialogDTO {
38
41
  this.unreadMessageCount = 0;
39
42
  this.name = '';
40
43
  this.photo = '';
44
+ this.isJoinRequired = undefined;
41
45
  }
42
46
  }
@@ -51,6 +51,9 @@ export class DialogLocalDTOMapper implements IMapper {
51
51
 
52
52
  dialog.photo = DialogLocalDTOMapper.getPhoto(dialogEntity);
53
53
 
54
+ // CSAMPLES-4138: persist the join flag into local storage.
55
+ dialog.isJoinRequired = (dialogEntity as GroupDialogEntity).isJoinRequired;
56
+
54
57
  return Promise.resolve(dialog as TResult);
55
58
  }
56
59
 
@@ -116,6 +119,8 @@ export class DialogLocalDTOMapper implements IMapper {
116
119
  dialog.name,
117
120
  dialog.photo,
118
121
  );
122
+ // CSAMPLES-4138: restore the join flag read from local storage.
123
+ (entity as GroupDialogEntity).isJoinRequired = dialog.isJoinRequired;
119
124
  break;
120
125
  default:
121
126
  return Promise.reject(
@@ -60,6 +60,10 @@ export class DialogRemoteDTOMapper implements IMapper {
60
60
  dialog.name = DialogRemoteDTOMapper.getDialogName(dialogEntity);
61
61
 
62
62
  dialog.photo = DialogRemoteDTOMapper.getPhoto(dialogEntity) || '';
63
+
64
+ // CSAMPLES-4138: carry the join flag back into the remote DTO
65
+ // (needed by the typing path, where the DTO is built from a local entity).
66
+ dialog.is_join_required = (dialogEntity as GroupDialogEntity).isJoinRequired;
63
67
  } catch (e) {
64
68
  console.log('MAPPER ERROR for entity: ', JSON.stringify(entity));
65
69
  }
@@ -148,6 +152,8 @@ export class DialogRemoteDTOMapper implements IMapper {
148
152
  dialog.name,
149
153
  formatPhotoUrl(),
150
154
  );
155
+ // CSAMPLES-4138: propagate the join flag into the domain entity.
156
+ (entity as GroupDialogEntity).isJoinRequired = dialog.is_join_required;
151
157
  break;
152
158
  default:
153
159
  return Promise.reject(
@@ -164,6 +164,8 @@ export class DialogDTOMapper implements IDTOMapper {
164
164
  dto.name = qbDialog.name;
165
165
  dto.photo = qbDialog.photo === null ? '' : qbDialog.photo;
166
166
  dto.participantsIds = qbDialog.occupants_ids;
167
+ // CSAMPLES-4138: carry the server "is join required" flag into the DTO.
168
+ dto.is_join_required = qbDialog.is_join_required;
167
169
  break;
168
170
  default:
169
171
  dto.id = qbDialog._id;
@@ -109,6 +109,8 @@ export class RemoteDataSource implements IRemoteDataSource {
109
109
  private joinStatusMap: Map<string, boolean> = new Map();
110
110
  private joinCheckInterval: NodeJS.Timeout | null = null;
111
111
  private processedDialogs = new Set<string>();
112
+ // CSAMPLES-4138: group dialogs with is_join_required===0 (join must be skipped).
113
+ private skipJoinDialogs = new Set<string>();
112
114
  private userCache: Map<string, RemoteUserDTO> = new Map();
113
115
  private userCachePreloadInterval: NodeJS.Timeout | null = null;
114
116
 
@@ -427,6 +429,8 @@ export class RemoteDataSource implements IRemoteDataSource {
427
429
 
428
430
  public resetProcessedDialogs(): void {
429
431
  this.processedDialogs.clear();
432
+ // CSAMPLES-4138: reset the join-skip cache with the rest of per-session state.
433
+ this.skipJoinDialogs.clear();
430
434
  }
431
435
 
432
436
  public async disconnectAndLogoutUser() {
@@ -905,6 +909,48 @@ export class RemoteDataSource implements IRemoteDataSource {
905
909
  }
906
910
  }
907
911
 
912
+ /**
913
+ * CSAMPLES-4138: single source of truth for the "is join required" rule.
914
+ * is_join_required === 0 => skip join. undefined/null/1 => join (legacy).
915
+ * SIDE EFFECT: when an explicit flag is passed, caches the skip decision in
916
+ * skipJoinDialogs so later flag-less call sites (sendMessage) can reuse it.
917
+ * @param dialogId target group dialog id.
918
+ * @param isJoinRequired server flag when known (variant B); omit to fall back
919
+ * to the skipJoinDialogs cache (variant A).
920
+ */
921
+ private isJoinRequiredForDialog(
922
+ dialogId: string,
923
+ isJoinRequired?: number | null,
924
+ ): boolean {
925
+ if (isJoinRequired !== undefined && isJoinRequired !== null) {
926
+ // B: explicit flag wins — remember the skip decision for flag-less callers.
927
+ if (isJoinRequired === 0) {
928
+ this.skipJoinDialogs.add(dialogId);
929
+ } else {
930
+ this.skipJoinDialogs.delete(dialogId);
931
+ }
932
+ return isJoinRequired !== 0;
933
+ }
934
+ if (this.skipJoinDialogs.has(dialogId)) {
935
+ return false; // A: cache filled during getDialogs / prior typing.
936
+ }
937
+ return true; // fallback: unknown dialog → join (legacy behavior).
938
+ }
939
+
940
+ /**
941
+ * CSAMPLES-4138: join wrapper that respects the "is join required" rule.
942
+ * Pass isJoinRequired when the flag is known at the call site.
943
+ */
944
+ private async joinGroupDialogIfRequired(
945
+ dialogId: string,
946
+ isJoinRequired?: number | null,
947
+ ): Promise<void> {
948
+ if (!this.isJoinRequiredForDialog(dialogId, isJoinRequired)) {
949
+ return; // skip join
950
+ }
951
+ await this.joinGroupDialog(dialogId);
952
+ }
953
+
908
954
  //version 0.5.0-beta.11,12,14
909
955
  private startJoinRetryProcess(): void {
910
956
  if (this.joinCheckInterval) return;
@@ -988,7 +1034,11 @@ export class RemoteDataSource implements IRemoteDataSource {
988
1034
  if (newDTO.type === DialogType.group && !this.processedDialogs.has(newDTO.id)) {
989
1035
  this.processedDialogs.add(newDTO.id);
990
1036
 
991
- if (!this.joinStatusMap.has(newDTO.id)) {
1037
+ // CSAMPLES-4138: skip join when the server flag says it's not required.
1038
+ if (!this.isJoinRequiredForDialog(newDTO.id, newDTO.is_join_required)) {
1039
+ // isJoinRequiredForDialog already cached the skip; never enters joinStatusMap.
1040
+ this.skipJoinDialogs.add(newDTO.id);
1041
+ } else if (!this.joinStatusMap.has(newDTO.id)) {
992
1042
  this.joinStatusMap.set(newDTO.id, false);
993
1043
  joinDialogIds.push(newDTO.id);
994
1044
  }
@@ -1629,7 +1679,11 @@ export class RemoteDataSource implements IRemoteDataSource {
1629
1679
 
1630
1680
  if (dialogDTO.type === DialogType.group) {
1631
1681
  if (!this.joinStatusMap.has(dialogDTO.id)) {
1632
- await this.joinGroupDialog(dialogDTO.id);
1682
+ // CSAMPLES-4138: respect the join flag (known here from the DTO).
1683
+ await this.joinGroupDialogIfRequired(
1684
+ dialogDTO.id,
1685
+ dialogDTO.is_join_required,
1686
+ );
1633
1687
  }
1634
1688
  // await QBJoinGroupDialog(dialogDTO.id).catch(() => {
1635
1689
  // throw new RemoteDataSourceException(
@@ -1763,7 +1817,8 @@ export class RemoteDataSource implements IRemoteDataSource {
1763
1817
  // if (!this.joinStatusMap.has(dto.dialogId)) {
1764
1818
  // await this.joinGroupDialog(dto.dialogId);
1765
1819
  // }
1766
- await this.joinGroupDialog(dto.dialogId);
1820
+ // CSAMPLES-4138: no dialog flag here — rely on the skipJoinDialogs cache.
1821
+ await this.joinGroupDialogIfRequired(dto.dialogId);
1767
1822
  const dialogJid = QB.chat.helpers.getRoomJidFromDialogId(dto.dialogId);
1768
1823
  try {
1769
1824
  qbMessageId = await QBChatSendMessage(dialogJid, qbEntity);
@@ -12,4 +12,6 @@ export interface DialogEntity {
12
12
  lastMessage: LastMessageEntity;
13
13
  unreadMessageCount: number;
14
14
  customData: CustomDataEntity;
15
+ // CSAMPLES-4138: 0 = join not required (skip join), 1/undefined/null = join (legacy).
16
+ isJoinRequired?: number | null;
15
17
  }
@@ -28,6 +28,9 @@ export class GroupDialogEntity implements DialogEntity {
28
28
 
29
29
  photo: string | null;
30
30
 
31
+ // CSAMPLES-4138: 0 = join not required (skip join), 1/undefined/null = join (legacy).
32
+ isJoinRequired?: number | null;
33
+
31
34
  constructor(
32
35
  customData: CustomDataEntity,
33
36
  id: string,