agora-appbuilder-core 2.2.0 → 2.3.0-beta.2

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 (301) hide show
  1. package/Readme.md +7 -1
  2. package/package.json +4 -3
  3. package/template/Gulpfile.js +306 -87
  4. package/template/_gitignore +4 -1
  5. package/template/_package-lock.json +32186 -3078
  6. package/template/agora-rn-uikit/src/AgoraUIKit.tsx +23 -20
  7. package/template/agora-rn-uikit/src/Contexts/LocalUserContext.tsx +13 -8
  8. package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +25 -9
  9. package/template/agora-rn-uikit/src/Contexts/RenderContext.tsx +10 -0
  10. package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +11 -5
  11. package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +6 -2
  12. package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +1 -1
  13. package/template/agora-rn-uikit/src/Controls/Local/EndCall.tsx +6 -2
  14. package/template/agora-rn-uikit/src/Controls/Local/LocalAudioMute.tsx +2 -2
  15. package/template/agora-rn-uikit/src/Controls/Local/LocalVideoMute.tsx +2 -2
  16. package/template/agora-rn-uikit/src/Controls/Local/SwitchCamera.tsx +6 -2
  17. package/template/agora-rn-uikit/src/Controls/LocalControls.tsx +11 -6
  18. package/template/agora-rn-uikit/src/Controls/Remote/RemoteAudioMute.tsx +10 -6
  19. package/template/agora-rn-uikit/src/Controls/Remote/RemoteSwap.tsx +7 -6
  20. package/template/agora-rn-uikit/src/Controls/Remote/RemoteVideoMute.tsx +6 -5
  21. package/template/agora-rn-uikit/src/Controls/RemoteControls.tsx +3 -3
  22. package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +16 -13
  23. package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +16 -13
  24. package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +13 -13
  25. package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +16 -13
  26. package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +28 -31
  27. package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +48 -35
  28. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +11 -13
  29. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +11 -13
  30. package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +18 -15
  31. package/template/agora-rn-uikit/src/Rtc/Create.tsx +14 -2
  32. package/template/agora-rn-uikit/src/Rtc/Join.tsx +19 -3
  33. package/template/agora-rn-uikit/src/RtcConfigure.tsx +161 -44
  34. package/template/agora-rn-uikit/src/Utils/useLocalUid.ts +8 -0
  35. package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +8 -6
  36. package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +8 -6
  37. package/template/agora-rn-uikit/src/Views/MinVideoView.tsx +18 -9
  38. package/template/agora-rn-uikit/src/index.ts +12 -12
  39. package/template/babel.config.js +17 -1
  40. package/template/bridge/rtc/webNg/RtcEngine.ts +34 -28
  41. package/template/bridge/rtc/webNg/SurfaceView.tsx +3 -2
  42. package/template/bridge/rtc/webNg/Types.ts +14 -0
  43. package/template/bridge/rtc/webNg/index.ts +5 -2
  44. package/template/bridge/rtm/web/index.ts +13 -7
  45. package/template/electron-builder.js +3 -2
  46. package/template/esbuild.rsdk.go +226 -0
  47. package/template/{src/subComponents/LayoutEnum.tsx → esbuildConfigTransform.js} +1 -5
  48. package/template/fpe-api/components.ts +42 -0
  49. package/template/fpe-api/context.ts +45 -0
  50. package/template/fpe-api/fpeEvents.ts +9 -0
  51. package/template/fpe-api/index.ts +21 -0
  52. package/template/fpe-api/install.ts +128 -0
  53. package/template/fpe-api/typeDefinition.ts +143 -0
  54. package/template/fpe-api/useFpe.tsx +35 -0
  55. package/template/fpe-api/utils.ts +62 -0
  56. package/template/fpe-implementation/createHook.ts +33 -0
  57. package/template/fpe-implementation/dummyFpe.ts +17 -0
  58. package/template/fpe-implementation/index.ts +1 -0
  59. package/template/fpe-todo.txt +14 -0
  60. package/template/fpe.config.js +29 -0
  61. package/template/global.d.ts +4 -0
  62. package/template/index.rsdk.tsx +27 -0
  63. package/template/index.wsdk.tsx +27 -0
  64. package/template/package.json +28 -12
  65. package/template/react-native-toast-message/src/index.js +9 -10
  66. package/template/react-native-toast-message/src/index.wsdk.js +419 -0
  67. package/template/src/App.tsx +97 -65
  68. package/template/src/AppWrapper.tsx +79 -0
  69. package/template/src/SDKAppWrapper.tsx +67 -0
  70. package/template/src/atoms/PrimaryButton.tsx +14 -8
  71. package/template/src/atoms/TextInput.tsx +13 -5
  72. package/template/src/components/Chat.tsx +171 -139
  73. package/template/src/components/ChatContext.ts +14 -22
  74. package/template/src/components/ColorConfigure.tsx +2 -2
  75. package/template/src/components/Controls.native.tsx +72 -62
  76. package/template/src/components/Controls.tsx +90 -69
  77. package/template/src/components/DeviceConfigure.tsx +1 -1
  78. package/template/src/components/DeviceContext.tsx +14 -7
  79. package/template/src/components/GraphQLProvider.tsx +9 -2
  80. package/template/src/components/GridVideo.tsx +20 -159
  81. package/template/src/components/HostControlView.tsx +54 -15
  82. package/template/src/components/Navbar.tsx +408 -157
  83. package/template/src/components/NetworkQualityContext.tsx +29 -22
  84. package/template/src/components/ParticipantsView.tsx +91 -115
  85. package/template/src/components/PinnedVideo.tsx +41 -188
  86. package/template/src/components/Precall.native.tsx +131 -97
  87. package/template/src/components/Precall.tsx +193 -158
  88. package/template/src/components/RTMConfigure.tsx +328 -416
  89. package/template/src/components/Router.sdk.ts +20 -0
  90. package/template/src/components/SessionContext.tsx +6 -3
  91. package/template/src/components/Settings.native.tsx +3 -0
  92. package/template/src/components/Settings.tsx +65 -31
  93. package/template/src/components/SettingsView.tsx +14 -8
  94. package/template/src/components/Share.tsx +188 -220
  95. package/template/src/components/StorageContext.tsx +5 -5
  96. package/template/src/components/StoreToken.tsx +5 -1
  97. package/template/src/components/chat-messages/useChatMessages.tsx +208 -0
  98. package/template/src/components/chat-notification/useChatNotification.tsx +78 -0
  99. package/template/src/components/chat-ui/useChatUIControl.tsx +66 -0
  100. package/template/src/components/common/Error.tsx +54 -0
  101. package/template/src/components/common/Logo.tsx +35 -0
  102. package/template/src/components/common/index.tsx +8 -0
  103. package/template/src/components/contexts/LiveStreamDataContext.tsx +79 -0
  104. package/template/src/components/contexts/ScreenShareContext.tsx +47 -0
  105. package/template/src/components/contexts/WhiteboardContext.tsx +59 -0
  106. package/template/src/components/dimension/DimensionContext.ts +27 -0
  107. package/template/src/components/dimension/DimensionProvider.tsx +34 -0
  108. package/template/src/components/livestream/LiveStreamContext.tsx +293 -272
  109. package/template/src/components/livestream/Types.ts +26 -7
  110. package/template/src/components/livestream/index.ts +13 -2
  111. package/template/src/components/livestream/views/LiveStreamControls.tsx +5 -1
  112. package/template/src/components/meeting-info/useMeetingInfo.tsx +63 -0
  113. package/template/src/components/meeting-info/useSetMeetingInfo.tsx +38 -0
  114. package/template/src/components/participants/AllAudienceParticipants.tsx +26 -21
  115. package/template/src/components/participants/AllHostParticipants.tsx +41 -53
  116. package/template/src/components/participants/MeParticipant.tsx +9 -10
  117. package/template/src/components/participants/ParticipantName.tsx +2 -1
  118. package/template/src/components/participants/RemoteParticipants.tsx +3 -3
  119. package/template/src/components/precall/LocalMute.native.tsx +91 -0
  120. package/template/src/components/precall/LocalMute.tsx +90 -0
  121. package/template/src/components/precall/VideoPreview.native.tsx +35 -0
  122. package/template/src/components/precall/VideoPreview.tsx +33 -0
  123. package/template/src/components/precall/index.tsx +28 -0
  124. package/template/src/components/precall/joinCallBtn.native.tsx +69 -0
  125. package/template/src/components/precall/joinCallBtn.tsx +91 -0
  126. package/template/src/components/precall/meetingTitle.tsx +26 -0
  127. package/template/src/components/precall/selectDevice.tsx +46 -0
  128. package/template/src/components/precall/textInput.tsx +43 -0
  129. package/template/src/components/precall/usePreCall.tsx +41 -0
  130. package/template/src/components/styles.ts +20 -3
  131. package/template/src/components/useShareLink.tsx +239 -0
  132. package/template/src/components/useWakeLock.tsx +3 -3
  133. package/template/src/custom-events/CustomEvents.ts +221 -0
  134. package/template/src/custom-events/index.tsx +4 -0
  135. package/template/src/custom-events/types.ts +51 -0
  136. package/template/src/language/default-labels/commonLabels.ts +21 -0
  137. package/template/src/language/default-labels/createScreenLabels.ts +22 -0
  138. package/template/src/language/default-labels/index.ts +38 -0
  139. package/template/src/language/default-labels/joinScreenLabels.ts +13 -0
  140. package/template/src/language/default-labels/precallScreenLabels.ts +33 -0
  141. package/template/src/language/default-labels/shareLinkScreenLabels.ts +44 -0
  142. package/template/src/language/default-labels/videoCallScreenLabels.ts +189 -0
  143. package/template/src/language/i18nTypes.ts +10 -0
  144. package/template/src/language/index.ts +18 -0
  145. package/template/src/language/useLanguage.tsx +92 -0
  146. package/template/src/pages/Authenticate.tsx +21 -15
  147. package/template/src/pages/Create.tsx +176 -159
  148. package/template/src/pages/Join.tsx +44 -32
  149. package/template/src/pages/VideoCall.tsx +134 -406
  150. package/template/src/pages/create/useCreate.tsx +37 -0
  151. package/template/src/pages/video-call/CustomLayout.ts +17 -0
  152. package/template/src/pages/video-call/CustomUserContextHolder.tsx +12 -0
  153. package/template/src/pages/video-call/DefaultLayouts.ts +65 -0
  154. package/template/src/pages/video-call/NameWithMicStatus.tsx +62 -0
  155. package/template/src/pages/video-call/RenderComponent.tsx +52 -0
  156. package/template/src/pages/video-call/VideoCallScreen.tsx +191 -0
  157. package/template/src/pages/video-call/VideoComponent.tsx +34 -0
  158. package/template/src/pages/video-call/VideoRenderer.tsx +86 -0
  159. package/template/src/pages/video-call/index.ts +20 -0
  160. package/template/src/rtm/RTMEngine.ts +58 -0
  161. package/template/src/rtm/utils.ts +44 -0
  162. package/template/src/rtm-events/EventUtils.ts +267 -0
  163. package/template/src/rtm-events/EventsQueue.ts +38 -0
  164. package/template/src/rtm-events/constants.ts +40 -0
  165. package/template/src/rtm-events/index.tsx +8 -0
  166. package/template/src/rtm-events/types.ts +7 -0
  167. package/template/src/subComponents/ChatBubble.tsx +18 -11
  168. package/template/src/subComponents/ChatContainer.tsx +79 -30
  169. package/template/src/subComponents/ChatInput.tsx +146 -70
  170. package/template/src/subComponents/CopyJoinInfo.tsx +52 -67
  171. package/template/src/subComponents/Error.tsx +35 -24
  172. package/template/src/subComponents/LanguageSelector.tsx +85 -0
  173. package/template/src/subComponents/LayoutIconDropdown.native.tsx +163 -0
  174. package/template/src/subComponents/LayoutIconDropdown.tsx +198 -0
  175. package/template/src/subComponents/LocalAudioMute.tsx +52 -30
  176. package/template/src/subComponents/LocalEndCall.tsx +52 -0
  177. package/template/src/subComponents/LocalSwitchCamera.tsx +61 -0
  178. package/template/src/subComponents/LocalVideoMute.tsx +48 -30
  179. package/template/src/subComponents/LogoutButton.tsx +20 -5
  180. package/template/src/subComponents/NetworkQualityPill.tsx +43 -13
  181. package/template/src/subComponents/OpenInNativeButton.tsx +3 -2
  182. package/template/src/subComponents/Recording.tsx +46 -138
  183. package/template/src/subComponents/RemoteAudioMute.tsx +30 -34
  184. package/template/src/subComponents/RemoteEndCall.tsx +18 -7
  185. package/template/src/subComponents/RemoteVideoMute.tsx +17 -9
  186. package/template/src/subComponents/ScreenShareNotice.tsx +40 -40
  187. package/template/src/subComponents/SelectDevice.tsx +88 -45
  188. package/template/src/subComponents/SelectOAuth.tsx +30 -6
  189. package/template/src/subComponents/SidePanelButtons.ts +39 -0
  190. package/template/src/subComponents/TextWithTooltip.native.tsx +2 -1
  191. package/template/src/subComponents/TextWithTooltip.tsx +15 -20
  192. package/template/src/subComponents/chat/ChatParticipants.tsx +31 -32
  193. package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +7 -3
  194. package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +32 -18
  195. package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +22 -8
  196. package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +12 -7
  197. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +24 -27
  198. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +23 -26
  199. package/template/src/subComponents/livestream/index.ts +10 -2
  200. package/template/src/subComponents/recording/useRecording.tsx +209 -0
  201. package/template/src/subComponents/recording/useRecordingLayoutQuery.tsx +64 -0
  202. package/template/src/subComponents/screenshare/ScreenshareButton.native.tsx +18 -0
  203. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +61 -31
  204. package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +57 -52
  205. package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +102 -143
  206. package/template/src/subComponents/screenshare/useScreenshare.tsx +29 -0
  207. package/template/src/subComponents/toastConfig.tsx +25 -20
  208. package/template/src/utils/IsAttendeeUser.ts +34 -0
  209. package/template/src/utils/SdkEvents.ts +68 -0
  210. package/template/src/utils/common.tsx +40 -0
  211. package/template/src/utils/eventEmitter.ts +29 -0
  212. package/template/src/utils/getMeetingInvite.ts +30 -0
  213. package/template/src/utils/index.tsx +11 -2
  214. package/template/src/utils/isAudioEnabled.ts +29 -0
  215. package/template/src/utils/isHostUser.ts +33 -0
  216. package/template/src/utils/isMobileOrTablet.native.ts +5 -0
  217. package/template/src/utils/{mobileWebTest.tsx → isMobileOrTablet.ts} +5 -2
  218. package/template/src/utils/isPSTNUser.ts +30 -0
  219. package/template/src/utils/isSDK.sdk.ts +5 -0
  220. package/template/src/utils/isSDK.ts +5 -0
  221. package/template/src/utils/isScreenShareUser.ts +31 -0
  222. package/template/src/utils/isVideoEnabled.ts +29 -0
  223. package/template/src/utils/useButtonTemplate.tsx +43 -0
  224. package/template/src/utils/useCreateMeeting.ts +74 -0
  225. package/template/src/utils/useGetLiveStreamingRequests.ts +24 -0
  226. package/template/src/utils/useGetMeetingPhrase.ts +68 -0
  227. package/template/src/utils/useGetName.ts +20 -0
  228. package/template/src/{subComponents/screenshare/ScreenshareContext.tsx → utils/useGroupMessages.ts} +10 -7
  229. package/template/src/utils/useJoinMeeting.ts +120 -0
  230. package/template/src/utils/useLayout.tsx +40 -0
  231. package/template/src/utils/useLiveStreamingUids.ts +26 -0
  232. package/template/src/utils/useMutePSTN.ts +43 -0
  233. package/template/src/utils/useMuteToggleLocal.ts +109 -0
  234. package/template/src/utils/useNavParams.ts +6 -0
  235. package/template/src/utils/useNavigateTo.ts +8 -0
  236. package/template/src/utils/usePrivateMessages.ts +33 -0
  237. package/template/src/utils/useRemoteEndCall.ts +27 -0
  238. package/template/src/utils/useRemoteMute.ts +64 -0
  239. package/template/src/utils/useSendControlMessage.ts +51 -0
  240. package/template/src/utils/useSendMessage.ts +40 -0
  241. package/template/src/utils/useSetName.ts +20 -0
  242. package/template/src/utils/useSetUnreadMessageCount.ts +43 -0
  243. package/template/src/utils/useSidePanel.tsx +41 -0
  244. package/template/src/utils/useString.ts +61 -0
  245. package/template/src/utils/useUnreadMessageCount.ts +50 -0
  246. package/template/src/utils/useUserList.ts +26 -0
  247. package/template/tsconfig.json +4 -4
  248. package/template/tsconfig_fpeApi.json +103 -0
  249. package/template/tsconfig_rsdk_index.json +105 -0
  250. package/template/tsconfig_wsdk_index.json +104 -0
  251. package/template/webpack.commons.js +40 -16
  252. package/template/webpack.main.config.js +2 -1
  253. package/template/webpack.renderer.config.js +1 -1
  254. package/template/webpack.rsdk.config.js +33 -0
  255. package/template/webpack.ts.config.js +89 -0
  256. package/template/webpack.web.config.js +8 -1
  257. package/template/webpack.wsdk.config.js +34 -0
  258. package/template/agora-rn-uikit/.git/HEAD +0 -1
  259. package/template/agora-rn-uikit/.git/config +0 -16
  260. package/template/agora-rn-uikit/.git/description +0 -1
  261. package/template/agora-rn-uikit/.git/hooks/applypatch-msg.sample +0 -15
  262. package/template/agora-rn-uikit/.git/hooks/commit-msg.sample +0 -24
  263. package/template/agora-rn-uikit/.git/hooks/fsmonitor-watchman.sample +0 -173
  264. package/template/agora-rn-uikit/.git/hooks/post-update.sample +0 -8
  265. package/template/agora-rn-uikit/.git/hooks/pre-applypatch.sample +0 -14
  266. package/template/agora-rn-uikit/.git/hooks/pre-commit.sample +0 -49
  267. package/template/agora-rn-uikit/.git/hooks/pre-merge-commit.sample +0 -13
  268. package/template/agora-rn-uikit/.git/hooks/pre-push.sample +0 -53
  269. package/template/agora-rn-uikit/.git/hooks/pre-rebase.sample +0 -169
  270. package/template/agora-rn-uikit/.git/hooks/pre-receive.sample +0 -24
  271. package/template/agora-rn-uikit/.git/hooks/prepare-commit-msg.sample +0 -42
  272. package/template/agora-rn-uikit/.git/hooks/push-to-checkout.sample +0 -78
  273. package/template/agora-rn-uikit/.git/hooks/update.sample +0 -128
  274. package/template/agora-rn-uikit/.git/index +0 -0
  275. package/template/agora-rn-uikit/.git/info/exclude +0 -6
  276. package/template/agora-rn-uikit/.git/logs/HEAD +0 -2
  277. package/template/agora-rn-uikit/.git/logs/refs/heads/ab-dev-auto +0 -1
  278. package/template/agora-rn-uikit/.git/logs/refs/heads/master +0 -1
  279. package/template/agora-rn-uikit/.git/logs/refs/remotes/origin/HEAD +0 -1
  280. package/template/agora-rn-uikit/.git/objects/pack/pack-0061d00cd98162a329a32b537488a35d0abeb069.idx +0 -0
  281. package/template/agora-rn-uikit/.git/objects/pack/pack-0061d00cd98162a329a32b537488a35d0abeb069.pack +0 -0
  282. package/template/agora-rn-uikit/.git/packed-refs +0 -24
  283. package/template/agora-rn-uikit/.git/refs/heads/ab-dev-auto +0 -1
  284. package/template/agora-rn-uikit/.git/refs/heads/master +0 -1
  285. package/template/agora-rn-uikit/.git/refs/remotes/origin/HEAD +0 -1
  286. package/template/agora-rn-uikit/.gitignore +0 -63
  287. package/template/agora-rn-uikit/package-lock.json +0 -7612
  288. package/template/agora-rn-uikit/src/Contexts/MaxUidContext.tsx +0 -7
  289. package/template/agora-rn-uikit/src/Contexts/MinUidContext.tsx +0 -8
  290. package/template/package-lock.json +0 -22923
  291. package/template/react-native-toast-message/.gitignore +0 -5
  292. package/template/react-native-toast-message/.npmignore +0 -5
  293. package/template/react-native-toast-message/package-lock.json +0 -10553
  294. package/template/src/.DS_Store +0 -0
  295. package/template/src/components/participants/context/ParticipantContext.tsx +0 -97
  296. package/template/src/subComponents/.DS_Store +0 -0
  297. package/template/src/subComponents/ScreenshareButton.tsx +0 -257
  298. package/template/src/subComponents/SwitchCamera.tsx +0 -35
  299. package/template/src/utils/hasBrandLogo.tsx +0 -3
  300. package/template/src/utils/mobileWebTest.native.tsx +0 -5
  301. package/template/src/utils/shouldAuthenticate.tsx +0 -7
@@ -0,0 +1,209 @@
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, {
13
+ createContext,
14
+ SetStateAction,
15
+ useContext,
16
+ useEffect,
17
+ useRef,
18
+ } from 'react';
19
+ import {gql, useMutation} from '@apollo/client';
20
+ import {useParams} from '../../components/Router';
21
+ import {PropsContext} from '../../../agora-rn-uikit';
22
+ import Toast from '../../../react-native-toast-message';
23
+ import {createHook} from 'fpe-implementation';
24
+ import {useString} from '../../utils/useString';
25
+ import ChatContext from '../../components/ChatContext';
26
+ import CustomEvents, {EventLevel} from '../../custom-events';
27
+ import {EventActions, EventNames} from '../../rtm-events';
28
+ import useRecordingLayoutQuery from './useRecordingLayoutQuery';
29
+ import {useScreenContext} from '../../components/contexts/ScreenShareContext';
30
+
31
+ export interface RecordingContextInterface {
32
+ startRecording: () => void;
33
+ stopRecording: () => void;
34
+ setRecordingActive: React.Dispatch<SetStateAction<boolean>>;
35
+ isRecordingActive: boolean;
36
+ }
37
+
38
+ const RecordingContext = createContext<RecordingContextInterface>({
39
+ startRecording: () => {},
40
+ stopRecording: () => {},
41
+ setRecordingActive: () => {},
42
+ isRecordingActive: false,
43
+ });
44
+
45
+ const START_RECORDING = gql`
46
+ mutation startRecordingSession($passphrase: String!, $secret: String) {
47
+ startRecordingSession(passphrase: $passphrase, secret: $secret)
48
+ }
49
+ `;
50
+
51
+ const STOP_RECORDING = gql`
52
+ mutation stopRecordingSession($passphrase: String!) {
53
+ stopRecordingSession(passphrase: $passphrase)
54
+ }
55
+ `;
56
+
57
+ /**
58
+ * Component to start / stop Agora cloud recording.
59
+ * Sends a control message to all users in the channel over RTM to indicate that
60
+ * Cloud recording has started/stopped.
61
+ */
62
+ function usePrevious<T = any>(value: any) {
63
+ const ref = useRef<T>();
64
+ useEffect(() => {
65
+ ref.current = value;
66
+ });
67
+ return ref.current;
68
+ }
69
+
70
+ interface RecordingProviderProps {
71
+ children: React.ReactNode;
72
+ value: Omit<RecordingContextInterface, 'startRecording' | 'stopRecording'>;
73
+ }
74
+
75
+ /**
76
+ * Component to start / stop Agora cloud recording.
77
+ * Sends a control message to all users in the channel over RTM to indicate that
78
+ * Cloud recording has started/stopped.
79
+ */
80
+
81
+ const RecordingProvider = (props: RecordingProviderProps) => {
82
+ const {rtcProps} = useContext(PropsContext);
83
+ const {setRecordingActive, isRecordingActive} = props?.value;
84
+ const {phrase} = useParams<{phrase: string}>();
85
+ const [startRecordingQuery] = useMutation(START_RECORDING);
86
+ const [stopRecordingQuery] = useMutation(STOP_RECORDING);
87
+ const prevRecordingState = usePrevious<{isRecordingActive: boolean}>({
88
+ isRecordingActive,
89
+ });
90
+ //commented for v1 release
91
+ //const recordingStartedText = useString<boolean>('recordingNotificationLabel');
92
+ const recordingStartedText = (active: boolean) =>
93
+ active ? 'Recording Started' : 'Recording Stopped';
94
+ const {executePresenterQuery} = useRecordingLayoutQuery();
95
+ const {localUid} = useContext(ChatContext);
96
+ const {screenShareData} = useScreenContext();
97
+
98
+ React.useEffect(() => {
99
+ CustomEvents.on(EventNames.RECORDING_ATTRIBUTE, (data) => {
100
+ switch (data?.payload?.action) {
101
+ case EventActions.RECORDING_STARTED:
102
+ setRecordingActive(true);
103
+ break;
104
+ case EventActions.RECORDING_STOPPED:
105
+ setRecordingActive(false);
106
+ break;
107
+ default:
108
+ break;
109
+ }
110
+ });
111
+ () => {
112
+ CustomEvents.off(EventNames.RECORDING_ATTRIBUTE);
113
+ };
114
+ }, []);
115
+
116
+ useEffect(() => {
117
+ /**
118
+ * The below check makes sure the notification is triggered
119
+ * only once. In native apps, this componenet is mounted everytime
120
+ * when chat icon is toggle, as Controls component is hidden and
121
+ * shown
122
+ */
123
+ if (prevRecordingState) {
124
+ if (prevRecordingState?.isRecordingActive === isRecordingActive) return;
125
+ Toast.show({
126
+ type: 'success',
127
+ text1: recordingStartedText(isRecordingActive),
128
+ visibilityTime: 1000,
129
+ });
130
+ }
131
+ }, [isRecordingActive]);
132
+
133
+ const startRecording = () => {
134
+ // If recording is not going on, start the recording by executing the graphql query
135
+ startRecordingQuery({
136
+ variables: {
137
+ passphrase: phrase,
138
+ secret:
139
+ rtcProps.encryption && rtcProps.encryption.key
140
+ ? rtcProps.encryption.key
141
+ : '',
142
+ },
143
+ })
144
+ .then((res) => {
145
+ console.log(res.data);
146
+ if (res.data.startRecordingSession === 'success') {
147
+ /**
148
+ * 1. Once the backend sucessfuly starts recording, send message
149
+ * in the channel indicating that cloud recording is now active.
150
+ */
151
+ CustomEvents.send(EventNames.RECORDING_ATTRIBUTE, {
152
+ action: EventActions.RECORDING_STARTED,
153
+ value: `${localUid}`,
154
+ level: EventLevel.LEVEL3,
155
+ });
156
+ // 2. set the local recording state to true to update the UI
157
+ setRecordingActive(true);
158
+ // 3. set the presenter mode if screen share is active
159
+ if (Object.values(screenShareData).some((item) => item.isActive)) {
160
+ console.log('Executing presenter query');
161
+ executePresenterQuery();
162
+ }
163
+ }
164
+ })
165
+ .catch((err) => {
166
+ console.log(err);
167
+ });
168
+ };
169
+
170
+ const stopRecording = () => {
171
+ // If recording is already going on, stop the recording by executing the graphql query.
172
+ stopRecordingQuery({variables: {passphrase: phrase}})
173
+ .then((res) => {
174
+ console.log(res.data);
175
+ if (res.data.stopRecordingSession === 'success') {
176
+ /**
177
+ * 1. Once the backend sucessfuly starts recording, send message
178
+ * in the channel indicating that cloud recording is now inactive.
179
+ */
180
+ CustomEvents.send(EventNames.RECORDING_ATTRIBUTE, {
181
+ action: EventActions.RECORDING_STOPPED,
182
+ value: '',
183
+ level: EventLevel.LEVEL3,
184
+ });
185
+ // 2. set the local recording state to false to update the UI
186
+ setRecordingActive(false);
187
+ }
188
+ })
189
+ .catch((err) => {
190
+ console.log(err);
191
+ });
192
+ };
193
+
194
+ return (
195
+ <RecordingContext.Provider
196
+ value={{
197
+ startRecording,
198
+ stopRecording,
199
+ isRecordingActive,
200
+ setRecordingActive,
201
+ }}>
202
+ {props.children}
203
+ </RecordingContext.Provider>
204
+ );
205
+ };
206
+
207
+ const useRecording = createHook(RecordingContext);
208
+
209
+ export {RecordingProvider, useRecording};
@@ -0,0 +1,64 @@
1
+ import React, {useContext} from 'react';
2
+ import {useParams} from '../../components/Router';
3
+
4
+ import {gql, useMutation} from '@apollo/client';
5
+ import {PropsContext} from '../../../agora-rn-uikit';
6
+
7
+ const SET_PRESENTER = gql`
8
+ mutation setPresenter($uid: Int!, $passphrase: String!) {
9
+ setPresenter(uid: $uid, passphrase: $passphrase)
10
+ }
11
+ `;
12
+
13
+ const SET_NORMAL = gql`
14
+ mutation setNormal($passphrase: String!) {
15
+ setNormal(passphrase: $passphrase)
16
+ }
17
+ `;
18
+
19
+ function useRecordingLayoutQuery() {
20
+ const [setPresenterQuery] = useMutation(SET_PRESENTER);
21
+ const [setNormalQuery] = useMutation(SET_NORMAL);
22
+ const {screenShareUid} = useContext(PropsContext).rtcProps;
23
+ const {phrase} = useParams<any>();
24
+
25
+ const executePresenterQuery = () => {
26
+ setPresenterQuery({
27
+ variables: {
28
+ uid: screenShareUid,
29
+ passphrase: phrase,
30
+ },
31
+ })
32
+ .then((res) => {
33
+ if (res.data.setPresenter === 'success') {
34
+ }
35
+ })
36
+ .catch((err) => {
37
+ console.log(err);
38
+ });
39
+ };
40
+
41
+ const executeNormalQuery = () => {
42
+ setNormalQuery({variables: {passphrase: phrase}})
43
+ .then((res) => {
44
+ console.log(res.data);
45
+ if (res.data.stopRecordingSession === 'success') {
46
+ // Once the backend sucessfuly stops recording,
47
+ // send a control message to everbody in the channel indicating that cloud recording is now inactive.
48
+ // sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
49
+ // set the local recording state to false to update the UI
50
+ // setScreenshareActive(false);
51
+ }
52
+ })
53
+ .catch((err) => {
54
+ console.log(err);
55
+ });
56
+ };
57
+
58
+ return {
59
+ executeNormalQuery,
60
+ executePresenterQuery,
61
+ };
62
+ }
63
+
64
+ export default useRecordingLayoutQuery;
@@ -0,0 +1,18 @@
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
+
14
+ const ScreenshareButton = () => {
15
+ return <></>;
16
+ };
17
+
18
+ export default ScreenshareButton;
@@ -9,43 +9,60 @@
9
9
  information visit https://appbuilder.agora.io.
10
10
  *********************************************
11
11
  */
12
- import React, {useContext} from 'react';
13
- import {TouchableOpacity, StyleSheet, View, Text} from 'react-native';
14
- import ColorContext from '../../components/ColorContext';
15
- import {ImageIcon} from '../../../agora-rn-uikit';
16
- import ScreenshareContext from './ScreenshareContext';
12
+ import React from 'react';
13
+ import {StyleSheet} from 'react-native';
14
+ import {BtnTemplate, BtnTemplateInterface} from '../../../agora-rn-uikit';
15
+ import {useString} from '../../utils/useString';
16
+ import {useScreenshare} from './useScreenshare';
17
+ import {
18
+ ButtonTemplateName,
19
+ useButtonTemplate,
20
+ } from '../../utils/useButtonTemplate';
17
21
  /**
18
22
  * A component to start and stop screen sharing on web clients.
19
23
  * Screen sharing is not yet implemented on mobile platforms.
20
24
  * Electron has it's own screen sharing component
21
25
  */
22
- const ScreenshareButton = () => {
23
- const {screenshareActive, startUserScreenshare} =
24
- useContext(ScreenshareContext);
25
- const {primaryColor} = useContext(ColorContext);
26
26
 
27
- return (
28
- <TouchableOpacity onPress={() => startUserScreenshare()}>
29
- <View
30
- style={
31
- screenshareActive
32
- ? style.greenLocalButton
33
- : [style.localButton, {borderColor: primaryColor}]
34
- }>
35
- <ImageIcon
36
- name={screenshareActive ? 'screenshareOffIcon' : 'screenshareIcon'}
37
- style={[style.buttonIcon]}
38
- />
39
- </View>
40
- <Text
41
- style={{
42
- textAlign: 'center',
43
- marginTop: 5,
44
- color: $config.PRIMARY_COLOR,
45
- }}>
46
- Share
47
- </Text>
48
- </TouchableOpacity>
27
+ export interface ScreenshareButtonProps {
28
+ buttonTemplateName?: ButtonTemplateName;
29
+ render?: (
30
+ onPress: () => void,
31
+ isScreenshareActive: boolean,
32
+ buttonTemplateName?: ButtonTemplateName,
33
+ ) => JSX.Element;
34
+ }
35
+
36
+ const ScreenshareButton = (props: ScreenshareButtonProps) => {
37
+ const {isScreenshareActive, startUserScreenshare, stopUserScreenShare} =
38
+ useScreenshare();
39
+ //commented for v1 release
40
+ //const screenShareButton = useString('screenShareButton')();
41
+ const screenShareButton = 'Share';
42
+ const defaultTemplateValue = useButtonTemplate().buttonTemplateName;
43
+ const {buttonTemplateName = defaultTemplateValue} = props;
44
+ const onPress = () =>
45
+ isScreenshareActive ? stopUserScreenShare() : startUserScreenshare();
46
+ let btnTemplateProps: BtnTemplateInterface = {
47
+ name: isScreenshareActive ? 'screenshareOffIcon' : 'screenshareIcon',
48
+ onPress,
49
+ };
50
+
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;
60
+ }
61
+
62
+ return props?.render ? (
63
+ props.render(onPress, isScreenshareActive, buttonTemplateName)
64
+ ) : (
65
+ <BtnTemplate {...btnTemplateProps} />
49
66
  );
50
67
  };
51
68
 
@@ -61,6 +78,19 @@ const style = StyleSheet.create({
61
78
  alignItems: 'center',
62
79
  justifyContent: 'center',
63
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
+ },
64
94
  greenLocalButton: {
65
95
  backgroundColor: '#4BEB5B',
66
96
  borderRadius: 20,
@@ -11,13 +11,16 @@
11
11
  */
12
12
  import React, {useEffect, useContext, useRef} from 'react';
13
13
  import KeepAwake from 'react-native-keep-awake';
14
- import Layout from '../LayoutEnum';
15
- import ChatContext from '../../components/ChatContext';
14
+ import {RtcContext, UidType} from '../../../agora-rn-uikit';
16
15
  import {
17
- RtcContext,
18
- MinUidContext,
19
- MaxUidContext,
20
- } from '../../../agora-rn-uikit/src';
16
+ useChangeDefaultLayout,
17
+ useSetPinnedLayout,
18
+ } from '../../pages/video-call/DefaultLayouts';
19
+ import useUserList from '../../utils/useUserList';
20
+ import {useScreenContext} from '../../components/contexts/ScreenShareContext';
21
+ import {useString} from '../../utils/useString';
22
+ import CustomEvents from '../../custom-events';
23
+ import {EventNames} from '../../rtm-events';
21
24
 
22
25
  function usePrevious(value: any) {
23
26
  const ref = useRef();
@@ -27,58 +30,60 @@ function usePrevious(value: any) {
27
30
  return ref.current;
28
31
  }
29
32
 
30
- export const ScreenshareConfigure: React.FC = (props: any) => {
31
- const {userList} = useContext(ChatContext);
33
+ export const ScreenshareConfigure = (props: {children: React.ReactNode}) => {
32
34
  const rtc = useContext(RtcContext);
33
35
  const {dispatch} = rtc;
34
- const max = useContext(MaxUidContext);
35
- const min = useContext(MinUidContext);
36
- const users = [...max, ...min];
37
- const prevUsers = usePrevious({users});
38
- const {setLayout} = props;
36
+ const {renderList, renderPosition} = useUserList();
37
+ const {setScreenShareData, screenShareData} = useScreenContext();
38
+ // commented for v1 release
39
+ // const getScreenShareName = useString('screenshareUserName');
40
+ // const userText = useString('remoteUserDefaultLabel')();
41
+ const getScreenShareName = (name: string) => `${name}'s screenshare`;
42
+ const userText = 'User';
43
+ const prevRenderPosition = usePrevious({renderPosition});
44
+ const setPinnedLayout = useSetPinnedLayout();
45
+ const changeLayout = useChangeDefaultLayout();
39
46
 
40
- useEffect(() => {
41
- // determine start and stop of screen share using new user left/join state and their type
42
- if (prevUsers !== undefined) {
43
- let joinedUser = users.filter((person) =>
44
- prevUsers?.users.every((person2) => !(person2.uid === person.uid)),
45
- );
46
- let leftUser = prevUsers?.users.filter((person) =>
47
- users.every((person2) => !(person2.uid === person.uid)),
48
- );
47
+ const renderListRef = useRef({renderList: renderList});
49
48
 
50
- if (joinedUser.length === 1) {
51
- const newUserUid = joinedUser[0].uid;
52
- // identify remote user screen type, if screen share, swap to PIN
53
- if (userList[newUserUid] && userList[newUserUid].type === 1) {
54
- dispatch({
55
- type: 'SwapVideo',
56
- value: [joinedUser[0]],
57
- });
58
- setLayout(Layout.Pinned);
59
- } else if (newUserUid === 1) {
60
- // identify local user screen type
61
- if (newUserUid !== users[0].uid) {
62
- // if not already maximized
63
- dispatch({
64
- type: 'SwapVideo',
65
- value: [joinedUser[0]],
66
- });
67
- }
68
- setLayout(Layout.Pinned);
69
- }
70
- }
49
+ useEffect(() => {
50
+ renderListRef.current.renderList = renderList;
51
+ }, [renderList]);
71
52
 
72
- if (leftUser.length === 1) {
73
- const leftUserUid = leftUser[0].uid;
74
- if (userList[leftUserUid] && userList[leftUserUid].type === 1) {
75
- setLayout((l: Layout) =>
76
- l === Layout.Pinned ? Layout.Grid : Layout.Pinned,
77
- );
78
- }
79
- }
53
+ const triggerChangeLayout = (pinned: boolean, screenShareUid?: UidType) => {
54
+ //screenshare is started set the layout to Pinned View
55
+ if (pinned && screenShareUid) {
56
+ dispatch({
57
+ type: 'SwapVideo',
58
+ value: [screenShareUid],
59
+ });
60
+ setPinnedLayout();
61
+ }
62
+ //screenshare is stopped set the layout Grid View
63
+ else {
64
+ changeLayout();
80
65
  }
81
- }, [users, userList]);
66
+ };
67
+
68
+ useEffect(() => {
69
+ CustomEvents.on(EventNames.SCREENSHARE_ATTRIBUTE, (data) => {
70
+ const screenUidOfUser =
71
+ renderListRef.current.renderList[data.sender].screenUid;
72
+ setScreenShareData((prevState) => {
73
+ return {
74
+ ...prevState,
75
+ [screenUidOfUser]: {
76
+ name: renderListRef.current.renderList[screenUidOfUser]?.name,
77
+ isActive: data.payload.value === 'true' ? true : false,
78
+ },
79
+ };
80
+ });
81
+ //if remote user started/stopped the screenshare then change the layout to pinned/grid
82
+ data.payload.value === 'true'
83
+ ? triggerChangeLayout(true, screenUidOfUser)
84
+ : triggerChangeLayout(false);
85
+ });
86
+ }, []);
82
87
 
83
88
  return (
84
89
  <>