quickblox-react-ui-kit 0.3.0-beta.3 → 0.3.0-beta.4

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 (122) hide show
  1. package/dist/Data/Stubs.d.ts +1 -1
  2. package/dist/Data/dto/file/RemoteFileDTO.d.ts +1 -1
  3. package/dist/Data/dto/message/RemoteMessageDTO.d.ts +1 -1
  4. package/dist/Data/dto/user/LocalUserDTO.d.ts +1 -1
  5. package/dist/Data/dto/user/RemoteUserDTO.d.ts +2 -2
  6. package/dist/Domain/entity/FileEntity.d.ts +1 -1
  7. package/dist/Domain/entity/UserEntity.d.ts +1 -1
  8. package/dist/Presentation/Views/Dialog/AIComponents/AIAssist/AIAssist.d.ts +2 -1
  9. package/dist/Presentation/Views/Dialog/AIComponents/AITranslate/AITranslate.d.ts +2 -1
  10. package/dist/Presentation/Views/Dialog/AIWidgets/AIRephraseWidget/AIRephraseWidget.d.ts +1 -0
  11. package/dist/Presentation/Views/Dialog/ForwardMessageFlow/ForwardMessageFlow.d.ts +1 -0
  12. package/dist/Presentation/Views/Dialog/ForwardMessageFlow/InputForForwarding/InputForForwarding.d.ts +2 -2
  13. package/dist/Presentation/Views/Dialog/MessageContextMenu/MessageContextMenu.d.ts +2 -1
  14. package/dist/Presentation/Views/Dialog/MessageItem/MessageItem.d.ts +2 -1
  15. package/dist/Presentation/Views/DialogInfo/DialogInfo.d.ts +1 -0
  16. package/dist/Presentation/Views/DialogList/DialogList.d.ts +1 -0
  17. package/dist/Presentation/Views/EditDialog/EditDialog.d.ts +2 -1
  18. package/dist/Presentation/Views/Flow/CreateDialogFlow/CreateNewDialogFlow.d.ts +1 -0
  19. package/dist/Presentation/Views/PreviewDialog/PreviewDialog.d.ts +1 -0
  20. package/dist/Presentation/providers/QuickBloxUIKitProvider/useQBConnection.d.ts +1 -0
  21. package/dist/Presentation/ui-components/DialogWindow/DialogWindow.d.ts +3 -2
  22. package/dist/Presentation/ui-components/Dropdown/DropdownOption.d.ts +2 -1
  23. package/dist/Presentation/ui-components/MessageInput/AttachmentUploader/AttachmentUploader.d.ts +1 -0
  24. package/dist/Presentation/ui-components/MessageInput/MessageInput.d.ts +1 -0
  25. package/dist/index-ui.js +518 -362
  26. package/dist/index-ui.js.map +1 -1
  27. package/dist/qb-api-calls/index.d.ts +8 -7
  28. package/global.d.ts +2513 -546
  29. package/package.json +1 -1
  30. package/src/App.scss +3 -0
  31. package/src/App.tsx +2 -2
  32. package/src/Data/Creator.ts +1 -2
  33. package/src/Data/DefaultConfigurations.ts +4 -4
  34. package/src/Data/Stubs.ts +4 -5
  35. package/src/Data/dto/file/RemoteFileDTO.ts +2 -2
  36. package/src/Data/dto/message/RemoteMessageDTO.ts +1 -1
  37. package/src/Data/dto/user/LocalUserDTO.ts +2 -2
  38. package/src/Data/dto/user/RemoteUserDTO.ts +4 -4
  39. package/src/Data/mapper/FileRemoteDTOMapper.ts +8 -6
  40. package/src/Data/mapper/MessageRemoteDTOMapper.ts +1 -1
  41. package/src/Data/mapper/UserLocalDTOMapper.ts +2 -2
  42. package/src/Data/mapper/UserRemoteDTOMapper.ts +2 -2
  43. package/src/Data/repository/MessagesRepository.ts +2 -2
  44. package/src/Data/repository/UsersRepository.ts +1 -1
  45. package/src/Data/source/remote/Mapper/FileDTOMapper.ts +23 -23
  46. package/src/Data/source/remote/Mapper/MessageDTOMapper.ts +2 -2
  47. package/src/Data/source/remote/Mapper/UserDTOMapper.ts +0 -2
  48. package/src/Data/source/remote/RemoteDataSource.ts +50 -8
  49. package/src/Domain/entity/FileEntity.ts +1 -1
  50. package/src/Domain/entity/UserEntity.ts +1 -11
  51. package/src/Domain/use_cases/UpdateDialogUseCase.ts +6 -1
  52. package/src/Domain/use_cases/base/Subscribable/SubscriptionPerformer.ts +1 -1
  53. package/src/Presentation/Views/Dialog/AIComponents/AIAssist/AIAssist.scss +5 -0
  54. package/src/Presentation/Views/Dialog/AIComponents/AIAssist/AIAssist.tsx +9 -2
  55. package/src/Presentation/Views/Dialog/AIComponents/AITranslate/AITranslate.scss +10 -0
  56. package/src/Presentation/Views/Dialog/AIComponents/AITranslate/AITranslate.tsx +16 -7
  57. package/src/Presentation/Views/Dialog/AIWidgets/AIRephraseWidget/AIRephraseWidget.scss +7 -2
  58. package/src/Presentation/Views/Dialog/AIWidgets/AIRephraseWidget/AIRephraseWidget.tsx +12 -3
  59. package/src/Presentation/Views/Dialog/ForwardMessageFlow/DialogsWithSearch/DialogListItem/DialogListItem.scss +1 -1
  60. package/src/Presentation/Views/Dialog/ForwardMessageFlow/ForwardMessageFlow.tsx +9 -5
  61. package/src/Presentation/Views/Dialog/ForwardMessageFlow/InputForForwarding/InputForForwarding.scss +31 -1
  62. package/src/Presentation/Views/Dialog/ForwardMessageFlow/InputForForwarding/InputForForwarding.tsx +7 -7
  63. package/src/Presentation/Views/Dialog/MessageContextMenu/MessageContextMenu.tsx +17 -6
  64. package/src/Presentation/Views/Dialog/MessageItem/MessageItem.tsx +6 -0
  65. package/src/Presentation/Views/Dialog/useDialogViewModel.ts +1 -0
  66. package/src/Presentation/Views/DialogInfo/DialogInfo.scss +11 -1
  67. package/src/Presentation/Views/DialogInfo/DialogInfo.tsx +36 -18
  68. package/src/Presentation/Views/DialogInfo/UsersList/useUsersListViewModel.ts +1 -0
  69. package/src/Presentation/Views/DialogList/DialogList.scss +5 -0
  70. package/src/Presentation/Views/DialogList/DialogList.tsx +12 -2
  71. package/src/Presentation/Views/DialogList/useDialogListViewModel.ts +33 -16
  72. package/src/Presentation/Views/EditDialog/EditDialog.scss +11 -0
  73. package/src/Presentation/Views/EditDialog/EditDialog.tsx +9 -1
  74. package/src/Presentation/Views/Flow/CreateDialogFlow/CreateNewDialogFlow.tsx +14 -0
  75. package/src/Presentation/Views/InviteMembers/useInviteMembersViewModel.ts +1 -11
  76. package/src/Presentation/Views/PreviewDialog/PreviewDialog.tsx +4 -0
  77. package/src/Presentation/icons/media/video-file.svg +2 -2
  78. package/src/Presentation/layouts/Desktop/QuickBloxUIKitDesktopLayout.tsx +110 -52
  79. package/src/Presentation/providers/QuickBloxUIKitProvider/useQBConnection.ts +16 -0
  80. package/src/Presentation/ui-components/DialogWindow/DialogWindow.scss +11 -0
  81. package/src/Presentation/ui-components/DialogWindow/DialogWindow.tsx +4 -1
  82. package/src/Presentation/ui-components/Dropdown/Dropdown.scss +4 -0
  83. package/src/Presentation/ui-components/Dropdown/Dropdown.tsx +1 -1
  84. package/src/Presentation/ui-components/Dropdown/DropdownOption.tsx +9 -1
  85. package/src/Presentation/ui-components/MessageInput/AttachmentUploader/AttachmentUploader.tsx +3 -0
  86. package/src/Presentation/ui-components/MessageInput/MessageInput.scss +18 -4
  87. package/src/Presentation/ui-components/MessageInput/MessageInput.tsx +8 -2
  88. package/src/Presentation/ui-components/PreviewFileMessage/PreviewFileMessage.tsx +2 -2
  89. package/src/Presentation/ui-components/SettingsItem/SettingsItem.stories.tsx +2 -0
  90. package/src/QBconfig.ts +4 -4
  91. package/src/index.scss +5 -2
  92. package/src/qb-api-calls/index.ts +58 -49
  93. package/storybook-static/758.53b4954a.iframe.bundle.js +14 -0
  94. package/storybook-static/{758.e75a5a47.iframe.bundle.js.map → 758.53b4954a.iframe.bundle.js.map} +1 -1
  95. package/storybook-static/{Presentation-ui-components-DialogItemPreview-DialogItemPreview-stories.90aa44c5.iframe.bundle.js → Presentation-ui-components-DialogItemPreview-DialogItemPreview-stories.6665bbfb.iframe.bundle.js} +1 -1
  96. package/storybook-static/Presentation-ui-components-DialogWindow-DialogWindow-stories.cf340397.iframe.bundle.js +1 -0
  97. package/storybook-static/{Presentation-ui-components-Dropdown-Dropdown-stories.aacf2ec2.iframe.bundle.js → Presentation-ui-components-Dropdown-Dropdown-stories.b32a1e17.iframe.bundle.js} +1 -1
  98. package/storybook-static/Presentation-ui-components-MessageInput-MessageInput-stories.c2ead6a5.iframe.bundle.js +1 -0
  99. package/storybook-static/{Presentation-ui-components-PreviewFileMessage-PreviewFileMessage-stories.1661d95b.iframe.bundle.js → Presentation-ui-components-PreviewFileMessage-PreviewFileMessage-stories.527e000e.iframe.bundle.js} +1 -1
  100. package/storybook-static/Presentation-ui-components-SettingsItem-SettingsItem-stories.2ff75703.iframe.bundle.js +1 -0
  101. package/storybook-static/iframe.html +2 -2
  102. package/storybook-static/project.json +1 -1
  103. package/storybook-static/{runtime~main.e945879b.iframe.bundle.js → runtime~main.12da9712.iframe.bundle.js} +1 -1
  104. package/storybook-static/static/css/{Presentation-ui-components-DialogItemPreview-DialogItemPreview-stories.e720ff21.chunk.css → Presentation-ui-components-DialogItemPreview-DialogItemPreview-stories.bee082ca.chunk.css} +2 -2
  105. package/storybook-static/static/css/{Presentation-ui-components-DialogItemPreview-DialogItemPreview-stories.e720ff21.chunk.css.map → Presentation-ui-components-DialogItemPreview-DialogItemPreview-stories.bee082ca.chunk.css.map} +1 -1
  106. package/storybook-static/static/css/{Presentation-ui-components-DialogWindow-DialogWindow-stories.6fb3af8d.chunk.css → Presentation-ui-components-DialogWindow-DialogWindow-stories.4f813450.chunk.css} +2 -2
  107. package/storybook-static/static/css/Presentation-ui-components-DialogWindow-DialogWindow-stories.4f813450.chunk.css.map +1 -0
  108. package/storybook-static/static/css/{Presentation-ui-components-Dropdown-Dropdown-stories.66965d64.chunk.css → Presentation-ui-components-Dropdown-Dropdown-stories.e37f549d.chunk.css} +2 -2
  109. package/storybook-static/static/css/Presentation-ui-components-Dropdown-Dropdown-stories.e37f549d.chunk.css.map +1 -0
  110. package/storybook-static/static/css/{Presentation-ui-components-MessageInput-MessageInput-stories.0e99d80b.chunk.css → Presentation-ui-components-MessageInput-MessageInput-stories.7eb916fc.chunk.css} +2 -2
  111. package/storybook-static/static/css/Presentation-ui-components-MessageInput-MessageInput-stories.7eb916fc.chunk.css.map +1 -0
  112. package/storybook-static/static/css/{main.6fa55a2c.css → main.a921485c.css} +2 -2
  113. package/storybook-static/static/css/{main.6fa55a2c.css.map → main.a921485c.css.map} +1 -1
  114. package/storybook-static/static/media/video-file.dbd1f8c63a3769f9e9a027f0922d56b2.svg +3 -0
  115. package/storybook-static/758.e75a5a47.iframe.bundle.js +0 -14
  116. package/storybook-static/Presentation-ui-components-DialogWindow-DialogWindow-stories.3523a670.iframe.bundle.js +0 -1
  117. package/storybook-static/Presentation-ui-components-MessageInput-MessageInput-stories.262a0cf2.iframe.bundle.js +0 -1
  118. package/storybook-static/Presentation-ui-components-SettingsItem-SettingsItem-stories.8f6fca84.iframe.bundle.js +0 -1
  119. package/storybook-static/static/css/Presentation-ui-components-DialogWindow-DialogWindow-stories.6fb3af8d.chunk.css.map +0 -1
  120. package/storybook-static/static/css/Presentation-ui-components-Dropdown-Dropdown-stories.66965d64.chunk.css.map +0 -1
  121. package/storybook-static/static/css/Presentation-ui-components-MessageInput-MessageInput-stories.0e99d80b.chunk.css.map +0 -1
  122. package/storybook-static/static/media/video-file.dc2971be489b2af7b1c04dcc55bfe881.svg +0 -3
@@ -50,6 +50,17 @@ $create-dialog-container-height: 180px;
50
50
 
51
51
  margin-bottom: 24px;
52
52
 
53
+ &--disable {
54
+ position: absolute;
55
+ top: 0;
56
+ left: 0;
57
+ width: 100%;
58
+ height: 100%;
59
+ background-color: rgba(0, 0, 0, 0.5);
60
+ z-index: 100;
61
+ display: block;
62
+ }
63
+
53
64
  &--wrapper {
54
65
  min-height: 180px;
55
66
  display: flex;
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import './EditDialog.scss';
2
+ import cn from 'classnames';
3
3
  import ColumnContainer from '../../components/containers/ColumnContainer/ColumnContainer';
4
4
  import User from '../../components/UI/svgs/Icons/Contents/User';
5
5
  import RowRightContainer from '../../components/containers/RowRightContainer/RowRightContainer';
@@ -14,6 +14,7 @@ import GroupChat from '../../components/UI/svgs/Icons/Contents/GroupChat';
14
14
  import PublicChannel from '../../components/UI/svgs/Icons/Contents/PublicChannel';
15
15
  import useQbInitializedDataContext from '../../providers/QuickBloxUIKitProvider/useQbInitializedDataContext';
16
16
  import { Button, TextField } from '../../ui-components';
17
+ import './EditDialog.scss';
17
18
 
18
19
  export const TypeOpenDialog = {
19
20
  edit: 'edit',
@@ -29,6 +30,7 @@ type EditDialogProps = {
29
30
  typeAddEditDialog: OpenDialogArcheType;
30
31
  clickUpdatedHandler?: FunctionTypeEditDialogParamsToVoid;
31
32
  clickCancelHandler?: FunctionTypeVoidToVoid;
33
+ disableActions?: boolean;
32
34
  };
33
35
 
34
36
  // eslint-disable-next-line react/function-component-definition,@typescript-eslint/no-unused-vars
@@ -39,6 +41,7 @@ const EditDialog: React.FC<EditDialogProps> = ({
39
41
  typeAddEditDialog = TypeOpenDialog.create,
40
42
  clickUpdatedHandler,
41
43
  clickCancelHandler,
44
+ disableActions = false,
42
45
  }) => {
43
46
  const currentContext = useQbInitializedDataContext();
44
47
  const maxUploadFileSize = currentContext.InitParams.maxFileSize;
@@ -176,6 +179,11 @@ const EditDialog: React.FC<EditDialogProps> = ({
176
179
  }}
177
180
  className="edit-container"
178
181
  >
182
+ <div
183
+ className={cn('', {
184
+ 'edit-dialog-container--disable': disableActions,
185
+ })}
186
+ />
179
187
  <div className="edit-dialog-container">
180
188
  <div className="edit-dialog-container--wrapper">
181
189
  <div className="edit-dialog-container--wrapper__inf">
@@ -17,6 +17,7 @@ type CreateNewDialogFlowProps = {
17
17
  dialogsViewModel: DialogListViewModel;
18
18
  onFinished: (newEntity: DialogEntity) => void;
19
19
  onCancel?: () => void;
20
+ isOnline: boolean;
20
21
  };
21
22
 
22
23
  // eslint-disable-next-line react/function-component-definition
@@ -24,6 +25,7 @@ const CreateNewDialogFlow: React.FC<CreateNewDialogFlowProps> = ({
24
25
  dialogsViewModel,
25
26
  onFinished,
26
27
  onCancel,
28
+ isOnline,
27
29
  }: CreateNewDialogFlowProps) => {
28
30
  const currentContext = React.useContext(qbDataContext);
29
31
  const remoteDataSourceMock: RemoteDataSource =
@@ -122,6 +124,18 @@ const CreateNewDialogFlow: React.FC<CreateNewDialogFlowProps> = ({
122
124
 
123
125
  return (
124
126
  <div>
127
+ <div
128
+ style={{
129
+ position: 'absolute',
130
+ top: '0',
131
+ left: '0',
132
+ width: '100%',
133
+ height: '100%',
134
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
135
+ zIndex: '100',
136
+ display: isOnline ? 'none' : 'block',
137
+ }}
138
+ />
125
139
  {stepToCreate === setUpDialogType && (
126
140
  <CreateDialog
127
141
  createPrivateDialogOnClick={() => {
@@ -116,17 +116,7 @@ export default function useInviteMembersViewModel(): InviteMembersViewModel {
116
116
 
117
117
  return {
118
118
  get entity(): UserEntity {
119
- return Stubs.createUserEntityWithParams(
120
- 0,
121
- '',
122
- '',
123
- '',
124
- '',
125
- '',
126
- '',
127
- '',
128
- '',
129
- );
119
+ return Stubs.createUserEntityWithParams(0, '', '', '', '', '', 0, '', '');
130
120
  },
131
121
  // id: Date.now(),
132
122
  // name: '',
@@ -53,6 +53,7 @@ type PreviewDialogsProps = {
53
53
  theme?: PreviewDialogsTheme;
54
54
  onLeaveDialog: FunctionTypeDialogEntityToVoid;
55
55
  additionalSettings?: PreviewDialogSettings;
56
+ disableActions?: boolean;
56
57
  };
57
58
  // eslint-disable-next-line react/function-component-definition
58
59
  const PreviewDialog: React.FC<PreviewDialogsProps> = ({
@@ -65,6 +66,7 @@ const PreviewDialog: React.FC<PreviewDialogsProps> = ({
65
66
  message_date_time_sent,
66
67
  theme = undefined,
67
68
  onLeaveDialog,
69
+ disableActions = false,
68
70
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
69
71
  additionalSettings = undefined,
70
72
  }: PreviewDialogsProps) => {
@@ -293,8 +295,10 @@ const PreviewDialog: React.FC<PreviewDialogsProps> = ({
293
295
  {
294
296
  value: 'Leave',
295
297
  label: 'Leave',
298
+ disabled: disableActions,
296
299
  },
297
300
  ]}
301
+ disabled={disableActions}
298
302
  onSelect={(value: string) => {
299
303
  if (value === 'Leave') {
300
304
  onLeaveDialog(dialogViewModel?.entity as DialogEntity);
@@ -1,3 +1,3 @@
1
- <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M8.69727 7.33337V16.6667L16.0306 12L8.69727 7.33337Z"/>
1
+ <svg viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M33.0001 7.33325L36.6667 14.6666H31.1667L27.5001 7.33325H23.8334L27.5001 14.6666H22.0001L18.3334 7.33325H14.6667L18.3334 14.6666H12.8334L9.16675 7.33325H7.33341C5.31675 7.33325 3.68508 8.98325 3.68508 10.9999L3.66675 32.9999C3.66675 35.0166 5.31675 36.6666 7.33341 36.6666H36.6667C38.6834 36.6666 40.3334 35.0166 40.3334 32.9999V7.33325H33.0001Z"/>
3
3
  </svg>
@@ -117,19 +117,45 @@ const QuickBloxUIKitDesktopLayout: React.FC<
117
117
  dialogsViewModel.entity,
118
118
  );
119
119
 
120
- const { connectionRepository, browserOnline } = useQBConnection();
121
- const [isOnline, setIsOnline] = useState<boolean>(browserOnline);
120
+ const { browserOnline, connectionStatus, connectionRepository } =
121
+ useQBConnection();
122
+
123
+ const [isOnline, setIsOnline] = useState<boolean>(
124
+ browserOnline && connectionStatus,
125
+ );
126
+
127
+ connectionRepository.subscribe((status) => {
128
+ console.log(`Connection status: ${status ? 'CONNECTED' : 'DISCONNECTED'}`);
129
+ if (status) setIsOnline(true);
130
+ else setIsOnline(false);
131
+ });
132
+
133
+ const [needRefresh, setNeedRefresh] = useState(false);
134
+ const toastConnectionErrorId = React.useRef(null);
122
135
 
123
136
  useEffect(() => {
124
- if (
125
- isOnline === false ||
126
- connectionRepository.isChatConnected() === false
127
- ) {
128
- setIsOnline(false);
129
- } else {
137
+ if (browserOnline) {
130
138
  setIsOnline(true);
139
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/ban-ts-comment
140
+ // @ts-ignore
141
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
142
+ toast.dismiss(toastConnectionErrorId.current);
143
+ } else {
144
+ setIsOnline(false);
145
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/ban-ts-comment
146
+ // @ts-ignore
147
+ toastConnectionErrorId.current = toast('Connection ...', {
148
+ autoClose: false,
149
+ isLoading: true,
150
+ });
131
151
  }
132
- }, [browserOnline, connectionRepository.isChatConnected()]);
152
+ }, [browserOnline && connectionStatus]);
153
+
154
+ useEffect(() => {
155
+ if (!isOnline) {
156
+ setNeedRefresh(true);
157
+ }
158
+ }, [isOnline]);
133
159
 
134
160
  let defaultAIRephraseWidget = AIRephrase?.AIWidget; // useDefaultTextInputWidget();
135
161
  let defaultAITranslateWidget = AITranslate?.AIWidget;
@@ -249,9 +275,11 @@ const QuickBloxUIKitDesktopLayout: React.FC<
249
275
  const { enableReplying } = QBConfig.appConfig;
250
276
 
251
277
  const selectDialogActions = (item: BaseViewModel<DialogEntity>): void => {
252
- if (!dialogsViewModel.loading) {
253
- setSelectedDialog(item.entity);
254
- // dialogsViewModel.entity = item.entity;
278
+ if (isOnline) {
279
+ if (!dialogsViewModel.loading) {
280
+ setSelectedDialog(item.entity);
281
+ // dialogsViewModel.entity = item.entity;
282
+ }
255
283
  }
256
284
  };
257
285
 
@@ -394,6 +422,15 @@ const QuickBloxUIKitDesktopLayout: React.FC<
394
422
  }
395
423
  }, [messagesViewModel.entity]);
396
424
 
425
+ useEffect(() => {
426
+ if (isOnline && needRefresh) {
427
+ if (messagesViewModel.entity) {
428
+ messagesViewModel.getMessages(new Pagination(0, messagePerPage));
429
+
430
+ setNeedRefresh(false);
431
+ }
432
+ }
433
+ }, [isOnline]);
397
434
  const fetchMoreData = () => {
398
435
  if (messagesViewModel.pagination.hasNextPage()) {
399
436
  const newPagination = messagesViewModel.pagination;
@@ -434,6 +471,9 @@ const QuickBloxUIKitDesktopLayout: React.FC<
434
471
 
435
472
  useEffect(() => {
436
473
  getDialogPhotoFileForPreview();
474
+ if (dialogsViewModel.entity) {
475
+ userViewModel.entity = dialogsViewModel.entity;
476
+ }
437
477
 
438
478
  return () => {
439
479
  if (dialogAvatarUrl) {
@@ -577,7 +617,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
577
617
  };
578
618
 
579
619
  repliedActions(replyData);
580
- } else {
620
+ } else if (isOnline) {
581
621
  // eslint-disable-next-line promise/catch-or-return
582
622
  messagesViewModel
583
623
  .sendAttachmentMessage(fileToSend)
@@ -782,30 +822,32 @@ const QuickBloxUIKitDesktopLayout: React.FC<
782
822
  //
783
823
 
784
824
  function sendTextMessageActions(textToSend: string) {
785
- // closeReplyMessageFlowHandler
786
- if (messagesViewModel?.loading) return;
787
- // setVoiceMessage(true);
788
- if (textToSend.length > 0 && textToSend.length <= 1000) {
789
- setMessageText('');
790
- if (showReplyMessage && messagesToReply?.length > 0) {
791
- const replyData: ReplyMessagesParams = {
792
- messagesToReply,
793
- relatedTextMessage: textToSend,
794
- };
825
+ if (isOnline) {
826
+ // closeReplyMessageFlowHandler
827
+ if (messagesViewModel?.loading) return;
828
+ // setVoiceMessage(true);
829
+ if (textToSend.length > 0 && textToSend.length <= 1000) {
830
+ setMessageText('');
831
+ if (showReplyMessage && messagesToReply?.length > 0) {
832
+ const replyData: ReplyMessagesParams = {
833
+ messagesToReply,
834
+ relatedTextMessage: textToSend,
835
+ };
795
836
 
796
- repliedActions(replyData);
797
- } else {
798
- messagesViewModel.sendTextMessage(textToSend);
837
+ repliedActions(replyData);
838
+ } else {
839
+ messagesViewModel.sendTextMessage(textToSend);
840
+ setMessageText('');
841
+ }
799
842
  setMessageText('');
843
+ } else {
844
+ setWarningErrorText(
845
+ 'length of text message must be less then 1000 chars.',
846
+ );
847
+ setTimeout(() => {
848
+ setWarningErrorText('');
849
+ }, 3000);
800
850
  }
801
- setMessageText('');
802
- } else {
803
- setWarningErrorText(
804
- 'length of text message must be less then 1000 chars.',
805
- );
806
- setTimeout(() => {
807
- setWarningErrorText('');
808
- }, 3000);
809
851
  }
810
852
  }
811
853
  //
@@ -833,16 +875,18 @@ const QuickBloxUIKitDesktopLayout: React.FC<
833
875
  //
834
876
 
835
877
  const ChangeFileHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
836
- const reader = new FileReader();
837
- const file = event.currentTarget.files
838
- ? event.currentTarget.files[0]
839
- : null;
878
+ if (isOnline) {
879
+ const reader = new FileReader();
880
+ const file = event.currentTarget.files
881
+ ? event.currentTarget.files[0]
882
+ : null;
840
883
 
841
- reader.onloadend = () => {
842
- setFileToSend(file);
843
- };
884
+ reader.onloadend = () => {
885
+ setFileToSend(file);
886
+ };
844
887
 
845
- if (file !== null) reader.readAsDataURL(file);
888
+ if (file !== null) reader.readAsDataURL(file);
889
+ }
846
890
  };
847
891
 
848
892
  //
@@ -1007,7 +1051,9 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1007
1051
 
1008
1052
  const [dialogToLeave, setDialogToLeave] = useState<DialogEntity>();
1009
1053
  const leaveDialogHandler = (dialog: DialogEntity) => {
1010
- setDialogToLeave(dialog);
1054
+ if (isOnline) {
1055
+ setDialogToLeave(dialog);
1056
+ }
1011
1057
  };
1012
1058
 
1013
1059
  const [isOpen, setIsOpen] = useState(false);
@@ -1092,12 +1138,15 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1092
1138
 
1093
1139
  const newModal = useModal();
1094
1140
 
1141
+ const createDialogHandler = () => {
1142
+ if (isOnline) {
1143
+ newModal.toggleModal();
1144
+ }
1145
+ };
1146
+
1095
1147
  return (
1096
1148
  <ToastProvider>
1097
- <div>
1098
- {/* <div style={{ height: '18px', border: '1px solid red' }}> */}
1099
- {/* h:{height},w:{width},ch:{clientHeight},wh:{workHeight} */}
1100
- {/* </div> */}
1149
+ <div className="qb-uikit-layout">
1101
1150
  <DesktopLayout
1102
1151
  mainContainerStyles={{
1103
1152
  minHeight: workHeight,
@@ -1108,13 +1157,14 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1108
1157
  dialogsView={
1109
1158
  showDialogList ? (
1110
1159
  <DialogList
1160
+ disableAction={!isOnline}
1111
1161
  scrollableHeight={dialogListScrollableHeight}
1112
1162
  // subHeaderContent={<CompanyLogo />}
1113
1163
  // upHeaderContent={<CompanyLogo />}
1114
1164
  dialogListViewModel={dialogsViewModel} // 1 Get 2 Update UseCase
1115
1165
  selectedDialog={dialogsViewModel.entity}
1116
1166
  onDialogSelected={selectDialogActions}
1117
- onCreateDialog={() => newModal.toggleModal()}
1167
+ onCreateDialog={createDialogHandler}
1118
1168
  onLeaveDialog={leaveDialogHandler}
1119
1169
  additionalSettings={{
1120
1170
  withoutHeader: false,
@@ -1175,7 +1225,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1175
1225
  className="messages-container"
1176
1226
  onEndReached={fetchMoreData}
1177
1227
  onEndReachedThreshold={0.95}
1178
- refreshing={messagesViewModel?.loading}
1228
+ refreshing={needRefresh || messagesViewModel?.loading}
1179
1229
  renderSectionHeader={(section) => (
1180
1230
  <div className="message-view-container--system-message-wrapper">
1181
1231
  <div
@@ -1196,6 +1246,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1196
1246
  renderItem={([, groupMessages], listRef) =>
1197
1247
  groupMessages.map((message) => (
1198
1248
  <MessageItem
1249
+ disableAction={!isOnline}
1199
1250
  // defaultGetSenderName={defaultGetSenderName}
1200
1251
  message={message}
1201
1252
  currentUserId={currentUserId || -1}
@@ -1205,8 +1256,10 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1205
1256
  handleOnReply(m);
1206
1257
  }}
1207
1258
  onForward={(m: MessageEntity) => {
1208
- setForwardMessage(m);
1209
- forwardMessageModal.toggleModal();
1259
+ if (isOnline) {
1260
+ setForwardMessage(m);
1261
+ forwardMessageModal.toggleModal();
1262
+ }
1210
1263
  }}
1211
1264
  listRef={listRef}
1212
1265
  AIAssistWidget={defaultAIAssistWidget}
@@ -1233,6 +1286,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1233
1286
  }
1234
1287
  renderMessageInput={
1235
1288
  <MessageInput
1289
+ disableActions={!isOnline}
1236
1290
  previewMessage={
1237
1291
  showReplyMessage ? (
1238
1292
  <ReplyMessagePreview
@@ -1263,11 +1317,12 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1263
1317
  onAttachment={ChangeFileHandler}
1264
1318
  enableVoice={isRecording}
1265
1319
  onVoice={() => {
1266
- if (messagesViewModel?.loading) return;
1320
+ if (messagesViewModel?.loading || !isOnline) return;
1267
1321
  setIsRecording(!isRecording);
1268
1322
  }}
1269
1323
  rephrase={
1270
1324
  <AIRephraseWidget
1325
+ disableActions={!isOnline}
1271
1326
  waitAIWidget={waitAIWidget}
1272
1327
  messageText={messageText}
1273
1328
  theme={theme}
@@ -1321,6 +1376,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1321
1376
  />
1322
1377
  ) : (
1323
1378
  <DialogInfo
1379
+ disableAction={!isOnline}
1324
1380
  onShowAllMemberClick={(value: boolean) => {
1325
1381
  setIsAllMembersShow(value);
1326
1382
  }}
@@ -1368,6 +1424,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1368
1424
  onFinished={() => {
1369
1425
  newModal.toggleModal();
1370
1426
  }}
1427
+ isOnline={isOnline}
1371
1428
  />
1372
1429
  </DialogWindow>
1373
1430
  {selectedDialog && (
@@ -1382,6 +1439,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1382
1439
  currentUserName={userName || ''}
1383
1440
  dialogs={dialogsViewModel.dialogs}
1384
1441
  onSendData={handleSendData}
1442
+ disableActions={!isOnline}
1385
1443
  />
1386
1444
  </DialogWindow>
1387
1445
  )}
@@ -5,19 +5,34 @@ import ConnectionRepository from '../../../Data/repository/ConnectionRepository'
5
5
  type QBConnectionInfo = {
6
6
  connectionRepository: ConnectionRepository;
7
7
  browserOnline: boolean;
8
+ connectionStatus: boolean;
8
9
  };
9
10
  const useQBConnection = (): QBConnectionInfo => {
10
11
  const currentQbDataContext = React.useContext(qbDataContext);
11
12
  const [navigatorOnline, setNavigatorOnline] = React.useState(
12
13
  navigator.onLine,
13
14
  );
15
+ const [connectStatus, setConnectStatus] = React.useState(
16
+ currentQbDataContext.storage.CONNECTION_REPOSITORY.isChatConnected(),
17
+ );
14
18
 
19
+ currentQbDataContext.storage.CONNECTION_REPOSITORY.subscribe((status) => {
20
+ console.log(`Connection status: ${status ? 'CONNECTED' : 'DISCONNECTED'}`);
21
+ if (status) setConnectStatus(true);
22
+ else setConnectStatus(false);
23
+ });
15
24
  useEffect(() => {
16
25
  const setOnline = () => {
17
26
  setNavigatorOnline(true);
27
+ setConnectStatus(
28
+ currentQbDataContext.storage.CONNECTION_REPOSITORY.isChatConnected(),
29
+ );
18
30
  };
19
31
  const setOffline = () => {
20
32
  setNavigatorOnline(false);
33
+ setConnectStatus(
34
+ currentQbDataContext.storage.CONNECTION_REPOSITORY.isChatConnected(),
35
+ );
21
36
  };
22
37
 
23
38
  window.addEventListener('online', setOnline);
@@ -32,6 +47,7 @@ const useQBConnection = (): QBConnectionInfo => {
32
47
  return {
33
48
  browserOnline: navigatorOnline,
34
49
  connectionRepository: currentQbDataContext.storage.CONNECTION_REPOSITORY,
50
+ connectionStatus: connectStatus,
35
51
  };
36
52
  };
37
53
 
@@ -11,6 +11,17 @@
11
11
  position: fixed;
12
12
  background-color: rgba(19, 29, 40, 0.8);
13
13
 
14
+ &--disable {
15
+ position: absolute;
16
+ top: 0;
17
+ left: 0;
18
+ width: 100%;
19
+ height: 100%;
20
+ background-color: rgba(0, 0, 0, 0.5);
21
+ z-index: 100;
22
+ display: block;
23
+ }
24
+
14
25
  &__content {
15
26
  width: 380px;
16
27
  position: absolute;
@@ -1,4 +1,4 @@
1
- import { ReactElement } from 'react';
1
+ import React, { ReactElement } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
  import cn from 'classnames';
4
4
 
@@ -12,6 +12,7 @@ interface DialogWindowProps {
12
12
  children: ReactElement | ReactElement[];
13
13
  onClose?: VoidFunction;
14
14
  className?: string;
15
+ disableActions?: boolean;
15
16
  }
16
17
 
17
18
  export default function DialogWindow({
@@ -20,11 +21,13 @@ export default function DialogWindow({
20
21
  open = false,
21
22
  title,
22
23
  className,
24
+ disableActions = false,
23
25
  }: DialogWindowProps) {
24
26
  if (!open) return null;
25
27
 
26
28
  return createPortal(
27
29
  <div className={cn('dialog-window', className)}>
30
+ <div className={cn('', { 'dialog-window--disable': disableActions })} />
28
31
  <div className="dialog-window__content">
29
32
  <Header
30
33
  className="dialog-window__header"
@@ -67,6 +67,10 @@
67
67
  padding: 4px 16px;
68
68
 
69
69
  cursor: pointer;
70
+
71
+ &--disabled {
72
+ color: var(--caption);
73
+ }
70
74
  }
71
75
 
72
76
  &__label {
@@ -65,7 +65,6 @@ export default function Dropdown({
65
65
  <div ref={dropdownRef} className={cn('dropdown', className)}>
66
66
  <button
67
67
  type="button"
68
- disabled={disabled}
69
68
  className="dropdown__toggle"
70
69
  onClick={handleToggleOpen}
71
70
  >
@@ -80,6 +79,7 @@ export default function Dropdown({
80
79
  <DropdownOption
81
80
  label={label}
82
81
  value={value}
82
+ disabled={disabled}
83
83
  onSelect={handleSelect}
84
84
  leftIcon={leftIcon}
85
85
  rightIcon={rightIcon}
@@ -1,8 +1,10 @@
1
1
  import { ReactElement } from 'react';
2
+ import cn from 'classnames';
2
3
 
3
4
  export interface Option {
4
5
  value: string;
5
6
  label: string;
7
+ disabled?: boolean;
6
8
  leftIcon?: ReactElement;
7
9
  rightIcon?: ReactElement;
8
10
  }
@@ -14,12 +16,18 @@ interface DropdownOptionProps extends Option {
14
16
  export default function DropdownOption({
15
17
  label,
16
18
  value,
19
+ disabled,
17
20
  leftIcon,
18
21
  rightIcon,
19
22
  onSelect,
20
23
  }: DropdownOptionProps) {
21
24
  return (
22
- <li className="dropdown__option" onClick={() => onSelect(value)}>
25
+ <li
26
+ className={cn('dropdown__option', {
27
+ 'dropdown__option--disabled': disabled,
28
+ })}
29
+ onClick={() => !disabled && onSelect(value)}
30
+ >
23
31
  <span className="dropdown__label">
24
32
  {leftIcon}
25
33
  {label}
@@ -3,11 +3,13 @@ import React from 'react';
3
3
  type AttachmentMessageProps = {
4
4
  icon: React.ReactNode;
5
5
  onChangeFile: (event: React.ChangeEvent<HTMLInputElement>) => void;
6
+ disableAction: boolean;
6
7
  };
7
8
  // eslint-disable-next-line react/function-component-definition
8
9
  const AttachmentUploader: React.FC<AttachmentMessageProps> = ({
9
10
  icon,
10
11
  onChangeFile,
12
+ disableAction,
11
13
  }: AttachmentMessageProps) => {
12
14
  return (
13
15
  <label
@@ -25,6 +27,7 @@ const AttachmentUploader: React.FC<AttachmentMessageProps> = ({
25
27
  onChange={(event) => {
26
28
  onChangeFile(event);
27
29
  }}
30
+ disabled={disableAction}
28
31
  />
29
32
  </label>
30
33
  );
@@ -3,12 +3,19 @@ $message-view-container-chat-input-min-height: 54px;
3
3
  .chat-container{
4
4
  width: 100%;
5
5
  &__icon{
6
- width: 32px;
7
- height: 32px;
8
- fill: var(--input-elements);
6
+ width: 24px;
7
+ height: 24px;
8
+ cursor: pointer;
9
+ fill: var(--secondary-elements);
10
+ &__send {
11
+ width: 24px;
12
+ height: 24px;
13
+ cursor: pointer;
14
+ fill: var(--main-elements);
15
+ }
9
16
 
10
17
  svg path{
11
- fill: var(--input-elements);
18
+ fill: var(--main-elements);
12
19
  }
13
20
  }
14
21
  &__icon--mute{
@@ -17,6 +24,13 @@ $message-view-container-chat-input-min-height: 54px;
17
24
  fill: var(--disabled-elements);
18
25
  }
19
26
  }
27
+ &__icon--disable{
28
+ fill: var(--disabled-elements);
29
+ cursor: default;
30
+ svg path{
31
+ fill: var(--disabled-elements);
32
+ }
33
+ }
20
34
  &__icon--red{
21
35
  fill: var(--error);
22
36
  svg path{