agora-appbuilder-core 1.0.8 → 2.0.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.
Files changed (134) hide show
  1. package/package.json +5 -2
  2. package/template/_package-lock.json +22850 -0
  3. package/template/agora-rn-uikit/.git/HEAD +1 -0
  4. package/template/agora-rn-uikit/.git/config +16 -0
  5. package/template/agora-rn-uikit/.git/description +1 -0
  6. package/template/agora-rn-uikit/.git/hooks/applypatch-msg.sample +15 -0
  7. package/template/agora-rn-uikit/.git/hooks/commit-msg.sample +24 -0
  8. package/template/agora-rn-uikit/.git/hooks/fsmonitor-watchman.sample +173 -0
  9. package/template/agora-rn-uikit/.git/hooks/post-update.sample +8 -0
  10. package/template/agora-rn-uikit/.git/hooks/pre-applypatch.sample +14 -0
  11. package/template/agora-rn-uikit/.git/hooks/pre-commit.sample +49 -0
  12. package/template/agora-rn-uikit/.git/hooks/pre-merge-commit.sample +13 -0
  13. package/template/agora-rn-uikit/.git/hooks/pre-push.sample +53 -0
  14. package/template/agora-rn-uikit/.git/hooks/pre-rebase.sample +169 -0
  15. package/template/agora-rn-uikit/.git/hooks/pre-receive.sample +24 -0
  16. package/template/agora-rn-uikit/.git/hooks/prepare-commit-msg.sample +42 -0
  17. package/template/agora-rn-uikit/.git/hooks/push-to-checkout.sample +78 -0
  18. package/template/agora-rn-uikit/.git/hooks/update.sample +128 -0
  19. package/template/agora-rn-uikit/.git/index +0 -0
  20. package/template/agora-rn-uikit/.git/info/exclude +6 -0
  21. package/template/agora-rn-uikit/.git/logs/HEAD +2 -0
  22. package/template/agora-rn-uikit/.git/logs/refs/heads/ab-dev-auto +1 -0
  23. package/template/agora-rn-uikit/.git/logs/refs/heads/master +1 -0
  24. package/template/agora-rn-uikit/.git/logs/refs/remotes/origin/HEAD +1 -0
  25. package/template/agora-rn-uikit/.git/objects/pack/pack-f379286d0537eb68377220b4929979324b8d5d1c.idx +0 -0
  26. package/template/agora-rn-uikit/.git/objects/pack/pack-f379286d0537eb68377220b4929979324b8d5d1c.pack +0 -0
  27. package/template/agora-rn-uikit/.git/packed-refs +12 -0
  28. package/template/agora-rn-uikit/.git/refs/heads/ab-dev-auto +1 -0
  29. package/template/agora-rn-uikit/.git/refs/heads/master +1 -0
  30. package/template/agora-rn-uikit/.git/refs/remotes/origin/HEAD +1 -0
  31. package/template/agora-rn-uikit/.gitignore +63 -0
  32. package/template/agora-rn-uikit/package-lock.json +7612 -0
  33. package/template/agora-rn-uikit/package.json +1 -0
  34. package/template/agora-rn-uikit/src/AgoraUIKit.tsx +8 -8
  35. package/template/agora-rn-uikit/src/{LocalUserContext.tsx → Contexts/LocalUserContext.tsx} +1 -1
  36. package/template/agora-rn-uikit/src/{MaxUidContext.tsx → Contexts/MaxUidContext.tsx} +0 -0
  37. package/template/agora-rn-uikit/src/{MinUidContext.tsx → Contexts/MinUidContext.tsx} +0 -0
  38. package/template/agora-rn-uikit/src/{PropsContext.tsx → Contexts/PropsContext.tsx} +34 -16
  39. package/template/agora-rn-uikit/src/{RtcContext.tsx → Contexts/RtcContext.tsx} +12 -21
  40. package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +25 -15
  41. package/template/agora-rn-uikit/src/Controls/Icons.ts +53 -3
  42. package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +53 -0
  43. package/template/agora-rn-uikit/src/Controls/Local/EndCall.tsx +4 -3
  44. package/template/agora-rn-uikit/src/Controls/Local/FullScreen.tsx +3 -3
  45. package/template/agora-rn-uikit/src/Controls/Local/LocalAudioMute.tsx +58 -14
  46. package/template/agora-rn-uikit/src/Controls/Local/LocalVideoMute.tsx +60 -14
  47. package/template/agora-rn-uikit/src/Controls/Local/Recording.tsx +2 -2
  48. package/template/agora-rn-uikit/src/Controls/Local/Screenshare.tsx +2 -2
  49. package/template/agora-rn-uikit/src/Controls/Local/SwitchCamera.tsx +9 -9
  50. package/template/agora-rn-uikit/src/Controls/LocalControls.tsx +20 -17
  51. package/template/agora-rn-uikit/src/Controls/Remote/RemoteAudioMute.tsx +8 -8
  52. package/template/agora-rn-uikit/src/Controls/Remote/RemoteSwap.tsx +3 -3
  53. package/template/agora-rn-uikit/src/Controls/Remote/RemoteVideoMute.tsx +13 -8
  54. package/template/agora-rn-uikit/src/Controls/RemoteControls.tsx +1 -2
  55. package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +20 -0
  56. package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +20 -0
  57. package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +26 -0
  58. package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +26 -0
  59. package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +46 -0
  60. package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +47 -0
  61. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +20 -0
  62. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +20 -0
  63. package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +21 -0
  64. package/template/agora-rn-uikit/src/Reducer/index.ts +9 -0
  65. package/template/agora-rn-uikit/src/Rtc/Create.tsx +138 -0
  66. package/template/agora-rn-uikit/src/Rtc/Join.tsx +100 -0
  67. package/template/agora-rn-uikit/src/RtcConfigure.tsx +197 -0
  68. package/template/agora-rn-uikit/src/Style.ts +3 -3
  69. package/template/agora-rn-uikit/src/Utils/actionTypeGuard.tsx +9 -0
  70. package/template/agora-rn-uikit/src/{events.ts → Utils/events.ts} +0 -0
  71. package/template/agora-rn-uikit/src/{permission.ts → Utils/permission.ts} +0 -0
  72. package/template/agora-rn-uikit/src/{quality.tsx → Utils/quality.tsx} +0 -0
  73. package/template/agora-rn-uikit/src/{MaxVideoView.native.tsx → Views/MaxVideoView.native.tsx} +3 -4
  74. package/template/agora-rn-uikit/src/{MaxVideoView.tsx → Views/MaxVideoView.tsx} +3 -4
  75. package/template/agora-rn-uikit/src/Views/MinVideoView.tsx +86 -0
  76. package/template/agora-rn-uikit/src/index.ts +67 -0
  77. package/template/bridge/rtc/webNg/RtcEngine.ts +23 -6
  78. package/template/package-lock.json +22850 -0
  79. package/template/package.json +6 -4
  80. package/template/react-native-toast-message/.gitignore +5 -0
  81. package/template/react-native-toast-message/.npmignore +5 -0
  82. package/template/react-native-toast-message/package-lock.json +10553 -0
  83. package/template/src/.DS_Store +0 -0
  84. package/template/src/assets/icons.ts +35 -6
  85. package/template/src/atoms/SecondaryButton.tsx +6 -5
  86. package/template/src/atoms/TextInput.tsx +6 -1
  87. package/template/src/components/Chat.tsx +50 -21
  88. package/template/src/components/ChatContext.ts +22 -1
  89. package/template/src/components/Controls.native.tsx +2 -2
  90. package/template/src/components/Controls.tsx +2 -2
  91. package/template/src/components/DeviceConfigure.tsx +1 -1
  92. package/template/src/components/GridVideo.tsx +69 -31
  93. package/template/src/components/Navbar.tsx +136 -113
  94. package/template/src/components/NetworkQualityContext.tsx +134 -0
  95. package/template/src/components/ParticipantsView.tsx +105 -49
  96. package/template/src/components/PinnedVideo.tsx +112 -71
  97. package/template/src/components/Precall.native.tsx +42 -23
  98. package/template/src/components/Precall.tsx +56 -51
  99. package/template/src/components/RTMConfigure.tsx +331 -181
  100. package/template/src/components/RTMEvents.tsx +84 -0
  101. package/template/src/components/Settings.tsx +19 -16
  102. package/template/src/components/Share.tsx +131 -62
  103. package/template/src/components/StorageContext.tsx +2 -0
  104. package/template/src/hooks/useImageDelay.tsx +28 -0
  105. package/template/src/pages/Authenticate.tsx +5 -4
  106. package/template/src/pages/Create.tsx +26 -16
  107. package/template/src/pages/Join.tsx +13 -30
  108. package/template/src/pages/VideoCall.tsx +181 -137
  109. package/template/src/subComponents/.DS_Store +0 -0
  110. package/template/src/subComponents/ChatContainer.tsx +40 -28
  111. package/template/src/subComponents/CopyJoinInfo.tsx +9 -12
  112. package/template/src/subComponents/LocalAudioMute.tsx +9 -9
  113. package/template/src/subComponents/LocalVideoMute.tsx +9 -9
  114. package/template/src/subComponents/LogoutButton.tsx +1 -1
  115. package/template/src/subComponents/NetworkQualityPill.tsx +161 -0
  116. package/template/src/subComponents/Recording.tsx +12 -16
  117. package/template/src/subComponents/RemoteAudioMute.tsx +23 -27
  118. package/template/src/subComponents/RemoteEndCall.tsx +7 -15
  119. package/template/src/subComponents/RemoteVideoMute.tsx +15 -28
  120. package/template/src/subComponents/ScreenShareNotice.tsx +61 -0
  121. package/template/src/subComponents/ScreenshareButton.tsx +76 -75
  122. package/template/src/subComponents/SelectOAuth.tsx +25 -12
  123. package/template/src/subComponents/SwitchCamera.tsx +5 -2
  124. package/template/src/subComponents/TextWithTooltip.native.tsx +128 -0
  125. package/template/src/subComponents/TextWithTooltip.tsx +44 -0
  126. package/template/src/subComponents/toastConfig.tsx +2 -2
  127. package/template/src/utils/hasBrandLogo.tsx +3 -0
  128. package/template/src/utils/isSafariBrowser.tsx +22 -0
  129. package/template/webpack.commons.js +1 -0
  130. package/template/agora-rn-uikit/Components.js +0 -35
  131. package/template/agora-rn-uikit/Contexts.js +0 -7
  132. package/template/agora-rn-uikit/index.js +0 -12
  133. package/template/agora-rn-uikit/src/MinVideoView.tsx +0 -87
  134. package/template/agora-rn-uikit/src/RTCConfigure.tsx +0 -516
@@ -12,16 +12,16 @@
12
12
  import React, {useContext, useEffect, useRef} from 'react';
13
13
  import {Image, TouchableOpacity, StyleSheet, View, Text} from 'react-native';
14
14
  import icons from '../assets/icons';
15
- import RtcContext from '../../agora-rn-uikit/src/RtcContext';
16
- import PropsContext from '../../agora-rn-uikit/src/PropsContext';
15
+ import {RtcContext} from '../../agora-rn-uikit';
16
+ import {PropsContext} from '../../agora-rn-uikit';
17
17
  import ColorContext from '../components/ColorContext';
18
18
  import {gql, useMutation} from '@apollo/client';
19
19
  import {useParams} from '../components/Router';
20
20
  import ChatContext, {controlMessageEnum} from '../components/ChatContext';
21
- import MinUidContext from '../../agora-rn-uikit/src/MinUidContext';
22
- import MaxUidContext from '../../agora-rn-uikit/src/MaxUidContext';
21
+ import {MinUidContext} from '../../agora-rn-uikit';
22
+ import {MaxUidContext} from '../../agora-rn-uikit';
23
23
  import Layout from '../subComponents/LayoutEnum';
24
-
24
+ import {ImageIcon} from '../../agora-rn-uikit';
25
25
 
26
26
  const SET_PRESENTER = gql`
27
27
  mutation setPresenter($uid: Int!, $passphrase: String!) {
@@ -35,7 +35,6 @@ const SET_NORMAL = gql`
35
35
  }
36
36
  `;
37
37
 
38
-
39
38
  interface ScreenSharingProps {
40
39
  screenshareActive: boolean;
41
40
  setScreenshareActive: React.Dispatch<React.SetStateAction<boolean>>;
@@ -64,70 +63,76 @@ const ScreenshareButton = (props: ScreenSharingProps) => {
64
63
  const prevUsers = usePrevious({users});
65
64
  const prevUserList = usePrevious({userList});
66
65
  const {phrase} = useParams();
67
- const {screenshareActive, setScreenshareActive, setLayout, recordingActive} = props;
66
+ const {screenshareActive, setScreenshareActive, setLayout, recordingActive} =
67
+ props;
68
68
  const {channel, appId, screenShareUid, screenShareToken, encryption} =
69
69
  useContext(PropsContext).rtcProps;
70
70
 
71
71
  const [setPresenterQuery] = useMutation(SET_PRESENTER);
72
72
  const [setNormalQuery] = useMutation(SET_NORMAL);
73
-
73
+
74
74
  useEffect(() => {
75
75
  rtc.RtcEngine.addListener('ScreenshareStopped', () => {
76
76
  setScreenshareActive(false);
77
- console.log('STOPPED SHARING')
77
+ console.log('STOPPED SHARING');
78
78
  setLayout((l: Layout) =>
79
79
  l === Layout.Pinned ? Layout.Grid : Layout.Pinned,
80
80
  );
81
81
  setNormalQuery({variables: {passphrase: phrase}})
82
- .then((res) => {
83
- console.log(res.data);
84
- if (res.data.stopRecordingSession === 'success') {
85
- // Once the backend sucessfuly stops recording,
86
- // send a control message to everbody in the channel indicating that cloud recording is now inactive.
87
- // sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
88
- // set the local recording state to false to update the UI
89
- // setScreenshareActive(false);
90
- }
91
- })
92
- .catch((err) => {
93
- console.log(err);
94
- });
95
-
82
+ .then((res) => {
83
+ console.log(res.data);
84
+ if (res.data.stopRecordingSession === 'success') {
85
+ // Once the backend sucessfuly stops recording,
86
+ // send a control message to everbody in the channel indicating that cloud recording is now inactive.
87
+ // sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
88
+ // set the local recording state to false to update the UI
89
+ // setScreenshareActive(false);
90
+ }
91
+ })
92
+ .catch((err) => {
93
+ console.log(err);
94
+ });
96
95
  });
97
96
  }, []);
98
97
 
99
98
  useEffect(() => {
100
- if(prevUsers !== undefined){
101
- let joinedUser = users.filter(person => prevUsers.users.every(person2 => !(person2.uid === person.uid)))
102
- let leftUser = prevUsers.users.filter(person => users.every(person2 => !(person2.uid === person.uid)))
99
+ if (prevUsers !== undefined) {
100
+ let joinedUser = users.filter((person) =>
101
+ prevUsers.users.every((person2) => !(person2.uid === person.uid)),
102
+ );
103
+ let leftUser = prevUsers.users.filter((person) =>
104
+ users.every((person2) => !(person2.uid === person.uid)),
105
+ );
103
106
 
104
- if(joinedUser.length === 1){
107
+ if (joinedUser.length === 1) {
105
108
  const newUserUid = joinedUser[0].uid;
106
- if(userList[newUserUid] && userList[newUserUid].type === 1){
107
- dispatch({
108
- type: 'SwapVideo',
109
- value: [joinedUser[0]],
110
- });
111
- setLayout(Layout.Pinned);
112
- }else if(newUserUid === 1){
109
+ if (userList[newUserUid] && userList[newUserUid].type === 1) {
113
110
  dispatch({
114
111
  type: 'SwapVideo',
115
112
  value: [joinedUser[0]],
116
113
  });
117
114
  setLayout(Layout.Pinned);
115
+ } else if (newUserUid === 1) {
116
+ if (newUserUid !== users[0].uid) {
117
+ dispatch({
118
+ type: 'SwapVideo',
119
+ value: [joinedUser[0]],
120
+ });
121
+ }
122
+ setLayout(Layout.Pinned);
118
123
  }
119
124
  }
120
125
 
121
- if(leftUser.length === 1){
126
+ if (leftUser.length === 1) {
122
127
  const leftUserUid = leftUser[0].uid;
123
- if(userList[leftUserUid] && userList[leftUserUid].type === 1){
124
- setLayout((l: Layout) =>
125
- l === Layout.Pinned ? Layout.Grid : Layout.Pinned,
126
- );
128
+ if (userList[leftUserUid] && userList[leftUserUid].type === 1) {
129
+ setLayout((l: Layout) =>
130
+ l === Layout.Pinned ? Layout.Grid : Layout.Pinned,
131
+ );
127
132
  }
128
133
  }
129
- }
130
- }, [users, userList])
134
+ }
135
+ }, [users, userList]);
131
136
  return (
132
137
  <TouchableOpacity
133
138
  onPress={async () => {
@@ -152,7 +157,7 @@ const ScreenshareButton = (props: ScreenSharingProps) => {
152
157
  .catch((err) => {
153
158
  console.log(err);
154
159
  });
155
- } else if(isScreenActive && recordingActive){
160
+ } else if (isScreenActive && recordingActive) {
156
161
  // If recording is already going on, stop the recording by executing the graphql query.
157
162
  setNormalQuery({variables: {passphrase: phrase}})
158
163
  .then((res) => {
@@ -183,41 +188,38 @@ const ScreenshareButton = (props: ScreenSharingProps) => {
183
188
  } catch (e) {
184
189
  console.error("can't start the screen share", e);
185
190
  setNormalQuery({variables: {passphrase: phrase}})
186
- .then((res) => {
187
- console.log(res.data);
188
- if (res.data.stopRecordingSession === 'success') {
189
- // Once the backend sucessfuly stops recording,
190
- // send a control message to everbody in the channel indicating that cloud recording is now inactive.
191
- // sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
192
- // set the local recording state to false to update the UI
193
- // setScreenshareActive(false);
194
- }
195
- })
196
- .catch((err) => {
197
- console.log(err);
198
- });
191
+ .then((res) => {
192
+ console.log(res.data);
193
+ if (res.data.stopRecordingSession === 'success') {
194
+ // Once the backend sucessfuly stops recording,
195
+ // send a control message to everbody in the channel indicating that cloud recording is now inactive.
196
+ // sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
197
+ // set the local recording state to false to update the UI
198
+ // setScreenshareActive(false);
199
+ }
200
+ })
201
+ .catch((err) => {
202
+ console.log(err);
203
+ });
199
204
  }
200
205
  }}>
201
- <View style={
202
- screenshareActive
203
- ? style.greenLocalButton
204
- : [style.localButton, {borderColor: primaryColor}]
205
- }>
206
- <Image
207
- source={{
208
- uri: screenshareActive
209
- ? icons.screenshareOffIcon
210
- : icons.screenshareIcon,
211
- }}
212
- style={[style.buttonIcon, {tintColor: primaryColor}]}
213
- resizeMode={'contain'}
214
- />
206
+ <View
207
+ style={
208
+ screenshareActive
209
+ ? style.greenLocalButton
210
+ : [style.localButton, {borderColor: primaryColor}]
211
+ }>
212
+ <ImageIcon
213
+ name={screenshareActive ? 'screenshareOffIcon' : 'screenshareIcon'}
214
+ style={[style.buttonIcon]}
215
+ />
215
216
  </View>
216
- <Text style={{
217
- textAlign: 'center',
218
- marginTop: 5,
219
- color: $config.PRIMARY_COLOR,
220
- }}>
217
+ <Text
218
+ style={{
219
+ textAlign: 'center',
220
+ marginTop: 5,
221
+ color: $config.PRIMARY_COLOR,
222
+ }}>
221
223
  Share
222
224
  </Text>
223
225
  </TouchableOpacity>
@@ -249,7 +251,6 @@ const style = StyleSheet.create({
249
251
  buttonIcon: {
250
252
  width: '90%',
251
253
  height: '90%',
252
- tintColor: $config.PRIMARY_COLOR,
253
254
  },
254
255
  });
255
256
 
@@ -17,56 +17,69 @@ import apple from '../assets/apple.png';
17
17
  import slack from '../assets/slack.png';
18
18
  import microsoft from '../assets/microsoft.png';
19
19
  import Logo from './Logo';
20
+ import hasBrandLogo from '../utils/hasBrandLogo';
20
21
 
21
22
  const SelectOAuth = ({onSelectOAuth}) => {
22
23
  // Linking.openURL(url);
23
24
  const {primaryColor} = useContext(ColorContext);
24
25
  return (
25
26
  <View style={style.main}>
26
- <View style={style.nav}>
27
- <Logo />
28
- </View>
27
+ <View style={style.nav}>{hasBrandLogo && <Logo />}</View>
29
28
  <View style={style.content}>
30
29
  <View style={style.leftContent}>
31
30
  <Text style={style.heading}>{$config.APP_NAME}</Text>
32
31
  <Text style={style.headline}>{$config.LANDING_SUB_HEADING}</Text>
33
32
  <View style={style.inputs}>
34
33
  <View style={style.oAuthContainer}>
35
- <Text style={{fontSize: 16, fontWeight: '500', marginBottom: 20, color: $config.PRIMARY_FONT_COLOR}}>
34
+ <Text
35
+ style={{
36
+ fontSize: 16,
37
+ fontWeight: '500',
38
+ marginBottom: 20,
39
+ color: $config.PRIMARY_FONT_COLOR,
40
+ }}>
36
41
  Login using OAuth
37
42
  </Text>
38
- {$config.ENABLE_GOOGLE_OAUTH ?
43
+ {$config.ENABLE_GOOGLE_OAUTH ? (
39
44
  <TouchableOpacity
40
45
  style={[style.secondaryBtn, {borderColor: primaryColor}]}
41
46
  onPress={() => onSelectOAuth({oAuthSystem: 'google'})}>
42
47
  <Image source={google} style={style.logo} />
43
48
  <Text style={[style.secondaryBtnText]}>Google</Text>
44
49
  </TouchableOpacity>
45
- : <></>}
46
- {$config.ENABLE_MICROSOFT_OAUTH ?
50
+ ) : (
51
+ <></>
52
+ )}
53
+ {$config.ENABLE_MICROSOFT_OAUTH ? (
47
54
  <TouchableOpacity
48
55
  style={[style.secondaryBtn, {borderColor: primaryColor}]}
49
56
  onPress={() => onSelectOAuth({oAuthSystem: 'microsoft'})}>
50
57
  <Image source={microsoft} style={style.logo} />
51
58
  <Text style={[style.secondaryBtnText]}>Microsoft</Text>
52
59
  </TouchableOpacity>
53
- : <></>}
54
- {$config.ENABLE_SLACK_OAUTH ?
60
+ ) : (
61
+ <></>
62
+ )}
63
+ {$config.ENABLE_SLACK_OAUTH ? (
55
64
  <TouchableOpacity
56
65
  style={[style.secondaryBtn, {borderColor: primaryColor}]}
57
66
  onPress={() => onSelectOAuth({oAuthSystem: 'slack'})}>
58
67
  <Image source={slack} style={style.logo} />
59
68
  <Text style={[style.secondaryBtnText]}>Slack</Text>
60
69
  </TouchableOpacity>
61
- : <></>}
62
- {$config.ENABLE_APPLE_OAUTH ?
70
+ ) : (
71
+ <></>
72
+ )}
73
+ {$config.ENABLE_APPLE_OAUTH ? (
63
74
  <TouchableOpacity
64
75
  style={[style.secondaryBtn, {borderColor: primaryColor}]}
65
76
  onPress={() => onSelectOAuth({oAuthSystem: 'apple'})}>
66
77
  <Image source={apple} style={style.logo} />
67
78
  <Text style={[style.secondaryBtnText]}>Apple</Text>
68
79
  </TouchableOpacity>
69
- : <></>}
80
+ ) : (
81
+ <></>
82
+ )}
70
83
  </View>
71
84
  </View>
72
85
  </View>
@@ -1,14 +1,17 @@
1
1
  import React, {useContext} from 'react';
2
2
  import {StyleSheet} from 'react-native';
3
- import RtcContext, {DispatchType} from '../../agora-rn-uikit/src/RtcContext';
4
- import BtnTemplate from '../../agora-rn-uikit/src/Controls/BtnTemplate';
3
+ import {RtcContext} from '../../agora-rn-uikit';
4
+ import {BtnTemplate} from '../../agora-rn-uikit';
5
+ import {LocalContext} from '../../agora-rn-uikit';
5
6
 
6
7
  function SwitchCamera() {
7
8
  const {RtcEngine} = useContext(RtcContext);
9
+ const local = useContext(LocalContext);
8
10
  return (
9
11
  <BtnTemplate
10
12
  name={'switchCamera'}
11
13
  btnText={'Switch'}
14
+ disabled={local.video ? false : true }
12
15
  style={{
13
16
  backgroundColor: $config.SECONDARY_FONT_COLOR, //'#fff',
14
17
  borderRadius: 23,
@@ -0,0 +1,128 @@
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, {useState, useRef} from 'react';
13
+ import {View, Text, Modal, TouchableOpacity, TouchableWithoutFeedback, StyleSheet, useWindowDimensions} from 'react-native';
14
+ /**
15
+ * Component showing text with tooltip on mobile native
16
+ */
17
+ const TextWithToolTip = (props: any) => {
18
+ const {width:globalWidth, height:globalHeight} = useWindowDimensions();
19
+ const [toolTipVisible, setToolTipVisible] = useState(false);
20
+ const [position, setPosition] = useState({})
21
+ const ref = useRef(null);
22
+ /**
23
+ * Private chat user list - we are using this component to show the username and that component itself clickable
24
+ * and user will navigate to next screen(chatting screen) so if we had touchable here they can't proceed futher,
25
+ * hence checked tocuable flag and creating the view based on that
26
+ * */
27
+ const CustomView = props?.touchable === false ? View : TouchableOpacity
28
+ return(
29
+ <View style={{flex: 1}}>
30
+ <Modal
31
+ animationType="fade"
32
+ transparent={true}
33
+ visible={toolTipVisible}
34
+ onRequestClose={() => {
35
+ setToolTipVisible(!toolTipVisible);
36
+ }}
37
+ >
38
+ <TouchableWithoutFeedback onPress={()=>{setToolTipVisible(!toolTipVisible)}}>
39
+ <View
40
+ style={style.backDrop}
41
+ />
42
+ </TouchableWithoutFeedback>
43
+ <View style={[style.textContainer, position]}>
44
+ <Text style={style.textStyle}>{props.value}</Text>
45
+ </View>
46
+ </Modal>
47
+ <CustomView style={{flex:1}} ref={ref} onPress={() => {
48
+ ref?.current?.measure( (fx: number, fy: number, localWidth: number, localHeight: number, px: number, py: number) => {
49
+ /* To display the tooltip we are setting to position and maxwidth. so it will display above and below actual name present with modal.
50
+ ---------
51
+ | A | B |
52
+ ---------
53
+ | C | D |
54
+ ---------
55
+ Assume we are spliting mobile/tablet screen into 4 section
56
+
57
+ When user click any username doing below the calculation to find (left or right postion and maxwidth).
58
+ so it won't hidden and we can use the maximum area to show tooltip
59
+
60
+ For ex:
61
+ Case 1: If element is present in the A or C section then we will set position top and left
62
+ Case 2: If element is present in the B or D section then we will set position top and right position
63
+
64
+ Note : we are also can doing some calculation based on height so that text won't hidden in the bottom.
65
+ **/
66
+
67
+ const rightPos = (globalWidth - (px + localWidth)) - 20 < 0 ? 10 : (globalWidth - (px + localWidth)) - 20
68
+ const leftPos = px < 0 ? 10 : px
69
+ if(px > globalWidth/2){
70
+ if(py > globalHeight/2){
71
+ setPosition({
72
+ top: py - localHeight,
73
+ right: rightPos,
74
+ maxWidth: (globalWidth - rightPos) - 30,
75
+ })
76
+ }else{
77
+ setPosition({
78
+ top: py+localHeight,
79
+ right: rightPos,
80
+ maxWidth: (globalWidth - rightPos) - 30,
81
+ })
82
+ }
83
+ }else{
84
+ if(py > globalHeight/2){
85
+ setPosition({
86
+ top: py - localHeight,
87
+ left: leftPos,
88
+ maxWidth: (globalWidth - leftPos - 5),
89
+ })
90
+ }else{
91
+ setPosition({
92
+ top: py+localHeight,
93
+ left: leftPos,
94
+ maxWidth: (globalWidth - leftPos - 5),
95
+ })
96
+ }
97
+ }
98
+ setTimeout(() =>{
99
+ setToolTipVisible(!toolTipVisible)
100
+ })
101
+ })
102
+ }}>
103
+ <Text style={props.style} numberOfLines={1}>{props.value}</Text>
104
+ </CustomView>
105
+ </View>
106
+ )
107
+ };
108
+
109
+ const style = StyleSheet.create({
110
+ backDrop:{
111
+ position: 'absolute',
112
+ top: 0,
113
+ bottom: 0,
114
+ left: 0,
115
+ right: 0,
116
+ backgroundColor: 'rgba(0,0,0,0.5)'
117
+ },
118
+ textContainer:{
119
+ position: 'absolute',
120
+ zIndex: 999,
121
+ marginRight: 20
122
+ },
123
+ textStyle:{
124
+ backgroundColor:'white', padding: 5, margin: 5
125
+ }
126
+ })
127
+
128
+ export default TextWithToolTip;
@@ -0,0 +1,44 @@
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 {Text} from 'react-native';
14
+ import mobileAndTabletCheck from '../utils/mobileWebTest';
15
+ import TextWithToolTipNative from './TextWithTooltip.native';
16
+ /**
17
+ * Text with tooltip
18
+ * web - used title attribute to show the tooltip
19
+ */
20
+ const TextWithToolTip = (props: any) => {
21
+ return(
22
+ <div
23
+ style={style.containerStyle}
24
+ title={props.value}
25
+ >
26
+ <Text
27
+ numberOfLines={1}
28
+ textBreakStrategy='simple'
29
+ style={[props.style]}
30
+ >{props.value}</Text>
31
+ </div>
32
+ )
33
+ };
34
+
35
+ const style = {
36
+ containerStyle:{
37
+ display: 'flex'
38
+ },
39
+ }
40
+ /**
41
+ * Web and Desktop : using the TextWithToolTip - which have the browser tooltip
42
+ * Mobile and Mobile Web : using the TextWithToolTipNative - which have the custom tooltip using modal
43
+ */
44
+ export default mobileAndTabletCheck() ? TextWithToolTipNative : TextWithToolTip;
@@ -24,11 +24,11 @@ const toastConfig = {
24
24
  {...rest}
25
25
  //BaseToast is modified to have zIndex: 100
26
26
  style={{ borderLeftColor: $config.PRIMARY_COLOR, backgroundColor: $config.SECONDARY_FONT_COLOR, width: !mobileAndTabletCheck() ? '40%' : '95%'}}
27
- contentContainerStyle={{ paddingHorizontal: 15 }}
27
+ contentContainerStyle={{ paddingHorizontal: 15, overflow: 'hidden'}}
28
28
  text1Style={{
29
29
  fontSize: 15,
30
30
  fontWeight: '400',
31
- color: $config.PRIMARY_FONT_COLOR,
31
+ color: $config.PRIMARY_FONT_COLOR
32
32
  }}
33
33
  text1={text1}
34
34
  text2={text2}
@@ -0,0 +1,3 @@
1
+ const hasBrandLogo: boolean = !!$config.LOGO;
2
+
3
+ export default hasBrandLogo;
@@ -0,0 +1,22 @@
1
+ const isSafariBrowser = () => {
2
+ if (!('userAgent' in navigator)) {
3
+ console.warn('unable to detect browser');
4
+ return false;
5
+ }
6
+
7
+ const userAgentString = navigator.userAgent;
8
+ // Detect Chrome
9
+ const chromeAgent = userAgentString.indexOf('Chrome') > -1;
10
+ // Detect Safari
11
+ const safariAgent = userAgentString.indexOf('Safari') > -1;
12
+
13
+ // One additional check is required in the case of the Safari browser
14
+ // as the user-agent of the Chrome browser also includes the Safari browser’s user-agent.
15
+ // If both the user-agents of Chrome and Safari are in the user-agent,
16
+ // it means that the browser is Chrome, and hence the Safari browser value is discarded.
17
+
18
+ if (chromeAgent && safariAgent) return false; // Discard Safari since it also matches Chrome
19
+ return true;
20
+ };
21
+
22
+ export default isSafariBrowser;
@@ -94,6 +94,7 @@ module.exports = {
94
94
  plugins: [
95
95
  // Adds support for class properties
96
96
  ['transform-define', configVars],
97
+ '@babel/plugin-proposal-optional-chaining',
97
98
  '@babel/plugin-proposal-class-properties',
98
99
  isDevelopment && require.resolve('react-refresh/babel'),
99
100
  ].filter(Boolean),
@@ -1,35 +0,0 @@
1
- import Endcall from './src/Controls/Local/EndCall';
2
- import FullScreen from './src/Controls/Local/FullScreen';
3
- import LocalAudioMute from './src/Controls/Local/LocalAudioMute';
4
- import LocalVideoMute from './src/Controls/Local/LocalVideoMute';
5
- import SwitchCamera from './src/Controls/Local/SwitchCamera';
6
- import Controls from './src/Controls/LocalControls';
7
- import RemoteAudioMute from './src/Controls/Remote/RemoteAudioMute';
8
- import RemoteSwap from './src/Controls/Remote/RemoteSwap';
9
- import RemoteVideoMute from './src/Controls/Remote/RemoteVideoMute';
10
- import RemoteControls from './src/Controls/RemoteControls';
11
- import MaxVideoView from './src/MaxVideoView';
12
- import MinVideoView from './src/MinVideoView';
13
- import RtcConfigure from "./src/RTCConfigure";
14
- import BtnTemplate from "./src/Controls/BtnTemplate";
15
- import Recording from './src/Controls/Local/Recording';
16
- import Screenshare from './src/Controls/Local/Screenshare';
17
-
18
- export {
19
- Endcall,
20
- FullScreen,
21
- LocalAudioMute,
22
- LocalVideoMute,
23
- SwitchCamera,
24
- Controls,
25
- RemoteAudioMute,
26
- RemoteSwap,
27
- RemoteVideoMute,
28
- RemoteControls,
29
- MaxVideoView,
30
- MinVideoView,
31
- RtcConfigure,
32
- BtnTemplate,
33
- Recording,
34
- Screenshare,
35
- };
@@ -1,7 +0,0 @@
1
- import MaxUidContext from './src/MaxUidContext';
2
- import MinUidContext from './src/MinUidContext';
3
- import PropsContext from './src/PropsContext';
4
- import RtcContext from './src/RtcContext';
5
- import LocalUserContext, {LocalContext} from "./src/LocalUserContext";
6
-
7
- export { MaxUidContext, MinUidContext, PropsContext, RtcContext, LocalUserContext, LocalContext };
@@ -1,12 +0,0 @@
1
- /**
2
- * @format
3
- */
4
-
5
- // import {AppRegistry} from 'react-native';
6
- // import App from './App';
7
- // import {name as appName} from './app.json';
8
-
9
- // AppRegistry.registerComponent(appName, () => App);
10
-
11
- import AgoraUIKit from './src/AgoraUIKit';
12
- export default AgoraUIKit;