quickblox-react-ui-kit 0.2.0 → 0.2.2

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 (114) hide show
  1. package/dist/CommonTypes/FunctionResult.d.ts +47 -0
  2. package/dist/Data/DefaultConfigurations.d.ts +7 -0
  3. package/dist/Data/Stubs.d.ts +1 -1
  4. package/dist/Data/source/AISource.d.ts +13 -0
  5. package/dist/Domain/entity/MessageEntity.d.ts +1 -1
  6. package/dist/Presentation/Views/Base/BaseViewModel.d.ts +10 -6
  7. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIMessageWidget.d.ts +16 -0
  8. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidgetActions/AIWidgetActions.d.ts +14 -0
  9. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/SliderMenu.d.ts +23 -0
  10. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/Tone.d.ts +15 -0
  11. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidget.d.ts +10 -0
  12. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIRephraseMessageWidget.d.ts +10 -0
  13. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAITranslateWidget.d.ts +10 -0
  14. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/useDefaultVoiceInputWidget.d.ts +2 -2
  15. package/dist/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.d.ts +2 -1
  16. package/dist/Presentation/components/UI/Dialogs/MessagesView/DropDownMenu/DropDownMenu.d.ts +26 -0
  17. package/dist/Presentation/components/UI/Dialogs/MessagesView/DropDownMenu/ItemDropDownMenu/ItemDropDownMenu.d.ts +11 -0
  18. package/dist/Presentation/components/UI/Dialogs/MessagesView/InComingMessage/AvatarContentIncomingUser/AvatarContentIncomingUser.d.ts +3 -0
  19. package/dist/Presentation/components/UI/Dialogs/MessagesView/InComingMessage/InComingMessage.d.ts +15 -0
  20. package/dist/Presentation/components/UI/Dialogs/MessagesView/MessagesView.d.ts +5 -5
  21. package/dist/Presentation/components/UI/Dialogs/MessagesView/OutGoingMessage/OutGoingMessage.d.ts +9 -0
  22. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/BookIcon/BookIcon.d.ts +3 -0
  23. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/HammerIcon/index.d.ts +3 -0
  24. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/HandshakeIcon/index.d.ts +3 -0
  25. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/MuscleIcon/index.d.ts +3 -0
  26. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/NecktieIcon/index.d.ts +3 -0
  27. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/NeutralFaceIcon/index.d.ts +3 -0
  28. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/PalmsUpTogetherIcon/index.d.ts +3 -0
  29. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/PerformingArtsIcon/index.d.ts +3 -0
  30. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/PointUpIcon/index.d.ts +3 -0
  31. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/SmileyIcon/index.d.ts +3 -0
  32. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/SmirkIcon/index.d.ts +3 -0
  33. package/dist/Presentation/components/UI/svgs/Icons/AIWidgets/WhiteCheckMarkIcon/index.d.ts +3 -0
  34. package/dist/Presentation/components/UI/svgs/Icons/Actions/AssistAnswer/index.d.ts +4 -0
  35. package/dist/Presentation/components/UI/svgs/Icons/Actions/Summarize/index.d.ts +4 -0
  36. package/dist/Presentation/components/UI/svgs/Icons/Actions/Tone/index.d.ts +4 -0
  37. package/dist/Presentation/components/UI/svgs/Icons/Media/Translate/index.d.ts +4 -0
  38. package/dist/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.d.ts +5 -5
  39. package/dist/Presentation/components/providers/QuickBloxUIKitProvider/QuickBloxUIKitProvider.d.ts +1 -1
  40. package/dist/QBconfig.d.ts +23 -0
  41. package/dist/index-ui.d.ts +5 -1
  42. package/dist/index-ui.js +361 -42
  43. package/global.d.ts +48 -6
  44. package/package.json +1 -1
  45. package/src/App.tsx +20 -14
  46. package/src/CommonTypes/FunctionResult.ts +54 -0
  47. package/src/Data/DefaultConfigurations.ts +197 -0
  48. package/src/Data/Stubs.ts +15 -15
  49. package/src/Data/mapper/MessageLocalDTOMapper.ts +3 -2
  50. package/src/Data/mapper/MessageRemoteDTOMapper.ts +3 -2
  51. package/src/Data/source/AISource.ts +133 -0
  52. package/src/Data/source/remote/Mapper/MessageDTOMapper.ts +3 -3
  53. package/src/Domain/entity/MessageEntity.ts +1 -1
  54. package/src/Presentation/Views/Base/BaseViewModel.ts +9 -4
  55. package/src/Presentation/Views/Dialogs/Dialogs.tsx +37 -21
  56. package/src/Presentation/components/UI/Dialogs/HeaderDialogs/HeaderDialogs.scss +2 -2
  57. package/src/Presentation/components/UI/Dialogs/HeaderDialogs/HeaderDialogs.tsx +5 -5
  58. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/{AIWidget.ts → AIMessageWidget.ts} +14 -3
  59. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidgetActions/AIWidgetActions.scss +55 -0
  60. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidgetActions/AIWidgetActions.tsx +116 -0
  61. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/SliderMenu.tsx +172 -0
  62. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/Tone.ts +21 -0
  63. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidget.tsx +99 -0
  64. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIRephraseMessageWidget.tsx +105 -0
  65. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAITranslateWidget.tsx +106 -0
  66. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/useDefaultVoiceInputWidget.tsx +7 -6
  67. package/src/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.tsx +5 -6
  68. package/src/Presentation/components/UI/Dialogs/MessagesView/DropDownMenu/DropDownMenu.scss +84 -0
  69. package/src/Presentation/components/UI/Dialogs/MessagesView/DropDownMenu/DropDownMenu.tsx +105 -0
  70. package/src/Presentation/components/UI/Dialogs/MessagesView/DropDownMenu/ItemDropDownMenu/ItemDropDownMenu.scss +50 -0
  71. package/src/Presentation/components/UI/Dialogs/MessagesView/DropDownMenu/ItemDropDownMenu/ItemDropDownMenu.tsx +43 -0
  72. package/src/Presentation/components/UI/Dialogs/MessagesView/HeaderMessages/HeaderMessages.tsx +14 -11
  73. package/src/Presentation/components/UI/Dialogs/MessagesView/InComingMessage/AvatarContentIncomingUser/AvatarContentIncomingUser.scss +39 -0
  74. package/src/Presentation/components/UI/Dialogs/MessagesView/InComingMessage/AvatarContentIncomingUser/AvatarContentIncomingUser.tsx +26 -0
  75. package/src/Presentation/components/UI/Dialogs/MessagesView/InComingMessage/InComingMessage.scss +394 -0
  76. package/src/Presentation/components/UI/Dialogs/MessagesView/InComingMessage/InComingMessage.tsx +747 -0
  77. package/src/Presentation/components/UI/Dialogs/MessagesView/MessagesView.scss +88 -4
  78. package/src/Presentation/components/UI/Dialogs/MessagesView/MessagesView.tsx +589 -246
  79. package/src/Presentation/components/UI/Dialogs/MessagesView/OutGoingMessage/OutGoingMessage.scss +7 -0
  80. package/src/Presentation/components/UI/Dialogs/MessagesView/OutGoingMessage/OutGoingMessage.tsx +99 -0
  81. package/src/Presentation/components/UI/Dialogs/MessagesView/useMessagesViewModel.ts +7 -5
  82. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/BookIcon/BookIcon.tsx +7 -0
  83. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/HammerIcon/index.tsx +7 -0
  84. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/HandshakeIcon/index.tsx +7 -0
  85. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/MuscleIcon/index.tsx +7 -0
  86. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/NecktieIcon/index.tsx +7 -0
  87. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/NeutralFaceIcon/index.tsx +7 -0
  88. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/PalmsUpTogetherIcon/index.tsx +7 -0
  89. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/PerformingArtsIcon/index.tsx +7 -0
  90. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/PointUpIcon/index.tsx +7 -0
  91. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/SmileyIcon/index.tsx +20 -0
  92. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/SmirkIcon/index.tsx +7 -0
  93. package/src/Presentation/components/UI/svgs/Icons/AIWidgets/WhiteCheckMarkIcon/index.tsx +7 -0
  94. package/src/Presentation/components/UI/svgs/Icons/Actions/AssistAnswer/AssistAnswer.svg +3 -0
  95. package/src/Presentation/components/UI/svgs/Icons/Actions/AssistAnswer/index.tsx +93 -0
  96. package/src/Presentation/components/UI/svgs/Icons/Actions/Summarize/Summarize.svg +6 -0
  97. package/src/Presentation/components/UI/svgs/Icons/Actions/Summarize/index.tsx +58 -0
  98. package/src/Presentation/components/UI/svgs/Icons/Actions/Tone/Tone.svg +3 -0
  99. package/src/Presentation/components/UI/svgs/Icons/Actions/Tone/index.tsx +34 -0
  100. package/src/Presentation/components/UI/svgs/Icons/Media/Translate/Translate.svg +3 -0
  101. package/src/Presentation/components/UI/svgs/Icons/Media/Translate/index.tsx +35 -0
  102. package/src/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.tsx +110 -36
  103. package/src/Presentation/components/providers/QuickBloxUIKitProvider/QuickBloxUIKitProvider.tsx +7 -6
  104. package/src/QBconfig.ts +33 -3
  105. package/src/index-ui.ts +9 -0
  106. package/src/utils/parse.ts +1 -1
  107. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidget.d.ts +0 -8
  108. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.d.ts +0 -9
  109. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultTextInputWidget.d.ts +0 -2
  110. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.tsx +0 -136
  111. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultTextInputWidget.tsx +0 -60
  112. /package/dist/Presentation/components/UI/svgs/Icons/{Media → AIWidgets}/AIWidget/index.d.ts +0 -0
  113. /package/src/Presentation/components/UI/svgs/Icons/{Media → AIWidgets}/AIWidget/Send.svg +0 -0
  114. /package/src/Presentation/components/UI/svgs/Icons/{Media → AIWidgets}/AIWidget/index.tsx +0 -0
@@ -0,0 +1,133 @@
1
+ import { stringifyError } from '../../utils/parse';
2
+ import RepositoryException from './exception/RepositoryException';
3
+
4
+ export interface IChatMessage {
5
+ role: string;
6
+ content: string;
7
+ }
8
+ export type AIParam = {
9
+ textToAI: string;
10
+ context: IChatMessage[];
11
+ };
12
+
13
+ export class AISource {
14
+ static async getData(
15
+ prompt: string,
16
+ dialogMessages: IChatMessage[],
17
+ servername: string,
18
+ api: string,
19
+ port: string,
20
+ sessionToken: string,
21
+ openAIModel = 'gpt-3.5-turbo',
22
+ ): Promise<string> {
23
+ const apiEndpoint = `${servername}/${api}`;
24
+ const apiKey = sessionToken;
25
+ const model = openAIModel; // 'gpt-3.5-turbo';
26
+
27
+ const requestOptions = {
28
+ method: 'POST',
29
+ headers: {
30
+ 'Content-Type': 'application/json',
31
+ Authorization: `Bearer ${apiKey}`,
32
+ },
33
+ body: JSON.stringify({
34
+ messages: [...dialogMessages, { role: 'user', content: prompt }],
35
+ model,
36
+ temperature: 0.5,
37
+ }),
38
+ };
39
+
40
+ try {
41
+ const response = await fetch(apiEndpoint, requestOptions);
42
+ const data = await response.json();
43
+
44
+ const outputMessage = data.choices[0].message?.content || '';
45
+
46
+ return outputMessage;
47
+ } catch (err) {
48
+ const outputMessage: string = stringifyError(err);
49
+
50
+ throw new RepositoryException(outputMessage, -1);
51
+ }
52
+ }
53
+
54
+ static async getDataWithOpenAI(
55
+ prompt: string,
56
+ dialogMessages: IChatMessage[],
57
+ servername: string,
58
+ api: string,
59
+ port: string,
60
+ sessionToken: string,
61
+ openAIModel = 'gpt-3.5-turbo',
62
+ ): Promise<string> {
63
+ const apiEndpoint = `${servername}/${api}`;
64
+ const apiKey = sessionToken;
65
+ const model = openAIModel; // 'gpt-3.5-turbo';
66
+
67
+ const requestOptions = {
68
+ method: 'POST',
69
+ headers: {
70
+ 'Content-Type': 'application/json',
71
+ Authorization: `Bearer ${apiKey}`,
72
+ },
73
+ body: JSON.stringify({
74
+ messages: [...dialogMessages, { role: 'user', content: prompt }],
75
+ model,
76
+ temperature: 0.5,
77
+ }),
78
+ };
79
+
80
+ try {
81
+ const response = await fetch(apiEndpoint, requestOptions);
82
+ const data = await response.json();
83
+
84
+ const outputMessage = data.choices[0].message?.content || '';
85
+
86
+ return outputMessage;
87
+ } catch (err) {
88
+ const outputMessage: string = stringifyError(err);
89
+
90
+ throw new RepositoryException(outputMessage, -1);
91
+ }
92
+ }
93
+
94
+ static async getDataWithProxyServer(
95
+ prompt: string,
96
+ dialogMessages: IChatMessage[],
97
+ servername: string,
98
+ api: string,
99
+ port: string,
100
+ sessionToken: string,
101
+ openAIModel = 'gpt-3.5-turbo',
102
+ ): Promise<string> {
103
+ const apiEndpoint = `${servername}:${port}/${api}`;
104
+ const apiKey = sessionToken;
105
+ const model = openAIModel; // 'gpt-3.5-turbo';
106
+
107
+ const requestOptions = {
108
+ method: 'POST',
109
+ headers: {
110
+ 'Content-Type': 'application/json',
111
+ 'qb-token': apiKey,
112
+ },
113
+ body: JSON.stringify({
114
+ messages: [...dialogMessages, { role: 'user', content: prompt }],
115
+ model,
116
+ temperature: 0.5,
117
+ }),
118
+ };
119
+
120
+ try {
121
+ const response = await fetch(apiEndpoint, requestOptions);
122
+ const data = await response.json();
123
+
124
+ const outputMessage = data.choices[0].message?.content || '';
125
+
126
+ return outputMessage;
127
+ } catch (err) {
128
+ const outputMessage: string = stringifyError(err);
129
+
130
+ throw new RepositoryException(outputMessage, -1);
131
+ }
132
+ }
133
+ }
@@ -47,14 +47,14 @@ export class MessageDTOMapper implements IDTOMapper {
47
47
  size: item.size,
48
48
  type: item.type,
49
49
  uid: item.uid,
50
- url: item.id.toString() && QB.content.privateUrl(item.id.toString()),
50
+ url: item.uid && QB.content.privateUrl(item.uid),
51
51
  file: {
52
52
  id: item.id,
53
53
  name: item.name,
54
54
  size: item.size,
55
55
  type: item.type,
56
56
  uid: item.uid || '',
57
- url: item.id.toString() && QB.content.privateUrl(item.id.toString()),
57
+ url: item.uid && QB.content.privateUrl(item.uid),
58
58
  },
59
59
  };
60
60
 
@@ -76,7 +76,7 @@ export class MessageDTOMapper implements IDTOMapper {
76
76
  dto.dialogId = qbMessage.chat_dialog_id;
77
77
  dto.message = qbMessage.message;
78
78
  dto.created_at = qbMessage.created_at;
79
- dto.date_sent = qbMessage.date_sent;
79
+ dto.date_sent = qbMessage.date_sent * 1000;
80
80
  dto.delivered_ids = qbMessage.delivered_ids ? qbMessage.delivered_ids : [];
81
81
  dto.read_ids = qbMessage.read_ids ? qbMessage.read_ids : [];
82
82
 
@@ -3,7 +3,7 @@ import { UserEntity } from './UserEntity';
3
3
  import { DialogType } from './DialogTypes';
4
4
 
5
5
  export interface MessageEntity {
6
- id: number;
6
+ id: string;
7
7
  dialogId: string;
8
8
  dialogType?: DialogType;
9
9
  // TODO: check ChatMessageAttachmentEntity
@@ -2,6 +2,7 @@ import { Pagination } from '../../../Domain/repository/Pagination';
2
2
  import { GroupDialogEntity } from '../../../Domain/entity/GroupDialogEntity';
3
3
  import { DialogEntity } from '../../../Domain/entity/DialogEntity';
4
4
  import { FileEntity } from '../../../Domain/entity/FileEntity';
5
+ import { IChatMessage } from '../../../Data/source/AISource';
5
6
 
6
7
  export default class BaseViewModel<TResult> {
7
8
  get entity(): TResult {
@@ -49,10 +50,7 @@ export type EditDialogParams = {
49
50
  dialogTitle: string;
50
51
  dialogAvatar: File | string | null;
51
52
  };
52
- export interface IChatMessage {
53
- role: string;
54
- content: string;
55
- }
53
+
56
54
  export type FunctionTypeFileToToVoid = (file: File) => void;
57
55
  export type FunctionTypePaginationToVoid = (pagination: Pagination) => void;
58
56
  export type FunctionTypeVoidToVoid = () => void;
@@ -76,8 +74,15 @@ export type FunctionTypeJSXElement = () => JSX.Element;
76
74
  export type FunctionTypeFileWithContextToToVoid = (
77
75
  file: File,
78
76
  context: IChatMessage[],
77
+ additionalSettings?: { [key: string]: any },
79
78
  ) => void;
80
79
  export type FunctionTypeStringWithContextToVoid = (
81
80
  value: string,
82
81
  context: IChatMessage[],
82
+ additionalSettings?: { [key: string]: any },
83
83
  ) => void;
84
+ export type FunctionTypeStringWithContextToString = (
85
+ value: string,
86
+ context: IChatMessage[],
87
+ additionalSettings?: { [key: string]: any },
88
+ ) => Promise<string>;
@@ -266,9 +266,9 @@ const DialogsComponent: React.FC<DialogsProps> = ({
266
266
  };
267
267
 
268
268
  const loaderTheme: IconTheme = {
269
- color: 'var(--divider)',
270
- width: '42',
271
- height: '42',
269
+ color: 'var(--color-background-info)',
270
+ width: '44',
271
+ height: '44',
272
272
  };
273
273
 
274
274
  const renderSearchDialogs = () => {
@@ -315,26 +315,42 @@ const DialogsComponent: React.FC<DialogsProps> = ({
315
315
  {useUpContent && upHeaderContent}
316
316
  {useHeader && HeaderContent}
317
317
  {useSubContent && subHeaderContent}
318
- {dialogsViewModel?.loading && (
319
- // <div style={{ maxHeight: '44px', minHeight: '44px', height: '44px' }}>
320
- // <LoaderComponent width="44" height="44" color="var(--divider)" />
321
- // </div>
322
- <LoaderComponent
323
- width={loaderTheme.width}
324
- height={loaderTheme.height}
325
- color={loaderTheme.color}
326
- />
327
- )}
328
- {dialogsViewModel?.error && (
329
- <ErrorComponent
330
- title="Something is wrong."
331
- ClickActionHandler={() => {
332
- alert('call click retry');
333
- }}
334
- />
335
- )}
336
318
  {/* <div className="scroll-box"> */}
337
319
  <div className="scroll-box">
320
+ {dialogsViewModel?.loading && (
321
+ // <div style={{ maxHeight: '44px', minHeight: '44px', height: '44px' }}>
322
+ // <LoaderComponent width="44" height="44" color="var(--divider)" />
323
+ // </div>
324
+ <div
325
+ style={{
326
+ display: 'flex',
327
+ flexDirection: 'row',
328
+ alignItems: 'center',
329
+ justifyContent: 'center',
330
+ }}
331
+ >
332
+ <div
333
+ style={{
334
+ height: '44px',
335
+ width: '44px',
336
+ }}
337
+ >
338
+ <LoaderComponent
339
+ width={loaderTheme.width}
340
+ height={loaderTheme.height}
341
+ color={loaderTheme.color}
342
+ />
343
+ </div>
344
+ </div>
345
+ )}
346
+ {dialogsViewModel?.error && (
347
+ <ErrorComponent
348
+ title="Something is wrong."
349
+ ClickActionHandler={() => {
350
+ alert('call click retry');
351
+ }}
352
+ />
353
+ )}
338
354
  {showSearchDialogs ? renderSearchDialogs() : null}
339
355
  {nameDialogForSearch.length > 0 &&
340
356
  dialogsToView
@@ -10,8 +10,8 @@ $header-container-title-font-size: 20px;
10
10
  $header-container-title-line-height: 24px;
11
11
  $header-container-title-width: 180px;
12
12
  $header-container-buttons-gap-width: 29px;
13
- $header-container-svg-icon-width: 32px;
14
- $header-container-svg-icon-height: 32px;
13
+ $header-container-svg-icon-width: 24px;
14
+ $header-container-svg-icon-height: 24px;
15
15
  $header-container-color-icon: var(--color-icon);
16
16
 
17
17
  .header-dialogs-container{
@@ -54,9 +54,9 @@ const HeaderDialogs: React.FC<HeaderDialogsProps> = ({
54
54
  const buttonsStyle = {
55
55
  background: 'none',
56
56
  svg: {
57
- width: '44',
58
- height: '44',
59
- viewBox: '0 0 44 44',
57
+ width: '24',
58
+ height: '24',
59
+ viewBox: '0 0 24 24',
60
60
  path: {
61
61
  fill: theme?.mainElements(),
62
62
  },
@@ -83,7 +83,7 @@ const HeaderDialogs: React.FC<HeaderDialogsProps> = ({
83
83
  </div>
84
84
  <div style={buttonsStyle} className="header-dialogs-container__buttons">
85
85
  <ActiveSvg
86
- content={<Search />}
86
+ content={<Search width="24" height="24" applyZoom />}
87
87
  touchAction={() => {
88
88
  console.log('touchSearchDialogsHandler');
89
89
  if (touchSearchHandler) touchSearchHandler();
@@ -94,7 +94,7 @@ const HeaderDialogs: React.FC<HeaderDialogsProps> = ({
94
94
  }}
95
95
  />
96
96
  <ActiveSvg
97
- content={<NewChat />}
97
+ content={<NewChat width="24" height="24" applyZoom />}
98
98
  touchAction={() => {
99
99
  console.log('touchAction: Hello from component 1');
100
100
  if (TouchActionHandler) TouchActionHandler();
@@ -1,13 +1,24 @@
1
1
  import {
2
2
  FunctionTypeFileWithContextToToVoid,
3
3
  FunctionTypeJSXElement,
4
- FunctionTypeStringWithContextToVoid,
4
+ FunctionTypeStringWithContextToString,
5
5
  } from '../../../../../Views/Base/BaseViewModel';
6
6
 
7
7
  export interface AIWidget {
8
8
  renderWidget: FunctionTypeJSXElement;
9
- textToWidget: FunctionTypeStringWithContextToVoid;
10
- fileToWidget: FunctionTypeFileWithContextToToVoid;
9
+ }
10
+ export interface AITextWidget extends AIWidget {
11
11
  textToContent: string | undefined;
12
+ }
13
+
14
+ export interface AIFileWidget extends AIWidget {
12
15
  fileToContent: File | undefined;
13
16
  }
17
+
18
+ export interface AIMessageWidget extends AITextWidget {
19
+ textToWidget: FunctionTypeStringWithContextToString;
20
+ }
21
+
22
+ export interface AIAttachmentWidget extends AIFileWidget {
23
+ fileToWidget: FunctionTypeFileWithContextToToVoid;
24
+ }
@@ -0,0 +1,55 @@
1
+
2
+ .dropdown-context-menu-tone * {
3
+ box-sizing: border-box;
4
+ }
5
+ .dropdown-context-menu-tone {
6
+ position: absolute;
7
+ bottom: -15px;
8
+ right: 0;
9
+ zIndex: 1;
10
+ width: max-content;
11
+ height: max-content;
12
+
13
+ background: var(--primary-primary-a-100, #ffffff);
14
+ border-radius: 4px;
15
+ padding: 8px 0px 8px 0px;
16
+
17
+ box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.04),
18
+ 0px 3px 14px 0px rgba(0, 0, 0, 0.08), 0px 8px 10px 0px rgba(0, 0, 0, 0.12);
19
+
20
+ }
21
+
22
+ .dropdown-context-menu-tone-menu-item {
23
+ padding: 4px 8px 4px 16px;
24
+ display: flex;
25
+ flex-direction: row;
26
+ align-items: center;
27
+ justify-content: flex-start;
28
+ align-self: stretch;
29
+ flex-shrink: 0;
30
+ position: relative;
31
+ }
32
+
33
+ .dropdown-context-menu-tone-menu-item-title {
34
+ color: var(--secondary-secondary-900, #0b121b);
35
+ text-align: left;
36
+ font: var(--body-body-medium, 400 14px/20px "Roboto", sans-serif);
37
+ position: relative;
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: flex-start;
41
+ }
42
+
43
+ .dropdown-context-menu-tone-menu-item-icon {
44
+ border-radius: 4px;
45
+ padding: 4px;
46
+ display: flex;
47
+ flex-direction: row;
48
+ gap: 0px;
49
+ align-items: center;
50
+ justify-content: center;
51
+ flex-shrink: 0;
52
+ width: 24px;
53
+ height: 24px;
54
+ position: relative;
55
+ }
@@ -0,0 +1,116 @@
1
+ import React, { useState, CSSProperties, useRef, useEffect } from 'react';
2
+ import './AIWidgetActions.scss';
3
+ import EditDots from '../../../../svgs/Icons/Actions/EditDots';
4
+
5
+ type MenuItem = {
6
+ title: string;
7
+ icon?: JSX.Element; // Добавлено поле для иконки пункта меню
8
+ action: () => void;
9
+ };
10
+
11
+ type ContextMenuProps = {
12
+ widgetToRender?: JSX.Element;
13
+ items?: MenuItem[];
14
+ title?: string | null;
15
+ };
16
+
17
+ const ContextMenuStyles: { [key: string]: CSSProperties } = {
18
+ contextMenuIcon: {
19
+ display: 'inline-block',
20
+ position: 'relative',
21
+ maxWidth: '42px',
22
+ maxHeight: '42px',
23
+ cursor: 'pointer',
24
+ },
25
+ contextMenuContent: {
26
+ position: 'absolute',
27
+ bottom: '10px',
28
+ right: '0',
29
+ backgroundColor: 'white',
30
+ border: '1px solid gray',
31
+ borderRadius: '8px',
32
+ padding: '4px',
33
+ zIndex: 1,
34
+ width: 'max-content',
35
+ },
36
+ menuItemContainer: {
37
+ display: 'flex',
38
+ alignItems: 'center',
39
+ padding: '4px',
40
+ cursor: 'pointer',
41
+ fontWeight: 'normal',
42
+ },
43
+ menuTitle: {
44
+ padding: '4px',
45
+ fontWeight: 'bold',
46
+ },
47
+ };
48
+
49
+ function AIWidgetActions({
50
+ items,
51
+ widgetToRender,
52
+ title = null,
53
+ }: ContextMenuProps) {
54
+ const [menuVisible, setMenuVisible] = useState(false);
55
+ const contextMenuRef = useRef<HTMLDivElement | null>(null);
56
+
57
+ const handleClick = () => {
58
+ setMenuVisible(!menuVisible);
59
+ };
60
+
61
+ const handleMenuItemClick = (action: () => void) => {
62
+ action();
63
+ setMenuVisible(false);
64
+ };
65
+
66
+ useEffect(() => {
67
+ function handleClickOutside(event: MouseEvent) {
68
+ if (
69
+ contextMenuRef.current &&
70
+ !contextMenuRef.current.contains(event.target as Node)
71
+ ) {
72
+ setMenuVisible(false);
73
+ }
74
+ }
75
+
76
+ document.addEventListener('mousedown', handleClickOutside);
77
+
78
+ return () => {
79
+ document.removeEventListener('mousedown', handleClickOutside);
80
+ };
81
+ }, []);
82
+
83
+ return (
84
+ <div style={ContextMenuStyles.contextMenuIcon}>
85
+ <div onClick={handleClick}>{widgetToRender || <EditDots />}</div>
86
+ {menuVisible && (
87
+ // <div ref={contextMenuRef} style={ContextMenuStyles.contextMenuContent}>
88
+ <div ref={contextMenuRef} className="dropdown-context-menu-tone">
89
+ {title && <div style={ContextMenuStyles.menuTitle}>{title}</div>}
90
+ {items?.map((item, index) => (
91
+ <div
92
+ key={index}
93
+ // style={ContextMenuStyles.menuItemContainer}
94
+ className="dropdown-context-menu-tone-menu-item"
95
+ onClick={() => {
96
+ handleMenuItemClick(item.action);
97
+ }}
98
+ >
99
+ {item.icon && (
100
+ <div className="dropdown-context-menu-tone-menu-item-icon">
101
+ {item.icon}
102
+ </div>
103
+ )}
104
+ <div className="dropdown-context-menu-tone-menu-item-title">
105
+ {item.title}
106
+ </div>
107
+ <div className="dropdown-context-menu-tone-menu-item-icon" />
108
+ </div>
109
+ ))}
110
+ </div>
111
+ )}
112
+ </div>
113
+ );
114
+ }
115
+
116
+ export default AIWidgetActions;
@@ -0,0 +1,172 @@
1
+ import React, { useState } from 'react';
2
+
3
+ type MenuItem = {
4
+ title: string;
5
+ icon?: JSX.Element;
6
+ action: () => void;
7
+ };
8
+
9
+ type SliderMenuProps = {
10
+ items: MenuItem[];
11
+ width: number;
12
+ arrowColor?: string;
13
+ activeArrowColor?: string;
14
+ borderColor?: string;
15
+ backgroundColor?: string;
16
+ itemBackgroundColor?: string;
17
+ itemWidth?: number;
18
+ itemHeight?: number;
19
+ itemBorder?: string;
20
+ fontSize?: number;
21
+ activeItemBorderColor?: string;
22
+ activeItemBoxShadow?: string;
23
+ };
24
+
25
+ // eslint-disable-next-line react/function-component-definition
26
+ const SliderMenu: React.FC<SliderMenuProps> = ({
27
+ items,
28
+ width,
29
+ arrowColor = 'black',
30
+ activeArrowColor = 'red',
31
+ borderColor = 'gray',
32
+ backgroundColor = 'white',
33
+ itemBackgroundColor = 'lightgray',
34
+ itemWidth = 100,
35
+ itemHeight = 20,
36
+ itemBorder = '1px solid gray',
37
+ fontSize = 14,
38
+ activeItemBorderColor = 'blue',
39
+ activeItemBoxShadow = '2px 2px 4px rgba(0, 0, 0, 0.2)',
40
+ }) => {
41
+ const [currentIndex, setCurrentIndex] = useState(-1);
42
+ const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
43
+
44
+ const handlePrev = () => {
45
+ setCurrentIndex((currentIndex - 1 + items.length) % items.length);
46
+ };
47
+
48
+ const handleNext = () => {
49
+ setCurrentIndex((currentIndex + 1) % items.length);
50
+ };
51
+
52
+ const handleItemClick = (index: number, action: () => void) => {
53
+ setCurrentIndex(index);
54
+ action();
55
+ };
56
+
57
+ return (
58
+ <div
59
+ style={{
60
+ border: `1px solid ${borderColor}`,
61
+ borderRadius: '10px',
62
+ padding: '4px',
63
+ display: 'flex',
64
+ alignItems: 'center',
65
+ height: '24px',
66
+ backgroundColor,
67
+ position: 'relative',
68
+ overflow: 'hidden',
69
+ }}
70
+ >
71
+ <div
72
+ style={{
73
+ cursor: 'pointer',
74
+ marginRight: '4px',
75
+ width: '12px',
76
+ height: '12px',
77
+ borderTop: '4px solid transparent',
78
+ borderBottom: '4px solid transparent',
79
+ borderRight: `6px solid ${
80
+ hoveredIndex === null || currentIndex === 0
81
+ ? arrowColor
82
+ : activeArrowColor
83
+ }`,
84
+ borderRadius: '5px',
85
+ transition: 'transform 0.3s ease-in-out',
86
+ transform:
87
+ hoveredIndex === null || currentIndex === 0
88
+ ? 'scale(1)'
89
+ : 'scale(1.2)',
90
+ }}
91
+ onClick={handlePrev}
92
+ />
93
+ <div
94
+ style={{
95
+ display: 'flex',
96
+ alignItems: 'center',
97
+ width: `${width}px`,
98
+ overflow: 'hidden',
99
+ }}
100
+ >
101
+ <div
102
+ style={{
103
+ display: 'flex',
104
+ transform: `translateX(-${currentIndex * itemWidth}px)`,
105
+ transition: 'transform 0.3s ease-in-out',
106
+ }}
107
+ >
108
+ {items.map((item, index) => (
109
+ <div
110
+ key={index}
111
+ style={{
112
+ width: `${itemWidth}px`,
113
+ height: `${itemHeight}px`,
114
+ display: 'flex',
115
+ alignItems: 'center',
116
+ paddingLeft: '4px',
117
+ backgroundColor: itemBackgroundColor,
118
+ borderRadius: '8px',
119
+ margin: '0 2px',
120
+ border:
121
+ index === currentIndex || index === hoveredIndex
122
+ ? `2px solid ${activeItemBorderColor}`
123
+ : itemBorder,
124
+ fontSize: `${fontSize}px`,
125
+ flexDirection: 'row',
126
+ justifyContent: 'flex-start',
127
+ cursor: 'pointer',
128
+ boxShadow:
129
+ (index === currentIndex || index === hoveredIndex) &&
130
+ currentIndex !== -1
131
+ ? activeItemBoxShadow
132
+ : 'none',
133
+ }}
134
+ onClick={() => handleItemClick(index, item.action)}
135
+ onMouseEnter={() => setHoveredIndex(index)}
136
+ onMouseLeave={() => setHoveredIndex(null)}
137
+ >
138
+ {item.icon && (
139
+ <div style={{ marginRight: '4px' }}>{item.icon}</div>
140
+ )}
141
+ {item.title}
142
+ </div>
143
+ ))}
144
+ </div>
145
+ </div>
146
+ <div
147
+ style={{
148
+ cursor: 'pointer',
149
+ marginLeft: '4px',
150
+ width: '12px',
151
+ height: '12px',
152
+ borderTop: '4px solid transparent',
153
+ borderBottom: '4px solid transparent',
154
+ borderLeft: `6px solid ${
155
+ hoveredIndex === null || currentIndex === items.length - 1
156
+ ? arrowColor
157
+ : activeArrowColor
158
+ }`,
159
+ borderRadius: '5px',
160
+ transition: 'transform 0.3s ease-in-out',
161
+ transform:
162
+ hoveredIndex === null || currentIndex === items.length - 1
163
+ ? 'scale(1)'
164
+ : 'scale(1.2)',
165
+ }}
166
+ onClick={handleNext}
167
+ />
168
+ </div>
169
+ );
170
+ };
171
+
172
+ export default SliderMenu;