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
@@ -1,46 +1,43 @@
1
- import {DualStreamMode, UidInterface} from '../Contexts/PropsContext';
2
- import {ActionType, UidStateInterface} from '../Contexts/RtcContext';
1
+ import {DualStreamMode} from '../Contexts/PropsContext';
2
+ import {
3
+ ActionType,
4
+ RenderStateInterface,
5
+ UidType,
6
+ } from '../Contexts/RtcContext';
3
7
 
4
8
  export default function UpdateDualStreamMode(
5
- state: UidStateInterface,
9
+ state: RenderStateInterface,
6
10
  action: ActionType<'UpdateDualStreamMode'>,
7
11
  ) {
8
12
  const newMode = action.value[0];
9
- let stateUpdate: UidStateInterface;
13
+ let renderList = {...state.renderList};
14
+ let stateUpdate: RenderStateInterface;
15
+ const setHighStreamType = (uid: UidType) => {
16
+ renderList[uid].streamType = 'high';
17
+ };
18
+
19
+ const setLowStreamType = (uid: UidType) => {
20
+ renderList[uid].streamType = 'low';
21
+ };
22
+
10
23
  if (newMode === DualStreamMode.HIGH) {
11
24
  // Update everybody to high
12
- const maxStateUpdate: UidInterface[] = state.max.map((user) => ({
13
- ...user,
14
- streamType: 'high',
15
- }));
16
- const minStateUpdate: UidInterface[] = state.min.map((user) => ({
17
- ...user,
18
- streamType: 'high',
19
- }));
20
- stateUpdate = {min: minStateUpdate, max: maxStateUpdate};
25
+ state.renderPosition.forEach(setHighStreamType);
21
26
  } else if (newMode === DualStreamMode.LOW) {
22
27
  // Update everybody to low
23
- const maxStateUpdate: UidInterface[] = state.max.map((user) => ({
24
- ...user,
25
- streamType: 'low',
26
- }));
27
- const minStateUpdate: UidInterface[] = state.min.map((user) => ({
28
- ...user,
29
- streamType: 'low',
30
- }));
31
- stateUpdate = {min: minStateUpdate, max: maxStateUpdate};
28
+ state.renderPosition.forEach(setLowStreamType);
32
29
  } else {
30
+ const [maxUid, ...minUids] = state.renderPosition;
33
31
  // if (newMode === DualStreamMode.DYNAMIC)
34
32
  // Max users are high other are low
35
- const maxStateUpdate: UidInterface[] = state.max.map((user) => ({
36
- ...user,
37
- streamType: 'high',
38
- }));
39
- const minStateUpdate: UidInterface[] = state.min.map((user) => ({
40
- ...user,
41
- streamType: 'low',
42
- }));
43
- stateUpdate = {min: minStateUpdate, max: maxStateUpdate};
33
+ //setting high for maxuid
34
+ setHighStreamType(maxUid);
35
+ //setting low for minuids
36
+ minUids.forEach(setLowStreamType);
44
37
  }
38
+ stateUpdate = {
39
+ renderList: renderList,
40
+ renderPosition: [...state.renderPosition],
41
+ };
45
42
  return stateUpdate;
46
43
  }
@@ -1,47 +1,60 @@
1
1
  import {DualStreamMode, ToggleState} from '../Contexts/PropsContext';
2
- import {ActionType, UidStateInterface} from '../Contexts/RtcContext';
2
+ import {
3
+ ActionType,
4
+ RenderStateInterface,
5
+ UidType,
6
+ } from '../Contexts/RtcContext';
3
7
 
4
8
  export default function UserJoined(
5
- state: UidStateInterface,
9
+ state: RenderStateInterface,
6
10
  action: ActionType<'UserJoined'>,
7
11
  dualStreamMode: DualStreamMode,
8
- uids: (string | number)[],
12
+ localUid: UidType,
9
13
  ) {
14
+ const newUid = action.value[0];
10
15
  let stateUpdate = {};
11
- if (uids.indexOf(action.value[0]) === -1) {
12
- //If new user has joined
13
- //By default add to minimized
14
- let minUpdate = [
15
- ...state.min,
16
- {
17
- uid: action.value[0],
18
- audio: ToggleState.disabled,
19
- video: ToggleState.disabled,
20
- streamType: dualStreamMode === DualStreamMode.HIGH ? 'high' : 'low', // Low if DualStreamMode is LOW or DYNAMIC by default
21
- },
22
- ];
16
+ //default type will be rtc
17
+ let typeData = {
18
+ type: 'rtc',
19
+ };
20
+ if (state.renderList[newUid] && 'type' in state.renderList[newUid]) {
21
+ typeData.type = state.renderList[newUid].type;
22
+ }
23
23
 
24
- if (minUpdate.length === 1 && state.max[0].uid === 'local') {
25
- //Only one remote and local is maximized
26
- //Change stream type to high if dualStreaMode is DYNAMIC
27
- if (dualStreamMode === DualStreamMode.DYNAMIC) {
28
- minUpdate[0].streamType = 'high';
29
- }
30
- //Swap max and min
31
- stateUpdate = {
32
- max: minUpdate,
33
- min: state.max,
34
- };
35
- } else {
36
- //More than one remote
37
- stateUpdate = {
38
- min: minUpdate,
39
- };
24
+ let renderList: RenderStateInterface['renderList'] = {
25
+ ...state.renderList,
26
+ [newUid]: {
27
+ ...state.renderList[newUid],
28
+ uid: newUid,
29
+ audio: ToggleState.disabled,
30
+ video: ToggleState.disabled,
31
+ streamType: dualStreamMode === DualStreamMode.HIGH ? 'high' : 'low', // Low if DualStreamMode is LOW or DYNAMIC by default,
32
+ ...typeData,
33
+ },
34
+ };
35
+ let renderPosition = [...state.renderPosition, newUid];
36
+ const [maxUid] = renderPosition;
37
+ if (renderPosition.length === 2 && maxUid === localUid) {
38
+ //Only one remote and local is maximized
39
+ //Change stream type to high if dualStreaMode is DYNAMIC
40
+ if (dualStreamMode === DualStreamMode.DYNAMIC) {
41
+ renderList[newUid].streamType = 'high';
40
42
  }
41
-
42
- console.log('new user joined!\n', state, stateUpdate, {
43
- dualStreamMode,
44
- });
43
+ //Swap render positions
44
+ stateUpdate = {
45
+ renderList: renderList,
46
+ renderPosition: renderPosition.reverse(),
47
+ };
48
+ } else {
49
+ //More than one remote
50
+ stateUpdate = {
51
+ renderList: renderList,
52
+ renderPosition: renderPosition,
53
+ };
45
54
  }
55
+
56
+ console.log('new user joined!\n', state, stateUpdate, {
57
+ dualStreamMode,
58
+ });
46
59
  return stateUpdate;
47
60
  }
@@ -1,20 +1,18 @@
1
- import {UidInterface} from '../Contexts/PropsContext';
2
- import {ActionType, UidStateInterface} from '../Contexts/RtcContext';
1
+ import {ActionType, RenderStateInterface} from '../Contexts/RtcContext';
3
2
 
4
3
  export default function UserMuteRemoteAudio(
5
- state: UidStateInterface,
4
+ state: RenderStateInterface,
6
5
  action: ActionType<'UserMuteRemoteAudio'>,
7
6
  ) {
8
- let stateUpdate = {};
9
- const audioMute = (user: UidInterface) => {
10
- if (user.uid === action.value[0].uid) {
11
- user.audio = action.value[1];
12
- }
13
- return user;
14
- };
15
- stateUpdate = {
16
- min: state.min.map(audioMute),
17
- max: state.max.map(audioMute),
7
+ let stateUpdate: RenderStateInterface = {
8
+ renderList: {
9
+ ...state.renderList,
10
+ [action.value[0]]: {
11
+ ...state.renderList[action.value[0]],
12
+ audio: action.value[1],
13
+ },
14
+ },
15
+ renderPosition: [...state.renderPosition],
18
16
  };
19
17
  return stateUpdate;
20
18
  }
@@ -1,20 +1,18 @@
1
- import {UidInterface} from '../Contexts/PropsContext';
2
- import {ActionType, UidStateInterface} from '../Contexts/RtcContext';
1
+ import {ActionType, RenderStateInterface} from '../Contexts/RtcContext';
3
2
 
4
3
  export default function UserMuteRemoteVideo(
5
- state: UidStateInterface,
4
+ state: RenderStateInterface,
6
5
  action: ActionType<'UserMuteRemoteVideo'>,
7
6
  ) {
8
- let stateUpdate = {};
9
- const videoMute = (user: UidInterface) => {
10
- if (user.uid === action.value[0].uid) {
11
- user.video = action.value[1];
12
- }
13
- return user;
14
- };
15
- stateUpdate = {
16
- min: state.min.map(videoMute),
17
- max: state.max.map(videoMute),
7
+ let stateUpdate: RenderStateInterface = {
8
+ renderList: {
9
+ ...state.renderList,
10
+ [action.value[0]]: {
11
+ ...state.renderList[action.value[0]],
12
+ video: action.value[1],
13
+ },
14
+ },
15
+ renderPosition: [...state.renderPosition],
18
16
  };
19
17
  return stateUpdate;
20
18
  }
@@ -1,21 +1,24 @@
1
- import {ActionType, UidStateInterface} from '../Contexts/RtcContext';
1
+ import {ActionType, RenderStateInterface} from '../Contexts/RtcContext';
2
2
 
3
3
  export default function UserOffline(
4
- state: UidStateInterface,
4
+ state: RenderStateInterface,
5
5
  action: ActionType<'UserOffline'>,
6
6
  ) {
7
- let stateUpdate = {};
8
- if (state.max[0].uid === action.value[0]) {
9
- //If max has the remote video
10
- let minUpdate = [...state.min];
11
- stateUpdate = {
12
- max: [minUpdate.pop()],
13
- min: minUpdate,
14
- };
15
- } else {
16
- stateUpdate = {
17
- min: state.min.filter((user) => user.uid !== action.value[0]),
18
- };
19
- }
7
+ // let updatedRenderList = {
8
+ // ...state.renderList,
9
+ // };
10
+ // //don't delete user data from renderlist
11
+ // //we will update user data with {offline:true} from RTM user left event
12
+ // if (updatedRenderList[action.value[0]]) {
13
+ // delete updatedRenderList[action.value[0]];
14
+ // }
15
+ const updatedRenderPosition = [...state.renderPosition].filter(
16
+ (uid) => uid !== action.value[0],
17
+ );
18
+ const stateUpdate: RenderStateInterface = {
19
+ renderList: state.renderList,
20
+ renderPosition: updatedRenderPosition,
21
+ };
22
+
20
23
  return stateUpdate;
21
24
  }
@@ -24,6 +24,10 @@ const Create = ({
24
24
  const {callbacks, rtcProps, mode} = useContext(PropsContext);
25
25
  const {geoFencing = true} = rtcProps || {};
26
26
  let engine = useRef<RtcEngine>({} as RtcEngine);
27
+ // commented for v1 release
28
+ // const beforeCreate = rtcProps?.lifecycle?.useBeforeCreate
29
+ // ? rtcProps.lifecycle.useBeforeCreate()
30
+ // : null;
27
31
  const isVideoEnabledRef = useRef<boolean>(false);
28
32
  const firstUpdate = useRef(true);
29
33
 
@@ -39,7 +43,7 @@ const Create = ({
39
43
  value: [ToggleState.disabled],
40
44
  });
41
45
  } catch (error) {
42
- const {status} = e as any;
46
+ const {status} = error as any;
43
47
  // App Builder web only
44
48
  if (status) {
45
49
  const {audioError, videoError} = status;
@@ -62,7 +66,7 @@ const Create = ({
62
66
  console.error('No video device', videoError);
63
67
  }
64
68
  }
65
- console.error('No devices', e);
69
+ console.error('No devices', error);
66
70
  }
67
71
  };
68
72
  const enableVideoAndAudioWithEnabledState = async () => {
@@ -121,6 +125,14 @@ const Create = ({
121
125
  //Request required permissions from Android
122
126
  await requestCameraAndAudioPermission();
123
127
  }
128
+ // commented for v1 release
129
+ // try {
130
+ // if (beforeCreate) {
131
+ // await beforeCreate();
132
+ // }
133
+ // } catch (error) {
134
+ // console.error('FPE:Error on executing useBeforeCreate', error);
135
+ // }
124
136
  try {
125
137
  if (
126
138
  geoFencing === true &&
@@ -1,17 +1,22 @@
1
1
  import React, {useEffect, useContext, useRef} from 'react';
2
2
  import RtcEngine from 'react-native-agora';
3
- import {UidStateInterface, DispatchType} from '../Contexts/RtcContext';
3
+ import {RenderStateInterface, DispatchType} from '../Contexts/RtcContext';
4
4
  import PropsContext, {ToggleState} from '../Contexts/PropsContext';
5
5
  import {Platform} from 'react-native';
6
6
 
7
7
  const Join: React.FC<{
8
+ children: React.ReactNode;
8
9
  precall: boolean;
9
10
  engineRef: React.MutableRefObject<RtcEngine>;
10
- uidState: UidStateInterface;
11
+ uidState: RenderStateInterface;
11
12
  dispatch: DispatchType;
12
13
  }> = ({children, precall, engineRef, uidState, dispatch}) => {
13
14
  let joinState = useRef(false);
14
15
  const {rtcProps} = useContext(PropsContext);
16
+ //commented for v1 release
17
+ // const beforeJoin = rtcProps?.lifecycle?.useBeforeJoin
18
+ // ? rtcProps.lifecycle.useBeforeJoin()
19
+ // : null;
15
20
 
16
21
  useEffect(() => {
17
22
  const engine = engineRef.current;
@@ -24,7 +29,9 @@ const Join: React.FC<{
24
29
  console.error('Cannot leave the channel:', err);
25
30
  }
26
31
  }
27
- const videoState = uidState.max[0].video;
32
+ const {renderList, renderPosition} = uidState;
33
+ const [maxUid] = renderPosition;
34
+ const videoState = renderList[maxUid].video;
28
35
  async function join() {
29
36
  if (
30
37
  rtcProps.encryption &&
@@ -48,6 +55,15 @@ const Join: React.FC<{
48
55
  value: [ToggleState.disabled],
49
56
  });
50
57
  }
58
+ //commented for v1 release
59
+ // try {
60
+ // if (beforeJoin) {
61
+ // await beforeJoin();
62
+ // }
63
+ // } catch (error) {
64
+ // console.error('FPE:Error on executing useBeforeJoin', error);
65
+ // }
66
+
51
67
  await engine.joinChannel(
52
68
  rtcProps.token || null,
53
69
  rtcProps.channel,
@@ -1,21 +1,18 @@
1
1
  import React, {useState, useReducer, useContext, useCallback} from 'react';
2
2
  import {
3
3
  RtcProvider,
4
- UidStateInterface,
4
+ RenderStateInterface,
5
5
  DispatchType,
6
6
  ActionType,
7
+ UidType,
7
8
  } from './Contexts/RtcContext';
8
9
  import PropsContext, {
9
10
  ToggleState,
10
- UidInterface,
11
11
  RtcPropsInterface,
12
12
  CallbacksInterface,
13
13
  DualStreamMode,
14
- ClientRole,
15
- ChannelProfile,
16
14
  } from './Contexts/PropsContext';
17
- import {MinUidProvider} from './Contexts/MinUidContext';
18
- import {MaxUidProvider} from './Contexts/MaxUidContext';
15
+ import {RenderProvider} from './Contexts/RenderContext';
19
16
  import {actionTypeGuard} from './Utils/actionTypeGuard';
20
17
 
21
18
  import {
@@ -31,23 +28,25 @@ import {
31
28
  } from './Reducer';
32
29
  import Create from './Rtc/Create';
33
30
  import Join from './Rtc/Join';
31
+ import useLocalUid from './Utils/useLocalUid';
34
32
 
35
- const RtcConfigure: React.FC<Partial<RtcPropsInterface>> = (props) => {
36
- const {callbacks, rtcProps, mode} = useContext(PropsContext);
33
+ const RtcConfigure = (props: {children: React.ReactNode}) => {
34
+ const {callbacks, rtcProps} = useContext(PropsContext);
37
35
  let [dualStreamMode, setDualStreamMode] = useState<DualStreamMode>(
38
36
  rtcProps?.initialDualStreamMode || DualStreamMode.DYNAMIC,
39
37
  );
40
-
41
- const initialLocalState: UidStateInterface = {
42
- min: [],
43
- max: [
44
- {
45
- uid: 'local',
38
+ const localUid = useLocalUid();
39
+ const initialLocalState: RenderStateInterface = {
40
+ renderList: {
41
+ [localUid]: {
42
+ uid: localUid,
46
43
  audio: ToggleState.disabled,
47
44
  video: ToggleState.disabled,
48
45
  streamType: 'high',
46
+ type: 'rtc',
49
47
  },
50
- ],
48
+ },
49
+ renderPosition: [localUid],
51
50
  };
52
51
 
53
52
  const [initialState, setInitialState] = React.useState(
@@ -58,14 +57,75 @@ const RtcConfigure: React.FC<Partial<RtcPropsInterface>> = (props) => {
58
57
  setInitialState(JSON.parse(JSON.stringify(initialLocalState)));
59
58
  }, []);
60
59
 
60
+ /**
61
+ *
62
+ * @param state RenderStateInterface
63
+ * @param action ActionType<'UpdateRenderList'>
64
+ * @returns void
65
+ *
66
+ * UpdateRenderList will update the renderlist for given uid
67
+ *
68
+ */
69
+ const UpdateRenderList = (
70
+ state: RenderStateInterface,
71
+ action: ActionType<'UpdateRenderList'>,
72
+ ) => {
73
+ const newState = {
74
+ ...state,
75
+ renderList: {
76
+ ...state.renderList,
77
+ [action.value[0]]: {
78
+ ...state.renderList[action.value[0]],
79
+ ...action.value[1],
80
+ },
81
+ },
82
+ };
83
+ return newState;
84
+ };
85
+
86
+ /**
87
+ *
88
+ * @param state RenderStateInterface
89
+ * @param action ActionType<'AddCustomContent'>
90
+ * @returns void
91
+ *
92
+ * AddCustomContent use to add new data into render position and render list
93
+ */
94
+ const AddCustomContent = (
95
+ state: RenderStateInterface,
96
+ action: ActionType<'AddCustomContent'>,
97
+ ) => {
98
+ const newState = {
99
+ ...state,
100
+ renderPosition: [...state.renderPosition, action.value[0]],
101
+ renderList: {
102
+ ...state.renderList,
103
+ [action.value[0]]: {
104
+ ...state.renderList[action.value[0]],
105
+ ...action.value[1],
106
+ },
107
+ },
108
+ };
109
+ return newState;
110
+ };
111
+
61
112
  const reducer = (
62
- state: UidStateInterface,
113
+ state: RenderStateInterface,
63
114
  action: ActionType<keyof CallbacksInterface>,
64
115
  ) => {
65
- let stateUpdate = {},
66
- uids = [...state.max, ...state.min].map((u: UidInterface) => u.uid);
116
+ let stateUpdate = {};
67
117
 
68
118
  switch (action.type) {
119
+ case 'AddCustomContent':
120
+ if (actionTypeGuard(action, action.type)) {
121
+ stateUpdate = AddCustomContent(state, action);
122
+ }
123
+ break;
124
+ case 'UpdateRenderList':
125
+ if (actionTypeGuard(action, action.type)) {
126
+ stateUpdate = UpdateRenderList(state, action);
127
+ }
128
+ break;
69
129
  case 'UpdateDualStreamMode':
70
130
  if (actionTypeGuard(action, action.type)) {
71
131
  stateUpdate = UpdateDualStreamMode(state, action);
@@ -73,7 +133,7 @@ const RtcConfigure: React.FC<Partial<RtcPropsInterface>> = (props) => {
73
133
  break;
74
134
  case 'UserJoined':
75
135
  if (actionTypeGuard(action, action.type)) {
76
- stateUpdate = UserJoined(state, action, dualStreamMode, uids);
136
+ stateUpdate = UserJoined(state, action, dualStreamMode, localUid);
77
137
  }
78
138
  break;
79
139
  case 'UserOffline':
@@ -86,6 +146,11 @@ const RtcConfigure: React.FC<Partial<RtcPropsInterface>> = (props) => {
86
146
  stateUpdate = swapVideo(state, action.value[0]);
87
147
  }
88
148
  break;
149
+ case 'DequeVideo':
150
+ if (actionTypeGuard(action, action.type)) {
151
+ stateUpdate = dequeVideo(state, action.value[0]);
152
+ }
153
+ break;
89
154
  case 'UserMuteRemoteAudio':
90
155
  if (actionTypeGuard(action, action.type)) {
91
156
  stateUpdate = UserMuteRemoteAudio(state, action);
@@ -98,12 +163,12 @@ const RtcConfigure: React.FC<Partial<RtcPropsInterface>> = (props) => {
98
163
  break;
99
164
  case 'LocalMuteAudio':
100
165
  if (actionTypeGuard(action, action.type)) {
101
- stateUpdate = LocalMuteAudio(state, action);
166
+ stateUpdate = LocalMuteAudio(state, action, localUid);
102
167
  }
103
168
  break;
104
169
  case 'LocalMuteVideo':
105
170
  if (actionTypeGuard(action, action.type)) {
106
- stateUpdate = LocalMuteVideo(state, action);
171
+ stateUpdate = LocalMuteVideo(state, action, localUid);
107
172
  }
108
173
  break;
109
174
  case 'RemoteAudioStateChanged':
@@ -137,36 +202,86 @@ const RtcConfigure: React.FC<Partial<RtcPropsInterface>> = (props) => {
137
202
  };
138
203
 
139
204
  const swapVideo = useCallback(
140
- (state: UidStateInterface, ele: UidInterface) => {
141
- let newState: UidStateInterface = {
142
- min: [],
143
- max: [],
205
+ (state: RenderStateInterface, newMaxUid: UidType) => {
206
+ let renderPosition: RenderStateInterface['renderPosition'] = [
207
+ ...state.renderPosition,
208
+ ];
209
+ let renderList: RenderStateInterface['renderList'] = {
210
+ ...state.renderList,
144
211
  };
145
- // Remove the minimized element which is being swapped out
146
- newState.min = state.min.filter((e) => e !== ele);
212
+ // Element which is currently maximized
213
+ const [currentMaxUid] = renderPosition;
147
214
 
148
- let maxEle = state.max[0]; // Element which is currently maximized
149
- let minEle = ele;
215
+ if (currentMaxUid === newMaxUid) {
216
+ return {};
217
+ }
150
218
 
151
219
  if (dualStreamMode === DualStreamMode.DYNAMIC) {
152
- maxEle.streamType = 'low'; // set stream quality to low
153
- minEle.streamType = 'high'; // set stream quality to high
154
-
220
+ renderList[currentMaxUid].streamType = 'low';
221
+ renderList[newMaxUid].streamType = 'high';
155
222
  // No need to modify the streamType if the mode is not dynamic
156
223
  }
157
224
 
158
- if (maxEle.uid === 'local') {
159
- newState.min.unshift(maxEle);
160
- } else {
161
- newState.min.push(maxEle);
225
+ /**
226
+ * old logic for swap
227
+ * if currentMaxUid === localUid then push newMaxId at first position
228
+ * else push newMaxUid at last position
229
+ */
230
+
231
+ const newMaxUidOldPosition = renderPosition.findIndex(
232
+ (i) => i === newMaxUid,
233
+ );
234
+
235
+ renderPosition[0] = newMaxUid;
236
+ renderPosition[newMaxUidOldPosition] = currentMaxUid;
237
+
238
+ return {
239
+ renderPosition: renderPosition,
240
+ renderList: renderList,
241
+ };
242
+ },
243
+ [dualStreamMode],
244
+ );
245
+
246
+ /**
247
+ * deque will
248
+ */
249
+ const dequeVideo = useCallback(
250
+ (state: RenderStateInterface, newMaxUid: UidType) => {
251
+ let renderPosition: RenderStateInterface['renderPosition'] = [
252
+ ...state.renderPosition,
253
+ ];
254
+ let renderList: RenderStateInterface['renderList'] = {
255
+ ...state.renderList,
256
+ };
257
+ // Element which is currently maximized
258
+ const [currentMaxUid] = renderPosition;
259
+
260
+ if (currentMaxUid === newMaxUid) {
261
+ return {};
262
+ }
263
+
264
+ if (dualStreamMode === DualStreamMode.DYNAMIC) {
265
+ renderList[currentMaxUid].streamType = 'low';
266
+ renderList[newMaxUid].streamType = 'high';
267
+ // No need to modify the streamType if the mode is not dynamic
162
268
  }
163
- newState.max = [minEle];
164
269
 
165
- return newState;
270
+ const minIds = renderPosition.filter(
271
+ (uid) => uid !== newMaxUid && uid !== currentMaxUid,
272
+ );
273
+
274
+ renderPosition = [newMaxUid, currentMaxUid, ...minIds];
275
+
276
+ return {
277
+ renderPosition: renderPosition,
278
+ renderList: renderList,
279
+ };
166
280
  },
167
281
  [dualStreamMode],
168
282
  );
169
- const [uidState, dispatch]: [UidStateInterface, DispatchType] = useReducer(
283
+
284
+ const [uidState, dispatch]: [RenderStateInterface, DispatchType] = useReducer(
170
285
  reducer,
171
286
  initialState,
172
287
  );
@@ -185,11 +300,13 @@ const RtcConfigure: React.FC<Partial<RtcPropsInterface>> = (props) => {
185
300
  dispatch,
186
301
  setDualStreamMode,
187
302
  }}>
188
- <MaxUidProvider value={uidState.max}>
189
- <MinUidProvider value={uidState.min}>
190
- {props.children}
191
- </MinUidProvider>
192
- </MaxUidProvider>
303
+ <RenderProvider
304
+ value={{
305
+ renderList: uidState.renderList,
306
+ renderPosition: uidState.renderPosition,
307
+ }}>
308
+ {props.children}
309
+ </RenderProvider>
193
310
  </RtcProvider>
194
311
  </Join>
195
312
  )}
@@ -0,0 +1,8 @@
1
+ import {useContext} from 'react';
2
+ import PropsContext from '../Contexts/PropsContext';
3
+
4
+ const useLocalUid = () => {
5
+ const {rtcProps} = useContext(PropsContext);
6
+ return rtcProps?.uid || 0;
7
+ };
8
+ export default useLocalUid;