agora-appbuilder-core 3.0.9 → 3.0.10

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 (248) hide show
  1. package/Readme.md +6 -0
  2. package/package.json +2 -2
  3. package/template/_package-lock.json +5871 -4728
  4. package/template/agora-rn-uikit/src/Contexts/LocalUserContext.tsx +4 -0
  5. package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +18 -0
  6. package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +2 -0
  7. package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +30 -26
  8. package/template/agora-rn-uikit/src/Controls/Icons.ts +30 -83
  9. package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +6 -6
  10. package/template/agora-rn-uikit/src/Reducer/ActiveSpeakerDetected.ts +11 -0
  11. package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +1 -0
  12. package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +1 -0
  13. package/template/agora-rn-uikit/src/Reducer/LocalPermissionState.ts +24 -0
  14. package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +1 -0
  15. package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +1 -0
  16. package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +1 -0
  17. package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +2 -0
  18. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +1 -0
  19. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +1 -0
  20. package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +1 -0
  21. package/template/agora-rn-uikit/src/Reducer/UserPin.ts +11 -0
  22. package/template/agora-rn-uikit/src/Reducer/index.ts +3 -0
  23. package/template/agora-rn-uikit/src/Rtc/Create.tsx +89 -1
  24. package/template/agora-rn-uikit/src/RtcConfigure.tsx +39 -2
  25. package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +15 -5
  26. package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +15 -9
  27. package/template/agora-rn-uikit/src/index.ts +3 -1
  28. package/template/android/app/build.gradle +1 -0
  29. package/template/android/app/src/main/AndroidManifest.xml +22 -15
  30. package/template/android/app/src/main/assets/fonts/SourceSansPro-Regular.ttf +0 -0
  31. package/template/android/app/src/main/assets/fonts/icomoon.ttf +0 -0
  32. package/template/android/app/src/main/java/com/helloworld/MainActivity.java +50 -0
  33. package/template/android/app/src/main/res/values/colors.xml +7 -0
  34. package/template/android/build.gradle +3 -3
  35. package/template/babel.config.js +1 -0
  36. package/template/bridge/rtc/webNg/RtcEngine.ts +110 -17
  37. package/template/customization-api/sub-components.ts +1 -1
  38. package/template/customization-api/typeDefinition.ts +2 -1
  39. package/template/electron/index.html +27 -27
  40. package/template/electron/renderer/index.js +1 -0
  41. package/template/global.d.ts +25 -4
  42. package/template/index.rsdk.tsx +1 -0
  43. package/template/index.web.js +2 -1
  44. package/template/index.wsdk.tsx +1 -1
  45. package/template/ios/HelloWorld/Info.plist +14 -1
  46. package/template/ios/HelloWorld.xcodeproj/project.pbxproj +17 -0
  47. package/template/metro.config.js +1 -1
  48. package/template/package.json +18 -7
  49. package/template/react-native-toast-message/index.d.ts +43 -43
  50. package/template/react-native-toast-message/src/colors/index.js +3 -2
  51. package/template/react-native-toast-message/src/components/base/index.js +46 -59
  52. package/template/react-native-toast-message/src/components/base/styles.js +16 -32
  53. package/template/react-native-toast-message/src/components/checkbox.js +178 -0
  54. package/template/react-native-toast-message/src/components/error.js +3 -2
  55. package/template/react-native-toast-message/src/components/info.js +3 -2
  56. package/template/react-native-toast-message/src/components/success.js +3 -2
  57. package/template/react-native-toast-message/src/index.js +122 -31
  58. package/template/react-native-toast-message/src/index.sdk.tsx +125 -35
  59. package/template/react-native-toast-message/src/styles.js +3 -4
  60. package/template/react-native-toast-message/src/styles.sdk.ts +3 -4
  61. package/template/react-native.config.js +7 -0
  62. package/template/src/App.tsx +6 -0
  63. package/template/src/AppWrapper.tsx +63 -28
  64. package/template/src/assets/font-styles.css +329 -0
  65. package/template/src/assets/fonts/SourceSansPro-Regular.ttf +0 -0
  66. package/template/src/assets/fonts/icomoon.ttf +0 -0
  67. package/template/src/assets/permission.png +0 -0
  68. package/template/src/assets/selection.json +1 -0
  69. package/template/src/atoms/ActionMenu.tsx +236 -0
  70. package/template/src/atoms/AnimatedActiveSpeaker.native.tsx +71 -0
  71. package/template/src/atoms/AnimatedActiveSpeaker.tsx +84 -0
  72. package/template/src/atoms/AnimatedRings.native.tsx +68 -0
  73. package/template/src/atoms/AnimatedRings.tsx +70 -0
  74. package/template/src/atoms/Card.tsx +61 -0
  75. package/template/src/atoms/CircularProgress.native.tsx +121 -0
  76. package/template/src/atoms/CircularProgress.tsx +102 -0
  77. package/template/src/atoms/CustomIcon.tsx +88 -0
  78. package/template/src/atoms/CustomSwitch.tsx +287 -0
  79. package/template/src/atoms/Dropdown.tsx +306 -0
  80. package/template/src/atoms/HorizontalRule.tsx +3 -1
  81. package/template/src/atoms/IconButton.tsx +162 -0
  82. package/template/src/atoms/ImageIcon.tsx +98 -0
  83. package/template/src/atoms/InfoBubble.tsx +291 -0
  84. package/template/src/atoms/Input.tsx +87 -0
  85. package/template/src/atoms/InviteInfo.tsx +166 -0
  86. package/template/src/atoms/LinkButton.tsx +28 -0
  87. package/template/src/atoms/OutlineButton.tsx +61 -0
  88. package/template/src/atoms/ParticipantsCount.tsx +73 -0
  89. package/template/src/atoms/Popup.tsx +147 -0
  90. package/template/src/atoms/PrimaryButton.tsx +51 -26
  91. package/template/src/atoms/RecordingInfo.tsx +49 -0
  92. package/template/src/atoms/SecondaryButton.tsx +8 -5
  93. package/template/src/atoms/Spacer.tsx +22 -0
  94. package/template/src/atoms/TertiaryButton.tsx +78 -0
  95. package/template/src/atoms/TextInput.tsx +12 -14
  96. package/template/src/atoms/Toggle.tsx +47 -0
  97. package/template/src/atoms/Tooltip.native.tsx +65 -0
  98. package/template/src/atoms/Tooltip.tsx +94 -0
  99. package/template/src/atoms/UserAvatar.tsx +60 -0
  100. package/template/src/components/Chat.tsx +86 -214
  101. package/template/src/components/ChatContext.ts +8 -1
  102. package/template/src/components/ColorConfigure.tsx +1 -1
  103. package/template/src/components/ColorContext.ts +1 -1
  104. package/template/src/components/CommonStyles.ts +44 -0
  105. package/template/src/components/Controls.tsx +342 -42
  106. package/template/src/components/{Controls.native.tsx → Controls1.native.tsx} +6 -4
  107. package/template/src/components/DeviceConfigure.tsx +461 -101
  108. package/template/src/components/DeviceContext.tsx +8 -4
  109. package/template/src/components/EventsConfigure.tsx +144 -7
  110. package/template/src/components/GraphQLProvider.tsx +1 -1
  111. package/template/src/components/GridVideo.tsx +59 -44
  112. package/template/src/components/HostControlView.tsx +114 -35
  113. package/template/src/components/Navbar.tsx +216 -398
  114. package/template/src/components/NetworkQualityContext.tsx +20 -20
  115. package/template/src/components/ParticipantsView.tsx +177 -154
  116. package/template/src/components/PinnedVideo.tsx +207 -120
  117. package/template/src/components/Precall.native.tsx +358 -119
  118. package/template/src/components/Precall.tsx +269 -135
  119. package/template/src/components/RTMConfigure.tsx +27 -4
  120. package/template/src/components/Router.electron.ts +1 -0
  121. package/template/src/components/Router.native.ts +1 -0
  122. package/template/src/components/Router.sdk.ts +1 -0
  123. package/template/src/components/Router.ts +1 -0
  124. package/template/src/components/Settings.tsx +26 -95
  125. package/template/src/components/SettingsView.tsx +251 -56
  126. package/template/src/components/Share.tsx +302 -273
  127. package/template/src/components/StorageContext.tsx +30 -3
  128. package/template/src/components/ToastComponent.tsx +8 -0
  129. package/template/src/components/chat-messages/useChatMessages.tsx +69 -23
  130. package/template/src/components/chat-ui/useChatUIControl.tsx +7 -0
  131. package/template/src/components/common/Error.tsx +20 -6
  132. package/template/src/components/common/Logo.tsx +16 -15
  133. package/template/src/components/contexts/LiveStreamDataContext.tsx +10 -5
  134. package/template/src/components/contexts/VideoMeetingDataContext.tsx +37 -7
  135. package/template/src/components/livestream/LiveStreamContext.tsx +270 -36
  136. package/template/src/components/livestream/Types.ts +39 -14
  137. package/template/src/components/livestream/index.ts +1 -0
  138. package/template/src/components/livestream/views/LiveStreamControls.tsx +12 -4
  139. package/template/src/components/participants/AllAudienceParticipants.tsx +101 -30
  140. package/template/src/components/participants/AllHostParticipants.tsx +103 -34
  141. package/template/src/components/participants/Participant.tsx +302 -0
  142. package/template/src/components/participants/ParticipantName.tsx +13 -7
  143. package/template/src/components/participants/ParticipantSectionTitle.tsx +35 -10
  144. package/template/src/components/participants/ScreenshareParticipants.tsx +144 -12
  145. package/template/src/components/participants/UserActionMenuOptions.tsx +398 -0
  146. package/template/src/components/popups/InvitePopup.tsx +115 -0
  147. package/template/src/components/popups/StopRecordingPopup.tsx +114 -0
  148. package/template/src/components/precall/LocalMute.tsx +84 -14
  149. package/template/src/components/precall/{LocalMute.native.tsx → LocalMute1.native.tsx} +21 -5
  150. package/template/src/components/precall/PermissionHelper.native.tsx +5 -0
  151. package/template/src/components/precall/PermissionHelper.tsx +126 -0
  152. package/template/src/components/precall/PreCallSettings.tsx +52 -0
  153. package/template/src/components/precall/VideoPreview.native.tsx +48 -3
  154. package/template/src/components/precall/VideoPreview.tsx +163 -7
  155. package/template/src/components/precall/joinCallBtn.tsx +15 -2
  156. package/template/src/components/precall/meetingTitle.tsx +15 -12
  157. package/template/src/components/precall/selectDevice.tsx +1 -21
  158. package/template/src/components/precall/textInput.tsx +32 -4
  159. package/template/src/components/precall/usePreCall.tsx +16 -0
  160. package/template/src/components/styles.ts +42 -21
  161. package/template/src/components/useShareLink.tsx +12 -14
  162. package/template/src/components/useToast.tsx +41 -0
  163. package/template/src/components/useVideoCall.tsx +65 -0
  164. package/template/src/language/default-labels/precallScreenLabels.ts +3 -3
  165. package/template/src/pages/Authenticate.tsx +5 -15
  166. package/template/src/pages/Create.tsx +293 -165
  167. package/template/src/pages/Endcall.tsx +148 -0
  168. package/template/src/pages/Join.tsx +93 -67
  169. package/template/src/pages/VideoCall.tsx +89 -64
  170. package/template/src/pages/video-call/ActionSheet.native.tsx +215 -0
  171. package/template/src/pages/video-call/ActionSheet.tsx +226 -0
  172. package/template/src/pages/video-call/ActionSheetContent.tsx +479 -0
  173. package/template/src/pages/video-call/ActionSheetHandle.tsx +38 -0
  174. package/template/src/pages/video-call/ActionSheetStyles.css +138 -0
  175. package/template/src/pages/video-call/DefaultLayouts.ts +4 -4
  176. package/template/src/pages/video-call/NameWithMicIcon.tsx +120 -44
  177. package/template/src/pages/video-call/RenderComponent.tsx +3 -2
  178. package/template/src/pages/video-call/SidePanelHeader.tsx +190 -0
  179. package/template/src/pages/video-call/VideoCallMobileView.tsx +139 -0
  180. package/template/src/pages/video-call/VideoCallScreen.native.tsx +37 -0
  181. package/template/src/pages/video-call/VideoCallScreen.tsx +45 -9
  182. package/template/src/pages/video-call/VideoComponent.tsx +18 -3
  183. package/template/src/pages/video-call/VideoRenderer.tsx +218 -60
  184. package/template/src/rtm-events/constants.ts +2 -0
  185. package/template/src/subComponents/ChatBubble.tsx +123 -83
  186. package/template/src/subComponents/ChatContainer.tsx +257 -84
  187. package/template/src/subComponents/ChatInput.ios.tsx +237 -0
  188. package/template/src/subComponents/ChatInput.tsx +61 -46
  189. package/template/src/subComponents/Checkbox.native.tsx +16 -5
  190. package/template/src/subComponents/Checkbox.tsx +2 -2
  191. package/template/src/subComponents/CopyJoinInfo.tsx +36 -58
  192. package/template/src/subComponents/EndcallPopup.tsx +107 -0
  193. package/template/src/subComponents/FallbackLogo.tsx +122 -40
  194. package/template/src/subComponents/LanguageSelector.tsx +1 -1
  195. package/template/src/subComponents/LayoutIconButton.tsx +201 -0
  196. package/template/src/subComponents/LayoutIconDropdown.tsx +131 -134
  197. package/template/src/subComponents/{LayoutIconDropdown.native.tsx → LayoutIconDropdown1.native.tsx} +4 -18
  198. package/template/src/subComponents/LocalAudioMute.tsx +119 -27
  199. package/template/src/subComponents/LocalEndCall.tsx +71 -33
  200. package/template/src/subComponents/LocalSwitchCamera.tsx +17 -30
  201. package/template/src/subComponents/LocalVideoMute.tsx +117 -27
  202. package/template/src/subComponents/Logo.tsx +3 -4
  203. package/template/src/subComponents/LogoutButton.tsx +1 -1
  204. package/template/src/subComponents/NetworkQualityPill.tsx +60 -63
  205. package/template/src/subComponents/OpenInNativeButton.tsx +3 -3
  206. package/template/src/subComponents/Recording.tsx +28 -29
  207. package/template/src/subComponents/RemoteAudioMute.tsx +83 -29
  208. package/template/src/subComponents/RemoteEndCall.tsx +8 -5
  209. package/template/src/subComponents/RemoteMutePopup.tsx +193 -0
  210. package/template/src/subComponents/RemoteVideoMute.tsx +74 -21
  211. package/template/src/subComponents/RemoveMeetingPopup.tsx +109 -0
  212. package/template/src/subComponents/RemoveScreensharePopup.tsx +109 -0
  213. package/template/src/subComponents/ScreenShareNotice.tsx +83 -8
  214. package/template/src/subComponents/SelectDevice.tsx +404 -61
  215. package/template/src/subComponents/SelectDeviceSettings.backup.tsx +207 -0
  216. package/template/src/subComponents/SelectOAuth.tsx +9 -8
  217. package/template/src/subComponents/SidePanelHeader.tsx +112 -0
  218. package/template/src/subComponents/ToastConfig.tsx +150 -10
  219. package/template/src/subComponents/chat/ChatParticipants.tsx +187 -78
  220. package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +95 -32
  221. package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +29 -33
  222. package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +6 -6
  223. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +24 -11
  224. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +17 -10
  225. package/template/src/subComponents/recording/useRecording.tsx +79 -27
  226. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +52 -70
  227. package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +11 -2
  228. package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +26 -4
  229. package/template/src/theme/index.ts +46 -0
  230. package/template/src/utils/PlatformWrapper.tsx +21 -0
  231. package/template/src/utils/common.tsx +155 -1
  232. package/template/src/utils/hexadecimalTransparency.ts +108 -0
  233. package/template/src/utils/index.tsx +19 -0
  234. package/template/src/utils/isMobileOrTablet.ts +7 -2
  235. package/template/src/utils/pendingStateUpdateHelper.ts +19 -0
  236. package/template/src/utils/useButtonTemplate.tsx +1 -0
  237. package/template/src/utils/useFocus.tsx +46 -0
  238. package/template/src/utils/useIsActiveSpeaker.ts +27 -0
  239. package/template/src/utils/useIsHandRaised.ts +13 -0
  240. package/template/src/utils/useMuteToggleLocal.ts +54 -3
  241. package/template/src/utils/useRemoteEndScreenshare.ts +26 -0
  242. package/template/src/utils/useRemoteRequest.ts +84 -0
  243. package/template/web/index.html +5 -0
  244. package/template/webpack.commons.js +13 -8
  245. package/template/webpack.web.config.js +1 -0
  246. package/template/src/assets/icons.ts +0 -102
  247. package/template/src/components/participants/MeParticipant.tsx +0 -38
  248. package/template/src/components/participants/RemoteParticipants.tsx +0 -71
@@ -1,29 +1,36 @@
1
1
  import React, {useContext} from 'react';
2
2
  import {View} from 'react-native';
3
- import {BtnTemplate, PropsContext, UidType} from '../../../../agora-rn-uikit';
3
+ import {PropsContext, UidType} from '../../../../agora-rn-uikit';
4
4
  import LiveStreamContext from '../../../components/livestream';
5
- import icons from '../../../assets/icons';
5
+ import TertiaryButton from '../../../atoms/TertiaryButton';
6
+ import Toast from '../../../../react-native-toast-message';
6
7
 
7
8
  interface RemoteLiveStreamControlProps {
8
9
  uid: UidType;
10
+ toastId: number;
9
11
  }
10
12
 
11
13
  const RemoteLiveStreamRequestReject = (props: RemoteLiveStreamControlProps) => {
12
- const {uid} = props;
14
+ const {uid, toastId} = props;
13
15
  const {hostRejectsRequestOfUID} = useContext(LiveStreamContext);
14
- const {styleProps} = useContext(PropsContext);
15
- const {remoteBtnStyles} = styleProps || {};
16
- const {liveStreamHostControlBtns} = remoteBtnStyles || {};
17
16
 
18
17
  return (
19
- <View style={{...(liveStreamHostControlBtns as object)}}>
20
- <BtnTemplate
18
+ <View style={{flex: 1}}>
19
+ <TertiaryButton
20
+ containerStyle={{
21
+ paddingHorizontal: 8,
22
+ paddingVertical: 8,
23
+ height: 38,
24
+ }}
21
25
  disabled={!uid}
22
- icon={icons['crossCircleIcon']}
23
- style={{...(liveStreamHostControlBtns as object)}}
24
26
  onPress={() => {
27
+ //Hiding the toast if its get rejected in the participant panel
28
+ if (Toast.getToastId() === toastId) {
29
+ Toast.hide();
30
+ }
25
31
  hostRejectsRequestOfUID(uid);
26
32
  }}
33
+ text={'DENY'}
27
34
  />
28
35
  </View>
29
36
  );
@@ -15,6 +15,7 @@ import React, {
15
15
  useContext,
16
16
  useEffect,
17
17
  useRef,
18
+ useState,
18
19
  } from 'react';
19
20
  import {gql, useMutation} from '@apollo/client';
20
21
  import {useParams} from '../../components/Router';
@@ -27,17 +28,21 @@ import events, {EventPersistLevel} from '../../rtm-events-api';
27
28
  import {EventActions, EventNames} from '../../rtm-events';
28
29
  import useRecordingLayoutQuery from './useRecordingLayoutQuery';
29
30
  import {useScreenContext} from '../../components/contexts/ScreenShareContext';
31
+ import {useRender} from 'customization-api';
32
+ import {trimText} from '../../utils/common';
30
33
 
31
34
  export interface RecordingContextInterface {
32
35
  startRecording: () => void;
33
36
  stopRecording: () => void;
34
37
  isRecordingActive: boolean;
38
+ inProgress: boolean;
35
39
  }
36
40
 
37
41
  const RecordingContext = createContext<RecordingContextInterface>({
38
42
  startRecording: () => {},
39
43
  stopRecording: () => {},
40
44
  isRecordingActive: false,
45
+ inProgress: false,
41
46
  });
42
47
 
43
48
  const START_RECORDING = gql`
@@ -82,6 +87,9 @@ interface RecordingProviderProps {
82
87
  const RecordingProvider = (props: RecordingProviderProps) => {
83
88
  const {rtcProps} = useContext(PropsContext);
84
89
  const {setRecordingActive, isRecordingActive} = props?.value;
90
+ const [inProgress, setInProgress] = useState(false);
91
+ const [uidWhoStarted, setUidWhoStarted] = useState(0);
92
+ const {renderList, activeUids} = useRender();
85
93
  const {phrase} = useParams<{phrase: string}>();
86
94
  const [startRecordingQuery] = useMutation(START_RECORDING);
87
95
  const [stopRecordingQuery] = useMutation(STOP_RECORDING);
@@ -101,14 +109,17 @@ const RecordingProvider = (props: RecordingProviderProps) => {
101
109
  const payload = JSON.parse(data.payload);
102
110
  const action = payload.action;
103
111
  const value = payload.value;
104
-
105
112
  switch (action) {
106
113
  case EventActions.RECORDING_STARTED:
114
+ setUidWhoStarted(parseInt(value));
107
115
  setRecordingActive(true);
108
116
  break;
109
117
  case EventActions.RECORDING_STOPPED:
110
118
  setRecordingActive(false);
111
119
  break;
120
+ case EventActions.RECORDING_STOP_REQUEST:
121
+ stopRecording();
122
+ break;
112
123
  default:
113
124
  break;
114
125
  }
@@ -128,14 +139,22 @@ const RecordingProvider = (props: RecordingProviderProps) => {
128
139
  if (prevRecordingState) {
129
140
  if (prevRecordingState?.isRecordingActive === isRecordingActive) return;
130
141
  Toast.show({
131
- type: 'success',
142
+ type: 'info',
132
143
  text1: recordingStartedText(isRecordingActive),
133
- visibilityTime: 1000,
144
+ text2: isRecordingActive
145
+ ? `This meeting is being recorded by ${
146
+ trimText(renderList[uidWhoStarted]?.name) || 'user'
147
+ }`
148
+ : '',
149
+ visibilityTime: 3000,
150
+ primaryBtn: null,
151
+ secondaryBtn: null,
134
152
  });
135
153
  }
136
154
  }, [isRecordingActive]);
137
155
 
138
156
  const startRecording = () => {
157
+ setInProgress(true);
139
158
  // If recording is not going on, start the recording by executing the graphql query
140
159
  startRecordingQuery({
141
160
  variables: {
@@ -148,6 +167,7 @@ const RecordingProvider = (props: RecordingProviderProps) => {
148
167
  })
149
168
  .then((res) => {
150
169
  console.log(res.data);
170
+ setInProgress(false);
151
171
  if (res.data.startRecordingSession === 'success') {
152
172
  /**
153
173
  * 1. Once the backend sucessfuly starts recording, send message
@@ -162,6 +182,7 @@ const RecordingProvider = (props: RecordingProviderProps) => {
162
182
  EventPersistLevel.LEVEL3,
163
183
  );
164
184
  // 2. set the local recording state to true to update the UI
185
+ setUidWhoStarted(localUid);
165
186
  setRecordingActive(true);
166
187
  // 3. set the presenter mode if screen share is active
167
188
  // 3.a Get the most recent screenshare uid
@@ -182,40 +203,71 @@ const RecordingProvider = (props: RecordingProviderProps) => {
182
203
  }
183
204
  })
184
205
  .catch((err) => {
206
+ setInProgress(false);
185
207
  console.log(err);
186
208
  });
187
209
  };
188
210
 
189
211
  const stopRecording = () => {
190
- // If recording is already going on, stop the recording by executing the graphql query.
191
- stopRecordingQuery({variables: {passphrase: phrase}})
192
- .then((res) => {
193
- console.log(res.data);
194
- if (res.data.stopRecordingSession === 'success') {
195
- /**
196
- * 1. Once the backend sucessfuly starts recording, send message
197
- * in the channel indicating that cloud recording is now inactive.
198
- */
199
- events.send(
200
- EventNames.RECORDING_ATTRIBUTE,
201
- JSON.stringify({
202
- action: EventActions.RECORDING_STOPPED,
203
- value: '',
204
- }),
205
- EventPersistLevel.LEVEL3,
206
- );
207
- // 2. set the local recording state to false to update the UI
208
- setRecordingActive(false);
209
- }
210
- })
211
- .catch((err) => {
212
- console.log(err);
213
- });
212
+ /**
213
+ * if condition added for below issue
214
+ *
215
+ * user 1 and user 2 in the call
216
+ * user 1 start the recording
217
+ * user 2 stops the recording
218
+ * user 2 join the call getting stop recording notification which is not needed
219
+ *
220
+ * solution
221
+ * case 1 - if recording is not started by the host then we will send level1 message to host who started the recording
222
+ * case 2 - if person who started the recording no longer available in the call then will stop the recording
223
+ */
224
+ if (
225
+ localUid === uidWhoStarted ||
226
+ activeUids.indexOf(uidWhoStarted) === -1
227
+ ) {
228
+ setInProgress(true);
229
+ // If recording is already going on, stop the recording by executing the graphql query.
230
+ stopRecordingQuery({variables: {passphrase: phrase}})
231
+ .then((res) => {
232
+ console.log(res.data);
233
+ setInProgress(false);
234
+ if (res.data.stopRecordingSession === 'success') {
235
+ /**
236
+ * 1. Once the backend sucessfuly starts recording, send message
237
+ * in the channel indicating that cloud recording is now inactive.
238
+ */
239
+ events.send(
240
+ EventNames.RECORDING_ATTRIBUTE,
241
+ JSON.stringify({
242
+ action: EventActions.RECORDING_STOPPED,
243
+ value: '',
244
+ }),
245
+ EventPersistLevel.LEVEL3,
246
+ );
247
+ // 2. set the local recording state to false to update the UI
248
+ setRecordingActive(false);
249
+ }
250
+ })
251
+ .catch((err) => {
252
+ setInProgress(false);
253
+ console.log(err);
254
+ });
255
+ } else {
256
+ events.send(
257
+ EventNames.RECORDING_ATTRIBUTE,
258
+ JSON.stringify({
259
+ action: EventActions.RECORDING_STOP_REQUEST,
260
+ value: '',
261
+ }),
262
+ EventPersistLevel.LEVEL1,
263
+ );
264
+ }
214
265
  };
215
266
 
216
267
  return (
217
268
  <RecordingContext.Provider
218
269
  value={{
270
+ inProgress,
219
271
  startRecording,
220
272
  stopRecording,
221
273
  isRecordingActive,
@@ -9,15 +9,16 @@
9
9
  information visit https://appbuilder.agora.io.
10
10
  *********************************************
11
11
  */
12
- import React from 'react';
13
- import {StyleSheet} from 'react-native';
14
- import {BtnTemplate, BtnTemplateInterface} from '../../../agora-rn-uikit';
12
+ import React, {useContext} from 'react';
13
+ import ThemeConfig from '../../theme';
14
+ import IconButton, {IconButtonProps} from '../../atoms/IconButton';
15
+ import Styles from '../../components/styles';
15
16
  import {useString} from '../../utils/useString';
16
17
  import {useScreenshare} from './useScreenshare';
17
- import {
18
- ButtonTemplateName,
19
- useButtonTemplate,
20
- } from '../../utils/useButtonTemplate';
18
+ import hexadecimalTransparency from '../../utils/hexadecimalTransparency';
19
+ import {PropsContext, ClientRole} from '../../../agora-rn-uikit';
20
+ import {useLocalUserInfo, useMeetingInfo} from 'customization-api';
21
+ import useIsHandRaised from '../../utils/useIsHandRaised';
21
22
  /**
22
23
  * A component to start and stop screen sharing on web clients.
23
24
  * Screen sharing is not yet implemented on mobile platforms.
@@ -25,86 +26,67 @@ import {
25
26
  */
26
27
 
27
28
  export interface ScreenshareButtonProps {
28
- buttonTemplateName?: ButtonTemplateName;
29
- render?: (
30
- onPress: () => void,
31
- isScreenshareActive: boolean,
32
- buttonTemplateName?: ButtonTemplateName,
33
- ) => JSX.Element;
29
+ render?: (onPress: () => void, isScreenshareActive: boolean) => JSX.Element;
34
30
  }
35
31
 
36
32
  const ScreenshareButton = (props: ScreenshareButtonProps) => {
33
+ const {rtcProps} = useContext(PropsContext);
34
+ const {
35
+ data: {isHost},
36
+ } = useMeetingInfo();
37
+ const local = useLocalUserInfo();
38
+ const isHandRaised = useIsHandRaised();
37
39
  const {isScreenshareActive, startUserScreenshare, stopUserScreenShare} =
38
40
  useScreenshare();
39
41
  //commented for v1 release
40
42
  //const screenShareButton = useString('screenShareButton')();
41
- const screenShareButton = 'Share';
42
- const defaultTemplateValue = useButtonTemplate().buttonTemplateName;
43
- const {buttonTemplateName = defaultTemplateValue} = props;
43
+
44
44
  const onPress = () =>
45
45
  isScreenshareActive ? stopUserScreenShare() : startUserScreenshare();
46
- let btnTemplateProps: BtnTemplateInterface = {
47
- name: isScreenshareActive ? 'screenshareOffIcon' : 'screenshareIcon',
46
+ const screenShareButton = isScreenshareActive ? 'Stop Share' : 'Share';
47
+ let iconButtonProps: IconButtonProps = {
48
+ iconProps: {
49
+ name: isScreenshareActive ? 'stop-screen-share' : 'screen-share',
50
+ tintColor: isScreenshareActive
51
+ ? $config.SEMANTIC_ERROR
52
+ : $config.SECONDARY_ACTION_COLOR,
53
+ },
48
54
  onPress,
55
+ btnTextProps: {
56
+ text: $config.ICON_TEXT ? screenShareButton : '',
57
+ textColor: $config.FONT_COLOR,
58
+ },
49
59
  };
50
60
 
51
- if (buttonTemplateName === ButtonTemplateName.topBar) {
52
- btnTemplateProps.style = isScreenshareActive
53
- ? (style.activeBtn as Object)
54
- : (style.nonActiveBtn as Object);
55
- } else {
56
- btnTemplateProps.btnText = screenShareButton;
57
- btnTemplateProps.style = isScreenshareActive
58
- ? style.greenLocalButton
59
- : style.localButton;
61
+ if (
62
+ rtcProps.role == ClientRole.Audience &&
63
+ $config.EVENT_MODE &&
64
+ !$config.RAISE_HAND
65
+ ) {
66
+ return null;
67
+ }
68
+
69
+ if (
70
+ rtcProps.role == ClientRole.Audience &&
71
+ $config.EVENT_MODE &&
72
+ $config.RAISE_HAND &&
73
+ !isHost
74
+ ) {
75
+ iconButtonProps.iconProps = {
76
+ ...iconButtonProps.iconProps,
77
+ tintColor: $config.SEMANTIC_NEUTRAL,
78
+ };
79
+ iconButtonProps.toolTipMessage = isHandRaised(local.uid)
80
+ ? 'Waiting for host to appove the request'
81
+ : 'Raise Hand in order to present';
82
+ iconButtonProps.disabled = true;
60
83
  }
61
84
 
62
85
  return props?.render ? (
63
- props.render(onPress, isScreenshareActive, buttonTemplateName)
86
+ props.render(onPress, isScreenshareActive)
64
87
  ) : (
65
- <BtnTemplate {...btnTemplateProps} />
88
+ <IconButton {...iconButtonProps} />
66
89
  );
67
90
  };
68
91
 
69
- const style = StyleSheet.create({
70
- localButton: {
71
- backgroundColor: $config.SECONDARY_FONT_COLOR,
72
- borderRadius: 20,
73
- borderColor: $config.PRIMARY_COLOR,
74
- width: 40,
75
- height: 40,
76
- display: 'flex',
77
- alignSelf: 'center',
78
- alignItems: 'center',
79
- justifyContent: 'center',
80
- },
81
- activeBtn: {
82
- backgroundColor: '#4BEB5B',
83
- borderRadius: 20,
84
- borderColor: '#F86051',
85
- width: '100%',
86
- height: '100%',
87
- resizeMode: 'contain',
88
- },
89
- nonActiveBtn: {
90
- width: '100%',
91
- height: '100%',
92
- resizeMode: 'contain',
93
- },
94
- greenLocalButton: {
95
- backgroundColor: '#4BEB5B',
96
- borderRadius: 20,
97
- borderColor: '#F86051',
98
- width: 40,
99
- height: 40,
100
- alignSelf: 'center',
101
- alignItems: 'center',
102
- justifyContent: 'center',
103
- },
104
- buttonIcon: {
105
- width: '90%',
106
- height: '90%',
107
- },
108
- });
109
-
110
92
  export default ScreenshareButton;
@@ -27,7 +27,7 @@ import {filterObject} from '../../utils';
27
27
 
28
28
  export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
29
29
  const {dispatch} = useRtc();
30
- const {renderList, activeUids, lastJoinedUid} = useRender();
30
+ const {renderList, activeUids, lastJoinedUid, pinnedUid} = useRender();
31
31
  const isPinned = useRef(0);
32
32
  const {setScreenShareData, screenShareData} = useScreenContext();
33
33
  // commented for v1 release
@@ -41,6 +41,12 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
41
41
  const renderListRef = useRef({renderList: renderList});
42
42
  const currentLayoutRef = useRef({currentLayout: currentLayout});
43
43
 
44
+ const pinnedUidRef = useRef({pinnedUid: pinnedUid});
45
+
46
+ useEffect(() => {
47
+ pinnedUidRef.current.pinnedUid = pinnedUid;
48
+ }, [pinnedUid]);
49
+
44
50
  useEffect(() => {
45
51
  renderListRef.current.renderList = renderList;
46
52
  }, [renderList]);
@@ -119,7 +125,10 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
119
125
  };
120
126
  });
121
127
  //if remote user started/stopped the screenshare then change the layout to pinned/grid
122
- triggerChangeLayout(false);
128
+ //if user pinned somebody then don't triggerlayout change
129
+ if (!pinnedUidRef.current.pinnedUid) {
130
+ triggerChangeLayout(false);
131
+ }
123
132
  break;
124
133
  default:
125
134
  break;
@@ -26,7 +26,12 @@ import {IAgoraRTC} from 'agora-rtc-sdk-ng';
26
26
  import useRecordingLayoutQuery from '../recording/useRecordingLayoutQuery';
27
27
  import {useString} from '../../utils/useString';
28
28
  import {timeNow} from '../../rtm/utils';
29
- import {useLayout, useRender, useRtc} from 'customization-api';
29
+ import {
30
+ controlMessageEnum,
31
+ useLayout,
32
+ useRender,
33
+ useRtc,
34
+ } from 'customization-api';
30
35
  import {filterObject} from '../../utils';
31
36
 
32
37
  export const ScreenshareContextConsumer = ScreenshareContext.Consumer;
@@ -35,7 +40,7 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
35
40
  const [isScreenshareActive, setScreenshareActive] = useState(false);
36
41
  const rtc = useRtc();
37
42
  const {dispatch} = rtc;
38
- const {renderList, activeUids, lastJoinedUid} = useRender();
43
+ const {renderList, activeUids, lastJoinedUid, pinnedUid} = useRender();
39
44
  const isPinned = useRef(0);
40
45
  const {isRecordingActive} = useRecording();
41
46
  const {executeNormalQuery, executePresenterQuery} = useRecordingLayoutQuery();
@@ -54,6 +59,11 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
54
59
  useContext(PropsContext).rtcProps;
55
60
 
56
61
  const renderListRef = useRef({renderList: renderList});
62
+ const pinnedUidRef = useRef({pinnedUid: pinnedUid});
63
+
64
+ useEffect(() => {
65
+ pinnedUidRef.current.pinnedUid = pinnedUid;
66
+ }, [pinnedUid]);
57
67
 
58
68
  useEffect(() => {
59
69
  renderListRef.current.renderList = renderList;
@@ -109,6 +119,12 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
109
119
  };
110
120
 
111
121
  useEffect(() => {
122
+ events.on(controlMessageEnum.kickScreenshare, () => {
123
+ //if screenscreen already active. then below method will stop the screen share
124
+ // @ts-ignore
125
+ rtc.RtcEngine.startScreenshare();
126
+ });
127
+
112
128
  events.on(EventNames.SCREENSHARE_ATTRIBUTE, (data) => {
113
129
  const payload = JSON.parse(data.payload);
114
130
  const action = payload.action;
@@ -141,7 +157,10 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
141
157
  };
142
158
  });
143
159
  //if remote user started/stopped the screenshare then change the layout to pinned/grid
144
- triggerChangeLayout(false);
160
+ //if user pinned somebody then don't triggerlayout change
161
+ if (!pinnedUidRef.current.pinnedUid) {
162
+ triggerChangeLayout(false);
163
+ }
145
164
  break;
146
165
  default:
147
166
  break;
@@ -174,7 +193,10 @@ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
174
193
  };
175
194
  });
176
195
  //if local user stopped the screenshare then change layout to grid
177
- triggerChangeLayout(false);
196
+ //if user pinned somebody then don't triggerlayout change
197
+ if (!pinnedUidRef.current.pinnedUid) {
198
+ triggerChangeLayout(false);
199
+ }
178
200
  });
179
201
  }, []);
180
202
 
@@ -0,0 +1,46 @@
1
+ import hexadecimalTransparency from '../utils/hexadecimalTransparency';
2
+
3
+ const EmphasisOpacity = {
4
+ high: 1,
5
+ medium: 0.85,
6
+ disabled: 0.4,
7
+ };
8
+ const EmphasisPlus = {
9
+ high: '',
10
+ medium: hexadecimalTransparency['85%'],
11
+ disabled: hexadecimalTransparency['40%'],
12
+ };
13
+ const FontSize: {
14
+ extraLarge: 32;
15
+ large: 20;
16
+ medium: 18;
17
+ normal: 16;
18
+ small: 14;
19
+ tiny: 12;
20
+ } = {
21
+ extraLarge: 32,
22
+ large: 20,
23
+ medium: 18,
24
+ normal: 16,
25
+ small: 14,
26
+ tiny: 12,
27
+ };
28
+ const FontFamily = {
29
+ sansPro: 'Source Sans Pro',
30
+ };
31
+
32
+ const BorderRadius: {small: 4; medium: 8; large: 12; extraLarge: 20} = {
33
+ small: 4,
34
+ medium: 8,
35
+ large: 12,
36
+ extraLarge: 20,
37
+ };
38
+
39
+ const ThemeConfig = {
40
+ EmphasisOpacity,
41
+ EmphasisPlus,
42
+ FontSize,
43
+ FontFamily,
44
+ BorderRadius,
45
+ };
46
+ export default ThemeConfig;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import {useState} from 'react';
3
+ import {isWebInternal} from './common';
4
+
5
+ const PlatformWrapper = ({children}) => {
6
+ const [isHovered, setIsHovered] = useState(false);
7
+ return isWebInternal() ? (
8
+ <div
9
+ onMouseEnter={() => {
10
+ setIsHovered(true);
11
+ }}
12
+ onMouseLeave={() => {
13
+ setIsHovered(false);
14
+ }}>
15
+ {children(isHovered)}
16
+ </div>
17
+ ) : (
18
+ <>{children(false)}</>
19
+ );
20
+ };
21
+ export default PlatformWrapper;