agora-appbuilder-core 4.0.0-api.5 → 4.0.0-api.6

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