agora-appbuilder-core 4.0.0 → 4.0.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 (475) hide show
  1. package/package.json +3 -3
  2. package/template/.bundle/config +2 -0
  3. package/template/Gemfile +4 -0
  4. package/template/Gulpfile.js +29 -29
  5. package/template/_eslintrc.js +3 -3
  6. package/template/_gitignore +12 -11
  7. package/template/_package-lock.json +28491 -23647
  8. package/template/_prettierrc.js +2 -2
  9. package/template/agora-rn-uikit/.eslintrc.js +5 -0
  10. package/template/agora-rn-uikit/package.json +14 -14
  11. package/template/agora-rn-uikit/src/AgoraUIKit.tsx +6 -6
  12. package/template/agora-rn-uikit/src/Contexts/ContentContext.tsx +10 -0
  13. package/template/agora-rn-uikit/src/Contexts/DispatchContext.tsx +22 -0
  14. package/template/agora-rn-uikit/src/Contexts/LocalUserContext.tsx +6 -6
  15. package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +79 -38
  16. package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +26 -17
  17. package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +1 -0
  18. package/template/agora-rn-uikit/src/Controls/Icons.ts +45 -0
  19. package/template/agora-rn-uikit/src/Controls/Local/EndCall.tsx +6 -4
  20. package/template/agora-rn-uikit/src/Controls/Local/FullScreen.tsx +3 -1
  21. package/template/agora-rn-uikit/src/Controls/Local/LocalAudioMute.tsx +5 -2
  22. package/template/agora-rn-uikit/src/Controls/Local/LocalVideoMute.tsx +5 -2
  23. package/template/agora-rn-uikit/src/Controls/Local/Recording.tsx +0 -2
  24. package/template/agora-rn-uikit/src/Controls/Local/SwitchCamera.tsx +7 -6
  25. package/template/agora-rn-uikit/src/Controls/LocalControls.tsx +5 -5
  26. package/template/agora-rn-uikit/src/Controls/Remote/RemoteAudioMute.tsx +5 -4
  27. package/template/agora-rn-uikit/src/Controls/Remote/RemoteSwap.tsx +3 -1
  28. package/template/agora-rn-uikit/src/Controls/Remote/RemoteVideoMute.tsx +5 -4
  29. package/template/agora-rn-uikit/src/Controls/RemoteControls.tsx +2 -2
  30. package/template/agora-rn-uikit/src/Reducer/ActiveSpeaker.ts +30 -0
  31. package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +8 -7
  32. package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +8 -7
  33. package/template/agora-rn-uikit/src/Reducer/LocalPermissionState.ts +6 -7
  34. package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +7 -8
  35. package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +9 -9
  36. package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +7 -8
  37. package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +14 -13
  38. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +6 -7
  39. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +6 -7
  40. package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +5 -6
  41. package/template/agora-rn-uikit/src/Reducer/UserPin.ts +20 -3
  42. package/template/agora-rn-uikit/src/Reducer/UserSecondaryPin.ts +23 -0
  43. package/template/agora-rn-uikit/src/Reducer/index.ts +2 -1
  44. package/template/agora-rn-uikit/src/Rtc/Create.tsx +138 -100
  45. package/template/agora-rn-uikit/src/Rtc/Join.tsx +55 -28
  46. package/template/agora-rn-uikit/src/RtcConfigure.tsx +177 -77
  47. package/template/agora-rn-uikit/src/Utils/isBotUser.ts +15 -0
  48. package/template/agora-rn-uikit/src/Utils/quality.tsx +8 -0
  49. package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +56 -12
  50. package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +47 -17
  51. package/template/agora-rn-uikit/src/Views/MinVideoView.tsx +19 -11
  52. package/template/agora-rn-uikit/src/index.ts +15 -9
  53. package/template/android/app/build.gradle +59 -156
  54. package/template/android/app/src/debug/AndroidManifest.xml +6 -1
  55. package/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java +7 -4
  56. package/template/android/app/src/main/AndroidManifest.xml +6 -19
  57. package/template/android/app/src/main/assets/fonts/icomoon.ttf +0 -0
  58. package/template/android/app/src/main/java/com/helloworld/MainActivity.java +17 -0
  59. package/template/android/app/src/main/java/com/helloworld/MainApplication.java +22 -36
  60. package/template/android/app/src/main/java/com/helloworld/SSLPinningFactory.java +30 -0
  61. package/template/android/app/src/main/res/values/strings.xml +3 -0
  62. package/template/android/app/src/release/java/com/helloworld/ReactNativeFlipper.java +20 -0
  63. package/template/android/build.gradle +19 -33
  64. package/template/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  65. package/template/android/gradle/wrapper/gradle-wrapper.properties +3 -2
  66. package/template/android/gradle.properties +18 -4
  67. package/template/android/gradlew +165 -104
  68. package/template/android/gradlew.bat +12 -23
  69. package/template/android/settings.gradle +1 -0
  70. package/template/bridge/rtc/webNg/RtcEngine.ts +200 -70
  71. package/template/bridge/rtc/webNg/{SurfaceView.tsx → RtcSurfaceView.tsx} +20 -26
  72. package/template/bridge/rtc/webNg/Types.ts +20 -5
  73. package/template/bridge/rtc/webNg/index.ts +81 -14
  74. package/template/bridge/rtm/web/index.ts +5 -3
  75. package/template/configTransform.js +16 -1
  76. package/template/customization-api/action-library.ts +4 -16
  77. package/template/customization-api/app-state.ts +15 -8
  78. package/template/customization-api/customEvents.ts +7 -2
  79. package/template/customization-api/customize.ts +1 -1
  80. package/template/customization-api/index.ts +4 -0
  81. package/template/customization-api/sub-components.ts +17 -16
  82. package/template/customization-api/temp.ts +52 -0
  83. package/template/customization-api/typeDefinition.ts +34 -46
  84. package/template/customization-api/types.ts +26 -0
  85. package/template/customization-api/utils.ts +4 -0
  86. package/template/customization-implementation/createHook.ts +24 -6
  87. package/template/customization-implementation/index.ts +1 -2
  88. package/template/customization-implementation/useCustomization.tsx +5 -7
  89. package/template/defaultConfig.js +72 -0
  90. package/template/global.d.ts +14 -1
  91. package/template/index.js +1 -4
  92. package/template/index.web.js +0 -5
  93. package/template/index.wsdk.tsx +1 -12
  94. package/template/ios/.xcode.env +11 -0
  95. package/template/ios/HelloWorld/AppDelegate.h +2 -4
  96. package/template/ios/HelloWorld/AppDelegate.mm +64 -0
  97. package/template/ios/HelloWorld/HelloWorldDebug.entitlements +10 -0
  98. package/template/ios/HelloWorld/Info.plist +8 -2
  99. package/template/ios/HelloWorld/main.m +2 -1
  100. package/template/ios/HelloWorld.xcodeproj/project.pbxproj +533 -17
  101. package/template/ios/HelloWorld.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  102. package/template/ios/HelloWorld.xcworkspace/contents.xcworkspacedata +10 -0
  103. package/template/ios/HelloWorld.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  104. package/template/ios/HelloWorldTests/HelloWorldTests.m +14 -13
  105. package/template/ios/HelloWorldTests/Info.plist +2 -2
  106. package/template/ios/Podfile +54 -20
  107. package/template/ios/Podfile.lock +809 -0
  108. package/template/ios/ScreenSharing/Info.plist +15 -0
  109. package/template/ios/ScreenSharing/SampleHandler.h +9 -0
  110. package/template/ios/ScreenSharing/SampleHandler.m +70 -0
  111. package/template/jest.config.js +4 -0
  112. package/template/metro.config.js +7 -32
  113. package/template/package.json +53 -39
  114. package/template/react-native-toast-message/index.d.ts +3 -1
  115. package/template/react-native-toast-message/index.js +1 -0
  116. package/template/react-native-toast-message/src/components/base/index.js +20 -32
  117. package/template/react-native-toast-message/src/components/base/styles.js +18 -21
  118. package/template/react-native-toast-message/src/components/checkbox.js +24 -19
  119. package/template/react-native-toast-message/src/index.js +3 -1
  120. package/template/react-native-toast-message/src/index.sdk.tsx +4 -1
  121. package/template/src/App.tsx +53 -69
  122. package/template/src/AppRoutes.tsx +90 -0
  123. package/template/src/AppWrapper.tsx +42 -25
  124. package/template/src/SDKAppWrapper.tsx +90 -57
  125. package/template/src/app-state/useLocalUserInfo.ts +3 -3
  126. package/template/src/app-state/useNoiseSupression.native.tsx +67 -0
  127. package/template/src/app-state/useNoiseSupression.tsx +107 -0
  128. package/template/src/app-state/useVideoQuality.tsx +39 -0
  129. package/template/src/assets/font-styles.css +175 -3
  130. package/template/src/assets/fonts/icomoon.ttf +0 -0
  131. package/template/src/assets/selection.json +1 -1
  132. package/template/src/atoms/ActionMenu.tsx +50 -11
  133. package/template/src/atoms/Avatar.tsx +51 -0
  134. package/template/src/atoms/Card.tsx +21 -8
  135. package/template/src/atoms/Carousel.native.tsx +105 -0
  136. package/template/src/atoms/Carousel.tsx +103 -0
  137. package/template/src/atoms/Checkbox.tsx +98 -0
  138. package/template/src/atoms/CircularProgress.tsx +0 -1
  139. package/template/src/atoms/ClipboardIconButton.tsx +91 -0
  140. package/template/src/atoms/CustomIcon.tsx +46 -0
  141. package/template/src/atoms/DropDownMulti.tsx +349 -0
  142. package/template/src/atoms/Dropdown.tsx +3 -3
  143. package/template/src/atoms/IconButton.tsx +52 -9
  144. package/template/src/atoms/ImageIcon.tsx +18 -5
  145. package/template/src/atoms/InlineNotification.tsx +81 -0
  146. package/template/src/atoms/InviteInfo.tsx +4 -4
  147. package/template/src/atoms/MeetingLink.tsx +160 -0
  148. package/template/src/atoms/ParticipantsCount.tsx +20 -8
  149. package/template/src/atoms/Popup.tsx +49 -27
  150. package/template/src/atoms/PrimaryButton.tsx +19 -5
  151. package/template/src/atoms/RecordingInfo.tsx +8 -5
  152. package/template/src/atoms/SecondaryButton.tsx +2 -0
  153. package/template/src/atoms/Spacer.tsx +1 -0
  154. package/template/src/atoms/TertiaryButton.tsx +35 -5
  155. package/template/src/atoms/TextInput.tsx +2 -1
  156. package/template/src/atoms/Toolbar.tsx +102 -0
  157. package/template/src/atoms/ToolbarItem.tsx +85 -0
  158. package/template/src/atoms/ToolbarMenu.tsx +40 -0
  159. package/template/src/atoms/ToolbarMenuItem.tsx +104 -0
  160. package/template/src/atoms/ToolbarPreset.tsx +71 -0
  161. package/template/src/atoms/Tooltip.tsx +30 -13
  162. package/template/src/atoms/pagination/Pagination.tsx +127 -0
  163. package/template/src/atoms/pagination/usePagination.tsx +88 -0
  164. package/template/src/auth/AuthProvider.tsx +500 -0
  165. package/template/src/auth/AuthRoute.tsx +94 -0
  166. package/template/src/auth/IDPAuth.electron.tsx +31 -0
  167. package/template/src/auth/IDPAuth.tsx +67 -0
  168. package/template/src/auth/IDPLogoutComponent.tsx +158 -0
  169. package/template/src/auth/UserCancelPopup.tsx +115 -0
  170. package/template/src/auth/config.ts +52 -0
  171. package/template/src/auth/openIDPURL.electron.tsx +39 -0
  172. package/template/src/auth/openIDPURL.native.tsx +51 -0
  173. package/template/src/auth/openIDPURL.tsx +20 -0
  174. package/template/src/auth/useIDPAuth.electron.tsx +65 -0
  175. package/template/src/auth/useIDPAuth.native.tsx +70 -0
  176. package/template/src/auth/useIDPAuth.tsx +63 -0
  177. package/template/src/auth/useTokenAuth.tsx +194 -0
  178. package/template/src/components/Chat.tsx +92 -72
  179. package/template/src/components/ChatContext.ts +2 -0
  180. package/template/src/components/ColorConfigure.tsx +0 -1
  181. package/template/src/components/CommonStyles.ts +9 -2
  182. package/template/src/components/Controls.tsx +914 -182
  183. package/template/src/components/Controls1.native.tsx +9 -5
  184. package/template/src/components/DeviceConfigure.native.tsx +2 -2
  185. package/template/src/components/DeviceConfigure.tsx +400 -149
  186. package/template/src/components/DeviceContext.tsx +2 -0
  187. package/template/src/components/EventsConfigure.tsx +722 -82
  188. package/template/src/components/GraphQLProvider.tsx +82 -39
  189. package/template/src/components/GridVideo.tsx +30 -16
  190. package/template/src/components/HostControlView.tsx +11 -14
  191. package/template/src/components/JoinPhrase.tsx +0 -1
  192. package/template/src/components/Leftbar.tsx +110 -0
  193. package/template/src/components/Navbar.tsx +305 -147
  194. package/template/src/components/NavbarMobile.tsx +119 -0
  195. package/template/src/components/Navigation.native.tsx +1 -15
  196. package/template/src/components/{Settings.native.tsx → Navigation.sdk.tsx} +17 -6
  197. package/template/src/components/NetworkQualityContext.tsx +12 -6
  198. package/template/src/components/ParticipantsView.tsx +63 -56
  199. package/template/src/components/PinnedVideo.tsx +191 -119
  200. package/template/src/components/Precall.native.tsx +177 -72
  201. package/template/src/components/Precall.tsx +247 -78
  202. package/template/src/components/RTMConfigure.tsx +205 -67
  203. package/template/src/components/Rightbar.tsx +112 -0
  204. package/template/src/components/Router.electron.ts +1 -0
  205. package/template/src/components/Router.native.ts +1 -0
  206. package/template/src/components/Router.sdk.ts +1 -0
  207. package/template/src/components/Router.ts +1 -0
  208. package/template/src/components/SdkApiContext.tsx +313 -0
  209. package/template/src/components/SdkMuteToggleListener.tsx +88 -0
  210. package/template/src/components/SessionContext.tsx +0 -1
  211. package/template/src/components/Settings.tsx +33 -4
  212. package/template/src/components/SettingsView.tsx +44 -9
  213. package/template/src/components/Share.tsx +152 -74
  214. package/template/src/components/StorageContext.tsx +23 -6
  215. package/template/src/components/ToastComponent.tsx +10 -1
  216. package/template/src/components/WhiteboardLayout.tsx +291 -0
  217. package/template/src/components/chat-messages/useChatMessages.tsx +454 -239
  218. package/template/src/components/chat-ui/{useChatUIControl.tsx → useChatUIControls.tsx} +29 -29
  219. package/template/src/components/common/Error.tsx +2 -0
  220. package/template/src/components/common/Logo.tsx +2 -2
  221. package/template/src/components/contexts/LiveStreamDataContext.tsx +13 -12
  222. package/template/src/components/contexts/ScreenShareContext.tsx +15 -1
  223. package/template/src/components/contexts/VideoMeetingDataContext.tsx +6 -6
  224. package/template/src/components/contexts/WaitingRoomContext.tsx +50 -0
  225. package/template/src/components/contexts/WhiteboardContext.tsx +54 -54
  226. package/template/src/components/disable-chat/useDisableChat.tsx +32 -0
  227. package/template/src/components/livestream/LiveStreamContext.tsx +314 -220
  228. package/template/src/components/livestream/Types.ts +36 -20
  229. package/template/src/components/livestream/views/LiveStreamAttendeeLandingTile.tsx +295 -0
  230. package/template/src/components/livestream/views/LiveStreamControls.tsx +5 -10
  231. package/template/src/components/meeting-info-invite/MeetingInfo.tsx +82 -0
  232. package/template/src/components/meeting-info-invite/MeetingInfoCardHeader.tsx +86 -0
  233. package/template/src/components/meeting-info-invite/MeetingInfoGridTile.tsx +218 -0
  234. package/template/src/components/meeting-info-invite/MeetingInfoLinks.tsx +122 -0
  235. package/template/src/components/participants/AllAudienceParticipants.tsx +19 -20
  236. package/template/src/components/participants/AllHostParticipants.tsx +20 -19
  237. package/template/src/components/participants/Participant.tsx +45 -16
  238. package/template/src/components/participants/ParticipantSectionTitle.tsx +5 -2
  239. package/template/src/components/participants/ScreenshareParticipants.tsx +17 -19
  240. package/template/src/components/participants/UserActionMenuOptions.tsx +173 -62
  241. package/template/src/components/participants/WaitingRoomParticipants.tsx +74 -0
  242. package/template/src/components/popups/InvitePopup.tsx +110 -45
  243. package/template/src/components/popups/StartScreenSharePopup.native.tsx +182 -0
  244. package/template/src/components/popups/StartScreenSharePopup.tsx +6 -0
  245. package/template/src/components/popups/StopRecordingPopup.tsx +11 -5
  246. package/template/src/components/popups/StopScreenSharePopup.native.tsx +135 -0
  247. package/template/src/components/popups/StopScreenSharePopup.tsx +6 -0
  248. package/template/src/components/popups/WhiteboardClearAllPopup.tsx +123 -0
  249. package/template/src/components/precall/LocalMute.tsx +69 -45
  250. package/template/src/components/precall/PermissionHelper.tsx +56 -28
  251. package/template/src/components/precall/PreCallSettings.tsx +1 -0
  252. package/template/src/components/precall/VideoFallback.tsx +173 -0
  253. package/template/src/components/precall/VideoPreview.native.tsx +19 -53
  254. package/template/src/components/precall/VideoPreview.tsx +29 -164
  255. package/template/src/components/precall/index.tsx +2 -0
  256. package/template/src/components/precall/joinCallBtn.native.tsx +12 -5
  257. package/template/src/components/precall/joinCallBtn.tsx +13 -4
  258. package/template/src/components/precall/joinWaitingRoomBtn.native.tsx +210 -0
  259. package/template/src/components/precall/joinWaitingRoomBtn.tsx +250 -0
  260. package/template/src/components/precall/meetingTitle.tsx +37 -11
  261. package/template/src/components/precall/selectDevice.tsx +5 -5
  262. package/template/src/components/precall/textInput.tsx +17 -19
  263. package/template/src/components/precall/usePreCall.tsx +33 -1
  264. package/template/src/components/recording-bot/RecordingBotRoute.tsx +42 -0
  265. package/template/src/components/recordings/RecordingsDateTable.tsx +62 -0
  266. package/template/src/components/recordings/RecordingsModal.tsx +135 -0
  267. package/template/src/components/recordings/ViewRecordingsModal.tsx +51 -0
  268. package/template/src/components/recordings/recording-table.tsx +154 -0
  269. package/template/src/components/recordings/style.ts +183 -0
  270. package/template/src/components/recordings/utils.ts +80 -0
  271. package/template/src/components/room-info/useRoomInfo.tsx +128 -0
  272. package/template/src/components/{meeting-info/useSetMeetingInfo.tsx → room-info/useSetRoomInfo.tsx} +12 -12
  273. package/template/src/components/useShareLink.tsx +28 -63
  274. package/template/src/components/useUserPreference.tsx +82 -16
  275. package/template/src/components/useVideoCall.tsx +93 -1
  276. package/template/src/components/virtual-background/VBButton.tsx +64 -0
  277. package/template/src/components/virtual-background/VBCard.native.tsx +282 -0
  278. package/template/src/components/virtual-background/VBCard.tsx +272 -0
  279. package/template/src/components/virtual-background/VBPanel.tsx +279 -0
  280. package/template/src/components/virtual-background/VButils.native.ts +37 -0
  281. package/template/src/components/virtual-background/VButils.ts +104 -0
  282. package/template/src/components/virtual-background/VideoPreview.native.tsx +43 -0
  283. package/template/src/components/virtual-background/VideoPreview.tsx +106 -0
  284. package/template/src/components/virtual-background/imagePaths.ts +87 -0
  285. package/template/src/components/virtual-background/images/beachImageBase64.ts +1 -0
  286. package/template/src/components/virtual-background/images/bedroomImageBase64.ts +1 -0
  287. package/template/src/components/virtual-background/images/bookImageBase64.ts +1 -0
  288. package/template/src/components/virtual-background/images/earthImageBase64.ts +1 -0
  289. package/template/src/components/virtual-background/images/index.ts +37 -0
  290. package/template/src/components/virtual-background/images/lampImageBase64.ts +1 -0
  291. package/template/src/components/virtual-background/images/mountainsImageBase64.ts +1 -0
  292. package/template/src/components/virtual-background/images/office1ImageBase64.ts +1 -0
  293. package/template/src/components/virtual-background/images/officeImageBase64.ts +1 -0
  294. package/template/src/components/virtual-background/images/plantsImageBase64.ts +1 -0
  295. package/template/src/components/virtual-background/images/skyImageBase64.ts +1 -0
  296. package/template/src/components/virtual-background/images/wallImageBase64.ts +1 -0
  297. package/template/src/components/virtual-background/useVB.native.tsx +185 -0
  298. package/template/src/components/virtual-background/useVB.tsx +267 -0
  299. package/template/src/components/whiteboard/StrokeWidthTool.tsx +137 -0
  300. package/template/src/components/whiteboard/WhiteboardButton.tsx +93 -0
  301. package/template/src/components/whiteboard/WhiteboardCanvas.tsx +99 -0
  302. package/template/src/components/whiteboard/WhiteboardConfigure.native.tsx +148 -0
  303. package/template/src/components/whiteboard/WhiteboardConfigure.tsx +446 -0
  304. package/template/src/components/whiteboard/WhiteboardCursor.tsx +152 -0
  305. package/template/src/components/whiteboard/WhiteboardToolBox.tsx +1246 -0
  306. package/template/src/components/whiteboard/WhiteboardView.native.tsx +188 -0
  307. package/template/src/components/whiteboard/WhiteboardView.tsx +81 -0
  308. package/template/src/components/whiteboard/WhiteboardWidget.tsx +685 -0
  309. package/template/src/components/whiteboard/WhiteboardWrapper.tsx +38 -0
  310. package/template/src/language/default-labels/commonLabels.ts +51 -14
  311. package/template/src/language/default-labels/createScreenLabels.ts +97 -17
  312. package/template/src/language/default-labels/joinScreenLabels.ts +45 -6
  313. package/template/src/language/default-labels/precallScreenLabels.ts +149 -25
  314. package/template/src/language/default-labels/shareLinkScreenLabels.ts +85 -37
  315. package/template/src/language/default-labels/videoCallScreenLabels.ts +1195 -158
  316. package/template/src/pages/Create.tsx +136 -106
  317. package/template/src/pages/Endcall.tsx +2 -2
  318. package/template/src/pages/Join.tsx +82 -40
  319. package/template/src/pages/Login.tsx +26 -0
  320. package/template/src/pages/VideoCall.tsx +329 -127
  321. package/template/src/pages/video-call/ActionSheet.native.tsx +54 -6
  322. package/template/src/pages/video-call/ActionSheet.tsx +55 -15
  323. package/template/src/pages/video-call/ActionSheetContent.tsx +498 -308
  324. package/template/src/pages/video-call/ActionSheetHandle.tsx +7 -1
  325. package/template/src/pages/video-call/DefaultLayouts.ts +20 -8
  326. package/template/src/pages/video-call/NameWithMicIcon.tsx +41 -64
  327. package/template/src/pages/video-call/PinchableView.tsx +119 -0
  328. package/template/src/pages/video-call/RenderComponent.tsx +14 -30
  329. package/template/src/pages/video-call/SidePanelHeader.tsx +227 -29
  330. package/template/src/pages/video-call/VideoCallMobileView.tsx +231 -89
  331. package/template/src/pages/video-call/VideoCallScreen.native.tsx +3 -2
  332. package/template/src/pages/video-call/VideoCallScreen.tsx +233 -84
  333. package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +41 -0
  334. package/template/src/pages/video-call/VideoComponent.tsx +60 -8
  335. package/template/src/pages/video-call/VideoRenderer.tsx +343 -57
  336. package/template/src/pages/video-call/VisibilitySensor.tsx +104 -0
  337. package/template/src/pages/video-call/ZoomableWrapper.native.tsx +34 -0
  338. package/template/src/pages/video-call/ZoomableWrapper.tsx +5 -0
  339. package/template/src/pages/video-call/index.ts +42 -8
  340. package/template/src/rtm/RTMEngine.ts +17 -4
  341. package/template/src/rtm-events/constants.ts +21 -3
  342. package/template/src/rtm-events-api/Events.ts +7 -4
  343. package/template/src/rtm-events-api/LocalEvents.ts +14 -0
  344. package/template/src/rtm-events-api/types.ts +5 -5
  345. package/template/src/selection.json +1 -0
  346. package/template/src/subComponents/ChatBubble.tsx +87 -67
  347. package/template/src/subComponents/ChatContainer.tsx +70 -49
  348. package/template/src/subComponents/ChatInput.ios.tsx +32 -85
  349. package/template/src/subComponents/ChatInput.tsx +31 -80
  350. package/template/src/subComponents/Checkbox.native.tsx +46 -46
  351. package/template/src/subComponents/Checkbox.tsx +7 -6
  352. package/template/src/subComponents/CopyJoinInfo.tsx +31 -11
  353. package/template/src/subComponents/EndcallPopup.tsx +83 -12
  354. package/template/src/subComponents/FallbackLogo.tsx +2 -2
  355. package/template/src/subComponents/LanguageSelector.tsx +34 -30
  356. package/template/src/subComponents/LayoutIconButton.tsx +34 -17
  357. package/template/src/subComponents/LayoutIconDropdown.tsx +21 -8
  358. package/template/src/subComponents/Loading.tsx +60 -0
  359. package/template/src/subComponents/LocalAudioMute.tsx +87 -34
  360. package/template/src/subComponents/LocalEndCall.tsx +61 -24
  361. package/template/src/subComponents/LocalSwitchCamera.tsx +57 -13
  362. package/template/src/subComponents/LocalVideoMute.tsx +105 -36
  363. package/template/src/subComponents/LogoutButton.tsx +1 -1
  364. package/template/src/subComponents/NetworkQualityPill.tsx +22 -38
  365. package/template/src/subComponents/Recording.tsx +29 -9
  366. package/template/src/subComponents/RemoteAudioMute.tsx +5 -5
  367. package/template/src/subComponents/RemoteMutePopup.tsx +55 -14
  368. package/template/src/subComponents/RemoteVideoMute.tsx +5 -5
  369. package/template/src/subComponents/RemoveMeetingPopup.tsx +19 -6
  370. package/template/src/subComponents/RemoveScreensharePopup.tsx +20 -5
  371. package/template/src/subComponents/ScreenShareNotice.tsx +11 -6
  372. package/template/src/subComponents/SelectDevice.tsx +103 -34
  373. package/template/src/subComponents/SelectDeviceSettings.backup.tsx +9 -6
  374. package/template/src/subComponents/SidePanelButtons.ts +0 -3
  375. package/template/src/subComponents/SidePanelEnum.tsx +2 -0
  376. package/template/src/subComponents/SidePanelHeader.tsx +97 -63
  377. package/template/src/subComponents/ToastConfig.tsx +70 -61
  378. package/template/src/subComponents/caption/Caption.tsx +132 -0
  379. package/template/src/subComponents/caption/CaptionContainer.tsx +302 -0
  380. package/template/src/subComponents/caption/CaptionIcon.tsx +111 -0
  381. package/template/src/subComponents/caption/CaptionText.tsx +182 -0
  382. package/template/src/subComponents/caption/DownloadTranscriptBtn.tsx +65 -0
  383. package/template/src/subComponents/caption/LanguageSelectorPopup.tsx +192 -0
  384. package/template/src/subComponents/caption/Transcript.tsx +452 -0
  385. package/template/src/subComponents/caption/TranscriptIcon.tsx +123 -0
  386. package/template/src/subComponents/caption/TranscriptText.tsx +98 -0
  387. package/template/src/subComponents/caption/index.ts +3 -0
  388. package/template/src/subComponents/caption/proto/ptoto.js +91 -0
  389. package/template/src/subComponents/caption/proto/test.proto +23 -0
  390. package/template/src/subComponents/caption/useCaption.tsx +123 -0
  391. package/template/src/subComponents/caption/useCaptionWidth.ts +27 -0
  392. package/template/src/subComponents/caption/useSTTAPI.tsx +179 -0
  393. package/template/src/subComponents/caption/useStreamMessageUtils.native.ts +211 -0
  394. package/template/src/subComponents/caption/useStreamMessageUtils.ts +235 -0
  395. package/template/src/subComponents/caption/useTranscriptDownload.native.ts +63 -0
  396. package/template/src/subComponents/caption/useTranscriptDownload.ts +52 -0
  397. package/template/src/subComponents/caption/utils.ts +126 -0
  398. package/template/src/subComponents/chat/ChatParticipants.tsx +60 -24
  399. package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +2 -2
  400. package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +19 -20
  401. package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +66 -35
  402. package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +3 -2
  403. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +10 -6
  404. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +28 -19
  405. package/template/src/subComponents/recording/useIsRecordingBot.tsx +38 -0
  406. package/template/src/subComponents/recording/useRecording.tsx +251 -138
  407. package/template/src/subComponents/recording/useRecordingLayoutQuery.tsx +0 -1
  408. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +39 -15
  409. package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +275 -69
  410. package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +193 -124
  411. package/template/src/subComponents/screenshare/useScreenshare.tsx +2 -0
  412. package/template/src/subComponents/waiting-rooms/WaitingRoomControls.tsx +85 -0
  413. package/template/src/subComponents/waiting-rooms/useWaitingRoomAPI.ts +75 -0
  414. package/template/src/theme/index.ts +13 -0
  415. package/template/src/utils/SdkEvents.ts +37 -14
  416. package/template/src/utils/SdkMethodEvents.ts +101 -0
  417. package/template/src/utils/axiomLogger.ts +117 -0
  418. package/template/src/utils/book.jpg +0 -0
  419. package/template/src/utils/common.tsx +118 -6
  420. package/template/src/utils/constants.ts +4 -0
  421. package/template/src/utils/getCustomRoute.ts +7 -0
  422. package/template/src/utils/index.tsx +34 -0
  423. package/template/src/utils/useActionSheet.tsx +50 -0
  424. package/template/src/utils/useActiveSpeaker.ts +38 -0
  425. package/template/src/utils/useAppState.ts +17 -0
  426. package/template/src/utils/useAsyncEffect.ts +138 -0
  427. package/template/src/utils/{useCreateMeeting.ts → useCreateRoom.ts} +27 -26
  428. package/template/src/utils/useEndCall.ts +65 -0
  429. package/template/src/utils/useFindActiveSpeaker.native.ts +4 -0
  430. package/template/src/utils/useFindActiveSpeaker.ts +335 -0
  431. package/template/src/utils/useGetMeetingPhrase.ts +10 -10
  432. package/template/src/utils/useIsAudioEnabled.ts +3 -3
  433. package/template/src/utils/useIsLocalUserSpeaking.native.ts +4 -0
  434. package/template/src/utils/useIsLocalUserSpeaking.ts +103 -0
  435. package/template/src/utils/useIsPSTN.ts +3 -3
  436. package/template/src/utils/useIsVideoEnabled.ts +3 -3
  437. package/template/src/utils/useJoinRoom.ts +199 -0
  438. package/template/src/utils/{useIsActiveSpeaker.ts → useLocalAudio.ts} +23 -12
  439. package/template/src/{components/OAuth.tsx → utils/useMenu.tsx} +16 -15
  440. package/template/src/utils/useModal.tsx +8 -0
  441. package/template/src/utils/useMutePSTN.ts +2 -2
  442. package/template/src/utils/useMuteToggleLocal.ts +121 -96
  443. package/template/src/utils/useRemoteEndCall.ts +4 -4
  444. package/template/src/utils/useRemoteEndScreenshare.ts +4 -4
  445. package/template/src/utils/useRemoteMute.ts +7 -7
  446. package/template/src/utils/useRemoteRequest.ts +7 -7
  447. package/template/src/utils/useSearchParams.tsx +28 -0
  448. package/template/src/utils/useString.ts +13 -3
  449. package/template/src/utils/useSwitchCamera.native.tsx +25 -0
  450. package/template/src/{subComponents/screenshare/ScreenshareButton.native.tsx → utils/useSwitchCamera.tsx} +12 -11
  451. package/template/src/utils/useToolbar.tsx +59 -0
  452. package/template/src/wasms/agora-virtual-background.wasm +0 -0
  453. package/template/static.d.ts +42 -0
  454. package/template/tsconfig_rsdk_index.json +3 -3
  455. package/template/tsconfig_wsdk_index.json +1 -1
  456. package/template/web/index.html +20 -0
  457. package/template/webpack.commons.js +21 -10
  458. package/template/webpack.rsdk.config.js +1 -2
  459. package/template/webpack.web.config.js +7 -3
  460. package/template/_buckconfig +0 -6
  461. package/template/_gitattributes +0 -1
  462. package/template/agora-rn-uikit/src/Contexts/RenderContext.tsx +0 -10
  463. package/template/agora-rn-uikit/src/Reducer/ActiveSpeakerDetected.ts +0 -11
  464. package/template/android/app/_BUCK +0 -55
  465. package/template/android/app/build_defs.bzl +0 -19
  466. package/template/bridge/rtc/webNg/LocalView.tsx +0 -20
  467. package/template/ios/HelloWorld/AppDelegate.m +0 -74
  468. package/template/src/components/OAuth.electron.tsx +0 -41
  469. package/template/src/components/OAuth.native.tsx +0 -55
  470. package/template/src/components/OAuthConfig.ts +0 -77
  471. package/template/src/components/StoreToken.tsx +0 -39
  472. package/template/src/components/meeting-info/useMeetingInfo.tsx +0 -70
  473. package/template/src/pages/video-call/CustomUserContextHolder.tsx +0 -20
  474. package/template/src/utils/useButtonTemplate.tsx +0 -44
  475. package/template/src/utils/useJoinMeeting.ts +0 -132
@@ -17,46 +17,92 @@ import React, {
17
17
  useRef,
18
18
  useContext,
19
19
  } from 'react';
20
- import {ClientRole} from '../../agora-rn-uikit';
20
+ import {ClientRoleType, RtcContext} from '../../agora-rn-uikit';
21
21
  import DeviceContext from './DeviceContext';
22
22
  import AgoraRTC, {DeviceInfo} from 'agora-rtc-sdk-ng';
23
- import {useRtc, PrimaryButton} from 'customization-api';
23
+ import {useRtc} from 'customization-api';
24
24
  import Toast from '../../react-native-toast-message';
25
- import TertiaryButton from '../atoms/TertiaryButton';
26
- import {StyleSheet, Text} from 'react-native';
27
- import CustomIcon from '../atoms/CustomIcon';
25
+ import {Text} from 'react-native';
28
26
  import StorageContext from './StorageContext';
29
27
 
30
28
  import type RtcEngine from '../../bridge/rtc/webNg/';
31
29
  import ColorContext from './ColorContext';
32
-
33
- const log = (...args) => {
30
+ import {SdkApiContext} from './SdkApiContext';
31
+ import SDKEvents from '../utils/SdkEvents';
32
+ import {getOS} from '../utils/common';
33
+ import LocalEventEmitter, {
34
+ LocalEventsEnum,
35
+ } from '../rtm-events-api/LocalEvents';
36
+ import {useString} from '../utils/useString';
37
+ import {
38
+ deviceDetectionSecondaryBtnText,
39
+ deviceDetectionCheckboxText,
40
+ deviceDetectionPrimaryBtnText,
41
+ deviceDetectionToastHeading,
42
+ deviceDetectionToastSubHeading,
43
+ } from '../language/default-labels/videoCallScreenLabels';
44
+
45
+ const log = (...args: any[]) => {
34
46
  console.log('[DeviceConfigure] ', ...args);
35
47
  };
36
48
 
37
49
  type WebRtcEngineInstance = InstanceType<typeof RtcEngine>;
38
50
 
39
51
  interface Props {
40
- userRole: ClientRole;
52
+ userRole: ClientRoleType;
41
53
  }
42
- type deviceInfo = MediaDeviceInfo;
43
- type deviceId = deviceInfo['deviceId'];
44
- type deviceKind = deviceInfo['kind'];
54
+ export type deviceInfo = MediaDeviceInfo;
55
+ export type deviceId = deviceInfo['deviceId'];
56
+ export type deviceKind = deviceInfo['kind'];
45
57
 
46
58
  const DeviceConfigure: React.FC<Props> = (props: any) => {
47
- const rtc = useRtc();
48
- const [selectedCam, setUiSelectedCam] = useState('');
49
- const [selectedMic, setUiSelectedMic] = useState('');
50
- const [selectedSpeaker, setUiSelectedSpeaker] = useState('');
59
+ const rtc = useContext(RtcContext);
60
+ const [uiSelectedCam, setUiSelectedCam] = useState('');
61
+ const [uiSelectedMic, setUiSelectedMic] = useState('');
62
+ const [uiSelectedSpeaker, setUiSelectedSpeaker] = useState('');
51
63
  const [deviceList, setDeviceList] = useState<deviceInfo[]>([]);
52
64
 
65
+ const toastHeading = useString(deviceDetectionToastHeading);
66
+ const toastSubHeading = useString<{name: string; label: string}>(
67
+ deviceDetectionToastSubHeading,
68
+ );
69
+ const toastPrimaryBtnText = useString(deviceDetectionPrimaryBtnText)();
70
+ const toastCancelBtnText = useString(deviceDetectionSecondaryBtnText)();
71
+ const toastCheckboxBtnText = useString(deviceDetectionCheckboxText)();
72
+
73
+ const micSelectInProgress = useRef(false);
74
+ const micSelectQueue = useRef([]);
75
+
76
+ const camSelectInProgress = useRef(false);
77
+ const camSelectQueue = useRef([]);
78
+
79
+ const speakerSelectInProgress = useRef(false);
80
+ const speakerSelectQueue = useRef([]);
81
+
53
82
  const {primaryColor} = useContext(ColorContext);
83
+
54
84
  const {store, setStore} = useContext(StorageContext);
55
85
  const {rememberedDevicesList, activeDeviceId} = store;
56
86
 
87
+ // const {mediaDevice: sdkMediaDevice} = useContext(SdkApiContext);
88
+ const {
89
+ microphoneDevice: sdkMicrophoneDevice,
90
+ speakerDevice: sdkSpeakerDevice,
91
+ cameraDevice: sdkCameraDevice,
92
+ clearState,
93
+ } = useContext(SdkApiContext);
94
+
95
+ // const sdkMediaDevice = useMemo(() => {
96
+ // return {
97
+ // audioinput: sdkMicrophoneDevice,
98
+ // audiooutput: sdkSpeakerDevice,
99
+ // videoinput: sdkCameraDevice,
100
+ // };
101
+ // }, [sdkMicrophoneDevice, sdkSpeakerDevice, sdkCameraDevice]);
102
+
57
103
  const isChrome = useMemo(() => {
58
104
  return (
59
- deviceList.filter((device) => device.deviceId === 'default').length > 0
105
+ deviceList.filter(device => device.deviceId === 'default').length > 0
60
106
  );
61
107
  }, [deviceList]);
62
108
 
@@ -74,7 +120,7 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
74
120
  ) => {
75
121
  // const {kind, deviceId} = device;
76
122
 
77
- setStore((prevState) => ({
123
+ setStore(prevState => ({
78
124
  ...prevState,
79
125
  activeDeviceId: {
80
126
  ...activeDeviceId,
@@ -93,7 +139,7 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
93
139
  // 'rememberedDevicesList',
94
140
  // JSON.stringify(rememberedDevicesList.current),
95
141
  // );
96
- setStore((prevState) => ({
142
+ setStore(prevState => ({
97
143
  ...prevState,
98
144
  rememberedDevicesList: {
99
145
  ...prevState.rememberedDevicesList,
@@ -107,13 +153,15 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
107
153
  }));
108
154
  };
109
155
 
110
- const {RtcEngine} = rtc as unknown as {RtcEngine: WebRtcEngineInstance};
111
- const {localStream} = RtcEngine;
156
+ const {RtcEngineUnsafe} = rtc as unknown as {
157
+ RtcEngineUnsafe: WebRtcEngineInstance;
158
+ };
159
+ const {localStream} = RtcEngineUnsafe;
112
160
 
113
- const refreshDeviceList = useCallback(async () => {
161
+ const refreshDeviceList = useCallback(async (noEmitLog?: boolean) => {
114
162
  let updatedDeviceList: MediaDeviceInfo[];
115
- await RtcEngine.getDevices(function (devices: deviceInfo[]) {
116
- log('Fetching all devices: ', devices);
163
+ await RtcEngineUnsafe.getDevices(function (devices: deviceInfo[]) {
164
+ !noEmitLog && log('Fetching all devices: ', devices);
117
165
  /**
118
166
  * Some browsers list the same microphone twice with different Id's,
119
167
  * their group Id's match as they are the same physical device.
@@ -135,8 +183,10 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
135
183
  device.kind == 'audiooutput'),
136
184
  );
137
185
 
138
- log('Setting unique devices', updatedDeviceList);
139
- setDeviceList(updatedDeviceList);
186
+ !noEmitLog && log('Setting unique devices', updatedDeviceList);
187
+ if (updatedDeviceList.length > 0) {
188
+ setDeviceList(updatedDeviceList);
189
+ }
140
190
  });
141
191
 
142
192
  return updatedDeviceList;
@@ -145,14 +195,22 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
145
195
  const getAgoraTrackDeviceId = (type: 'audio' | 'video') => {
146
196
  const mutedState =
147
197
  //@ts-ignore
148
- type === 'audio' ? !RtcEngine.isAudioEnabled : !RtcEngine.isVideoEnabled;
198
+ type === 'audio'
199
+ ? //@ts-ignore
200
+ !RtcEngineUnsafe.isAudioEnabled
201
+ : //@ts-ignore
202
+ !RtcEngineUnsafe.isVideoEnabled;
149
203
 
150
204
  let currentDevice: string;
151
205
 
152
206
  if (mutedState) {
153
207
  currentDevice =
154
208
  //@ts-ignore
155
- type === 'audio' ? RtcEngine.audioDeviceId : RtcEngine.videoDeviceId;
209
+ type === 'audio'
210
+ ? //@ts-ignore
211
+ RtcEngineUnsafe.audioDeviceId
212
+ : //@ts-ignore
213
+ RtcEngineUnsafe.videoDeviceId;
156
214
  log(`Agora ${type} Engine is using`, currentDevice);
157
215
  } else {
158
216
  currentDevice = localStream[type]
@@ -173,16 +231,37 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
173
231
  log('Refreshing', kind ?? 'all');
174
232
  switch (kind) {
175
233
  case 'audioinput':
176
- setUiSelectedMic(getAgoraTrackDeviceId('audio'));
234
+ let micId = getAgoraTrackDeviceId('audio');
235
+ micId && SDKEvents.emit('devices-selected-microphone-changed', micId);
236
+ setUiSelectedMic(micId);
177
237
  break;
178
238
  case 'videoinput':
179
- setUiSelectedCam(getAgoraTrackDeviceId('video'));
239
+ let camId = getAgoraTrackDeviceId('video');
240
+ camId && SDKEvents.emit('devices-selected-camera-changed', camId);
241
+ setUiSelectedCam(camId);
180
242
  break;
181
243
  case 'audiooutput':
244
+ //@ts-ignore
245
+ let speakerId = RtcEngineUnsafe.speakerDeviceId;
246
+ speakerId &&
247
+ SDKEvents.emit('devices-selected-speaker-changed', speakerId);
248
+ setUiSelectedSpeaker(speakerId);
182
249
  break;
183
250
  default:
184
- setUiSelectedMic(getAgoraTrackDeviceId('audio'));
185
- setUiSelectedCam(getAgoraTrackDeviceId('video'));
251
+ micId = getAgoraTrackDeviceId('audio');
252
+ camId = getAgoraTrackDeviceId('video');
253
+ //@ts-ignore
254
+ speakerId = RtcEngineUnsafe.speakerDeviceId;
255
+
256
+ micId && SDKEvents.emit('devices-selected-microphone-changed', micId);
257
+ setUiSelectedMic(micId);
258
+
259
+ camId && SDKEvents.emit('devices-selected-camera-changed', camId);
260
+ setUiSelectedCam(camId);
261
+
262
+ speakerId &&
263
+ SDKEvents.emit('devices-selected-speaker-changed', speakerId);
264
+ setUiSelectedSpeaker(speakerId);
186
265
  }
187
266
  };
188
267
 
@@ -200,7 +279,7 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
200
279
  switch (kind) {
201
280
  case 'audioinput':
202
281
  const audioInputFallbackDeviceId = deviceListLocal.find(
203
- (device) =>
282
+ device =>
204
283
  device.kind === 'audioinput' &&
205
284
  (isChrome ? device.deviceId === 'default' : true),
206
285
  )?.deviceId;
@@ -208,13 +287,13 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
208
287
  break;
209
288
  case 'videoinput':
210
289
  const videoInputFallbackDeviceId = deviceListLocal.find(
211
- (device) => device.kind === 'videoinput',
290
+ device => device.kind === 'videoinput',
212
291
  )?.deviceId;
213
292
  setSelectedCam(videoInputFallbackDeviceId);
214
293
  break;
215
294
  case 'audiooutput':
216
295
  const audioOutputFallbackDeviceId = deviceListLocal.find(
217
- (device) =>
296
+ device =>
218
297
  device.kind === 'audiooutput' &&
219
298
  (isChrome ? device.deviceId === 'default' : true),
220
299
  )?.deviceId;
@@ -224,15 +303,89 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
224
303
  }
225
304
  };
226
305
 
306
+ const checkDeviceExists = (
307
+ deviceId: deviceId,
308
+ deviceList: MediaDeviceInfo[],
309
+ ) => {
310
+ return deviceList.find(device => device.deviceId === deviceId)
311
+ ? true
312
+ : false;
313
+ };
314
+
315
+ const applySdkDeviceChangeRequest = (kind: deviceKind) => {
316
+ const {sdkStateName, sdkState} = {
317
+ audioinput: {
318
+ sdkStateName: 'microphoneDevice',
319
+ sdkState: sdkMicrophoneDevice,
320
+ },
321
+ audiooutput: {sdkStateName: 'speakerDevice', sdkState: sdkSpeakerDevice},
322
+ videoinput: {sdkStateName: 'cameraDevice', sdkState: sdkCameraDevice},
323
+ }[kind];
324
+
325
+ const {deviceId, promise} = sdkState;
326
+ const queuedSetWrapper = (deviceId: deviceId) =>
327
+ setDeviceQueued(deviceId, kind);
328
+
329
+ const {setMethod} = {
330
+ audiooutput: {
331
+ setMethod: speakerSelectInProgress.current
332
+ ? queuedSetWrapper
333
+ : setSelectedSpeaker,
334
+ },
335
+ audioinput: {
336
+ setMethod: micSelectInProgress.current
337
+ ? queuedSetWrapper
338
+ : setSelectedMic,
339
+ },
340
+ videoinput: {
341
+ setMethod: camSelectInProgress.current
342
+ ? queuedSetWrapper
343
+ : setSelectedCam,
344
+ },
345
+ }[kind];
346
+
347
+ setMethod(deviceId)
348
+ .then(() => {
349
+ promise.res();
350
+ })
351
+ .catch(e => {
352
+ promise.rej(e);
353
+ })
354
+ .finally(() => {
355
+ clearState(sdkStateName[kind]);
356
+ });
357
+ };
358
+
227
359
  useEffect(() => {
228
- const interval = setInterval(() => {
229
- navigator.mediaDevices.enumerateDevices();
230
- }, 2000);
231
- return () => {
232
- clearInterval(interval);
233
- };
360
+ // Notify updated state every 20s
361
+ if (getOS() !== 'macos') {
362
+ let count = 0;
363
+ const interval = setInterval(() => {
364
+ count = count + 1;
365
+ refreshDeviceList(count % 10 !== 0);
366
+ }, 2000);
367
+ return () => {
368
+ clearInterval(interval);
369
+ };
370
+ }
234
371
  }, []);
235
372
 
373
+ useEffect(() => {
374
+ if (sdkMicrophoneDevice?.deviceId && uiSelectedMic) {
375
+ applySdkDeviceChangeRequest('audioinput');
376
+ }
377
+ }, [sdkMicrophoneDevice]);
378
+ useEffect(() => {
379
+ if (sdkSpeakerDevice?.deviceId && uiSelectedSpeaker) {
380
+ applySdkDeviceChangeRequest('audiooutput');
381
+ }
382
+ }, [sdkSpeakerDevice]);
383
+ useEffect(() => {
384
+ if (sdkCameraDevice?.deviceId && uiSelectedCam) {
385
+ applySdkDeviceChangeRequest('videoinput');
386
+ }
387
+ }, [sdkCameraDevice]);
388
+
236
389
  useEffect(() => {
237
390
  // Labels are empty in firefox when permission is granted first time
238
391
  // refresh device list if labels are empty
@@ -240,68 +393,110 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
240
393
  const logTag = 'useEffect[rtc,store]';
241
394
 
242
395
  if (activeDeviceId && deviceList.length > 0) {
243
- // If stream exists and selected devices are empty, check for devices again
244
- if (!selectedCam || selectedCam.trim().length == 0) {
245
- log(logTag, 'cam: Device list populated but No selected cam');
246
- const currentVideoDevice = getAgoraTrackDeviceId('video');
247
- const {videoinput: storedVideoInput} = activeDeviceId;
248
-
249
- if (
250
- storedVideoInput &&
251
- currentVideoDevice &&
252
- currentVideoDevice !== storedVideoInput &&
253
- deviceList.find((device) => device.deviceId === storedVideoInput)
254
- ) {
255
- log(logTag, 'cam: Setting cam to active id', storedVideoInput);
256
- setSelectedCam(storedVideoInput);
257
- } else {
258
- setUiSelectedCam(currentVideoDevice);
396
+ const initializeDevice = (kind: deviceKind) => {
397
+ const {uiSelectedState} = {
398
+ videoinput: {
399
+ uiSelectedState: uiSelectedCam,
400
+ },
401
+ audioinput: {
402
+ uiSelectedState: uiSelectedMic,
403
+ },
404
+ audiooutput: {
405
+ uiSelectedState: uiSelectedSpeaker,
406
+ },
407
+ }[kind];
408
+
409
+ // non chrome, ignore speaker
410
+ if (!isChrome && kind === 'audiooutput') {
411
+ setUiSelectedSpeaker('');
412
+ return;
259
413
  }
260
- }
261
414
 
262
- if (!selectedMic || selectedMic.trim().length == 0) {
263
- log(logTag, 'mic: Device list populated but No selected mic');
264
- const currentAudioDevice = getAgoraTrackDeviceId('audio');
265
- const {audioinput: storedAudioInput} = activeDeviceId;
266
-
267
- if (
268
- storedAudioInput &&
269
- currentAudioDevice &&
270
- currentAudioDevice !== storedAudioInput &&
271
- deviceList.find((device) => device.deviceId === storedAudioInput)
272
- ) {
273
- log(logTag, 'mic: Setting mic to active id', storedAudioInput);
274
- setSelectedMic(storedAudioInput);
275
- } else {
276
- setUiSelectedMic(currentAudioDevice);
415
+ if (uiSelectedState && uiSelectedState.trim().length != 0) {
416
+ return;
277
417
  }
278
- }
279
418
 
280
- if (!selectedSpeaker || selectedSpeaker.trim().length == 0) {
281
- log(logTag, 'speaker: Device list populated but No selected speaker');
282
- const {audiooutput: storedAudioOutput} = activeDeviceId;
283
419
  const defaultSpeaker = deviceList.find(
284
- (device) =>
420
+ device =>
285
421
  device.deviceId === 'default' &&
286
422
  (isChrome ? device.deviceId === 'default' : true),
287
423
  )?.deviceId;
288
424
 
289
- if (
290
- defaultSpeaker &&
291
- storedAudioOutput &&
292
- defaultSpeaker !== storedAudioOutput &&
293
- deviceList.find((device) => device.deviceId === storedAudioOutput)
425
+ const storedDevice = activeDeviceId[kind];
426
+ const {
427
+ currentDevice,
428
+ deviceLogTag,
429
+ setDevice,
430
+ setDeviceUi,
431
+ eventEmitter,
432
+ sdkDevice,
433
+ } = {
434
+ videoinput: {
435
+ currentDevice: getAgoraTrackDeviceId('video'),
436
+ deviceLogTag: 'cam:',
437
+ setDevice: setSelectedCam,
438
+ setDeviceUi: setUiSelectedCam,
439
+ eventEmitter: (deviceId: deviceId) => {
440
+ SDKEvents.emit('devices-selected-camera-changed', deviceId);
441
+ },
442
+ sdkDevice: sdkCameraDevice,
443
+ },
444
+ audioinput: {
445
+ currentDevice: getAgoraTrackDeviceId('audio'),
446
+ deviceLogTag: 'mic:',
447
+ setDevice: setSelectedMic,
448
+ setDeviceUi: setUiSelectedMic,
449
+ eventEmitter: (deviceId: deviceId) => {
450
+ SDKEvents.emit('devices-selected-microphone-changed', deviceId);
451
+ },
452
+ sdkDevice: sdkMicrophoneDevice,
453
+ },
454
+ audiooutput: {
455
+ currentDevice: defaultSpeaker,
456
+ deviceLogTag: 'speaker:',
457
+ setDevice: setSelectedSpeaker,
458
+ setDeviceUi: setUiSelectedSpeaker,
459
+ eventEmitter: (deviceId: deviceId) => {
460
+ SDKEvents.emit('devices-selected-speaker-changed', deviceId);
461
+ },
462
+ sdkDevice: sdkSpeakerDevice,
463
+ },
464
+ }[kind];
465
+
466
+ log(logTag, deviceLogTag, 'Device list populated but none selected');
467
+
468
+ if (sdkDevice?.deviceId && currentDevice) {
469
+ if (checkDeviceExists(sdkDevice.deviceId, deviceList)) {
470
+ applySdkDeviceChangeRequest(kind);
471
+ } else {
472
+ sdkDevice.promise.rej(new Error('Provided device not detected'));
473
+ }
474
+ } else if (
475
+ storedDevice &&
476
+ currentDevice &&
477
+ currentDevice !== storedDevice &&
478
+ checkDeviceExists(storedDevice, deviceList)
294
479
  ) {
295
- log(
296
- logTag,
297
- 'speaker: Setting speaker to active id',
298
- storedAudioOutput,
299
- );
300
- setSelectedSpeaker(storedAudioOutput);
480
+ log(logTag, deviceLogTag, 'Setting to active id', storedDevice);
481
+ setDevice(storedDevice).catch((e: Error) => {
482
+ log(
483
+ logTag,
484
+ deviceLogTag,
485
+ 'ERROR:Setting to active id',
486
+ storedDevice,
487
+ e.message,
488
+ );
489
+ });
301
490
  } else {
302
- setUiSelectedSpeaker(defaultSpeaker);
491
+ eventEmitter(currentDevice);
492
+ setDeviceUi(currentDevice);
303
493
  }
304
- }
494
+ };
495
+
496
+ // If stream exists and selected devices are empty, check for devices again
497
+ initializeDevice('videoinput');
498
+ initializeDevice('audioinput');
499
+ initializeDevice('audiooutput');
305
500
  }
306
501
 
307
502
  if (
@@ -311,7 +506,7 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
311
506
  log(logTag, 'Empty device list');
312
507
  refreshDeviceList();
313
508
  }
314
- }, [rtc, store]);
509
+ }, [rtc, store, deviceList]);
315
510
 
316
511
  const commonOnChangedEvent = async (changedDeviceData: DeviceInfo) => {
317
512
  // Extracted devicelist because we want to perform fallback with
@@ -323,17 +518,17 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
323
518
  const {logTag, currentDevice, setCurrentDevice} = {
324
519
  audioinput: {
325
520
  logTag: 'mic: on-microphone-changed',
326
- currentDevice: selectedMic,
521
+ currentDevice: uiSelectedMic,
327
522
  setCurrentDevice: setSelectedMic,
328
523
  },
329
524
  audiooutput: {
330
525
  logTag: 'speaker: on-speaker-changed',
331
- currentDevice: selectedSpeaker,
526
+ currentDevice: uiSelectedSpeaker,
332
527
  setCurrentDevice: setSelectedSpeaker,
333
528
  },
334
529
  videoinput: {
335
530
  logTag: 'cam: on-camera-changed',
336
- currentDevice: selectedCam,
531
+ currentDevice: uiSelectedCam,
337
532
  setCurrentDevice: setSelectedCam,
338
533
  },
339
534
  }[changedDevice.kind];
@@ -368,7 +563,7 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
368
563
  }
369
564
 
370
565
  const didChangeDeviceExistBefore = previousDeviceList.find(
371
- (device) => device.deviceId === changedDevice.deviceId,
566
+ device => device.deviceId === changedDevice.deviceId,
372
567
  )
373
568
  ? true
374
569
  : false;
@@ -396,70 +591,122 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
396
591
  // Port this to useEffectEvent(https://beta.reactjs.org/reference/react/useEffectEvent) when
397
592
  // released
398
593
  useEffect(() => {
399
- log('previous devicelist updated', deviceList);
400
- AgoraRTC.onMicrophoneChanged = commonOnChangedEvent;
401
- }, [selectedMic, deviceList]);
594
+ AgoraRTC.onMicrophoneChanged = data => {
595
+ LocalEventEmitter.emit(LocalEventsEnum.MIC_CHANGED);
596
+ commonOnChangedEvent(data);
597
+ };
598
+ return () => {
599
+ AgoraRTC.onMicrophoneChanged = null;
600
+ };
601
+ }, [uiSelectedMic, deviceList]);
402
602
 
403
603
  useEffect(() => {
404
604
  AgoraRTC.onPlaybackDeviceChanged = commonOnChangedEvent;
405
- }, [selectedSpeaker, deviceList]);
605
+ return () => {
606
+ AgoraRTC.onPlaybackDeviceChanged = null;
607
+ };
608
+ }, [uiSelectedSpeaker, deviceList]);
406
609
 
407
610
  useEffect(() => {
408
611
  AgoraRTC.onCameraChanged = commonOnChangedEvent;
409
- }, [selectedCam, deviceList]);
612
+ return () => {
613
+ AgoraRTC.onCameraChanged = null;
614
+ };
615
+ }, [uiSelectedCam, deviceList]);
616
+
617
+ const setDeviceQueued = async (deviceId: deviceId, kind: deviceId) => {
618
+ const {queue} = {
619
+ audiooutput: {
620
+ queue: speakerSelectQueue.current,
621
+ },
622
+ audioinput: {
623
+ queue: micSelectQueue.current,
624
+ },
625
+ videoinput: {
626
+ queue: camSelectQueue.current,
627
+ },
628
+ }[kind];
410
629
 
411
- const setSelectedMic = (deviceId: deviceId) => {
412
- log('mic: setting to', deviceId);
413
630
  return new Promise((res, rej) => {
414
- RtcEngine.changeMic(
631
+ queue.push({
415
632
  deviceId,
416
- () => {
417
- syncSelectedDeviceUi('audioinput');
418
- updateActiveDeviceId('audioinput', deviceId);
419
- res(null);
420
- },
421
- (e: any) => {
422
- console.error('DeviceConfigure: Error setting mic', e);
423
- rej(e);
424
- },
425
- );
633
+ resolveQueued: res,
634
+ rejectQueued: rej,
635
+ });
426
636
  });
427
637
  };
428
638
 
429
- const setSelectedCam = (deviceId: deviceId) => {
430
- log('cam: setting to', deviceId);
431
- return new Promise((res, rej) => {
432
- RtcEngine.changeCamera(
639
+ const setDeviceCommon = (deviceId: deviceId, kind: deviceKind) => {
640
+ const {mutexRef, queueRef, setMethod, logtag} = {
641
+ audioinput: {
642
+ mutexRef: micSelectInProgress,
643
+ queueRef: micSelectQueue,
644
+ setMethod: 'changeMic',
645
+ logtag: 'setMic:',
646
+ },
647
+ audiooutput: {
648
+ mutexRef: speakerSelectInProgress,
649
+ queueRef: speakerSelectQueue,
650
+ setMethod: 'changeSpeaker',
651
+ logtag: 'setSpeaker:',
652
+ },
653
+ videoinput: {
654
+ mutexRef: camSelectInProgress,
655
+ queueRef: camSelectQueue,
656
+ setMethod: 'changeCamera',
657
+ logtag: 'setCam:',
658
+ },
659
+ }[kind];
660
+
661
+ log(logtag, kind, 'setting to', deviceId);
662
+
663
+ const handleQueue = () => {
664
+ if (queueRef.current.length > 0) {
665
+ const queueItem = queueRef.current.shift();
666
+ setDeviceCommon(queueItem.deviceId, kind)
667
+ .then(() => {
668
+ queueItem.resolveQueued();
669
+ })
670
+ .catch(e => queueItem.rejectQueued(e));
671
+ }
672
+ };
673
+ return new Promise<void>((res, rej) => {
674
+ if (mutexRef.current) {
675
+ const e = new Error(logtag + ' Change already in progress');
676
+ log('DeviceConfigure:', logtag, 'Error setting', kind, e.message);
677
+ rej(e);
678
+ return;
679
+ }
680
+ mutexRef.current = true;
681
+ RtcEngineUnsafe[setMethod](
433
682
  deviceId,
434
683
  () => {
435
- syncSelectedDeviceUi('videoinput');
436
- updateActiveDeviceId('videoinput', deviceId);
684
+ syncSelectedDeviceUi(kind);
685
+ updateActiveDeviceId(kind, deviceId);
686
+ mutexRef.current = false;
437
687
  res(null);
688
+ handleQueue();
438
689
  },
439
690
  (e: any) => {
440
- console.error('Device Configure: Error setting webcam', e);
691
+ mutexRef.current = false;
692
+ console.error('DeviceConfigure:', logtag, 'Error setting', kind, e);
441
693
  rej(e);
694
+ handleQueue();
442
695
  },
443
696
  );
444
697
  });
445
698
  };
446
699
 
700
+ const setSelectedMic = (deviceId: deviceId) => {
701
+ return setDeviceCommon(deviceId, 'audioinput');
702
+ };
703
+
704
+ const setSelectedCam = (deviceId: deviceId) => {
705
+ return setDeviceCommon(deviceId, 'videoinput');
706
+ };
707
+
447
708
  const setSelectedSpeaker = (deviceId: deviceId) => {
448
- log('speaker: setting to', deviceId);
449
- return new Promise((res, rej) => {
450
- RtcEngine.changeSpeaker(
451
- deviceId,
452
- () => {
453
- setUiSelectedSpeaker(deviceId);
454
- updateActiveDeviceId('audiooutput', deviceId);
455
- res(null);
456
- },
457
- (e: any) => {
458
- console.error('Device Configure: Error setting speaker', e);
459
- rej(selectedSpeaker);
460
- },
461
- );
462
- });
709
+ return setDeviceCommon(deviceId, 'audiooutput');
463
710
  };
464
711
 
465
712
  const showNewDeviceDetectedToast = (device: MediaDeviceInfo) => {
@@ -480,24 +727,27 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
480
727
 
481
728
  Toast.show({
482
729
  type: 'checked',
730
+ leadingIconName: 'mic-on',
483
731
  // leadingIcon: <CustomIcon name={'mic-on'} />,
484
- text1: `New ${name} detected`,
732
+ text1: toastHeading(name),
733
+ text2: toastSubHeading({name, label: device?.label}),
485
734
  // @ts-ignore
486
- text2: (
487
- <Text>
488
- <Text>New {name} named </Text>
489
- <Text style={{fontWeight: 'bold'}}>{device.label}</Text>
490
- <Text> detected. Do you want to switch?</Text>
491
- </Text>
492
- ),
735
+ // text2: (
736
+ // <Text>
737
+ // <Text>New {name} named </Text>
738
+ // <Text style={{fontWeight: 'bold'}}>{device.label}</Text>
739
+ // <Text> detected. Do you want to switch?</Text>
740
+ // </Text>
741
+ // ),
493
742
  visibilityTime: 6000,
743
+ //@ts-ignore
494
744
  checkbox: {
495
745
  disabled: false,
496
746
  color: primaryColor,
497
- text: 'Remember my choice',
747
+ text: toastCheckboxBtnText,
498
748
  },
499
749
  primaryBtn: {
500
- text: 'SWITCH DEVICE',
750
+ text: toastPrimaryBtnText,
501
751
  onPress: (checked: boolean) => {
502
752
  setAction(device.deviceId);
503
753
  checked && updateRememberedDeviceList(device, true);
@@ -505,7 +755,7 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
505
755
  },
506
756
  },
507
757
  secondaryBtn: {
508
- text: 'IGNORE',
758
+ text: toastCancelBtnText,
509
759
  onPress: (checked: boolean) => {
510
760
  checked && updateRememberedDeviceList(device, false);
511
761
  Toast.hide();
@@ -517,14 +767,15 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
517
767
  return (
518
768
  <DeviceContext.Provider
519
769
  value={{
520
- selectedCam,
770
+ selectedCam: uiSelectedCam,
521
771
  setSelectedCam,
522
- selectedMic,
772
+ selectedMic: uiSelectedMic,
523
773
  setSelectedMic,
524
- selectedSpeaker,
774
+ selectedSpeaker: uiSelectedSpeaker,
525
775
  setSelectedSpeaker,
526
776
  deviceList,
527
777
  setDeviceList,
778
+ isChrome,
528
779
  }}>
529
780
  {props.children}
530
781
  </DeviceContext.Provider>