quickblox-react-ui-kit 0.3.0-beta.3 → 0.3.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.
Files changed (121) 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 +776 -710
  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 +2 -2
  30. package/src/App.scss +3 -0
  31. package/src/Data/Creator.ts +1 -2
  32. package/src/Data/Stubs.ts +4 -5
  33. package/src/Data/dto/file/RemoteFileDTO.ts +2 -2
  34. package/src/Data/dto/message/RemoteMessageDTO.ts +1 -1
  35. package/src/Data/dto/user/LocalUserDTO.ts +2 -2
  36. package/src/Data/dto/user/RemoteUserDTO.ts +4 -4
  37. package/src/Data/mapper/FileRemoteDTOMapper.ts +8 -6
  38. package/src/Data/mapper/MessageRemoteDTOMapper.ts +1 -1
  39. package/src/Data/mapper/UserLocalDTOMapper.ts +2 -2
  40. package/src/Data/mapper/UserRemoteDTOMapper.ts +2 -2
  41. package/src/Data/repository/MessagesRepository.ts +2 -2
  42. package/src/Data/repository/UsersRepository.ts +1 -1
  43. package/src/Data/source/remote/Mapper/FileDTOMapper.ts +23 -23
  44. package/src/Data/source/remote/Mapper/MessageDTOMapper.ts +2 -2
  45. package/src/Data/source/remote/Mapper/UserDTOMapper.ts +0 -2
  46. package/src/Data/source/remote/RemoteDataSource.ts +50 -8
  47. package/src/Domain/entity/FileEntity.ts +1 -1
  48. package/src/Domain/entity/UserEntity.ts +1 -11
  49. package/src/Domain/use_cases/UpdateDialogUseCase.ts +6 -1
  50. package/src/Domain/use_cases/base/Subscribable/SubscriptionPerformer.ts +1 -1
  51. package/src/Presentation/Views/Dialog/AIComponents/AIAssist/AIAssist.scss +5 -0
  52. package/src/Presentation/Views/Dialog/AIComponents/AIAssist/AIAssist.tsx +9 -2
  53. package/src/Presentation/Views/Dialog/AIComponents/AITranslate/AITranslate.scss +10 -0
  54. package/src/Presentation/Views/Dialog/AIComponents/AITranslate/AITranslate.tsx +16 -7
  55. package/src/Presentation/Views/Dialog/AIWidgets/AIRephraseWidget/AIRephraseWidget.scss +7 -2
  56. package/src/Presentation/Views/Dialog/AIWidgets/AIRephraseWidget/AIRephraseWidget.tsx +12 -3
  57. package/src/Presentation/Views/Dialog/ForwardMessageFlow/DialogsWithSearch/DialogListItem/DialogListItem.scss +1 -1
  58. package/src/Presentation/Views/Dialog/ForwardMessageFlow/ForwardMessageFlow.tsx +9 -5
  59. package/src/Presentation/Views/Dialog/ForwardMessageFlow/InputForForwarding/InputForForwarding.scss +31 -1
  60. package/src/Presentation/Views/Dialog/ForwardMessageFlow/InputForForwarding/InputForForwarding.tsx +7 -7
  61. package/src/Presentation/Views/Dialog/MessageContextMenu/MessageContextMenu.tsx +17 -6
  62. package/src/Presentation/Views/Dialog/MessageItem/MessageItem.tsx +6 -0
  63. package/src/Presentation/Views/Dialog/useDialogViewModel.ts +1 -0
  64. package/src/Presentation/Views/DialogInfo/DialogInfo.scss +11 -1
  65. package/src/Presentation/Views/DialogInfo/DialogInfo.tsx +36 -18
  66. package/src/Presentation/Views/DialogInfo/UsersList/useUsersListViewModel.ts +1 -0
  67. package/src/Presentation/Views/DialogList/DialogList.scss +5 -0
  68. package/src/Presentation/Views/DialogList/DialogList.tsx +12 -2
  69. package/src/Presentation/Views/DialogList/useDialogListViewModel.ts +33 -16
  70. package/src/Presentation/Views/EditDialog/EditDialog.scss +11 -0
  71. package/src/Presentation/Views/EditDialog/EditDialog.tsx +9 -1
  72. package/src/Presentation/Views/Flow/CreateDialogFlow/CreateNewDialogFlow.tsx +14 -0
  73. package/src/Presentation/Views/InviteMembers/useInviteMembersViewModel.ts +1 -11
  74. package/src/Presentation/Views/PreviewDialog/PreviewDialog.tsx +4 -0
  75. package/src/Presentation/icons/media/video-file.svg +2 -2
  76. package/src/Presentation/layouts/Desktop/QuickBloxUIKitDesktopLayout.tsx +426 -499
  77. package/src/Presentation/providers/QuickBloxUIKitProvider/useQBConnection.ts +16 -0
  78. package/src/Presentation/ui-components/DialogWindow/DialogWindow.scss +11 -0
  79. package/src/Presentation/ui-components/DialogWindow/DialogWindow.tsx +4 -1
  80. package/src/Presentation/ui-components/Dropdown/Dropdown.scss +4 -0
  81. package/src/Presentation/ui-components/Dropdown/Dropdown.tsx +1 -1
  82. package/src/Presentation/ui-components/Dropdown/DropdownOption.tsx +9 -1
  83. package/src/Presentation/ui-components/MessageInput/AttachmentUploader/AttachmentUploader.tsx +3 -0
  84. package/src/Presentation/ui-components/MessageInput/MessageInput.scss +18 -4
  85. package/src/Presentation/ui-components/MessageInput/MessageInput.tsx +8 -2
  86. package/src/Presentation/ui-components/PreviewFileMessage/PreviewFileMessage.tsx +2 -2
  87. package/src/Presentation/ui-components/SettingsItem/SettingsItem.stories.tsx +2 -0
  88. package/src/index.scss +5 -2
  89. package/src/qb-api-calls/index.ts +58 -49
  90. package/storybook-static/758.53b4954a.iframe.bundle.js +14 -0
  91. package/storybook-static/{758.e75a5a47.iframe.bundle.js.map → 758.53b4954a.iframe.bundle.js.map} +1 -1
  92. 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
  93. package/storybook-static/Presentation-ui-components-DialogWindow-DialogWindow-stories.cf340397.iframe.bundle.js +1 -0
  94. 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
  95. package/storybook-static/Presentation-ui-components-MessageInput-MessageInput-stories.c2ead6a5.iframe.bundle.js +1 -0
  96. 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
  97. package/storybook-static/Presentation-ui-components-SettingsItem-SettingsItem-stories.2ff75703.iframe.bundle.js +1 -0
  98. package/storybook-static/{docs-Introduction-mdx.ac401482.iframe.bundle.js → docs-Introduction-mdx.bcb06844.iframe.bundle.js} +2 -2
  99. package/storybook-static/{docs-Introduction-mdx.ac401482.iframe.bundle.js.map → docs-Introduction-mdx.bcb06844.iframe.bundle.js.map} +1 -1
  100. package/storybook-static/iframe.html +2 -2
  101. package/storybook-static/project.json +1 -1
  102. package/storybook-static/{runtime~main.e945879b.iframe.bundle.js → runtime~main.7ee2126e.iframe.bundle.js} +1 -1
  103. 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
  104. 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
  105. 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
  106. package/storybook-static/static/css/Presentation-ui-components-DialogWindow-DialogWindow-stories.4f813450.chunk.css.map +1 -0
  107. 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
  108. package/storybook-static/static/css/Presentation-ui-components-Dropdown-Dropdown-stories.e37f549d.chunk.css.map +1 -0
  109. 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
  110. package/storybook-static/static/css/Presentation-ui-components-MessageInput-MessageInput-stories.7eb916fc.chunk.css.map +1 -0
  111. package/storybook-static/static/css/{main.6fa55a2c.css → main.a921485c.css} +2 -2
  112. package/storybook-static/static/css/{main.6fa55a2c.css.map → main.a921485c.css.map} +1 -1
  113. package/storybook-static/static/media/video-file.dbd1f8c63a3769f9e9a027f0922d56b2.svg +3 -0
  114. package/storybook-static/758.e75a5a47.iframe.bundle.js +0 -14
  115. package/storybook-static/Presentation-ui-components-DialogWindow-DialogWindow-stories.3523a670.iframe.bundle.js +0 -1
  116. package/storybook-static/Presentation-ui-components-MessageInput-MessageInput-stories.262a0cf2.iframe.bundle.js +0 -1
  117. package/storybook-static/Presentation-ui-components-SettingsItem-SettingsItem-stories.8f6fca84.iframe.bundle.js +0 -1
  118. package/storybook-static/static/css/Presentation-ui-components-DialogWindow-DialogWindow-stories.6fb3af8d.chunk.css.map +0 -1
  119. package/storybook-static/static/css/Presentation-ui-components-Dropdown-Dropdown-stories.66965d64.chunk.css.map +0 -1
  120. package/storybook-static/static/css/Presentation-ui-components-MessageInput-MessageInput-stories.0e99d80b.chunk.css.map +0 -1
  121. package/storybook-static/static/media/video-file.dc2971be489b2af7b1c04dcc55bfe881.svg +0 -3
@@ -41,8 +41,6 @@ import { useMobileLayout } from '../../components/containers/SectionList/hooks';
41
41
  import { MessageDTOMapper } from '../../../Data/source/remote/Mapper/MessageDTOMapper';
42
42
  import MembersList from '../../Views/DialogInfo/MembersList/MembersList';
43
43
  import useUsersListViewModel from '../../Views/DialogInfo/UsersList/useUsersListViewModel';
44
- import { GetUserNameFct } from '../../Views/Dialog/Message/IncomingMessage/IncomingMessage';
45
- import { UserEntity } from '../../../Domain/entity/UserEntity';
46
44
  import Header from '../../ui-components/Header/Header';
47
45
  import Avatar from '../../ui-components/Avatar/Avatar';
48
46
  import {
@@ -81,57 +79,36 @@ const QuickBloxUIKitDesktopLayout: React.FC<
81
79
  // eslint-disable-next-line @typescript-eslint/no-unused-vars,react/function-component-definition
82
80
  > = ({
83
81
  theme = undefined,
84
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
85
82
  AITranslate = undefined,
86
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
87
83
  AIRephrase = undefined,
88
84
  AIAssist = undefined,
89
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
90
85
  uikitHeightOffset = '0px',
91
86
  }: QuickBloxUIKitDesktopLayoutProps) => {
92
- console.log('create QuickBloxUIKitDesktopLayout');
93
- const [forwardMessage, setForwardMessage] = useState<null | MessageEntity>();
94
- const forwardMessageModal = useModal();
95
- const [selectedDialog, setSelectedDialog] = React.useState<DialogEntity>();
87
+ const mimeType = 'audio/webm;codecs=opus'; // audio/ogg audio/mpeg audio/webm audio/x-wav audio/mp4
88
+ const messagePerPage = 47;
96
89
 
97
90
  const currentContext = useQbInitializedDataContext();
98
91
  const QBConfig =
99
92
  currentContext.InitParams.qbConfig ||
100
93
  DefaultConfigurations.getDefaultQBConfig();
101
- // const eventMessaging = useEventMessagesRepository();
102
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
103
- // @ts-ignore
104
94
  const userName =
105
95
  currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.userName;
106
96
  const currentUserId =
107
97
  currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.userId;
108
98
  const sessionToken =
109
99
  currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.sessionToken;
100
+ const { enableForwarding } = QBConfig.appConfig;
101
+ const { enableReplying } = QBConfig.appConfig;
102
+ const { maxFileSize } = currentContext.InitParams;
110
103
 
111
- const dialogsViewModel: DialogListViewModel =
112
- useDialogListViewModel(currentContext);
113
-
114
- // must re-create as result dialog changing
115
- const messagesViewModel: DialogViewModel = useDialogViewModel(
116
- dialogsViewModel.entity?.type,
117
- dialogsViewModel.entity,
118
- );
119
-
120
- const { connectionRepository, browserOnline } = useQBConnection();
121
- const [isOnline, setIsOnline] = useState<boolean>(browserOnline);
104
+ const maxTokensForAIRephrase =
105
+ currentContext.InitParams.qbConfig.configAIApi.AIRephraseWidgetConfig
106
+ .maxTokens;
122
107
 
123
- useEffect(() => {
124
- if (
125
- isOnline === false ||
126
- connectionRepository.isChatConnected() === false
127
- ) {
128
- setIsOnline(false);
129
- } else {
130
- setIsOnline(true);
131
- }
132
- }, [browserOnline, connectionRepository.isChatConnected()]);
108
+ const rephraseTones: Tone[] =
109
+ currentContext.InitParams.qbConfig.configAIApi.AIRephraseWidgetConfig.Tones;
133
110
 
134
- let defaultAIRephraseWidget = AIRephrase?.AIWidget; // useDefaultTextInputWidget();
111
+ let defaultAIRephraseWidget = AIRephrase?.AIWidget;
135
112
  let defaultAITranslateWidget = AITranslate?.AIWidget;
136
113
  let defaultAIAssistWidget = AIAssist?.AIWidget;
137
114
 
@@ -244,32 +221,101 @@ const QuickBloxUIKitDesktopLayout: React.FC<
244
221
  getAITranslate();
245
222
  getAIRephrase();
246
223
  getAIAssistAnswer();
224
+ const dialogsViewModel: DialogListViewModel =
225
+ useDialogListViewModel(currentContext);
247
226
 
248
- const { enableForwarding } = QBConfig.appConfig;
249
- const { enableReplying } = QBConfig.appConfig;
227
+ const messagesViewModel: DialogViewModel = useDialogViewModel(
228
+ dialogsViewModel.entity?.type,
229
+ dialogsViewModel.entity,
230
+ );
250
231
 
251
- const selectDialogActions = (item: BaseViewModel<DialogEntity>): void => {
252
- if (!dialogsViewModel.loading) {
253
- setSelectedDialog(item.entity);
254
- // dialogsViewModel.entity = item.entity;
255
- }
256
- };
232
+ const [forwardMessage, setForwardMessage] = useState<null | MessageEntity>();
233
+ const forwardMessageModal = useModal();
234
+ const [selectedDialog, setSelectedDialog] = React.useState<DialogEntity>();
235
+ const userViewModel = useUsersListViewModel(selectedDialog);
236
+ const [dialogAvatarUrl, setDialogAvatarUrl] = React.useState('');
237
+
238
+ const { browserOnline, connectionStatus, connectionRepository } =
239
+ useQBConnection();
240
+
241
+ const [isOnline, setIsOnline] = useState<boolean>(
242
+ browserOnline && connectionStatus,
243
+ );
244
+
245
+ connectionRepository.subscribe((status) => {
246
+ console.log(`Connection status: ${status ? 'CONNECTED' : 'DISCONNECTED'}`);
247
+ if (status) setIsOnline(true);
248
+ else setIsOnline(false);
249
+ });
250
+
251
+ const [needRefresh, setNeedRefresh] = useState(false);
252
+ const toastConnectionErrorId = React.useRef(null);
253
+
254
+ //
255
+ const [waitAIWidget, setWaitAIWidget] = useState<boolean>(false);
256
+ const [messageText, setMessageText] = useState<string>('');
257
257
 
258
258
  const [showReplyMessage, setShowReplyMessage] = useState(false);
259
259
  const [messagesToReply, setMessagesToReply] = useState<MessageEntity[]>([]);
260
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
260
261
  const [isMobile, width, height, breakpoint] = useMobileLayout();
261
262
  const [clientHeight, setClientHeight] = useState<number>(0);
262
263
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
263
264
  const [scrollUpToDown, setScrollUpToDown] = React.useState(false);
265
+ const [needDialogInformation, setNeedDialogInformation] = useState(false);
266
+ const informationCloseHandler = (): void => {
267
+ setNeedDialogInformation(false);
268
+ };
269
+ const informationOpenHandler = (): void => {
270
+ setNeedDialogInformation(true);
271
+ };
272
+ //
273
+ const maxWidthToResizing =
274
+ selectedDialog && needDialogInformation
275
+ ? '$message-view-container-wrapper-min-width'
276
+ : '1040px';
277
+ const workHeight = isMobile
278
+ ? `calc(${height.toString()}px - ${uikitHeightOffset} - 28px)`
279
+ : `calc(100vh - ${uikitHeightOffset} - 28px)`;
280
+ const messagesContainerMobileHeight = showReplyMessage
281
+ ? `calc(${clientHeight}px - 128px - 64px - 16px)`
282
+ : `calc(${clientHeight}px - 128px - 16px)`;
283
+ const messagesContainerHeight = showReplyMessage
284
+ ? `calc(${clientHeight}px - 128px - 64px)`
285
+ : `calc(${clientHeight}px - 128px - 1px)`;
286
+ const clientContainerHeight = `${clientHeight - 5}px`;
287
+ const headerHeight = 64;
288
+ const dialogListScrollableHeight = clientHeight - headerHeight - 6;
289
+
290
+ const [warningErrorText, setWarningErrorText] = useState<string>('');
291
+ const [useAudioWidget, setUseAudioWidget] = useState<boolean>(false);
292
+ const [fileToSend, setFileToSend] = useState<File | null>(null);
293
+ const [isRecording, setIsRecording] = useState(false);
294
+ const [permission, setPermission] = useState(false);
295
+ const [stream, setStream] = useState<MediaStream>();
296
+ const mediaRecorder = useRef<MediaRecorder>();
297
+ const [resultAudioBlob, setResultAudioBlob] = useState<Blob>();
298
+ const [audioChunks, setAudioChunks] = useState<Array<Blob>>([]);
299
+ const newModal = useModal();
300
+ const [dialogToLeave, setDialogToLeave] = useState<DialogEntity>();
301
+ const [showDialogList, setShowDialogList] = useState<boolean>(true);
302
+ const [showDialogMessages, setShowDialogMessages] = useState<boolean>(true);
303
+ const [showDialogInformation, setShowDialogInformation] =
304
+ useState<boolean>(false);
305
+ const [isAllMembersShow, setIsAllMembersShow] = React.useState(false);
306
+ const [isOpen, setIsOpen] = useState(false);
307
+
308
+ // functions
264
309
 
265
- // const [dialogMessagesCount, setDialogMessageCount] = useState(100);
266
- // const [hasMore, setHasMore] = React.useState(true);
267
- // const [messagesToView, setMessagesToView] = React.useState<MessageEntity[]>(
268
- // [],
269
- // );
310
+ const selectDialogActions = (item: BaseViewModel<DialogEntity>): void => {
311
+ if (isOnline) {
312
+ if (!dialogsViewModel.loading) {
313
+ setSelectedDialog(item.entity);
314
+ // dialogsViewModel.entity = item.entity;
315
+ }
316
+ }
317
+ };
270
318
 
271
- // инициализация СДК и загрузка тестовых данных, запуск пинга - может не быть
272
- // todo: добавить метод в контекст
273
319
  const isAuthProcessed = (): boolean => {
274
320
  console.log('call isAuthProcessed');
275
321
  const result =
@@ -294,106 +340,6 @@ const QuickBloxUIKitDesktopLayout: React.FC<
294
340
  return result;
295
341
  };
296
342
 
297
- useEffect(() => {
298
- const codeVersion = '0.3.0';
299
-
300
- console.log(`React UIKit CODE VERSION IS ${codeVersion}`);
301
- console.log('TestStage: GET DATA ');
302
- console.log(
303
- `auth data: ${JSON.stringify(
304
- currentContext.InitParams.loginData,
305
- )} at ${new Date().toLocaleTimeString()}`,
306
- );
307
- if (isAuthProcessed()) {
308
- console.log('auth is completed, CAN GET DATA');
309
- const pagination: Pagination = new Pagination();
310
-
311
- dialogsViewModel?.getDialogs(pagination);
312
- }
313
-
314
- return () => {
315
- console.log('TestStage: USE EFFECT release');
316
- dialogsViewModel.release();
317
- };
318
- }, []);
319
-
320
- useEffect(() => {
321
- console.log('TestStage: GET DATA AFTER User data has CHANGED');
322
- console.log(
323
- `auth is ${JSON.stringify(
324
- currentContext.InitParams.loginData,
325
- )} at ${new Date().toLocaleTimeString()}`,
326
- );
327
-
328
- if (isAuthProcessed()) {
329
- console.log('auth is completed, FETCH DATA');
330
- const pagination: Pagination = new Pagination();
331
-
332
- dialogsViewModel?.getDialogs(pagination);
333
- }
334
- }, [currentContext.InitParams]);
335
-
336
- // const fetchMoreData = () => {
337
- // if (messagesToView.length >= dialogMessagesCount) {
338
- // setHasMore(false);
339
- //
340
- // return;
341
- // }
342
- // if (
343
- // hasMore &&
344
- // messagesToView.length > 0 &&
345
- // messagesToView.length < dialogMessagesCount
346
- // ) {
347
- // setMessagesToView((prevState) => {
348
- // const newState = [...prevState];
349
- //
350
- // const newMessageEntity: MessageEntity =
351
- // messagesViewModel.messages[prevState.length];
352
- //
353
- // newState.push(newMessageEntity);
354
- // // newState.unshift(newMessageEntity);
355
- //
356
- // return newState;
357
- // });
358
- // }
359
- // };
360
-
361
- // function prepareFirstPage(initData: MessageEntity[]) {
362
- // const firstPageSize = messagesViewModel.messages.length;
363
- //
364
- // for (let i = firstPageSize - 1; i >= 0; i -= 1) {
365
- // initData.push(messagesViewModel.messages[i]);
366
- // }
367
- // }
368
-
369
- //
370
- // useEffect(() => {
371
- // setDialogMessageCount(messagesViewModel?.messages?.length || 0);
372
- // if (messagesToView?.length === 0 && messagesViewModel.messages.length > 0) {
373
- // const initData: MessageEntity[] = [];
374
- //
375
- // console.log(JSON.stringify(messagesViewModel.messages));
376
- // prepareFirstPage(initData);
377
- // setMessagesToView(initData);
378
- // } else if (messagesViewModel.messages.length - messagesToView.length >= 1) {
379
- // setHasMore(true);
380
- // setScrollUpToDown(true);
381
- // }
382
- // }, [messagesViewModel.messages]);
383
- //
384
- // useEffect(() => {
385
- // if (messagesViewModel.messages.length - messagesToView.length >= 1) {
386
- // fetchMoreData();
387
- // }
388
- // }, [dialogMessagesCount]);
389
- const messagePerPage = 47;
390
-
391
- useEffect(() => {
392
- if (messagesViewModel.entity) {
393
- messagesViewModel.getMessages(new Pagination(0, messagePerPage));
394
- }
395
- }, [messagesViewModel.entity]);
396
-
397
343
  const fetchMoreData = () => {
398
344
  if (messagesViewModel.pagination.hasNextPage()) {
399
345
  const newPagination = messagesViewModel.pagination;
@@ -405,8 +351,6 @@ const QuickBloxUIKitDesktopLayout: React.FC<
405
351
  }
406
352
  };
407
353
 
408
- const userViewModel = useUsersListViewModel(selectedDialog);
409
- const [dialogAvatarUrl, setDialogAvatarUrl] = React.useState('');
410
354
  const getUserAvatarByUid = async () => {
411
355
  let result = '';
412
356
  const participants: Array<number> =
@@ -432,15 +376,6 @@ const QuickBloxUIKitDesktopLayout: React.FC<
432
376
  }
433
377
  }
434
378
 
435
- useEffect(() => {
436
- getDialogPhotoFileForPreview();
437
-
438
- return () => {
439
- if (dialogAvatarUrl) {
440
- URL.revokeObjectURL(dialogAvatarUrl);
441
- }
442
- };
443
- }, [dialogsViewModel.entity]);
444
379
  // eslint-disable-next-line consistent-return
445
380
  const renderIconForTypeDialog = (dialogEntity: DialogEntity) => {
446
381
  if (dialogEntity.type === DialogType.group) {
@@ -470,62 +405,6 @@ const QuickBloxUIKitDesktopLayout: React.FC<
470
405
  }
471
406
  };
472
407
 
473
- useEffect(() => {
474
- console.log(
475
- `Clear selected dialog: ${
476
- selectedDialog?.name || 'Dialog Name is empty'
477
- }`,
478
- );
479
- if (!dialogsViewModel.entity) {
480
- setSelectedDialog(undefined);
481
- }
482
- }, [dialogsViewModel.entity]);
483
-
484
- const [needDialogInformation, setNeedDialogInformation] = useState(false);
485
- const informationCloseHandler = (): void => {
486
- setNeedDialogInformation(false);
487
- };
488
- const informationOpenHandler = (): void => {
489
- setNeedDialogInformation(true);
490
- };
491
- //
492
- const maxTokensForAIRephrase =
493
- currentContext.InitParams.qbConfig.configAIApi.AIRephraseWidgetConfig
494
- .maxTokens;
495
-
496
- const rephraseTones: Tone[] =
497
- currentContext.InitParams.qbConfig.configAIApi.AIRephraseWidgetConfig.Tones;
498
-
499
- const { maxFileSize } = currentContext.InitParams;
500
- //
501
- const [waitAIWidget, setWaitAIWidget] = useState<boolean>(false);
502
- const [messageText, setMessageText] = useState<string>('');
503
-
504
- const [warningErrorText, setWarningErrorText] = useState<string>('');
505
- // const [showErrorToast, setShowErrorToast] = useState<boolean>(false);
506
- // const [messageErrorToast, setMessageErrorToast] = useState<string>('');
507
-
508
- const [useAudioWidget, setUseAudioWidget] = useState<boolean>(false);
509
-
510
- const [fileToSend, setFileToSend] = useState<File | null>(null);
511
-
512
- const [isRecording, setIsRecording] = useState(false);
513
- //
514
- const [permission, setPermission] = useState(false);
515
-
516
- // const [recordingStatus, setRecordingStatus] = useState('inactive');
517
-
518
- const [stream, setStream] = useState<MediaStream>();
519
- // const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder>();
520
- const mediaRecorder = useRef<MediaRecorder>();
521
- const [resultAudioBlob, setResultAudioBlob] = useState<Blob>();
522
-
523
- const [audioChunks, setAudioChunks] = useState<Array<Blob>>([]);
524
-
525
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
526
- const mimeType = 'audio/webm;codecs=opus'; // audio/ogg audio/mpeg audio/webm audio/x-wav audio/mp4
527
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
528
-
529
408
  const showErrorMessage = (errorMessage: string) => {
530
409
  setWarningErrorText(errorMessage);
531
410
  setTimeout(() => {
@@ -561,41 +440,6 @@ const QuickBloxUIKitDesktopLayout: React.FC<
561
440
  });
562
441
  };
563
442
 
564
- useEffect(() => {
565
- const MAXSIZE = maxFileSize || 90 * 1000000;
566
- const MAXSIZE_FOR_MESSAGE = MAXSIZE / (1024 * 1024);
567
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
568
- const flag = fileToSend?.size && fileToSend?.size < MAXSIZE;
569
-
570
- if (fileToSend?.size && fileToSend?.size < MAXSIZE) {
571
- if (showReplyMessage && messagesToReply?.length > 0) {
572
- const replyData: ReplyMessagesParams = {
573
- messagesToReply,
574
- relatedFileMessage: fileToSend,
575
- relatedTextMessage:
576
- messageText || MessageDTOMapper.REPLY_MESSAGE_PREFIX,
577
- };
578
-
579
- repliedActions(replyData);
580
- } else {
581
- // eslint-disable-next-line promise/catch-or-return
582
- messagesViewModel
583
- .sendAttachmentMessage(fileToSend)
584
- .then((resultOperation) => {
585
- // eslint-disable-next-line promise/always-return
586
- if (!resultOperation) {
587
- toast(`Incorrect data`);
588
- }
589
- });
590
- }
591
- } else if (fileToSend) {
592
- toast(
593
- `file size ${fileToSend?.size} must be less then ${MAXSIZE_FOR_MESSAGE} mb.`,
594
- );
595
- }
596
- }, [fileToSend]);
597
-
598
- // const [isVoiceMessage, setVoiceMessage] = useState(true);
599
443
  const getMicrophonePermission = async () => {
600
444
  if (window) {
601
445
  try {
@@ -707,151 +551,51 @@ const QuickBloxUIKitDesktopLayout: React.FC<
707
551
  return resultFile;
708
552
  };
709
553
 
710
- useEffect(() => {
711
- const fileExt = 'mp4';
712
-
713
- if (resultAudioBlob) {
714
- const voiceMessage = blobToFile(
715
- resultAudioBlob,
716
- `${userName || ''}_voice_message.${fileExt}`,
717
- );
718
-
719
- setFileToSend(voiceMessage);
720
- if (useAudioWidget) {
721
- setUseAudioWidget(false);
722
- }
723
- //
724
- }
725
- }, [resultAudioBlob]);
726
-
727
- useEffect(() => {
728
- // setFileToSend(null);
729
- if (isRecording) {
730
- if (!permission) {
731
- // eslint-disable-next-line promise/catch-or-return,promise/always-return
732
- getMicrophonePermission().catch(() => {
733
- showErrorMessage(`Have no audio.`);
734
- });
735
- } else {
736
- // eslint-disable-next-line promise/catch-or-return,promise/always-return
737
- startRecording().then(() => {
738
- setWarningErrorText(`Your voice is recording during for 1 minutes`);
739
- });
740
- }
741
- } else {
742
- if (permission && mediaRecorder.current) {
743
- stopRecording();
744
- }
745
- setWarningErrorText('');
746
- }
747
- }, [isRecording]);
748
-
749
- useEffect(() => {
750
- if (isRecording && permission) {
751
- // eslint-disable-next-line promise/always-return,promise/catch-or-return
752
- startRecording().then(() => {
753
- setWarningErrorText(`Your voice is recording during for 1 minutes`);
754
- });
755
- }
756
- }, [permission]);
757
-
758
- useEffect(() => {
759
- setWaitAIWidget(false);
760
- if (
761
- defaultAIRephraseWidget?.textToContent &&
762
- defaultAIRephraseWidget?.textToContent.length > 0
763
- ) {
764
- setMessageText(defaultAIRephraseWidget?.textToContent);
765
- }
766
- }, [defaultAIRephraseWidget?.textToContent]);
767
-
768
- useEffect(() => {
769
- setWaitAIWidget(false);
770
- }, [defaultAITranslateWidget?.textToContent]);
771
-
772
- useEffect(() => {
773
- setWaitAIWidget(false);
774
- if (
775
- defaultAIAssistWidget?.textToContent &&
776
- defaultAIAssistWidget?.textToContent.length > 0
777
- ) {
778
- setMessageText(defaultAIAssistWidget?.textToContent);
779
- }
780
- }, [defaultAIAssistWidget?.textToContent]);
781
-
782
- //
783
-
784
554
  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
- };
555
+ if (isOnline) {
556
+ // closeReplyMessageFlowHandler
557
+ if (messagesViewModel?.loading) return;
558
+ // setVoiceMessage(true);
559
+ if (textToSend.length > 0 && textToSend.length <= 1000) {
560
+ setMessageText('');
561
+ if (showReplyMessage && messagesToReply?.length > 0) {
562
+ const replyData: ReplyMessagesParams = {
563
+ messagesToReply,
564
+ relatedTextMessage: textToSend,
565
+ };
795
566
 
796
- repliedActions(replyData);
797
- } else {
798
- messagesViewModel.sendTextMessage(textToSend);
567
+ repliedActions(replyData);
568
+ } else {
569
+ messagesViewModel.sendTextMessage(textToSend);
570
+ setMessageText('');
571
+ }
799
572
  setMessageText('');
573
+ } else {
574
+ setWarningErrorText(
575
+ 'length of text message must be less then 1000 chars.',
576
+ );
577
+ setTimeout(() => {
578
+ setWarningErrorText('');
579
+ }, 3000);
800
580
  }
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
581
  }
810
582
  }
811
- //
812
- useEffect(() => {
813
- messagesViewModel.entity = dialogsViewModel.entity;
814
- // setMessagesToView([]);
815
- setMessageText('');
816
- }, [dialogsViewModel.entity]);
817
-
818
- //
819
- useEffect(() => {
820
- if (!isMobile && messagesViewModel.entity) {
821
- dialogsViewModel.setWaitLoadingStatus(messagesViewModel?.loading);
822
- const timeoutId = setTimeout(() => {
823
- dialogsViewModel.setWaitLoadingStatus(false); // wait only for 3 sec
824
- }, 3000);
825
-
826
- return () => clearTimeout(timeoutId);
827
- }
828
-
829
- return () => {
830
- // Placeholder: Cleanup handler is not required
831
- };
832
- }, [messagesViewModel?.loading]);
833
- //
834
583
 
835
584
  const ChangeFileHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
836
- const reader = new FileReader();
837
- const file = event.currentTarget.files
838
- ? event.currentTarget.files[0]
839
- : null;
585
+ if (isOnline) {
586
+ const reader = new FileReader();
587
+ const file = event.currentTarget.files
588
+ ? event.currentTarget.files[0]
589
+ : null;
840
590
 
841
- reader.onloadend = () => {
842
- setFileToSend(file);
843
- };
591
+ reader.onloadend = () => {
592
+ setFileToSend(file);
593
+ };
844
594
 
845
- if (file !== null) reader.readAsDataURL(file);
595
+ if (file !== null) reader.readAsDataURL(file);
596
+ }
846
597
  };
847
598
 
848
- //
849
- //
850
- const maxWidthToResizing =
851
- selectedDialog && needDialogInformation
852
- ? '$message-view-container-wrapper-min-width'
853
- : '1040px';
854
-
855
599
  const handleOnReply = (message: MessageEntity): void => {
856
600
  setMessagesToReply([message]);
857
601
  setShowReplyMessage(true);
@@ -924,13 +668,107 @@ const QuickBloxUIKitDesktopLayout: React.FC<
924
668
  return sections;
925
669
  }
926
670
 
927
- const [showDialogList, setShowDialogList] = useState<boolean>(true);
928
- const [showDialogMessages, setShowDialogMessages] = useState<boolean>(true);
929
- const [showDialogInformation, setShowDialogInformation] =
930
- useState<boolean>(false);
671
+ const handleHeightChange = (newHeight: number) => {
672
+ console.log('The new height is:', newHeight);
673
+ setClientHeight(newHeight);
674
+ };
675
+
676
+ const leaveDialogHandler = (dialog: DialogEntity) => {
677
+ if (isOnline) {
678
+ setDialogToLeave(dialog);
679
+ }
680
+ };
681
+
682
+ const handleDialogOnClick = () => {
683
+ if (isOpen) {
684
+ setDialogToLeave(undefined);
685
+ }
686
+ setIsOpen((state) => !state);
687
+ };
688
+
689
+ const handleLeaveDialog = () => {
690
+ if (dialogToLeave) {
691
+ dialogsViewModel
692
+ .deleteDialog(dialogToLeave as GroupDialogEntity)
693
+ .then((result) => {
694
+ // eslint-disable-next-line promise/always-return
695
+ if (!result) {
696
+ toast('Dialog have not been left');
697
+ }
698
+ handleDialogOnClick();
699
+ })
700
+ .catch((e) => {
701
+ console.log(e);
702
+ toast("Can't leave dialog");
703
+ });
704
+ }
705
+ };
706
+ // // eslint-disable-next-line react/prop-types,@typescript-eslint/no-unused-vars
707
+ // const defaultGetSenderName: GetUserNameFct = async (props: {
708
+ // userId?: number;
709
+ // sender?: UserEntity;
710
+ // }): Promise<string | undefined> => {
711
+ // let result = 'undefined user';
931
712
  //
932
- const [isAllMembersShow, setIsAllMembersShow] = React.useState(false);
713
+ // // eslint-disable-next-line react/prop-types
714
+ // if (!props.sender) {
715
+ // // eslint-disable-next-line react/prop-types
716
+ // if (props.userId && props.userId > 0) {
717
+ // // eslint-disable-next-line react/prop-types,@typescript-eslint/no-unsafe-call
718
+ // const senderUser = await userViewModel.getUserById(props.userId);
719
+ //
720
+ // if (!senderUser) {
721
+ // return result;
722
+ // }
723
+ // result =
724
+ // senderUser.full_name ||
725
+ // senderUser.login ||
726
+ // senderUser.email ||
727
+ // // eslint-disable-next-line @typescript-eslint/no-unsafe-call
728
+ // senderUser.id.toString();
729
+ // } else return result;
730
+ // } else {
731
+ // result =
732
+ // // eslint-disable-next-line react/prop-types
733
+ // props.sender.full_name ||
734
+ // // eslint-disable-next-line react/prop-types
735
+ // props.sender.login ||
736
+ // // eslint-disable-next-line react/prop-types
737
+ // props.sender.email ||
738
+ // // eslint-disable-next-line react/prop-types
739
+ // props.sender.id.toString();
740
+ // }
741
+ //
742
+ // return result;
743
+ // };
744
+
745
+ const createDialogHandler = () => {
746
+ if (isOnline) {
747
+ newModal.toggleModal();
748
+ }
749
+ };
933
750
 
751
+ useEffect(() => {
752
+ const codeVersion = '0.3.0';
753
+
754
+ console.log(`React UIKit CODE VERSION IS ${codeVersion}`);
755
+ if (isAuthProcessed()) {
756
+ const pagination: Pagination = new Pagination();
757
+
758
+ dialogsViewModel?.getDialogs(pagination);
759
+ }
760
+
761
+ return () => {
762
+ dialogsViewModel.release();
763
+ };
764
+ }, []);
765
+ useEffect(() => {
766
+ if (isAuthProcessed()) {
767
+ const pagination: Pagination = new Pagination();
768
+
769
+ dialogsViewModel?.getDialogs(pagination);
770
+ }
771
+ }, [currentContext.InitParams]);
934
772
  useEffect(() => {
935
773
  if (isMobile) {
936
774
  if (!selectedDialog) {
@@ -955,16 +793,78 @@ const QuickBloxUIKitDesktopLayout: React.FC<
955
793
  setShowDialogInformation(true);
956
794
  }
957
795
  //
958
- const sizeChangingLogString = `SIZE INFO: height: ${height.toString()} clientHeight: ${clientHeight} width: ${width.toString()} breakpont: ${breakpoint.toString()} isMobile:
959
- ${isMobile?.toString()} selectedDialog:
960
- ${selectedDialog ? 'true' : 'false'} showDialogMessages:
961
- ${showDialogMessages?.toString()} showDialogList:
962
- ${showDialogList?.toString()} showDialogInformation:
963
- ${showDialogInformation?.toString()}`;
964
-
965
- console.log(sizeChangingLogString);
796
+ // const sizeChangingLogString = `SIZE INFO: height: ${height.toString()} clientHeight: ${clientHeight} width: ${width.toString()} breakpont: ${breakpoint.toString()} isMobile:
797
+ // ${isMobile?.toString()} selectedDialog:
798
+ // ${selectedDialog ? 'true' : 'false'} showDialogMessages:
799
+ // ${showDialogMessages?.toString()} showDialogList:
800
+ // ${showDialogList?.toString()} showDialogInformation:
801
+ // ${showDialogInformation?.toString()}`;
802
+ //
803
+ // console.log(sizeChangingLogString);
966
804
  }, [isMobile]);
805
+ useEffect(() => {
806
+ if (browserOnline) {
807
+ setIsOnline(true);
808
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/ban-ts-comment
809
+ // @ts-ignore
810
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
811
+ toast.dismiss(toastConnectionErrorId.current);
812
+ } else {
813
+ setIsOnline(false);
814
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/ban-ts-comment
815
+ // @ts-ignore
816
+ toastConnectionErrorId.current = toast('Connection ...', {
817
+ autoClose: false,
818
+ isLoading: true,
819
+ });
820
+ }
821
+ }, [browserOnline && connectionStatus]);
822
+ useEffect(() => {
823
+ if (!isOnline) {
824
+ setNeedRefresh(true);
825
+ }
826
+ }, [isOnline]);
827
+ useEffect(() => {
828
+ if (isOnline && needRefresh) {
829
+ if (messagesViewModel.entity) {
830
+ messagesViewModel.getMessages(new Pagination(0, messagePerPage));
831
+
832
+ setNeedRefresh(false);
833
+ }
834
+ }
835
+ }, [isOnline]);
836
+ useEffect(() => {
837
+ getDialogPhotoFileForPreview();
838
+ if (dialogsViewModel.entity) {
839
+ userViewModel.entity = dialogsViewModel.entity;
840
+ }
967
841
 
842
+ return () => {
843
+ if (dialogAvatarUrl) {
844
+ URL.revokeObjectURL(dialogAvatarUrl);
845
+ }
846
+ };
847
+ }, [dialogsViewModel.entity]);
848
+ useEffect(() => {
849
+ console.log(
850
+ `Clear selected dialog: ${
851
+ selectedDialog?.name || 'Dialog Name is empty'
852
+ }`,
853
+ );
854
+ if (!dialogsViewModel.entity) {
855
+ setSelectedDialog(undefined);
856
+ }
857
+ }, [dialogsViewModel.entity]);
858
+ useEffect(() => {
859
+ messagesViewModel.entity = dialogsViewModel.entity;
860
+ // setMessagesToView([]);
861
+ setMessageText('');
862
+ }, [dialogsViewModel.entity]);
863
+ useEffect(() => {
864
+ if (userViewModel.entity) {
865
+ userViewModel.getUsers();
866
+ }
867
+ }, [userViewModel.entity]);
968
868
  useEffect(() => {
969
869
  if (selectedDialog && selectedDialog) {
970
870
  dialogsViewModel.entity = selectedDialog;
@@ -978,13 +878,124 @@ const QuickBloxUIKitDesktopLayout: React.FC<
978
878
  setShowDialogList(true);
979
879
  }
980
880
  }, [selectedDialog]);
881
+ useEffect(() => {
882
+ if (messagesViewModel.entity) {
883
+ messagesViewModel.getMessages(new Pagination(0, messagePerPage));
884
+ }
885
+ }, [messagesViewModel.entity]);
886
+ useEffect(() => {
887
+ if (!isMobile && messagesViewModel.entity) {
888
+ dialogsViewModel.setWaitLoadingStatus(messagesViewModel?.loading);
889
+ const timeoutId = setTimeout(() => {
890
+ dialogsViewModel.setWaitLoadingStatus(false); // wait only for 3 sec
891
+ }, 3000);
981
892
 
893
+ return () => clearTimeout(timeoutId);
894
+ }
895
+
896
+ return () => {
897
+ // Placeholder: Cleanup handler is not required
898
+ };
899
+ }, [messagesViewModel?.loading]);
982
900
  useEffect(() => {
983
- if (userViewModel.entity) {
984
- userViewModel.getUsers();
901
+ const MAXSIZE = maxFileSize || 90 * 1000000;
902
+ const MAXSIZE_FOR_MESSAGE = MAXSIZE / (1024 * 1024);
903
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
904
+ const flag = fileToSend?.size && fileToSend?.size < MAXSIZE;
905
+
906
+ if (fileToSend?.size && fileToSend?.size < MAXSIZE) {
907
+ if (showReplyMessage && messagesToReply?.length > 0) {
908
+ const replyData: ReplyMessagesParams = {
909
+ messagesToReply,
910
+ relatedFileMessage: fileToSend,
911
+ relatedTextMessage:
912
+ messageText || MessageDTOMapper.REPLY_MESSAGE_PREFIX,
913
+ };
914
+
915
+ repliedActions(replyData);
916
+ } else if (isOnline) {
917
+ // eslint-disable-next-line promise/catch-or-return
918
+ messagesViewModel
919
+ .sendAttachmentMessage(fileToSend)
920
+ .then((resultOperation) => {
921
+ // eslint-disable-next-line promise/always-return
922
+ if (!resultOperation) {
923
+ toast(`Incorrect data`);
924
+ }
925
+ });
926
+ }
927
+ } else if (fileToSend) {
928
+ toast(
929
+ `file size ${fileToSend?.size} must be less then ${MAXSIZE_FOR_MESSAGE} mb.`,
930
+ );
985
931
  }
986
- }, [userViewModel.entity]);
932
+ }, [fileToSend]);
933
+ useEffect(() => {
934
+ const fileExt = 'mp4';
987
935
 
936
+ if (resultAudioBlob) {
937
+ const voiceMessage = blobToFile(
938
+ resultAudioBlob,
939
+ `${userName || ''}_voice_message.${fileExt}`,
940
+ );
941
+
942
+ setFileToSend(voiceMessage);
943
+ if (useAudioWidget) {
944
+ setUseAudioWidget(false);
945
+ }
946
+ //
947
+ }
948
+ }, [resultAudioBlob]);
949
+ useEffect(() => {
950
+ // setFileToSend(null);
951
+ if (isRecording) {
952
+ if (!permission) {
953
+ // eslint-disable-next-line promise/catch-or-return,promise/always-return
954
+ getMicrophonePermission().catch(() => {
955
+ showErrorMessage(`Have no audio.`);
956
+ });
957
+ } else {
958
+ // eslint-disable-next-line promise/catch-or-return,promise/always-return
959
+ startRecording().then(() => {
960
+ setWarningErrorText(`Your voice is recording during for 1 minutes`);
961
+ });
962
+ }
963
+ } else {
964
+ if (permission && mediaRecorder.current) {
965
+ stopRecording();
966
+ }
967
+ setWarningErrorText('');
968
+ }
969
+ }, [isRecording]);
970
+ useEffect(() => {
971
+ if (isRecording && permission) {
972
+ // eslint-disable-next-line promise/always-return,promise/catch-or-return
973
+ startRecording().then(() => {
974
+ setWarningErrorText(`Your voice is recording during for 1 minutes`);
975
+ });
976
+ }
977
+ }, [permission]);
978
+ useEffect(() => {
979
+ setWaitAIWidget(false);
980
+ if (
981
+ defaultAIRephraseWidget?.textToContent &&
982
+ defaultAIRephraseWidget?.textToContent.length > 0
983
+ ) {
984
+ setMessageText(defaultAIRephraseWidget?.textToContent);
985
+ }
986
+ }, [defaultAIRephraseWidget?.textToContent]);
987
+ useEffect(() => {
988
+ setWaitAIWidget(false);
989
+ }, [defaultAITranslateWidget?.textToContent]);
990
+ useEffect(() => {
991
+ setWaitAIWidget(false);
992
+ if (
993
+ defaultAIAssistWidget?.textToContent &&
994
+ defaultAIAssistWidget?.textToContent.length > 0
995
+ ) {
996
+ setMessageText(defaultAIAssistWidget?.textToContent);
997
+ }
998
+ }, [defaultAIAssistWidget?.textToContent]);
988
999
  useEffect(() => {
989
1000
  if (isMobile) {
990
1001
  if (needDialogInformation) {
@@ -996,108 +1007,15 @@ const QuickBloxUIKitDesktopLayout: React.FC<
996
1007
  }
997
1008
  }
998
1009
  }, [needDialogInformation]);
999
-
1000
- const handleHeightChange = (newHeight: number) => {
1001
- console.log('The new height is:', newHeight);
1002
- setClientHeight(newHeight);
1003
- };
1004
- const workHeight = isMobile
1005
- ? `calc(${height.toString()}px - ${uikitHeightOffset} - 28px)`
1006
- : `calc(100vh - ${uikitHeightOffset} - 28px)`;
1007
-
1008
- const [dialogToLeave, setDialogToLeave] = useState<DialogEntity>();
1009
- const leaveDialogHandler = (dialog: DialogEntity) => {
1010
- setDialogToLeave(dialog);
1011
- };
1012
-
1013
- const [isOpen, setIsOpen] = useState(false);
1014
-
1015
- const handleDialogOnClick = () => {
1016
- if (isOpen) {
1017
- setDialogToLeave(undefined);
1018
- }
1019
- setIsOpen((state) => !state);
1020
- };
1021
-
1022
1010
  useEffect(() => {
1023
1011
  if (dialogToLeave) {
1024
1012
  handleDialogOnClick();
1025
1013
  }
1026
1014
  }, [dialogToLeave]);
1027
1015
 
1028
- const handleLeaveDialog = () => {
1029
- if (dialogToLeave) {
1030
- dialogsViewModel
1031
- .deleteDialog(dialogToLeave as GroupDialogEntity)
1032
- .then((result) => {
1033
- // eslint-disable-next-line promise/always-return
1034
- if (!result) {
1035
- toast('Dialog have not been left');
1036
- }
1037
- handleDialogOnClick();
1038
- })
1039
- .catch((e) => {
1040
- console.log(e);
1041
- toast("Can't leave dialog");
1042
- });
1043
- }
1044
- };
1045
- // eslint-disable-next-line react/prop-types,@typescript-eslint/no-unused-vars
1046
- const defaultGetSenderName: GetUserNameFct = async (props: {
1047
- userId?: number;
1048
- sender?: UserEntity;
1049
- }): Promise<string | undefined> => {
1050
- let result = 'undefined user';
1051
-
1052
- // eslint-disable-next-line react/prop-types
1053
- if (!props.sender) {
1054
- // eslint-disable-next-line react/prop-types
1055
- if (props.userId && props.userId > 0) {
1056
- // eslint-disable-next-line react/prop-types,@typescript-eslint/no-unsafe-call
1057
- const senderUser = await userViewModel.getUserById(props.userId);
1058
-
1059
- if (!senderUser) {
1060
- return result;
1061
- }
1062
- result =
1063
- senderUser.full_name ||
1064
- senderUser.login ||
1065
- senderUser.email ||
1066
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
1067
- senderUser.id.toString();
1068
- } else return result;
1069
- } else {
1070
- result =
1071
- // eslint-disable-next-line react/prop-types
1072
- props.sender.full_name ||
1073
- // eslint-disable-next-line react/prop-types
1074
- props.sender.login ||
1075
- // eslint-disable-next-line react/prop-types
1076
- props.sender.email ||
1077
- // eslint-disable-next-line react/prop-types
1078
- props.sender.id.toString();
1079
- }
1080
-
1081
- return result;
1082
- };
1083
- const messagesContainerMobileHeight = showReplyMessage
1084
- ? `calc(${clientHeight}px - 128px - 64px - 16px)`
1085
- : `calc(${clientHeight}px - 128px - 16px)`;
1086
- const messagesContainerHeight = showReplyMessage
1087
- ? `calc(${clientHeight}px - 128px - 64px)`
1088
- : `calc(${clientHeight}px - 128px - 1px)`;
1089
- const clientContainerHeight = `${clientHeight - 5}px`;
1090
- const headerHeight = 64;
1091
- const dialogListScrollableHeight = clientHeight - headerHeight - 6;
1092
-
1093
- const newModal = useModal();
1094
-
1095
1016
  return (
1096
1017
  <ToastProvider>
1097
- <div>
1098
- {/* <div style={{ height: '18px', border: '1px solid red' }}> */}
1099
- {/* h:{height},w:{width},ch:{clientHeight},wh:{workHeight} */}
1100
- {/* </div> */}
1018
+ <div className="qb-uikit-layout">
1101
1019
  <DesktopLayout
1102
1020
  mainContainerStyles={{
1103
1021
  minHeight: workHeight,
@@ -1108,13 +1026,14 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1108
1026
  dialogsView={
1109
1027
  showDialogList ? (
1110
1028
  <DialogList
1029
+ disableAction={!isOnline}
1111
1030
  scrollableHeight={dialogListScrollableHeight}
1112
1031
  // subHeaderContent={<CompanyLogo />}
1113
1032
  // upHeaderContent={<CompanyLogo />}
1114
1033
  dialogListViewModel={dialogsViewModel} // 1 Get 2 Update UseCase
1115
1034
  selectedDialog={dialogsViewModel.entity}
1116
1035
  onDialogSelected={selectDialogActions}
1117
- onCreateDialog={() => newModal.toggleModal()}
1036
+ onCreateDialog={createDialogHandler}
1118
1037
  onLeaveDialog={leaveDialogHandler}
1119
1038
  additionalSettings={{
1120
1039
  withoutHeader: false,
@@ -1175,7 +1094,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1175
1094
  className="messages-container"
1176
1095
  onEndReached={fetchMoreData}
1177
1096
  onEndReachedThreshold={0.95}
1178
- refreshing={messagesViewModel?.loading}
1097
+ refreshing={needRefresh || messagesViewModel?.loading}
1179
1098
  renderSectionHeader={(section) => (
1180
1099
  <div className="message-view-container--system-message-wrapper">
1181
1100
  <div
@@ -1196,6 +1115,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1196
1115
  renderItem={([, groupMessages], listRef) =>
1197
1116
  groupMessages.map((message) => (
1198
1117
  <MessageItem
1118
+ disableAction={!isOnline}
1199
1119
  // defaultGetSenderName={defaultGetSenderName}
1200
1120
  message={message}
1201
1121
  currentUserId={currentUserId || -1}
@@ -1205,8 +1125,10 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1205
1125
  handleOnReply(m);
1206
1126
  }}
1207
1127
  onForward={(m: MessageEntity) => {
1208
- setForwardMessage(m);
1209
- forwardMessageModal.toggleModal();
1128
+ if (isOnline) {
1129
+ setForwardMessage(m);
1130
+ forwardMessageModal.toggleModal();
1131
+ }
1210
1132
  }}
1211
1133
  listRef={listRef}
1212
1134
  AIAssistWidget={defaultAIAssistWidget}
@@ -1233,6 +1155,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1233
1155
  }
1234
1156
  renderMessageInput={
1235
1157
  <MessageInput
1158
+ disableActions={!isOnline}
1236
1159
  previewMessage={
1237
1160
  showReplyMessage ? (
1238
1161
  <ReplyMessagePreview
@@ -1263,11 +1186,12 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1263
1186
  onAttachment={ChangeFileHandler}
1264
1187
  enableVoice={isRecording}
1265
1188
  onVoice={() => {
1266
- if (messagesViewModel?.loading) return;
1189
+ if (messagesViewModel?.loading || !isOnline) return;
1267
1190
  setIsRecording(!isRecording);
1268
1191
  }}
1269
1192
  rephrase={
1270
1193
  <AIRephraseWidget
1194
+ disableActions={!isOnline}
1271
1195
  waitAIWidget={waitAIWidget}
1272
1196
  messageText={messageText}
1273
1197
  theme={theme}
@@ -1321,6 +1245,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1321
1245
  />
1322
1246
  ) : (
1323
1247
  <DialogInfo
1248
+ disableAction={!isOnline}
1324
1249
  onShowAllMemberClick={(value: boolean) => {
1325
1250
  setIsAllMembersShow(value);
1326
1251
  }}
@@ -1368,6 +1293,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1368
1293
  onFinished={() => {
1369
1294
  newModal.toggleModal();
1370
1295
  }}
1296
+ isOnline={isOnline}
1371
1297
  />
1372
1298
  </DialogWindow>
1373
1299
  {selectedDialog && (
@@ -1382,6 +1308,7 @@ const QuickBloxUIKitDesktopLayout: React.FC<
1382
1308
  currentUserName={userName || ''}
1383
1309
  dialogs={dialogsViewModel.dialogs}
1384
1310
  onSendData={handleSendData}
1311
+ disableActions={!isOnline}
1385
1312
  />
1386
1313
  </DialogWindow>
1387
1314
  )}