agora-appbuilder-core 4.1.7-beta.8 → 4.1.8-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/_package-lock.json +30671 -5376
- package/template/defaultConfig.js +2 -2
- package/template/esbuild.rsdk.go +1 -2
- package/template/package.json +0 -1
- package/template/src/AppWrapper.tsx +30 -35
- package/template/src/auth/AuthProvider.tsx +28 -35
- package/template/src/auth/IDPAuth.tsx +1 -14
- package/template/src/components/Controls.tsx +45 -15
- package/template/src/components/common/GenericModal.tsx +143 -0
- package/template/src/components/common/GenericPopup.tsx +152 -0
- package/template/src/components/common/data-table.tsx +385 -0
- package/template/src/components/controls/useControlPermissionMatrix.tsx +6 -7
- package/template/src/components/precall/usePreCall.tsx +1 -2
- package/template/src/components/stt-transcript/STTTranscriptTable.tsx +295 -0
- package/template/src/components/stt-transcript/ViewSTTTranscriptModal.tsx +44 -0
- package/template/src/components/stt-transcript/useFetchSTTTranscript.tsx +193 -0
- package/template/src/components/useUserPreference.tsx +0 -11
- package/template/src/language/default-labels/videoCallScreenLabels.ts +7 -0
- package/template/src/logger/AppBuilderLogger.tsx +1 -0
- package/template/src/pages/Create.tsx +2 -2
- package/template/src/pages/VideoCall.tsx +0 -5
- package/template/src/subComponents/LogoutButton.tsx +1 -11
- package/template/src/subComponents/recording/useRecordingLayoutQuery.tsx +83 -78
- package/template/src/utils/common.tsx +79 -1
- package/template/src/utils/useCreateRoom.ts +94 -112
- package/template/src/utils/useEndCall.ts +16 -3
- package/template/src/utils/useGetMeetingPhrase.ts +67 -76
- package/template/src/utils/useJoinRoom.ts +0 -3
- package/template/src/utils/useMutePSTN.ts +47 -45
- package/template/webpack.rsdk.config.js +1 -2
- package/template/src/components/GraphQLProvider.tsx +0 -122
|
@@ -77,8 +77,8 @@ const DefaultConfig = {
|
|
|
77
77
|
CHAT_ORG_NAME: '',
|
|
78
78
|
CHAT_APP_NAME: '',
|
|
79
79
|
CHAT_URL: '',
|
|
80
|
-
CLI_VERSION: '3.1.
|
|
81
|
-
CORE_VERSION: '4.1.
|
|
80
|
+
CLI_VERSION: '3.1.8-beta.1',
|
|
81
|
+
CORE_VERSION: '4.1.8-beta.1',
|
|
82
82
|
DISABLE_LANDSCAPE_MODE: false,
|
|
83
83
|
STT_AUTO_START: false,
|
|
84
84
|
CLOUD_RECORDING_AUTO_START: false,
|
package/template/esbuild.rsdk.go
CHANGED
package/template/package.json
CHANGED
|
@@ -13,7 +13,6 @@ import React, {useContext} from 'react';
|
|
|
13
13
|
import {Router} from './components/Router';
|
|
14
14
|
import Navigation from './components/Navigation';
|
|
15
15
|
import {StorageProvider} from './components/StorageContext';
|
|
16
|
-
import GraphQLProvider from './components/GraphQLProvider';
|
|
17
16
|
import {SessionProvider} from './components/SessionContext';
|
|
18
17
|
import {
|
|
19
18
|
ImageBackground,
|
|
@@ -89,40 +88,36 @@ const AppWrapper = (props: AppWrapperProps) => {
|
|
|
89
88
|
{$config.DISABLE_LANDSCAPE_MODE && <BlockUI />}
|
|
90
89
|
<StorageProvider>
|
|
91
90
|
<LanguageProvider>
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
</AuthProvider>
|
|
123
|
-
</ToastProvider>
|
|
124
|
-
</Router>
|
|
125
|
-
</GraphQLProvider>
|
|
91
|
+
<Router
|
|
92
|
+
/*@ts-ignore Router will be memory Router in sdk*/
|
|
93
|
+
initialEntries={[
|
|
94
|
+
//@ts-ignore
|
|
95
|
+
isSDK && SdkJoinState.phrase
|
|
96
|
+
? //@ts-ignore
|
|
97
|
+
`/${SdkJoinState.phrase}`
|
|
98
|
+
: '',
|
|
99
|
+
]}>
|
|
100
|
+
<ToastProvider>
|
|
101
|
+
<ToastContext.Consumer>
|
|
102
|
+
{({isActionSheetVisible}) => {
|
|
103
|
+
return !isActionSheetVisible ? <ToastComponent /> : null;
|
|
104
|
+
}}
|
|
105
|
+
</ToastContext.Consumer>
|
|
106
|
+
<AuthProvider>
|
|
107
|
+
<SessionProvider>
|
|
108
|
+
<ColorConfigure>
|
|
109
|
+
<DimensionProvider>
|
|
110
|
+
<ErrorProvider>
|
|
111
|
+
<Error />
|
|
112
|
+
<Navigation />
|
|
113
|
+
{props.children}
|
|
114
|
+
</ErrorProvider>
|
|
115
|
+
</DimensionProvider>
|
|
116
|
+
</ColorConfigure>
|
|
117
|
+
</SessionProvider>
|
|
118
|
+
</AuthProvider>
|
|
119
|
+
</ToastProvider>
|
|
120
|
+
</Router>
|
|
126
121
|
</LanguageProvider>
|
|
127
122
|
</StorageProvider>
|
|
128
123
|
</SafeAreaView>
|
|
@@ -8,7 +8,6 @@ import React, {
|
|
|
8
8
|
useRef,
|
|
9
9
|
} from 'react';
|
|
10
10
|
import {useHistory, useLocation} from '../components/Router';
|
|
11
|
-
import {gql, useApolloClient} from '@apollo/client';
|
|
12
11
|
import {useIDPAuth} from './useIDPAuth';
|
|
13
12
|
import Loading from '../subComponents/Loading';
|
|
14
13
|
import useTokenAuth from './useTokenAuth';
|
|
@@ -45,14 +44,7 @@ import LocalEventEmitter, {
|
|
|
45
44
|
LocalEventsEnum,
|
|
46
45
|
} from '../rtm-events-api/LocalEvents';
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
query getUser {
|
|
50
|
-
getUser {
|
|
51
|
-
name
|
|
52
|
-
email
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
`;
|
|
47
|
+
const GET_USER_URL = `${$config.BACKEND_ENDPOINT}/v1/user/details`;
|
|
56
48
|
|
|
57
49
|
type AuthProviderProps = {
|
|
58
50
|
enableAuth?: boolean;
|
|
@@ -87,7 +79,6 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
87
79
|
const history = useHistory();
|
|
88
80
|
const location = useLocation();
|
|
89
81
|
// client
|
|
90
|
-
const apolloClient = useApolloClient();
|
|
91
82
|
const {isRecordingBot} = useIsRecordingBot();
|
|
92
83
|
const indexesOf = (arr, item) =>
|
|
93
84
|
arr.reduce((acc, v, i) => (v === item && acc.push(i), acc), []);
|
|
@@ -324,44 +315,47 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
324
315
|
async function getUserDetails() {
|
|
325
316
|
const requestId = getUniqueID();
|
|
326
317
|
const startReqTs = Date.now();
|
|
318
|
+
//fetch user details
|
|
319
|
+
logger.log(
|
|
320
|
+
LogSource.NetworkRest,
|
|
321
|
+
'user_details',
|
|
322
|
+
'API fetching user_details, to check if user is authenticated',
|
|
323
|
+
{
|
|
324
|
+
requestId,
|
|
325
|
+
startReqTs,
|
|
326
|
+
},
|
|
327
|
+
);
|
|
328
|
+
const token = store?.token;
|
|
327
329
|
try {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
);
|
|
338
|
-
const token = store?.token;
|
|
339
|
-
const res = await apolloClient.query({
|
|
340
|
-
query: GET_USER,
|
|
341
|
-
fetchPolicy: 'network-only',
|
|
342
|
-
context: {
|
|
343
|
-
headers: {
|
|
344
|
-
'X-Request-Id': requestId,
|
|
345
|
-
'X-Session-Id': logger.getSessionId(),
|
|
346
|
-
...(token && {
|
|
347
|
-
authorization: token ? `Bearer ${token}` : '',
|
|
348
|
-
}),
|
|
349
|
-
},
|
|
330
|
+
const res = await fetch(`${GET_USER_URL}`, {
|
|
331
|
+
method: 'POST',
|
|
332
|
+
headers: {
|
|
333
|
+
'Content-Type': 'application/json',
|
|
334
|
+
'X-Request-Id': requestId,
|
|
335
|
+
'X-Session-Id': logger.getSessionId(),
|
|
336
|
+
...(token && {
|
|
337
|
+
authorization: token ? `Bearer ${token}` : '',
|
|
338
|
+
}),
|
|
350
339
|
},
|
|
351
340
|
});
|
|
341
|
+
const response = await res.json();
|
|
342
|
+
if (response?.error) {
|
|
343
|
+
throw response?.error;
|
|
344
|
+
}
|
|
352
345
|
const endRequestTs = Date.now();
|
|
353
346
|
logger.log(
|
|
354
347
|
LogSource.NetworkRest,
|
|
355
348
|
'user_details',
|
|
356
349
|
'API user_details query succesful. User is authenticated',
|
|
357
350
|
{
|
|
358
|
-
responseData:
|
|
351
|
+
responseData: response,
|
|
359
352
|
startReqTs,
|
|
360
353
|
endRequestTs,
|
|
361
354
|
latency: endRequestTs - startReqTs,
|
|
362
355
|
requestId,
|
|
363
356
|
},
|
|
364
357
|
);
|
|
358
|
+
setLoading(false);
|
|
365
359
|
} catch (error) {
|
|
366
360
|
const endRequestTs = Date.now();
|
|
367
361
|
logger.log(
|
|
@@ -376,9 +370,8 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
376
370
|
requestId,
|
|
377
371
|
},
|
|
378
372
|
);
|
|
379
|
-
throw new Error(error);
|
|
380
|
-
} finally {
|
|
381
373
|
setLoading(false);
|
|
374
|
+
throw new Error(error);
|
|
382
375
|
}
|
|
383
376
|
}
|
|
384
377
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React, {useEffect} from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {useAuth} from './AuthProvider';
|
|
3
3
|
import {useHistory, useParams} from '../components/Router';
|
|
4
4
|
import Loading from '../subComponents/Loading';
|
|
5
|
-
import {useApolloClient} from '@apollo/client';
|
|
6
5
|
import Toast from '../../react-native-toast-message';
|
|
7
6
|
import {getParamFromURL} from '../utils/common';
|
|
8
7
|
import useTokenAuth from './useTokenAuth';
|
|
@@ -20,20 +19,8 @@ export const IDPAuth = () => {
|
|
|
20
19
|
const history = useHistory();
|
|
21
20
|
const {token: returnTo}: {token: string} = useParams();
|
|
22
21
|
//token used as returnTo and webToken is sent on the token query param
|
|
23
|
-
const apolloClient = useApolloClient();
|
|
24
22
|
const {enableTokenAuth} = useTokenAuth();
|
|
25
23
|
|
|
26
|
-
async function getUserDetails() {
|
|
27
|
-
try {
|
|
28
|
-
await apolloClient.query({
|
|
29
|
-
query: GET_USER,
|
|
30
|
-
fetchPolicy: 'network-only',
|
|
31
|
-
});
|
|
32
|
-
} catch (error) {
|
|
33
|
-
throw error;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
24
|
useEffect(() => {
|
|
38
25
|
const token = getParamFromURL(history.location.search, 'token');
|
|
39
26
|
if (token) {
|
|
@@ -103,6 +103,7 @@ import {
|
|
|
103
103
|
toolbarItemTranscriptText,
|
|
104
104
|
toolbarItemVirtualBackgroundText,
|
|
105
105
|
toolbarItemWhiteboardText,
|
|
106
|
+
toolbarItemManageTranscriptText,
|
|
106
107
|
} from '../language/default-labels/videoCallScreenLabels';
|
|
107
108
|
import {LogSource, logger} from '../logger/AppBuilderLogger';
|
|
108
109
|
import {useModal} from '../utils/useModal';
|
|
@@ -115,6 +116,7 @@ import {
|
|
|
115
116
|
InviteToolbarItem,
|
|
116
117
|
ScreenshareToolbarItem,
|
|
117
118
|
} from './controls/toolbar-items';
|
|
119
|
+
import ViewSTTTranscriptModal from './stt-transcript/ViewSTTTranscriptModal';
|
|
118
120
|
|
|
119
121
|
export const useToggleWhiteboard = () => {
|
|
120
122
|
const {
|
|
@@ -276,6 +278,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
276
278
|
const viewRecordingsLabel = useString<boolean>(
|
|
277
279
|
toolbarItemViewRecordingText,
|
|
278
280
|
)();
|
|
281
|
+
const viewSTTLabel = useString<boolean>(toolbarItemManageTranscriptText)();
|
|
279
282
|
const moreButtonLabel = useString(toolbarItemMoreText)();
|
|
280
283
|
const virtualBackgroundLabel = useString(toolbarItemVirtualBackgroundText)();
|
|
281
284
|
const chatLabel = useString(toolbarItemChatText)();
|
|
@@ -293,6 +296,11 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
293
296
|
setModalOpen: setVRModalOpen,
|
|
294
297
|
toggle: toggleVRModal,
|
|
295
298
|
} = useModal();
|
|
299
|
+
const {
|
|
300
|
+
modalOpen: isSTTTranscriptModalOpen,
|
|
301
|
+
setModalOpen: setSTTTranscriptModalOpen,
|
|
302
|
+
toggle: toggleSTTTranscriptModal,
|
|
303
|
+
} = useModal();
|
|
296
304
|
const moreBtnRef = useRef(null);
|
|
297
305
|
const {width: globalWidth, height: globalHeight} = useWindowDimensions();
|
|
298
306
|
const layouts = useLayoutsData();
|
|
@@ -330,7 +338,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
330
338
|
|
|
331
339
|
const {isNoiseSupressionEnabled, setNoiseSupression} = useNoiseSupression();
|
|
332
340
|
|
|
333
|
-
//AINS
|
|
341
|
+
//0. AINS
|
|
334
342
|
if ($config.ENABLE_NOISE_CANCELLATION) {
|
|
335
343
|
actionMenuitems.push({
|
|
336
344
|
componentName: 'noise-cancellation',
|
|
@@ -354,7 +362,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
354
362
|
}
|
|
355
363
|
//AINS
|
|
356
364
|
|
|
357
|
-
//virtual background
|
|
365
|
+
//1. virtual background
|
|
358
366
|
const {isVBActive, setIsVBActive} = useVB();
|
|
359
367
|
|
|
360
368
|
const toggleVB = () => {
|
|
@@ -385,7 +393,6 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
385
393
|
//virtual background
|
|
386
394
|
|
|
387
395
|
//whiteboard start
|
|
388
|
-
|
|
389
396
|
const {
|
|
390
397
|
whiteboardRoomState,
|
|
391
398
|
whiteboardActive,
|
|
@@ -472,8 +479,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
472
479
|
? true
|
|
473
480
|
: false;
|
|
474
481
|
|
|
475
|
-
//whiteboard ends
|
|
476
|
-
|
|
482
|
+
// 2. whiteboard ends
|
|
477
483
|
if (isHost && $config.ENABLE_WHITEBOARD && isWebInternal()) {
|
|
478
484
|
actionMenuitems.push({
|
|
479
485
|
componentName: 'whiteboard',
|
|
@@ -515,8 +521,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
515
521
|
});
|
|
516
522
|
}
|
|
517
523
|
|
|
518
|
-
// host can see stt options and attendee can view only when stt is enabled by a host in the channel
|
|
519
|
-
|
|
524
|
+
// 3. host can see stt options and attendee can view only when stt is enabled by a host in the channel
|
|
520
525
|
if ($config.ENABLE_STT && $config.ENABLE_CAPTION) {
|
|
521
526
|
actionMenuitems.push({
|
|
522
527
|
componentName: 'caption',
|
|
@@ -546,7 +551,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
546
551
|
}
|
|
547
552
|
},
|
|
548
553
|
});
|
|
549
|
-
|
|
554
|
+
// 4. Meeting transcript
|
|
550
555
|
if ($config.ENABLE_MEETING_TRANSCRIPT) {
|
|
551
556
|
actionMenuitems.push({
|
|
552
557
|
componentName: 'transcript',
|
|
@@ -583,8 +588,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
583
588
|
}
|
|
584
589
|
}
|
|
585
590
|
|
|
586
|
-
// view recordings
|
|
587
|
-
|
|
591
|
+
// 5. view recordings
|
|
588
592
|
if (isHost && $config.CLOUD_RECORDING && isWeb()) {
|
|
589
593
|
actionMenuitems.push({
|
|
590
594
|
componentName: 'view-recordings',
|
|
@@ -599,7 +603,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
599
603
|
});
|
|
600
604
|
}
|
|
601
605
|
|
|
602
|
-
// Particpants
|
|
606
|
+
// 6. Particpants
|
|
603
607
|
const canAccessParticipants =
|
|
604
608
|
useControlPermissionMatrix('participantControl');
|
|
605
609
|
if (canAccessParticipants) {
|
|
@@ -619,7 +623,8 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
619
623
|
},
|
|
620
624
|
});
|
|
621
625
|
}
|
|
622
|
-
|
|
626
|
+
|
|
627
|
+
// 7. Chat
|
|
623
628
|
const canAccessChat = useControlPermissionMatrix('chatControl');
|
|
624
629
|
if (canAccessChat) {
|
|
625
630
|
//disable chat button when BE sends error on chat
|
|
@@ -669,7 +674,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
669
674
|
});
|
|
670
675
|
}
|
|
671
676
|
|
|
672
|
-
// Screenshare
|
|
677
|
+
// 8. Screenshare
|
|
673
678
|
const canAccessScreenshare = useControlPermissionMatrix('screenshareControl');
|
|
674
679
|
if (canAccessScreenshare) {
|
|
675
680
|
if (
|
|
@@ -706,6 +711,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
706
711
|
}
|
|
707
712
|
}
|
|
708
713
|
|
|
714
|
+
// 9. Recording
|
|
709
715
|
if (isHost && $config.CLOUD_RECORDING) {
|
|
710
716
|
actionMenuitems.push({
|
|
711
717
|
hide: w => {
|
|
@@ -733,6 +739,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
733
739
|
});
|
|
734
740
|
}
|
|
735
741
|
|
|
742
|
+
// 10. layout
|
|
736
743
|
actionMenuitems.push({
|
|
737
744
|
hide: w => {
|
|
738
745
|
return w >= BREAKPOINTS.lg ? true : false;
|
|
@@ -767,7 +774,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
767
774
|
),
|
|
768
775
|
});
|
|
769
776
|
|
|
770
|
-
// Invite
|
|
777
|
+
// 11. Invite
|
|
771
778
|
const canAccessInvite = useControlPermissionMatrix('inviteControl');
|
|
772
779
|
if (canAccessInvite) {
|
|
773
780
|
actionMenuitems.push({
|
|
@@ -787,7 +794,7 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
787
794
|
});
|
|
788
795
|
}
|
|
789
796
|
|
|
790
|
-
// Settings
|
|
797
|
+
// 12.Settings
|
|
791
798
|
const canAccessSettings = useControlPermissionMatrix('settingsControl');
|
|
792
799
|
if (canAccessSettings) {
|
|
793
800
|
actionMenuitems.push({
|
|
@@ -807,6 +814,24 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
807
814
|
});
|
|
808
815
|
}
|
|
809
816
|
|
|
817
|
+
// 13. Transcripts to download
|
|
818
|
+
const canAccessAllTranscripts =
|
|
819
|
+
useControlPermissionMatrix('viewAllTranscripts');
|
|
820
|
+
|
|
821
|
+
if (canAccessAllTranscripts) {
|
|
822
|
+
actionMenuitems.push({
|
|
823
|
+
componentName: 'view-all-transcripts',
|
|
824
|
+
order: 13,
|
|
825
|
+
icon: 'transcript',
|
|
826
|
+
iconColor: $config.SECONDARY_ACTION_COLOR,
|
|
827
|
+
textColor: $config.FONT_COLOR,
|
|
828
|
+
title: viewSTTLabel,
|
|
829
|
+
onPress: () => {
|
|
830
|
+
toggleSTTTranscriptModal();
|
|
831
|
+
},
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
|
|
810
835
|
useEffect(() => {
|
|
811
836
|
if (isHovered) {
|
|
812
837
|
setActionMenuVisible(true);
|
|
@@ -953,6 +978,11 @@ const MoreButton = (props: {fields: ToolbarMoreButtonDefaultFields}) => {
|
|
|
953
978
|
)}
|
|
954
979
|
</>
|
|
955
980
|
)}
|
|
981
|
+
{canAccessAllTranscripts && isSTTTranscriptModalOpen ? (
|
|
982
|
+
<ViewSTTTranscriptModal setModalOpen={setSTTTranscriptModalOpen} />
|
|
983
|
+
) : (
|
|
984
|
+
<></>
|
|
985
|
+
)}
|
|
956
986
|
<ActionMenu
|
|
957
987
|
containerStyle={globalWidth < 720 ? {width: 180} : {width: 260}}
|
|
958
988
|
hoverMode={true}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
StyleSheet,
|
|
3
|
+
Text,
|
|
4
|
+
View,
|
|
5
|
+
Modal,
|
|
6
|
+
TouchableWithoutFeedback,
|
|
7
|
+
ModalProps,
|
|
8
|
+
ViewStyle,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import IconButton from '../../atoms/IconButton';
|
|
12
|
+
import ThemeConfig from '../../theme';
|
|
13
|
+
import hexadecimalTransparency from '../../utils/hexadecimalTransparency';
|
|
14
|
+
import {isMobileUA, useIsDesktop} from '../../utils/common';
|
|
15
|
+
|
|
16
|
+
interface GenericModalProps extends ModalProps {
|
|
17
|
+
title?: string;
|
|
18
|
+
cancelable?: boolean;
|
|
19
|
+
showCloseIcon?: boolean;
|
|
20
|
+
contentContainerStyle?: ViewStyle;
|
|
21
|
+
}
|
|
22
|
+
const GenericModal = (props: GenericModalProps) => {
|
|
23
|
+
const {
|
|
24
|
+
visible,
|
|
25
|
+
onRequestClose,
|
|
26
|
+
title,
|
|
27
|
+
children,
|
|
28
|
+
cancelable = false,
|
|
29
|
+
showCloseIcon = true,
|
|
30
|
+
contentContainerStyle = {},
|
|
31
|
+
...modalProps
|
|
32
|
+
} = props;
|
|
33
|
+
|
|
34
|
+
const isDesktop = useIsDesktop()('popup');
|
|
35
|
+
|
|
36
|
+
// Fallback Handle close
|
|
37
|
+
const handleClose = () => {
|
|
38
|
+
onRequestClose?.(undefined);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Modal
|
|
43
|
+
animationType="none"
|
|
44
|
+
transparent={true}
|
|
45
|
+
visible={visible}
|
|
46
|
+
onRequestClose={handleClose}>
|
|
47
|
+
<View style={[styles.centeredView, isDesktop && styles.desktopAlign]}>
|
|
48
|
+
<TouchableWithoutFeedback
|
|
49
|
+
onPress={() => {
|
|
50
|
+
cancelable && handleClose();
|
|
51
|
+
}}>
|
|
52
|
+
<View style={styles.backDrop} />
|
|
53
|
+
</TouchableWithoutFeedback>
|
|
54
|
+
<View style={[styles.modalView, contentContainerStyle]}>
|
|
55
|
+
<View style={styles.header}>
|
|
56
|
+
<Text style={styles.title}>{title}</Text>
|
|
57
|
+
{showCloseIcon && (
|
|
58
|
+
<View>
|
|
59
|
+
<IconButton
|
|
60
|
+
hoverEffect={true}
|
|
61
|
+
hoverEffectStyle={{
|
|
62
|
+
backgroundColor: $config.ICON_BG_COLOR,
|
|
63
|
+
borderRadius: 20,
|
|
64
|
+
}}
|
|
65
|
+
iconProps={{
|
|
66
|
+
iconType: 'plain',
|
|
67
|
+
iconContainerStyle: {
|
|
68
|
+
padding: isMobileUA() ? 0 : 5,
|
|
69
|
+
},
|
|
70
|
+
name: 'close',
|
|
71
|
+
tintColor: $config.SECONDARY_ACTION_COLOR,
|
|
72
|
+
}}
|
|
73
|
+
onPress={handleClose}
|
|
74
|
+
/>
|
|
75
|
+
</View>
|
|
76
|
+
)}
|
|
77
|
+
</View>
|
|
78
|
+
{children}
|
|
79
|
+
</View>
|
|
80
|
+
</View>
|
|
81
|
+
</Modal>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export default GenericModal;
|
|
86
|
+
|
|
87
|
+
const styles = StyleSheet.create({
|
|
88
|
+
centeredView: {
|
|
89
|
+
flex: 1,
|
|
90
|
+
position: 'relative',
|
|
91
|
+
justifyContent: 'center',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
paddingHorizontal: 20,
|
|
94
|
+
},
|
|
95
|
+
desktopAlign: {
|
|
96
|
+
alignItems: 'center',
|
|
97
|
+
},
|
|
98
|
+
modalView: {
|
|
99
|
+
backgroundColor: $config.CARD_LAYER_1_COLOR,
|
|
100
|
+
borderWidth: 1,
|
|
101
|
+
borderColor: $config.CARD_LAYER_3_COLOR,
|
|
102
|
+
borderRadius: ThemeConfig.BorderRadius.large,
|
|
103
|
+
shadowColor: $config.HARD_CODED_BLACK_COLOR,
|
|
104
|
+
shadowOffset: {
|
|
105
|
+
width: 0,
|
|
106
|
+
height: 2,
|
|
107
|
+
},
|
|
108
|
+
shadowOpacity: 0.1,
|
|
109
|
+
shadowRadius: 4,
|
|
110
|
+
elevation: 5,
|
|
111
|
+
maxWidth: 680,
|
|
112
|
+
minWidth: 340,
|
|
113
|
+
height: 620,
|
|
114
|
+
maxHeight: 620,
|
|
115
|
+
zIndex: 2,
|
|
116
|
+
},
|
|
117
|
+
backDrop: {
|
|
118
|
+
zIndex: 1,
|
|
119
|
+
position: 'absolute',
|
|
120
|
+
top: 0,
|
|
121
|
+
bottom: 0,
|
|
122
|
+
left: 0,
|
|
123
|
+
right: 0,
|
|
124
|
+
backgroundColor:
|
|
125
|
+
$config.HARD_CODED_BLACK_COLOR + hexadecimalTransparency['60%'],
|
|
126
|
+
},
|
|
127
|
+
header: {
|
|
128
|
+
flexDirection: 'row',
|
|
129
|
+
justifyContent: 'space-between',
|
|
130
|
+
alignItems: 'flex-start',
|
|
131
|
+
paddingVertical: 12,
|
|
132
|
+
paddingHorizontal: 20,
|
|
133
|
+
width: '100%',
|
|
134
|
+
},
|
|
135
|
+
title: {
|
|
136
|
+
color: $config.FONT_COLOR + ThemeConfig.EmphasisPlus.high,
|
|
137
|
+
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
138
|
+
fontSize: ThemeConfig.FontSize.xLarge,
|
|
139
|
+
lineHeight: 32,
|
|
140
|
+
fontWeight: '500',
|
|
141
|
+
alignSelf: 'center',
|
|
142
|
+
},
|
|
143
|
+
});
|