agora-appbuilder-core 2.0.2 → 2.1.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/Readme.md +2 -1
- package/package.json +1 -1
- package/template/_package-lock.json +864 -684
- package/template/agora-rn-uikit/.git/index +0 -0
- package/template/agora-rn-uikit/.git/logs/HEAD +2 -2
- package/template/agora-rn-uikit/.git/logs/refs/heads/ab-dev-auto +1 -1
- package/template/agora-rn-uikit/.git/logs/refs/heads/master +1 -1
- package/template/agora-rn-uikit/.git/logs/refs/remotes/origin/HEAD +1 -1
- package/template/agora-rn-uikit/.git/objects/pack/pack-9181e9e59978901afdcfb1d244e221810fd813e3.idx +0 -0
- package/template/agora-rn-uikit/.git/objects/pack/{pack-f379286d0537eb68377220b4929979324b8d5d1c.pack → pack-9181e9e59978901afdcfb1d244e221810fd813e3.pack} +0 -0
- package/template/agora-rn-uikit/.git/packed-refs +4 -2
- package/template/agora-rn-uikit/.git/refs/heads/ab-dev-auto +1 -1
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +21 -0
- package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +22 -14
- package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +17 -13
- package/template/agora-rn-uikit/src/Controls/types.ts +4 -0
- package/template/agora-rn-uikit/src/Rtc/Create.tsx +117 -19
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +24 -13
- package/template/{src/utils/isSafariBrowser.tsx → agora-rn-uikit/src/Utils/isSafariBrowser.ts} +3 -0
- package/template/{src → agora-rn-uikit/src}/hooks/useImageDelay.tsx +5 -2
- package/template/agora-rn-uikit/src/index.ts +2 -0
- package/template/bridge/rtc/webNg/RtcEngine.ts +73 -70
- package/template/bridge/rtc/webNg/Types.ts +59 -5
- package/template/bridge/rtm/web/Types.ts +13 -0
- package/template/bridge/rtm/web/index.ts +78 -1
- package/template/global.d.ts +2 -0
- package/template/package-lock.json +864 -684
- package/template/package.json +2 -3
- package/template/react-native-toast-message/src/components/base/styles.js +4 -2
- package/template/src/assets/icons.ts +41 -28
- package/template/src/components/Chat.tsx +70 -184
- package/template/src/components/ChatContext.ts +13 -2
- package/template/src/components/Controls.native.tsx +37 -76
- package/template/src/components/Controls.tsx +50 -158
- package/template/src/components/DeviceConfigure.native.tsx +5 -1
- package/template/src/components/DeviceConfigure.tsx +38 -20
- package/template/src/components/Navbar.tsx +185 -226
- package/template/src/components/ParticipantsView.tsx +176 -184
- package/template/src/components/Precall.native.tsx +83 -69
- package/template/src/components/Precall.tsx +174 -191
- package/template/src/components/RTMConfigure.tsx +264 -78
- package/template/src/components/SettingsView.tsx +9 -19
- package/template/src/components/livestream/LiveStreamContext.tsx +411 -0
- package/template/src/components/livestream/Types.ts +69 -0
- package/template/src/components/livestream/index.ts +9 -0
- package/template/src/components/livestream/views/LiveStreamControls.tsx +27 -0
- package/template/src/components/participants/AllAudienceParticipants.tsx +53 -0
- package/template/src/components/participants/AllHostParticipants.tsx +65 -0
- package/template/src/components/participants/MeParticipant.tsx +37 -0
- package/template/src/components/participants/ParticipantName.tsx +47 -0
- package/template/src/components/participants/ParticipantSectionTitle.tsx +29 -0
- package/template/src/components/participants/RemoteParticipants.tsx +69 -0
- package/template/src/components/participants/ScreenshareParticipants.tsx +28 -0
- package/template/src/components/participants/context/ParticipantContext.tsx +97 -0
- package/template/src/components/styles.ts +13 -0
- package/template/src/pages/Create.tsx +25 -14
- package/template/src/pages/VideoCall.tsx +197 -159
- package/template/src/subComponents/ChatBubble.tsx +4 -1
- package/template/src/subComponents/ChatContainer.tsx +44 -20
- package/template/src/subComponents/ChatInput.tsx +4 -12
- package/template/src/subComponents/Checkbox.native.tsx +6 -5
- package/template/src/subComponents/Checkbox.tsx +1 -0
- package/template/src/subComponents/Recording.tsx +23 -9
- package/template/src/subComponents/RemoteVideoMute.tsx +2 -3
- package/template/src/subComponents/SelectDevice.tsx +70 -35
- package/template/src/subComponents/chat/ChatParticipants.tsx +121 -0
- package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +23 -0
- package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +70 -0
- package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +57 -0
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +24 -0
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +38 -0
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +37 -0
- package/template/src/subComponents/livestream/index.ts +18 -0
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +80 -0
- package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +24 -0
- package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +200 -0
- package/template/src/subComponents/screenshare/ScreenshareContext.tsx +21 -0
- package/template/src/utils/index.tsx +48 -0
- package/template/agora-rn-uikit/.git/objects/pack/pack-f379286d0537eb68377220b4929979324b8d5d1c.idx +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
********************************************
|
|
3
|
+
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
+
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
+
(the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
+
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
+
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
+
any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
|
|
9
|
+
information visit https://appbuilder.agora.io.
|
|
10
|
+
*********************************************
|
|
11
|
+
*/
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import {View, StyleSheet, useWindowDimensions, Platform} from 'react-native';
|
|
14
|
+
import TextWithToolTip from '../../subComponents/TextWithTooltip';
|
|
15
|
+
import {RFValue} from 'react-native-responsive-fontsize';
|
|
16
|
+
|
|
17
|
+
const ParticipantName = ({value}: {value: string}) => {
|
|
18
|
+
const {height, width} = useWindowDimensions();
|
|
19
|
+
const fontSize = Platform.OS === 'web' ? 14 : 16;
|
|
20
|
+
return (
|
|
21
|
+
<View style={{flex: 1}}>
|
|
22
|
+
<TextWithToolTip
|
|
23
|
+
value={value}
|
|
24
|
+
style={[
|
|
25
|
+
style.participantText,
|
|
26
|
+
{
|
|
27
|
+
fontSize: RFValue(fontSize, height > width ? height : width),
|
|
28
|
+
},
|
|
29
|
+
]}
|
|
30
|
+
/>
|
|
31
|
+
</View>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
export default ParticipantName;
|
|
35
|
+
|
|
36
|
+
const style = StyleSheet.create({
|
|
37
|
+
participantText: {
|
|
38
|
+
flex: 1,
|
|
39
|
+
fontWeight: '500',
|
|
40
|
+
flexDirection: 'row',
|
|
41
|
+
color: $config.PRIMARY_FONT_COLOR,
|
|
42
|
+
lineHeight: 20,
|
|
43
|
+
paddingHorizontal: 5,
|
|
44
|
+
textAlign: 'left',
|
|
45
|
+
flexShrink: 1,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {StyleSheet, Text} from 'react-native';
|
|
3
|
+
|
|
4
|
+
interface PropsInterface {
|
|
5
|
+
title: string;
|
|
6
|
+
count?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function ParticipantSectionTitle(props: PropsInterface) {
|
|
10
|
+
const {title, count = 0} = props;
|
|
11
|
+
return (
|
|
12
|
+
<Text style={style.subheading}>
|
|
13
|
+
{title} {count > 0 && <Text style={style.count}>({count})</Text>}
|
|
14
|
+
</Text>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const style = StyleSheet.create({
|
|
19
|
+
subheading: {
|
|
20
|
+
fontSize: 15,
|
|
21
|
+
letterSpacing: 0.8,
|
|
22
|
+
fontWeight: '700',
|
|
23
|
+
color: $config.PRIMARY_FONT_COLOR,
|
|
24
|
+
},
|
|
25
|
+
count: {
|
|
26
|
+
fontSize: 13,
|
|
27
|
+
fontWeight: '500',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
********************************************
|
|
3
|
+
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
+
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
+
(the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
+
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
+
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
+
any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
|
|
9
|
+
information visit https://appbuilder.agora.io.
|
|
10
|
+
*********************************************
|
|
11
|
+
*/
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import {View, Text} from 'react-native';
|
|
14
|
+
import RemoteAudioMute from '../../subComponents/RemoteAudioMute';
|
|
15
|
+
import RemoteVideoMute from '../../subComponents/RemoteVideoMute';
|
|
16
|
+
import {ApprovedLiveStreamControlsView} from '../../subComponents/livestream';
|
|
17
|
+
import RemoteEndCall from '../../subComponents/RemoteEndCall';
|
|
18
|
+
import ParticipantName from './ParticipantName';
|
|
19
|
+
|
|
20
|
+
interface remoteParticipantsInterface {
|
|
21
|
+
p_styles: any;
|
|
22
|
+
name: string;
|
|
23
|
+
user: any;
|
|
24
|
+
showControls: boolean;
|
|
25
|
+
isHost: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const RemoteParticipants = (props: remoteParticipantsInterface) => {
|
|
29
|
+
const {p_styles, user, name, showControls, isHost} = props;
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<View style={p_styles.participantRow}>
|
|
33
|
+
<ParticipantName value={name} />
|
|
34
|
+
{showControls ? (
|
|
35
|
+
<View style={p_styles.participantActionContainer}>
|
|
36
|
+
{$config.EVENT_MODE && (
|
|
37
|
+
<ApprovedLiveStreamControlsView
|
|
38
|
+
p_styles={p_styles}
|
|
39
|
+
uid={user.uid}
|
|
40
|
+
/>
|
|
41
|
+
)}
|
|
42
|
+
<View style={[p_styles.actionBtnIcon, {marginRight: 10}]}>
|
|
43
|
+
<RemoteEndCall uid={user.uid} isHost={isHost} />
|
|
44
|
+
</View>
|
|
45
|
+
<View style={[p_styles.actionBtnIcon, {marginRight: 10}]}>
|
|
46
|
+
<RemoteAudioMute
|
|
47
|
+
uid={user.uid}
|
|
48
|
+
audio={user.audio}
|
|
49
|
+
isHost={isHost}
|
|
50
|
+
/>
|
|
51
|
+
</View>
|
|
52
|
+
<View style={[p_styles.actionBtnIcon]}>
|
|
53
|
+
<RemoteVideoMute
|
|
54
|
+
uid={user.uid}
|
|
55
|
+
video={user.video}
|
|
56
|
+
isHost={isHost}
|
|
57
|
+
/>
|
|
58
|
+
</View>
|
|
59
|
+
</View>
|
|
60
|
+
) : (
|
|
61
|
+
<></>
|
|
62
|
+
// <View style={p_styles.dummyView}>
|
|
63
|
+
// <Text>Remote screen sharing</Text>
|
|
64
|
+
// </View>
|
|
65
|
+
)}
|
|
66
|
+
</View>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
export default RemoteParticipants;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
********************************************
|
|
3
|
+
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
+
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
+
(the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
+
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
+
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
+
any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
|
|
9
|
+
information visit https://appbuilder.agora.io.
|
|
10
|
+
*********************************************
|
|
11
|
+
*/
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import {View, Text} from 'react-native';
|
|
14
|
+
import ParticipantName from './ParticipantName';
|
|
15
|
+
|
|
16
|
+
const ScreenshareParticipants = (props: any) => {
|
|
17
|
+
const {p_styles, name} = props;
|
|
18
|
+
return (
|
|
19
|
+
<View style={p_styles.participantRow}>
|
|
20
|
+
<ParticipantName value={name} />
|
|
21
|
+
<View style={p_styles.dummyView}>
|
|
22
|
+
{/** its just the placeholder to adjust the UI. if no icon option to be shown */}
|
|
23
|
+
<Text>local screen sharing</Text>
|
|
24
|
+
</View>
|
|
25
|
+
</View>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
export default ScreenshareParticipants;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
********************************************
|
|
3
|
+
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
+
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
+
(the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
+
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
+
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
+
any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
|
|
9
|
+
information visit https://appbuilder.agora.io.
|
|
10
|
+
*********************************************
|
|
11
|
+
*/
|
|
12
|
+
import {createContext} from 'react';
|
|
13
|
+
import React, {useState, useContext, useEffect} from 'react';
|
|
14
|
+
import chatContext from '../../ChatContext';
|
|
15
|
+
import {UserType} from '../../../components/RTMConfigure';
|
|
16
|
+
import {filterObject} from '../../../utils';
|
|
17
|
+
import {
|
|
18
|
+
ClientRole,
|
|
19
|
+
MinUidContext,
|
|
20
|
+
MaxUidContext,
|
|
21
|
+
} from '../../../../agora-rn-uikit';
|
|
22
|
+
|
|
23
|
+
interface ParticipantContext {
|
|
24
|
+
hostList: any;
|
|
25
|
+
audienceList: any;
|
|
26
|
+
hostCount: number;
|
|
27
|
+
audienceCount: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const ParticipantContext = createContext(null as unknown as ParticipantContext);
|
|
31
|
+
|
|
32
|
+
export const ParticipantContextProvider: React.FC = (props: any) => {
|
|
33
|
+
const [hostCount, setHostCount] = useState(0);
|
|
34
|
+
const [hostList, setHostList] = useState({});
|
|
35
|
+
const [audienceList, setAudienceList] = useState({});
|
|
36
|
+
const [audienceCount, setAudienceCount] = useState(0);
|
|
37
|
+
|
|
38
|
+
const {userList, localUid} = useContext(chatContext);
|
|
39
|
+
// For host list which are publishing
|
|
40
|
+
const min = useContext(MinUidContext);
|
|
41
|
+
const max = useContext(MaxUidContext);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const hostList = [...min, ...max].reduce((acc, cur) => {
|
|
45
|
+
if (
|
|
46
|
+
cur.uid === 'local' &&
|
|
47
|
+
userList[localUid]?.role == ClientRole.Audience
|
|
48
|
+
) {
|
|
49
|
+
// If local user skip
|
|
50
|
+
return acc;
|
|
51
|
+
}
|
|
52
|
+
const userUID =
|
|
53
|
+
cur.uid === 'local'
|
|
54
|
+
? localUid
|
|
55
|
+
: cur.uid == 1
|
|
56
|
+
? userList[localUid].screenUid
|
|
57
|
+
: cur.uid;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
...acc,
|
|
61
|
+
[userUID]: {...userList[userUID]},
|
|
62
|
+
};
|
|
63
|
+
}, {});
|
|
64
|
+
setHostList(hostList);
|
|
65
|
+
setHostCount(Object.keys(hostList).length);
|
|
66
|
+
}, [min, max, userList]);
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (Object.keys(userList).length !== 0) {
|
|
70
|
+
const audienceList = filterObject(
|
|
71
|
+
userList,
|
|
72
|
+
([k, v]) =>
|
|
73
|
+
v?.type === UserType.Normal &&
|
|
74
|
+
v?.role == ClientRole.Audience &&
|
|
75
|
+
!v.offline,
|
|
76
|
+
);
|
|
77
|
+
setAudienceList(audienceList);
|
|
78
|
+
setAudienceCount(Object.keys(audienceList).length);
|
|
79
|
+
}
|
|
80
|
+
}, [userList]);
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<ParticipantContext.Provider
|
|
84
|
+
value={{
|
|
85
|
+
hostList,
|
|
86
|
+
audienceList,
|
|
87
|
+
hostCount,
|
|
88
|
+
audienceCount,
|
|
89
|
+
}}>
|
|
90
|
+
{props.children}
|
|
91
|
+
</ParticipantContext.Provider>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const ParticipantContextConsumer = ParticipantContext.Consumer;
|
|
96
|
+
|
|
97
|
+
export default ParticipantContext;
|
|
@@ -65,6 +65,19 @@ const styles = {
|
|
|
65
65
|
marginHorizontal: 0,
|
|
66
66
|
backgroundColor: $config.SECONDARY_FONT_COLOR, //'#fff',
|
|
67
67
|
},
|
|
68
|
+
liveStreamHostControlBtns: {
|
|
69
|
+
width: 20,
|
|
70
|
+
height: 20,
|
|
71
|
+
borderTopRightRadius: 0,
|
|
72
|
+
borderTopLeftRadius: 0,
|
|
73
|
+
borderBottomLeftRadius: 0,
|
|
74
|
+
borderBottomRightRadius: 0,
|
|
75
|
+
borderWidth: 0,
|
|
76
|
+
borderRightWidth: 0,
|
|
77
|
+
borderLeftWidth: 0,
|
|
78
|
+
marginHorizontal: 0,
|
|
79
|
+
backgroundColor: $config.SECONDARY_FONT_COLOR,
|
|
80
|
+
},
|
|
68
81
|
minCloseBtn: {
|
|
69
82
|
alignItems: 'center',
|
|
70
83
|
justifyContent: 'center',
|
|
@@ -10,7 +10,14 @@
|
|
|
10
10
|
*********************************************
|
|
11
11
|
*/
|
|
12
12
|
import React, {useEffect, useState} from 'react';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
View,
|
|
15
|
+
Text,
|
|
16
|
+
StyleSheet,
|
|
17
|
+
Dimensions,
|
|
18
|
+
ScrollView,
|
|
19
|
+
Platform,
|
|
20
|
+
} from 'react-native';
|
|
14
21
|
import {useHistory} from '../components/Router';
|
|
15
22
|
import Checkbox from '../subComponents/Checkbox';
|
|
16
23
|
import {gql, useMutation} from '@apollo/client';
|
|
@@ -74,10 +81,10 @@ const Create = () => {
|
|
|
74
81
|
console.log('mutation data', data);
|
|
75
82
|
|
|
76
83
|
useEffect(() => {
|
|
77
|
-
if(Platform.OS === 'web'){
|
|
84
|
+
if (Platform.OS === 'web') {
|
|
78
85
|
document.title = $config.APP_NAME;
|
|
79
86
|
}
|
|
80
|
-
},[])
|
|
87
|
+
}, []);
|
|
81
88
|
|
|
82
89
|
const createRoom = () => {
|
|
83
90
|
if (roomTitle !== '') {
|
|
@@ -121,7 +128,7 @@ const Create = () => {
|
|
|
121
128
|
// style={style.full}
|
|
122
129
|
// resizeMode={'cover'}>
|
|
123
130
|
// <KeyboardAvoidingView behavior={'height'} style={style.main}>
|
|
124
|
-
<ScrollView contentContainerStyle={style.main}>
|
|
131
|
+
<ScrollView contentContainerStyle={style.main}>
|
|
125
132
|
<View style={style.nav}>
|
|
126
133
|
{hasBrandLogo && <Logo />}
|
|
127
134
|
{error ? <Error error={error} /> : <></>}
|
|
@@ -141,16 +148,20 @@ const Create = () => {
|
|
|
141
148
|
/>
|
|
142
149
|
<View style={{paddingVertical: 10}}>
|
|
143
150
|
<View style={style.checkboxHolder}>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
{$config.EVENT_MODE ? (
|
|
152
|
+
<></>
|
|
153
|
+
) : (
|
|
154
|
+
<>
|
|
155
|
+
<Checkbox
|
|
156
|
+
disabled={$config.EVENT_MODE}
|
|
157
|
+
value={hostControlCheckbox}
|
|
158
|
+
onValueChange={setHostControlCheckbox}
|
|
159
|
+
/>
|
|
160
|
+
<Text style={style.checkboxTitle}>
|
|
161
|
+
Restrict Host Controls (Separate host link)
|
|
162
|
+
</Text>
|
|
163
|
+
</>
|
|
164
|
+
)}
|
|
154
165
|
</View>
|
|
155
166
|
{$config.PSTN ? (
|
|
156
167
|
<View style={style.checkboxHolder}>
|