quickblox-react-ui-kit 0.1.7 → 0.2.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.
- package/dist/Presentation/Views/Base/BaseViewModel.d.ts +8 -0
- package/dist/Presentation/Views/Dialogs/Dialogs.d.ts +3 -1
- package/dist/Presentation/components/UI/Dialogs/DialogInformation/DialogInformation.d.ts +3 -1
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidget.d.ts +8 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/ErrorMessageIcon.d.ts +11 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.d.ts +9 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultTextInputWidget.d.ts +2 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/useDefaultVoiceInputWidget.d.ts +2 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.d.ts +10 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/MessagesView.d.ts +7 -1
- package/dist/Presentation/components/UI/svgs/Icons/Media/AIWidget/index.d.ts +4 -0
- package/dist/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.d.ts +9 -0
- package/dist/Presentation/components/layouts/TestStage/CompanyLogo/CompanyLogo.d.ts +3 -0
- package/dist/Presentation/components/providers/QuickBloxUIKitProvider/useQbInitializedDataContext.d.ts +3 -0
- package/dist/Presentation/components/providers/QuickBloxUIKitProvider/useQbUIKitDataContext.d.ts +3 -0
- package/dist/QBconfig.d.ts +12 -0
- package/dist/index-ui.d.ts +3 -2
- package/dist/index-ui.js +72 -17
- package/dist/utils/utils.d.ts +3 -0
- package/package.json +1 -1
- package/src/App.tsx +21 -19
- package/src/Presentation/Views/Base/BaseViewModel.ts +17 -1
- package/src/Presentation/Views/Dialogs/Dialogs.tsx +14 -9
- package/src/Presentation/Views/Dialogs/useDialogsViewModel.ts +1 -1
- package/src/Presentation/components/UI/Dialogs/DialogInformation/DialogInformation.tsx +17 -8
- package/src/Presentation/components/UI/Dialogs/DialogInformation/UsersList/useUsersListViewModel.ts +2 -2
- package/src/Presentation/components/UI/Dialogs/EditDialog/EditDialog.tsx +2 -2
- package/src/Presentation/components/UI/Dialogs/InviteMembers/useInviteMembersViewModel.ts +2 -2
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidget.ts +13 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/ErrorMessageIcon.tsx +98 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.tsx +136 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultTextInputWidget.tsx +60 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/useDefaultVoiceInputWidget.tsx +86 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.tsx +96 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/MessagesView.tsx +275 -51
- package/src/Presentation/components/UI/Dialogs/MessagesView/useMessagesViewModel.ts +2 -2
- package/src/Presentation/components/UI/svgs/Icons/Media/AIWidget/Send.svg +3 -0
- package/src/Presentation/components/UI/svgs/Icons/Media/AIWidget/index.tsx +39 -0
- package/src/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.tsx +83 -8
- package/src/Presentation/components/layouts/TestStage/CompanyLogo/CompanyLogo.tsx +27 -0
- package/src/Presentation/components/layouts/TestStage/LoginView/Login.tsx +2 -2
- package/src/Presentation/components/providers/QuickBloxUIKitProvider/useEventMessagesRepository.ts +2 -2
- package/src/Presentation/components/providers/QuickBloxUIKitProvider/{useQbDataContext.ts → useQbInitializedDataContext.ts} +2 -2
- package/src/Presentation/components/providers/QuickBloxUIKitProvider/useQbUIKitDataContext.ts +11 -0
- package/src/QBconfig.ts +12 -0
- package/src/index-ui.ts +4 -2
- package/src/utils/utils.ts +39 -0
- package/dist/Presentation/components/providers/QuickBloxUIKitProvider/useQbDataContext.d.ts +0 -3
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -5,9 +5,7 @@ import { QBConfig } from './QBconfig';
|
|
|
5
5
|
import useQBConnection from './Presentation/components/providers/QuickBloxUIKitProvider/useQBConnection';
|
|
6
6
|
import { LocalDataSource } from './Data/source/local/LocalDataSource';
|
|
7
7
|
import Login from './Presentation/components/layouts/TestStage/LoginView/Login';
|
|
8
|
-
import QuickBloxUIKitProvider
|
|
9
|
-
qbDataContext,
|
|
10
|
-
} from './Presentation/components/providers/QuickBloxUIKitProvider/QuickBloxUIKitProvider';
|
|
8
|
+
import QuickBloxUIKitProvider from './Presentation/components/providers/QuickBloxUIKitProvider/QuickBloxUIKitProvider';
|
|
11
9
|
import TestStageMarkup from './Presentation/components/layouts/TestStage/TestStageMarkup';
|
|
12
10
|
import { Stubs } from './Data/Stubs';
|
|
13
11
|
import {
|
|
@@ -16,10 +14,13 @@ import {
|
|
|
16
14
|
} from './Data/source/remote/RemoteDataSource';
|
|
17
15
|
import QuickBloxUIKitDesktopLayout from './Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout';
|
|
18
16
|
import DefaultTheme from './Presentation/assets/DefaultThemes/DefaultTheme';
|
|
17
|
+
import useQbUIKitDataContext from './Presentation/components/providers/QuickBloxUIKitProvider/useQbUIKitDataContext';
|
|
19
18
|
|
|
20
19
|
function App() {
|
|
21
|
-
const currentContext = React.useContext(qbDataContext);
|
|
22
|
-
const
|
|
20
|
+
// const currentContext = React.useContext(qbDataContext);
|
|
21
|
+
const currentContext = useQbUIKitDataContext();
|
|
22
|
+
|
|
23
|
+
const remoteDataSource: RemoteDataSource =
|
|
23
24
|
currentContext.storage.REMOTE_DATA_SOURCE;
|
|
24
25
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
25
26
|
const localDataSource: LocalDataSource =
|
|
@@ -50,7 +51,7 @@ function App() {
|
|
|
50
51
|
console.log('call release...');
|
|
51
52
|
connectionRepository.stopKeepAlive();
|
|
52
53
|
console.log('call stopKeepAlive...');
|
|
53
|
-
await
|
|
54
|
+
await remoteDataSource.disconnectAndLogoutUser();
|
|
54
55
|
console.log('call disconnectAndLogoutUser...');
|
|
55
56
|
await currentContext.storage.LOCAL_DATA_SOURCE.clearAll();
|
|
56
57
|
console.log('call clearAll...');
|
|
@@ -61,9 +62,9 @@ function App() {
|
|
|
61
62
|
const prepareSDK = async (authData: LoginData): Promise<void> => {
|
|
62
63
|
console.log('call prepareSDK with data:', authData);
|
|
63
64
|
// todo: must be real remote datasource
|
|
64
|
-
if (
|
|
65
|
+
if (remoteDataSource.needInit) {
|
|
65
66
|
console.log('start prepareSDK actions with data:', authData);
|
|
66
|
-
await
|
|
67
|
+
await remoteDataSource.initSDKWithUser(
|
|
67
68
|
{
|
|
68
69
|
appIdOrToken: currentContext.InitParams.accountData.appId,
|
|
69
70
|
authKeyOrAppId: currentContext.InitParams.accountData.authKey,
|
|
@@ -114,10 +115,10 @@ function App() {
|
|
|
114
115
|
console.log('call reloginSDK with data:', JSON.stringify(authData));
|
|
115
116
|
currentContext.storage.SYNC_DIALOGS_USE_CASE.release();
|
|
116
117
|
connectionRepository.stopKeepAlive();
|
|
117
|
-
await
|
|
118
|
+
await remoteDataSource.disconnectAndLogoutUser();
|
|
118
119
|
await currentContext.storage.LOCAL_DATA_SOURCE.clearAll();
|
|
119
120
|
|
|
120
|
-
await
|
|
121
|
+
await remoteDataSource.loginWithUser(authData);
|
|
121
122
|
//
|
|
122
123
|
// todo: temporary off, must turn on and reorganize code rows
|
|
123
124
|
await connectionRepository.initializeStates();
|
|
@@ -135,20 +136,25 @@ function App() {
|
|
|
135
136
|
const prepareContent = async (): Promise<void> => {
|
|
136
137
|
console.log('PREPARE CONTENT');
|
|
137
138
|
// todo: must delete it and ADD Preload data (read first page everywhere)
|
|
139
|
+
// или во все юзкейсы 2) Get/Sync execute(completed/callback):Promise<Entity[]>
|
|
140
|
+
// await prepareMockData();
|
|
138
141
|
console.log('ADD REAL DATA TO DIALOG MOCK DATA ');
|
|
142
|
+
// await remoteDataSource.getDialogsFirstPage();
|
|
143
|
+
// await remoteDataSource.setUpMockStorage();
|
|
144
|
+
//
|
|
139
145
|
//
|
|
140
146
|
};
|
|
141
147
|
|
|
142
148
|
const loginHandler = async (data: LoginData): Promise<void> => {
|
|
143
149
|
setCurrentUser(data);
|
|
144
150
|
console.log(`call login actions: ${JSON.stringify(data)}`);
|
|
145
|
-
if (
|
|
151
|
+
if (remoteDataSource.authInformation) {
|
|
146
152
|
console.log(
|
|
147
153
|
`authInformation: ${JSON.stringify(
|
|
148
|
-
|
|
154
|
+
remoteDataSource?.authInformation.userName,
|
|
149
155
|
)}`,
|
|
150
156
|
);
|
|
151
|
-
if (data.login !==
|
|
157
|
+
if (data.login !== remoteDataSource.authInformation.userName) {
|
|
152
158
|
await reloginSDK(data).catch((e) => {
|
|
153
159
|
console.log(
|
|
154
160
|
`exception in reloginSDK ${(e as unknown as Error).message}`,
|
|
@@ -161,9 +167,9 @@ function App() {
|
|
|
161
167
|
}
|
|
162
168
|
} else {
|
|
163
169
|
console.log('need prepare SDK with data:', data);
|
|
164
|
-
if (
|
|
170
|
+
if (remoteDataSource.needInit) {
|
|
165
171
|
console.log('start prepareSDK actions with data:', data);
|
|
166
|
-
await
|
|
172
|
+
await remoteDataSource.initSDKWithUser(
|
|
167
173
|
{
|
|
168
174
|
appIdOrToken: currentContext.InitParams.accountData.appId,
|
|
169
175
|
authKeyOrAppId: currentContext.InitParams.accountData.authKey,
|
|
@@ -215,10 +221,6 @@ function App() {
|
|
|
215
221
|
<Route
|
|
216
222
|
path="/desktop-test-mock"
|
|
217
223
|
element={
|
|
218
|
-
// <QuickBloxUIKitDesktopLayout theme={new CustomTheme()} InputWidgetLeftPlaceHolder={CustomWidgetVoiceToText('','')} />
|
|
219
|
-
|
|
220
|
-
// <QuickBloxUIKitDesktopLayout theme={new CustomTheme()} />
|
|
221
|
-
|
|
222
224
|
<QuickBloxUIKitDesktopLayout theme={new DefaultTheme()} />
|
|
223
225
|
}
|
|
224
226
|
/>
|
|
@@ -49,7 +49,10 @@ export type EditDialogParams = {
|
|
|
49
49
|
dialogTitle: string;
|
|
50
50
|
dialogAvatar: File | string | null;
|
|
51
51
|
};
|
|
52
|
-
|
|
52
|
+
export interface IChatMessage {
|
|
53
|
+
role: string;
|
|
54
|
+
content: string;
|
|
55
|
+
}
|
|
53
56
|
export type FunctionTypeFileToToVoid = (file: File) => void;
|
|
54
57
|
export type FunctionTypePaginationToVoid = (pagination: Pagination) => void;
|
|
55
58
|
export type FunctionTypeVoidToVoid = () => void;
|
|
@@ -65,3 +68,16 @@ export type FunctionTypeDialogEntityToBoolean = (
|
|
|
65
68
|
entity: GroupDialogEntity,
|
|
66
69
|
) => Promise<boolean>;
|
|
67
70
|
export type FunctionTypeFileToFileEntity = (file: File) => Promise<FileEntity>;
|
|
71
|
+
export type FunctionTypeJSXElement = () => JSX.Element;
|
|
72
|
+
// export type FunctionTypeChatMessagesToVoid = (
|
|
73
|
+
// lastMessage: string,
|
|
74
|
+
// messages: IChatMessage,
|
|
75
|
+
// ) => void;
|
|
76
|
+
export type FunctionTypeFileWithContextToToVoid = (
|
|
77
|
+
file: File,
|
|
78
|
+
context: IChatMessage[],
|
|
79
|
+
) => void;
|
|
80
|
+
export type FunctionTypeStringWithContextToVoid = (
|
|
81
|
+
value: string,
|
|
82
|
+
context: IChatMessage[],
|
|
83
|
+
) => void;
|
|
@@ -27,6 +27,7 @@ type DialogsComponentSettings = {
|
|
|
27
27
|
themeName?: ThemeNames;
|
|
28
28
|
withoutHeader?: boolean;
|
|
29
29
|
useSubHeader?: boolean;
|
|
30
|
+
useUpHeader?: boolean;
|
|
30
31
|
themeHeader?: UiKitTheme;
|
|
31
32
|
themePreview?: UiKitTheme;
|
|
32
33
|
};
|
|
@@ -34,7 +35,8 @@ type DialogsComponentSettings = {
|
|
|
34
35
|
type DialogsProps = {
|
|
35
36
|
header?: React.ReactNode;
|
|
36
37
|
subHeaderContent?: React.ReactNode;
|
|
37
|
-
|
|
38
|
+
upHeaderContent?: React.ReactNode;
|
|
39
|
+
onDialogSelectHandler?: FunctionTypeViewModelToVoid<DialogEntity>;
|
|
38
40
|
dialogsViewModel: DialogsViewModel;
|
|
39
41
|
additionalSettings?: DialogsComponentSettings;
|
|
40
42
|
};
|
|
@@ -43,7 +45,8 @@ type DialogsProps = {
|
|
|
43
45
|
const DialogsComponent: React.FC<DialogsProps> = ({
|
|
44
46
|
header,
|
|
45
47
|
subHeaderContent,
|
|
46
|
-
|
|
48
|
+
upHeaderContent,
|
|
49
|
+
onDialogSelectHandler,
|
|
47
50
|
dialogsViewModel,
|
|
48
51
|
additionalSettings = undefined,
|
|
49
52
|
}: DialogsProps) => {
|
|
@@ -68,15 +71,15 @@ const DialogsComponent: React.FC<DialogsProps> = ({
|
|
|
68
71
|
dialogsViewModel?.dialogs.forEach((entiy, index) => {
|
|
69
72
|
const pw: PreviewDialogViewModel = new PreviewDialogViewModel(
|
|
70
73
|
(it) => {
|
|
71
|
-
if (
|
|
74
|
+
if (onDialogSelectHandler) {
|
|
72
75
|
setSelectedItem({ selectedIndex: index, item: it });
|
|
73
|
-
|
|
76
|
+
onDialogSelectHandler(it);
|
|
74
77
|
}
|
|
75
78
|
},
|
|
76
79
|
(it) => {
|
|
77
|
-
if (
|
|
80
|
+
if (onDialogSelectHandler) {
|
|
78
81
|
setSelectedItem({ selectedIndex: index, item: it });
|
|
79
|
-
|
|
82
|
+
onDialogSelectHandler(it);
|
|
80
83
|
}
|
|
81
84
|
},
|
|
82
85
|
// Number(entiy.id),
|
|
@@ -149,7 +152,9 @@ const DialogsComponent: React.FC<DialogsProps> = ({
|
|
|
149
152
|
const useHeader = !additionalSettings?.withoutHeader || header || false;
|
|
150
153
|
const useSubContent =
|
|
151
154
|
additionalSettings?.useSubHeader || subHeaderContent || false;
|
|
152
|
-
const
|
|
155
|
+
const useUpContent =
|
|
156
|
+
additionalSettings?.useUpHeader || upHeaderContent || false;
|
|
157
|
+
const HeaderContent = header || (
|
|
153
158
|
<HeaderDialogs
|
|
154
159
|
title="Dialogs"
|
|
155
160
|
clickSearchHandler={() => {
|
|
@@ -307,8 +312,8 @@ const DialogsComponent: React.FC<DialogsProps> = ({
|
|
|
307
312
|
}}
|
|
308
313
|
>
|
|
309
314
|
<ColumnContainer>
|
|
310
|
-
{
|
|
311
|
-
{
|
|
315
|
+
{useUpContent && upHeaderContent}
|
|
316
|
+
{useHeader && HeaderContent}
|
|
312
317
|
{useSubContent && subHeaderContent}
|
|
313
318
|
{dialogsViewModel?.loading && (
|
|
314
319
|
// <div style={{ maxHeight: '44px', minHeight: '44px', height: '44px' }}>
|
|
@@ -44,7 +44,7 @@ export default function useDialogsViewModel(
|
|
|
44
44
|
//
|
|
45
45
|
const currentUserId =
|
|
46
46
|
currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.userId;
|
|
47
|
-
// const currentContext =
|
|
47
|
+
// const currentContext = useQbInitializedDataContext();
|
|
48
48
|
const remoteDataSourceMock: RemoteDataSource =
|
|
49
49
|
currentContext.storage.REMOTE_DATA_SOURCE;
|
|
50
50
|
|
|
@@ -35,24 +35,28 @@ import { stringifyError } from '../../../../../utils/parse';
|
|
|
35
35
|
import { FileEntity } from '../../../../../Domain/entity/FileEntity';
|
|
36
36
|
import UserAvatar from '../EditDialog/UserAvatar/UserAvatar';
|
|
37
37
|
import MainButton, { TypeButton } from '../../Buttons/MainButton/MainButton';
|
|
38
|
-
import
|
|
38
|
+
import useQbInitializedDataContext from '../../../providers/QuickBloxUIKitProvider/useQbInitializedDataContext';
|
|
39
39
|
import UiKitTheme from '../../../../assets/UiKitTheme';
|
|
40
40
|
|
|
41
41
|
type HeaderDialogsProps = {
|
|
42
42
|
dialog: DialogEntity;
|
|
43
43
|
dialogViewModel: DialogsViewModel;
|
|
44
|
-
|
|
44
|
+
onCloseDialogInformationHandler: FunctionTypeVoidToVoid;
|
|
45
45
|
theme?: UiKitTheme;
|
|
46
|
+
subHeaderContent?: React.ReactNode;
|
|
47
|
+
upHeaderContent?: React.ReactNode;
|
|
46
48
|
};
|
|
47
49
|
// eslint-disable-next-line react/function-component-definition
|
|
48
50
|
const DialogInformation: React.FC<HeaderDialogsProps> = ({
|
|
49
51
|
dialog,
|
|
50
52
|
dialogViewModel,
|
|
51
|
-
|
|
53
|
+
onCloseDialogInformationHandler,
|
|
52
54
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
53
55
|
theme = undefined,
|
|
56
|
+
subHeaderContent = undefined,
|
|
57
|
+
upHeaderContent = undefined,
|
|
54
58
|
}: HeaderDialogsProps) => {
|
|
55
|
-
const currentContext =
|
|
59
|
+
const currentContext = useQbInitializedDataContext();
|
|
56
60
|
const currentUserId =
|
|
57
61
|
currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.userId.toString();
|
|
58
62
|
const { handleModal } = React.useContext(ModalContext);
|
|
@@ -62,9 +66,9 @@ const DialogInformation: React.FC<HeaderDialogsProps> = ({
|
|
|
62
66
|
|
|
63
67
|
useEffect(() => {
|
|
64
68
|
console.log('HAVE NEW DIALOG');
|
|
65
|
-
if (dialog === undefined &&
|
|
69
|
+
if (dialog === undefined && onCloseDialogInformationHandler) {
|
|
66
70
|
console.log('HAVE UNDEFINED NEW DIALOG');
|
|
67
|
-
|
|
71
|
+
onCloseDialogInformationHandler();
|
|
68
72
|
|
|
69
73
|
return;
|
|
70
74
|
}
|
|
@@ -244,6 +248,9 @@ const DialogInformation: React.FC<HeaderDialogsProps> = ({
|
|
|
244
248
|
}
|
|
245
249
|
};
|
|
246
250
|
|
|
251
|
+
const useSubContent = subHeaderContent || false;
|
|
252
|
+
const useUpContent = upHeaderContent || false;
|
|
253
|
+
|
|
247
254
|
return isAllMembersShow ? (
|
|
248
255
|
<MembersList
|
|
249
256
|
closeInformationHandler={() => {
|
|
@@ -254,6 +261,7 @@ const DialogInformation: React.FC<HeaderDialogsProps> = ({
|
|
|
254
261
|
) : (
|
|
255
262
|
<div className="dialog-information-container">
|
|
256
263
|
<ColumnContainer maxWidth="320px">
|
|
264
|
+
{useUpContent && upHeaderContent}
|
|
257
265
|
<div className="dialog-information-container--dialog-information-wrapper">
|
|
258
266
|
<div className="dialog-information-container__dialog-information">
|
|
259
267
|
<div>Dialog information</div>
|
|
@@ -262,13 +270,14 @@ const DialogInformation: React.FC<HeaderDialogsProps> = ({
|
|
|
262
270
|
<ActiveSvg
|
|
263
271
|
content={<Close applyZoom color="var(--secondary-elements)" />}
|
|
264
272
|
clickAction={() => {
|
|
265
|
-
if (
|
|
266
|
-
|
|
273
|
+
if (onCloseDialogInformationHandler) {
|
|
274
|
+
onCloseDialogInformationHandler();
|
|
267
275
|
}
|
|
268
276
|
}}
|
|
269
277
|
/>
|
|
270
278
|
</div>
|
|
271
279
|
</div>
|
|
280
|
+
{useSubContent && subHeaderContent}
|
|
272
281
|
<div className="dialog-information-container--icon-dialog-wrapper">
|
|
273
282
|
<div className="dialog-information-container__icon-dialog">
|
|
274
283
|
<div className="dialog-information-container__icon-dialog__info">
|
package/src/Presentation/components/UI/Dialogs/DialogInformation/UsersList/useUsersListViewModel.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { DialogEntity } from '../../../../../../Domain/entity/DialogEntity';
|
|
3
|
-
import
|
|
3
|
+
import useQbInitializedDataContext from '../../../../providers/QuickBloxUIKitProvider/useQbInitializedDataContext';
|
|
4
4
|
import { UserEntity } from '../../../../../../Domain/entity/UserEntity';
|
|
5
5
|
import { UsersListViewModel } from './UsersListViewModel';
|
|
6
6
|
import { GetUsersByIdsUseCase } from '../../../../../../Domain/use_cases/GetUsersByIdsUseCase';
|
|
@@ -18,7 +18,7 @@ export default function useUsersListViewModel(
|
|
|
18
18
|
const [users, setUsers] = useState<UserEntity[]>([]);
|
|
19
19
|
const [dialog, setDialog] = useState<DialogEntity>(dialogEntity);
|
|
20
20
|
|
|
21
|
-
const currentContext =
|
|
21
|
+
const currentContext = useQbInitializedDataContext();
|
|
22
22
|
|
|
23
23
|
async function getUsers() {
|
|
24
24
|
console.log('call getUsers in useUsersListViewModel');
|
|
@@ -13,7 +13,7 @@ import UserAvatar from './UserAvatar/UserAvatar';
|
|
|
13
13
|
import { DialogType } from '../../../../../Domain/entity/DialogTypes';
|
|
14
14
|
import GroupChat from '../../svgs/Icons/Contents/GroupChat';
|
|
15
15
|
import PublicChannel from '../../svgs/Icons/Contents/PublicChannel';
|
|
16
|
-
import
|
|
16
|
+
import useQbInitializedDataContext from '../../../providers/QuickBloxUIKitProvider/useQbInitializedDataContext';
|
|
17
17
|
|
|
18
18
|
export const TypeOpenDialog = {
|
|
19
19
|
edit: 'edit',
|
|
@@ -40,7 +40,7 @@ const EditDialog: React.FC<EditDialogProps> = ({
|
|
|
40
40
|
clickUpdatedHandler,
|
|
41
41
|
clickCancelHandler,
|
|
42
42
|
}) => {
|
|
43
|
-
const currentContext =
|
|
43
|
+
const currentContext = useQbInitializedDataContext();
|
|
44
44
|
const maxUploadFileSize = currentContext.InitParams.maxFileSize;
|
|
45
45
|
const minLengthNameDialog = 3;
|
|
46
46
|
const maxLengthNameDialog = 60;
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import { UserEntity } from '../../../../../Domain/entity/UserEntity';
|
|
8
8
|
import { GetAllUsersUseCase } from '../../../../../Domain/use_cases/GetAllUsersUseCase';
|
|
9
9
|
import UsersRepository from '../../../../../Data/repository/UsersRepository';
|
|
10
|
-
import
|
|
10
|
+
import useQbInitializedDataContext from '../../../providers/QuickBloxUIKitProvider/useQbInitializedDataContext';
|
|
11
11
|
import { Stubs } from '../../../../../Data/Stubs';
|
|
12
12
|
import { stringifyError } from '../../../../../utils/parse';
|
|
13
13
|
import {
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
export default function useInviteMembersViewModel(): InviteMembersViewModel {
|
|
19
19
|
// initPagination?: Pagination,
|
|
20
20
|
console.log('create useUsersListViewModel');
|
|
21
|
-
const currentContext =
|
|
21
|
+
const currentContext = useQbInitializedDataContext();
|
|
22
22
|
const [loading, setLoading] = useState(false);
|
|
23
23
|
const [error, setError] = useState('error with getting user list');
|
|
24
24
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FunctionTypeFileWithContextToToVoid,
|
|
3
|
+
FunctionTypeJSXElement,
|
|
4
|
+
FunctionTypeStringWithContextToVoid,
|
|
5
|
+
} from '../../../../../Views/Base/BaseViewModel';
|
|
6
|
+
|
|
7
|
+
export interface AIWidget {
|
|
8
|
+
renderWidget: FunctionTypeJSXElement;
|
|
9
|
+
textToWidget: FunctionTypeStringWithContextToVoid;
|
|
10
|
+
fileToWidget: FunctionTypeFileWithContextToToVoid;
|
|
11
|
+
textToContent: string | undefined;
|
|
12
|
+
fileToContent: File | undefined;
|
|
13
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React, { useState, CSSProperties } from 'react';
|
|
2
|
+
|
|
3
|
+
type ErrorDescription = {
|
|
4
|
+
title: string;
|
|
5
|
+
action: () => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type ErrorMessageIconProps = {
|
|
9
|
+
errorMessageText: string;
|
|
10
|
+
errorsDescriptions?: ErrorDescription[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const errorMessageIconStyles: { [key: string]: CSSProperties } = {
|
|
14
|
+
errorIcon: {
|
|
15
|
+
display: 'inline-block',
|
|
16
|
+
position: 'relative',
|
|
17
|
+
width: '21px', // Уменьшен размер круга
|
|
18
|
+
height: '21px', // Уменьшен размер круга
|
|
19
|
+
cursor: 'pointer',
|
|
20
|
+
},
|
|
21
|
+
circle: {
|
|
22
|
+
width: '21px', // Уменьшен размер круга
|
|
23
|
+
height: '21px', // Уменьшен размер круга
|
|
24
|
+
backgroundColor: 'red',
|
|
25
|
+
borderRadius: '50%',
|
|
26
|
+
display: 'flex',
|
|
27
|
+
justifyContent: 'center',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
},
|
|
30
|
+
exclamationMark: {
|
|
31
|
+
color: 'white',
|
|
32
|
+
fontSize: '12px', // Уменьшен размер восклицательного знака
|
|
33
|
+
},
|
|
34
|
+
errorMessage: {
|
|
35
|
+
position: 'absolute',
|
|
36
|
+
bottom: '100%', // Изменено выравнивание, чтобы текст был выше
|
|
37
|
+
left: '50%',
|
|
38
|
+
transform: 'translateX(-50%)',
|
|
39
|
+
backgroundColor: 'lightgray',
|
|
40
|
+
border: '1px solid gray',
|
|
41
|
+
padding: '6px',
|
|
42
|
+
borderRadius: '8px',
|
|
43
|
+
whiteSpace: 'nowrap',
|
|
44
|
+
display: 'inline-block',
|
|
45
|
+
zIndex: 1, // Установлен zIndex, чтобы текст был выше других элементов
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function ErrorMessageIcon({
|
|
50
|
+
errorMessageText,
|
|
51
|
+
errorsDescriptions,
|
|
52
|
+
}: ErrorMessageIconProps) {
|
|
53
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
54
|
+
|
|
55
|
+
const handleMouseEnter = () => {
|
|
56
|
+
setIsHovered(true);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const handleMouseLeave = () => {
|
|
60
|
+
setIsHovered(false);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
style={{
|
|
66
|
+
...errorMessageIconStyles.errorIcon,
|
|
67
|
+
...(isHovered ? { backgroundColor: 'yellow' } : {}),
|
|
68
|
+
}}
|
|
69
|
+
onMouseEnter={handleMouseEnter}
|
|
70
|
+
onMouseLeave={handleMouseLeave}
|
|
71
|
+
>
|
|
72
|
+
<div style={errorMessageIconStyles.circle}>
|
|
73
|
+
<span style={errorMessageIconStyles.exclamationMark}>!</span>
|
|
74
|
+
</div>
|
|
75
|
+
{isHovered && (
|
|
76
|
+
<div style={errorMessageIconStyles.errorMessage}>
|
|
77
|
+
{errorMessageText}
|
|
78
|
+
{errorsDescriptions?.map((item, index) => (
|
|
79
|
+
<div
|
|
80
|
+
key={index}
|
|
81
|
+
style={{
|
|
82
|
+
padding: '4px',
|
|
83
|
+
cursor: 'pointer',
|
|
84
|
+
}}
|
|
85
|
+
onClick={() => {
|
|
86
|
+
item.action();
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
{item.title}
|
|
90
|
+
</div>
|
|
91
|
+
))}
|
|
92
|
+
</div>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default ErrorMessageIcon;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { AIWidget } from './AIWidget';
|
|
3
|
+
import AIWidgetIcon from '../../../svgs/Icons/Media/AIWidget';
|
|
4
|
+
import { IChatMessage } from '../../../../../Views/Base/BaseViewModel';
|
|
5
|
+
import { stringifyError } from '../../../../../../utils/parse';
|
|
6
|
+
import ErrorMessageIcon from './ErrorMessageIcon';
|
|
7
|
+
|
|
8
|
+
interface MessageWidgetProps {
|
|
9
|
+
// https://api.openai.com/v1/chat/completions'
|
|
10
|
+
// api: 'v1/chat/completions',
|
|
11
|
+
// servername: 'https://myproxy.com',
|
|
12
|
+
// https://func270519800.azurewebsites.net/api/TranslateTextToEng
|
|
13
|
+
servername: string;
|
|
14
|
+
api: string;
|
|
15
|
+
port: string;
|
|
16
|
+
sessionToken: string;
|
|
17
|
+
}
|
|
18
|
+
export default function UseDefaultAIAssistAnswerWidgetWithProxy({
|
|
19
|
+
servername,
|
|
20
|
+
api,
|
|
21
|
+
port,
|
|
22
|
+
sessionToken,
|
|
23
|
+
}: MessageWidgetProps): AIWidget {
|
|
24
|
+
const [errorMessage, setErrorMessage] = useState<string>('');
|
|
25
|
+
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
|
|
27
|
+
const fileToWidget = (file: File, context: IChatMessage[]): void => {};
|
|
28
|
+
|
|
29
|
+
const renderWidget = (): JSX.Element => {
|
|
30
|
+
if (errorMessage && errorMessage.length > 0) {
|
|
31
|
+
const errorsDescriptions:
|
|
32
|
+
| { title: string; action: () => void }[]
|
|
33
|
+
| undefined = [];
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<ErrorMessageIcon
|
|
37
|
+
errorMessageText={errorMessage}
|
|
38
|
+
errorsDescriptions={errorsDescriptions}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return <AIWidgetIcon applyZoom color="green" />;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// async function getData(
|
|
47
|
+
// textToSend: string,
|
|
48
|
+
// dialogMessages: ChatCompletionRequestMessage[],
|
|
49
|
+
// ): Promise<string> {
|
|
50
|
+
// //
|
|
51
|
+
// const apiEndpoint = 'https://api.openai.com/v1/chat/completions';
|
|
52
|
+
// const { apiKey } = QBConfig.configAIApi.AIAnswerAssistWidgetConfig; // Замените на ваш реальный ключ API
|
|
53
|
+
// const model = 'gpt-3.5-turbo';
|
|
54
|
+
// const requestOptions = {
|
|
55
|
+
// method: 'POST',
|
|
56
|
+
// headers: {
|
|
57
|
+
// 'Content-Type': 'application/json',
|
|
58
|
+
// Authorization: `Bearer ${apiKey}`,
|
|
59
|
+
// },
|
|
60
|
+
// body: JSON.stringify({
|
|
61
|
+
// messages: [...dialogMessages, { role: 'user', content: textToSend }],
|
|
62
|
+
// model,
|
|
63
|
+
// temperature: 0.5,
|
|
64
|
+
// }),
|
|
65
|
+
// };
|
|
66
|
+
//
|
|
67
|
+
async function getData(
|
|
68
|
+
textToSend: string,
|
|
69
|
+
dialogMessages: IChatMessage[],
|
|
70
|
+
): Promise<string> {
|
|
71
|
+
let outputMessage = '';
|
|
72
|
+
const apiEndpoint = `${servername}${port}${api}`;
|
|
73
|
+
const apiKey = sessionToken; // Замените на ваш реальный ключ API
|
|
74
|
+
const model = 'gpt-3.5-turbo';
|
|
75
|
+
const prompt = `Respond as a knowledgeable customer support specialist with access to ChatGPT features, and provide a simple and informative response to the inquiry :"${textToSend}"`;
|
|
76
|
+
|
|
77
|
+
const requestOptions = {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
Authorization: `Bearer ${apiKey}`,
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({
|
|
84
|
+
messages: [...dialogMessages, { role: 'user', content: prompt }],
|
|
85
|
+
model,
|
|
86
|
+
temperature: 0.5,
|
|
87
|
+
}),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
//
|
|
91
|
+
try {
|
|
92
|
+
const response = await fetch(apiEndpoint, requestOptions);
|
|
93
|
+
const data = await response.json();
|
|
94
|
+
|
|
95
|
+
outputMessage = data.choices[0].message?.content || '';
|
|
96
|
+
} catch (err) {
|
|
97
|
+
outputMessage = stringifyError(err);
|
|
98
|
+
setErrorMessage(outputMessage);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return outputMessage;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const [textFromWidgetToContent, setTextFromWidgetToContent] = useState('');
|
|
105
|
+
// const textToWidget = (value: string, context: IChatMessage[]): void => {
|
|
106
|
+
// if (value && value.length > 0) {
|
|
107
|
+
// // eslint-disable-next-line promise/catch-or-return
|
|
108
|
+
// getOpenAIApiData(value, context as ChatCompletionRequestMessage[]).then(
|
|
109
|
+
// // eslint-disable-next-line promise/always-return
|
|
110
|
+
// (data) => {
|
|
111
|
+
// setTextFromWidgetToContent(data);
|
|
112
|
+
// },
|
|
113
|
+
// );
|
|
114
|
+
// }
|
|
115
|
+
// };
|
|
116
|
+
|
|
117
|
+
const textToWidget = (value: string, context: IChatMessage[]): void => {
|
|
118
|
+
if (value && value.length > 0) {
|
|
119
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
120
|
+
getData(value, context).then(
|
|
121
|
+
// eslint-disable-next-line promise/always-return
|
|
122
|
+
(data) => {
|
|
123
|
+
setTextFromWidgetToContent(data);
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
fileToContent: undefined,
|
|
131
|
+
textToContent: textFromWidgetToContent,
|
|
132
|
+
fileToWidget,
|
|
133
|
+
renderWidget,
|
|
134
|
+
textToWidget,
|
|
135
|
+
};
|
|
136
|
+
}
|