agora-appbuilder-core 3.0.10 → 3.0.12

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 (249) hide show
  1. package/Readme.md +0 -6
  2. package/package.json +2 -2
  3. package/template/_package-lock.json +4979 -7086
  4. package/template/agora-rn-uikit/src/Contexts/LocalUserContext.tsx +0 -4
  5. package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +0 -18
  6. package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +0 -2
  7. package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +26 -30
  8. package/template/agora-rn-uikit/src/Controls/Icons.ts +83 -30
  9. package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +6 -6
  10. package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +0 -1
  11. package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +0 -1
  12. package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +0 -1
  13. package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +0 -1
  14. package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +0 -1
  15. package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +0 -2
  16. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +0 -1
  17. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +0 -1
  18. package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +0 -1
  19. package/template/agora-rn-uikit/src/Reducer/index.ts +0 -3
  20. package/template/agora-rn-uikit/src/Rtc/Create.tsx +1 -89
  21. package/template/agora-rn-uikit/src/RtcConfigure.tsx +2 -39
  22. package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +5 -15
  23. package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +9 -15
  24. package/template/agora-rn-uikit/src/index.ts +1 -3
  25. package/template/android/app/build.gradle +0 -1
  26. package/template/android/app/src/main/AndroidManifest.xml +15 -22
  27. package/template/android/app/src/main/java/com/helloworld/MainActivity.java +0 -50
  28. package/template/android/build.gradle +3 -3
  29. package/template/babel.config.js +0 -1
  30. package/template/bridge/rtc/webNg/RtcEngine.ts +17 -110
  31. package/template/customization-api/sub-components.ts +1 -1
  32. package/template/customization-api/typeDefinition.ts +1 -2
  33. package/template/electron/index.html +27 -27
  34. package/template/electron/renderer/index.js +0 -1
  35. package/template/global.d.ts +4 -26
  36. package/template/index.js +0 -4
  37. package/template/index.rsdk.tsx +0 -1
  38. package/template/index.web.js +1 -7
  39. package/template/index.wsdk.tsx +1 -1
  40. package/template/ios/HelloWorld/Info.plist +1 -14
  41. package/template/ios/HelloWorld.xcodeproj/project.pbxproj +0 -17
  42. package/template/metro.config.js +1 -1
  43. package/template/package.json +7 -21
  44. package/template/react-native-toast-message/index.d.ts +43 -43
  45. package/template/react-native-toast-message/src/colors/index.js +2 -3
  46. package/template/react-native-toast-message/src/components/base/index.js +59 -46
  47. package/template/react-native-toast-message/src/components/base/styles.js +32 -16
  48. package/template/react-native-toast-message/src/components/error.js +2 -3
  49. package/template/react-native-toast-message/src/components/info.js +2 -3
  50. package/template/react-native-toast-message/src/components/success.js +2 -3
  51. package/template/react-native-toast-message/src/index.js +31 -122
  52. package/template/react-native-toast-message/src/index.sdk.tsx +35 -125
  53. package/template/react-native-toast-message/src/styles.js +4 -3
  54. package/template/react-native-toast-message/src/styles.sdk.ts +4 -3
  55. package/template/src/App.tsx +0 -6
  56. package/template/src/AppWrapper.tsx +28 -63
  57. package/template/src/assets/icons.ts +102 -0
  58. package/template/src/atoms/HorizontalRule.tsx +1 -3
  59. package/template/src/atoms/PrimaryButton.tsx +26 -51
  60. package/template/src/atoms/SecondaryButton.tsx +5 -8
  61. package/template/src/atoms/TextInput.tsx +14 -12
  62. package/template/src/components/Chat.tsx +214 -86
  63. package/template/src/components/ChatContext.ts +1 -8
  64. package/template/src/components/ColorConfigure.tsx +1 -1
  65. package/template/src/components/ColorContext.ts +1 -1
  66. package/template/src/components/{Controls1.native.tsx → Controls.native.tsx} +4 -6
  67. package/template/src/components/Controls.tsx +42 -342
  68. package/template/src/components/DeviceConfigure.tsx +101 -461
  69. package/template/src/components/DeviceContext.tsx +4 -8
  70. package/template/src/components/EventsConfigure.tsx +7 -144
  71. package/template/src/components/GraphQLProvider.tsx +1 -1
  72. package/template/src/components/GridVideo.tsx +44 -59
  73. package/template/src/components/HostControlView.tsx +35 -114
  74. package/template/src/components/Navbar.tsx +398 -216
  75. package/template/src/components/NetworkQualityContext.tsx +20 -20
  76. package/template/src/components/ParticipantsView.tsx +154 -177
  77. package/template/src/components/PinnedVideo.tsx +120 -207
  78. package/template/src/components/Precall.native.tsx +119 -358
  79. package/template/src/components/Precall.tsx +135 -269
  80. package/template/src/components/RTMConfigure.tsx +4 -27
  81. package/template/src/components/Router.electron.ts +0 -1
  82. package/template/src/components/Router.native.ts +0 -1
  83. package/template/src/components/Router.sdk.ts +0 -1
  84. package/template/src/components/Router.ts +0 -1
  85. package/template/src/components/Settings.tsx +95 -26
  86. package/template/src/components/SettingsView.tsx +56 -251
  87. package/template/src/components/Share.tsx +273 -302
  88. package/template/src/components/StorageContext.tsx +3 -30
  89. package/template/src/components/chat-messages/useChatMessages.tsx +23 -69
  90. package/template/src/components/chat-ui/useChatUIControl.tsx +0 -7
  91. package/template/src/components/common/Error.tsx +6 -20
  92. package/template/src/components/common/Logo.tsx +15 -16
  93. package/template/src/components/contexts/LiveStreamDataContext.tsx +5 -10
  94. package/template/src/components/contexts/VideoMeetingDataContext.tsx +7 -37
  95. package/template/src/components/livestream/LiveStreamContext.tsx +36 -270
  96. package/template/src/components/livestream/Types.ts +14 -39
  97. package/template/src/components/livestream/index.ts +0 -1
  98. package/template/src/components/livestream/views/LiveStreamControls.tsx +4 -12
  99. package/template/src/components/participants/AllAudienceParticipants.tsx +30 -101
  100. package/template/src/components/participants/AllHostParticipants.tsx +34 -103
  101. package/template/src/components/participants/MeParticipant.tsx +38 -0
  102. package/template/src/components/participants/ParticipantName.tsx +7 -13
  103. package/template/src/components/participants/ParticipantSectionTitle.tsx +10 -35
  104. package/template/src/components/participants/RemoteParticipants.tsx +71 -0
  105. package/template/src/components/participants/ScreenshareParticipants.tsx +12 -144
  106. package/template/src/components/precall/{LocalMute1.native.tsx → LocalMute.native.tsx} +5 -21
  107. package/template/src/components/precall/LocalMute.tsx +14 -84
  108. package/template/src/components/precall/VideoPreview.native.tsx +3 -48
  109. package/template/src/components/precall/VideoPreview.tsx +7 -163
  110. package/template/src/components/precall/joinCallBtn.tsx +2 -15
  111. package/template/src/components/precall/meetingTitle.tsx +12 -15
  112. package/template/src/components/precall/selectDevice.tsx +21 -1
  113. package/template/src/components/precall/textInput.tsx +4 -32
  114. package/template/src/components/precall/usePreCall.tsx +0 -16
  115. package/template/src/components/styles.ts +21 -42
  116. package/template/src/components/useShareLink.tsx +14 -12
  117. package/template/src/language/default-labels/precallScreenLabels.ts +3 -3
  118. package/template/src/pages/Authenticate.tsx +15 -5
  119. package/template/src/pages/Create.tsx +165 -293
  120. package/template/src/pages/Join.tsx +67 -93
  121. package/template/src/pages/VideoCall.tsx +64 -89
  122. package/template/src/pages/video-call/DefaultLayouts.ts +4 -4
  123. package/template/src/pages/video-call/NameWithMicIcon.tsx +44 -120
  124. package/template/src/pages/video-call/RenderComponent.tsx +2 -3
  125. package/template/src/pages/video-call/VideoCallScreen.tsx +9 -45
  126. package/template/src/pages/video-call/VideoComponent.tsx +3 -18
  127. package/template/src/pages/video-call/VideoRenderer.tsx +60 -218
  128. package/template/src/rtm-events/constants.ts +0 -2
  129. package/template/src/subComponents/ChatBubble.tsx +83 -123
  130. package/template/src/subComponents/ChatContainer.tsx +84 -257
  131. package/template/src/subComponents/ChatInput.tsx +46 -61
  132. package/template/src/subComponents/Checkbox.native.tsx +5 -16
  133. package/template/src/subComponents/Checkbox.tsx +2 -2
  134. package/template/src/subComponents/CopyJoinInfo.tsx +58 -36
  135. package/template/src/subComponents/FallbackLogo.tsx +40 -122
  136. package/template/src/subComponents/LanguageSelector.tsx +1 -1
  137. package/template/src/subComponents/{LayoutIconDropdown1.native.tsx → LayoutIconDropdown.native.tsx} +18 -4
  138. package/template/src/subComponents/LayoutIconDropdown.tsx +134 -131
  139. package/template/src/subComponents/LocalAudioMute.tsx +27 -119
  140. package/template/src/subComponents/LocalEndCall.tsx +33 -71
  141. package/template/src/subComponents/LocalSwitchCamera.tsx +30 -17
  142. package/template/src/subComponents/LocalVideoMute.tsx +27 -117
  143. package/template/src/subComponents/Logo.tsx +4 -3
  144. package/template/src/subComponents/LogoutButton.tsx +1 -1
  145. package/template/src/subComponents/NetworkQualityPill.tsx +63 -60
  146. package/template/src/subComponents/OpenInNativeButton.tsx +3 -3
  147. package/template/src/subComponents/Recording.tsx +29 -28
  148. package/template/src/subComponents/RemoteAudioMute.tsx +29 -83
  149. package/template/src/subComponents/RemoteEndCall.tsx +5 -8
  150. package/template/src/subComponents/RemoteVideoMute.tsx +21 -74
  151. package/template/src/subComponents/ScreenShareNotice.tsx +8 -83
  152. package/template/src/subComponents/SelectDevice.tsx +61 -404
  153. package/template/src/subComponents/SelectOAuth.tsx +8 -9
  154. package/template/src/subComponents/ToastConfig.tsx +10 -150
  155. package/template/src/subComponents/chat/ChatParticipants.tsx +78 -187
  156. package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +32 -95
  157. package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +33 -29
  158. package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +6 -6
  159. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +11 -24
  160. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +10 -17
  161. package/template/src/subComponents/recording/useRecording.tsx +27 -79
  162. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +70 -52
  163. package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +2 -11
  164. package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +4 -26
  165. package/template/src/utils/common.tsx +1 -155
  166. package/template/src/utils/index.tsx +0 -19
  167. package/template/src/utils/isMobileOrTablet.ts +2 -7
  168. package/template/src/utils/useButtonTemplate.tsx +0 -1
  169. package/template/src/utils/useMuteToggleLocal.ts +3 -54
  170. package/template/web/index.html +0 -5
  171. package/template/webpack.commons.js +8 -13
  172. package/template/webpack.web.config.js +0 -1
  173. package/template/agora-rn-uikit/src/Reducer/ActiveSpeakerDetected.ts +0 -11
  174. package/template/agora-rn-uikit/src/Reducer/LocalPermissionState.ts +0 -24
  175. package/template/agora-rn-uikit/src/Reducer/UserPin.ts +0 -11
  176. package/template/android/app/src/main/assets/fonts/SourceSansPro-Regular.ttf +0 -0
  177. package/template/android/app/src/main/assets/fonts/icomoon.ttf +0 -0
  178. package/template/android/app/src/main/res/values/colors.xml +0 -7
  179. package/template/react-native-toast-message/src/components/checkbox.js +0 -178
  180. package/template/react-native.config.js +0 -7
  181. package/template/src/assets/font-styles.css +0 -329
  182. package/template/src/assets/fonts/SourceSansPro-Regular.ttf +0 -0
  183. package/template/src/assets/fonts/icomoon.ttf +0 -0
  184. package/template/src/assets/permission.png +0 -0
  185. package/template/src/assets/selection.json +0 -1
  186. package/template/src/atoms/ActionMenu.tsx +0 -236
  187. package/template/src/atoms/AnimatedActiveSpeaker.native.tsx +0 -71
  188. package/template/src/atoms/AnimatedActiveSpeaker.tsx +0 -84
  189. package/template/src/atoms/AnimatedRings.native.tsx +0 -68
  190. package/template/src/atoms/AnimatedRings.tsx +0 -70
  191. package/template/src/atoms/Card.tsx +0 -61
  192. package/template/src/atoms/CircularProgress.native.tsx +0 -121
  193. package/template/src/atoms/CircularProgress.tsx +0 -102
  194. package/template/src/atoms/CustomIcon.tsx +0 -88
  195. package/template/src/atoms/CustomSwitch.tsx +0 -287
  196. package/template/src/atoms/Dropdown.tsx +0 -306
  197. package/template/src/atoms/IconButton.tsx +0 -162
  198. package/template/src/atoms/ImageIcon.tsx +0 -98
  199. package/template/src/atoms/InfoBubble.tsx +0 -291
  200. package/template/src/atoms/Input.tsx +0 -87
  201. package/template/src/atoms/InviteInfo.tsx +0 -166
  202. package/template/src/atoms/LinkButton.tsx +0 -28
  203. package/template/src/atoms/OutlineButton.tsx +0 -61
  204. package/template/src/atoms/ParticipantsCount.tsx +0 -73
  205. package/template/src/atoms/Popup.tsx +0 -147
  206. package/template/src/atoms/RecordingInfo.tsx +0 -49
  207. package/template/src/atoms/Spacer.tsx +0 -22
  208. package/template/src/atoms/TertiaryButton.tsx +0 -78
  209. package/template/src/atoms/Toggle.tsx +0 -47
  210. package/template/src/atoms/Tooltip.native.tsx +0 -65
  211. package/template/src/atoms/Tooltip.tsx +0 -94
  212. package/template/src/atoms/UserAvatar.tsx +0 -60
  213. package/template/src/components/CommonStyles.ts +0 -44
  214. package/template/src/components/ToastComponent.tsx +0 -8
  215. package/template/src/components/participants/Participant.tsx +0 -302
  216. package/template/src/components/participants/UserActionMenuOptions.tsx +0 -398
  217. package/template/src/components/popups/InvitePopup.tsx +0 -115
  218. package/template/src/components/popups/StopRecordingPopup.tsx +0 -114
  219. package/template/src/components/precall/PermissionHelper.native.tsx +0 -5
  220. package/template/src/components/precall/PermissionHelper.tsx +0 -126
  221. package/template/src/components/precall/PreCallSettings.tsx +0 -52
  222. package/template/src/components/useToast.tsx +0 -41
  223. package/template/src/components/useVideoCall.tsx +0 -65
  224. package/template/src/pages/Endcall.tsx +0 -148
  225. package/template/src/pages/video-call/ActionSheet.native.tsx +0 -215
  226. package/template/src/pages/video-call/ActionSheet.tsx +0 -226
  227. package/template/src/pages/video-call/ActionSheetContent.tsx +0 -479
  228. package/template/src/pages/video-call/ActionSheetHandle.tsx +0 -38
  229. package/template/src/pages/video-call/ActionSheetStyles.css +0 -138
  230. package/template/src/pages/video-call/SidePanelHeader.tsx +0 -190
  231. package/template/src/pages/video-call/VideoCallMobileView.tsx +0 -139
  232. package/template/src/pages/video-call/VideoCallScreen.native.tsx +0 -37
  233. package/template/src/subComponents/ChatInput.ios.tsx +0 -237
  234. package/template/src/subComponents/EndcallPopup.tsx +0 -107
  235. package/template/src/subComponents/LayoutIconButton.tsx +0 -201
  236. package/template/src/subComponents/RemoteMutePopup.tsx +0 -193
  237. package/template/src/subComponents/RemoveMeetingPopup.tsx +0 -109
  238. package/template/src/subComponents/RemoveScreensharePopup.tsx +0 -109
  239. package/template/src/subComponents/SelectDeviceSettings.backup.tsx +0 -207
  240. package/template/src/subComponents/SidePanelHeader.tsx +0 -112
  241. package/template/src/theme/index.ts +0 -46
  242. package/template/src/utils/PlatformWrapper.tsx +0 -21
  243. package/template/src/utils/hexadecimalTransparency.ts +0 -108
  244. package/template/src/utils/pendingStateUpdateHelper.ts +0 -19
  245. package/template/src/utils/useFocus.tsx +0 -46
  246. package/template/src/utils/useIsActiveSpeaker.ts +0 -27
  247. package/template/src/utils/useIsHandRaised.ts +0 -13
  248. package/template/src/utils/useRemoteEndScreenshare.ts +0 -26
  249. package/template/src/utils/useRemoteRequest.ts +0 -84
@@ -9,111 +9,36 @@
9
9
  information visit https://appbuilder.agora.io.
10
10
  *********************************************
11
11
  */
12
- import React, {
13
- useState,
14
- useEffect,
15
- useCallback,
16
- useMemo,
17
- useRef,
18
- useContext,
19
- } from 'react';
12
+ import React, {useState, useEffect, useCallback} from 'react';
20
13
  import {ClientRole} from '../../agora-rn-uikit';
21
14
  import DeviceContext from './DeviceContext';
22
- import AgoraRTC, {DeviceInfo} from 'agora-rtc-sdk-ng';
23
- import {useRtc, PrimaryButton} from 'customization-api';
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';
28
- import StorageContext from './StorageContext';
29
-
30
- import type RtcEngine from '../../bridge/rtc/webNg/';
31
- import ColorContext from './ColorContext';
32
-
33
- const log = (...args) => {
34
- console.log('[DeviceConfigure] ', ...args);
35
- };
36
-
37
- type WebRtcEngineInstance = InstanceType<typeof RtcEngine>;
15
+ import AgoraRTC from 'agora-rtc-sdk-ng';
16
+ import {useRtc} from 'customization-api';
38
17
 
39
18
  interface Props {
40
19
  userRole: ClientRole;
41
20
  }
42
- type deviceInfo = MediaDeviceInfo;
43
- type deviceId = deviceInfo['deviceId'];
44
- type deviceKind = deviceInfo['kind'];
45
-
21
+ interface deviceInfo {
22
+ deviceId: string;
23
+ groupId: string;
24
+ kind: string;
25
+ label: string;
26
+ }
27
+ interface changedDeviceInfo {
28
+ device: deviceInfo;
29
+ initAt: number;
30
+ state: 'INACTIVE' | 'ACTIVE';
31
+ updateAt: number;
32
+ }
46
33
  const DeviceConfigure: React.FC<Props> = (props: any) => {
34
+ const [selectedCam, setSelectedCam] = useState('');
35
+ const [selectedMic, setSelectedMic] = useState('');
36
+ const [deviceList, setDeviceList] = useState<any>([]);
47
37
  const rtc = useRtc();
48
- const [selectedCam, setUiSelectedCam] = useState('');
49
- const [selectedMic, setUiSelectedMic] = useState('');
50
- const [selectedSpeaker, setUiSelectedSpeaker] = useState('');
51
- const [deviceList, setDeviceList] = useState<deviceInfo[]>([]);
52
-
53
- const {primaryColor} = useContext(ColorContext);
54
- const {store, setStore} = useContext(StorageContext);
55
- const {rememberedDevicesList, activeDeviceId} = store;
56
-
57
- const isChrome = useMemo(() => {
58
- return (
59
- deviceList.filter((device) => device.deviceId === 'default').length > 0
60
- );
61
- }, [deviceList]);
62
-
63
- // const rememberedDevicesList = useRef<
64
- // Record<MediaDeviceInfo['kind'], savedDeviceInfo[]>
65
- // >({
66
- // audioinput: [],
67
- // videoinput: [],
68
- // audiooutput: [],
69
- // });
70
38
 
71
- const updateActiveDeviceId = (
72
- kind: MediaDeviceInfo['kind'],
73
- deviceId: string,
74
- ) => {
75
- // const {kind, deviceId} = device;
76
-
77
- setStore((prevState) => ({
78
- ...prevState,
79
- activeDeviceId: {
80
- ...activeDeviceId,
81
- [kind]: deviceId,
82
- },
83
- }));
84
- };
85
-
86
- const updateRememberedDeviceList = (
87
- device: MediaDeviceInfo,
88
- switchOnConnect: boolean,
89
- ) => {
90
- const {kind} = device;
91
- // rememberedDevicesList.current[kind].push({...device, switchOnConnect});
92
- // window.localStorage.setItem(
93
- // 'rememberedDevicesList',
94
- // JSON.stringify(rememberedDevicesList.current),
95
- // );
96
- setStore((prevState) => ({
97
- ...prevState,
98
- rememberedDevicesList: {
99
- ...prevState.rememberedDevicesList,
100
- [kind]: {
101
- [device.deviceId]: switchOnConnect
102
- ? 'switch-on-connect'
103
- : 'ignore-on-connect',
104
- ...prevState.rememberedDevicesList[kind],
105
- },
106
- },
107
- }));
108
- };
109
-
110
- const {RtcEngine} = rtc as unknown as {RtcEngine: WebRtcEngineInstance};
111
- const {localStream} = RtcEngine;
112
-
113
- const refreshDeviceList = useCallback(async () => {
114
- let updatedDeviceList: MediaDeviceInfo[];
115
- await RtcEngine.getDevices(function (devices: deviceInfo[]) {
116
- log('Fetching all devices: ', devices);
39
+ const refreshDevices = useCallback(async () => {
40
+ rtc.RtcEngine.getDevices(function (devices: deviceInfo[]) {
41
+ console.log('DeviceTesting: fetching all devices: ', devices);
117
42
  /**
118
43
  * Some browsers list the same microphone twice with different Id's,
119
44
  * their group Id's match as they are the same physical device.
@@ -121,398 +46,115 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
121
46
  * preference
122
47
  */
123
48
  /**
124
- * 1. Fetch devices and filter so the deviceId with empty
125
- * values are exluded
49
+ * 1. Fetch devices and filter so the deviceId with default or empty
50
+ * values are exluded for both audio and video devices. Also exclude
51
+ * output devices. ex: Mac speakers are of type audiooutput(device.kind)
126
52
  * 2. Store only unique devices with unique groupIds
127
53
  */
128
54
 
129
- updatedDeviceList = devices.filter(
55
+ const uniqueDevices = devices.filter(
130
56
  (device: deviceInfo) =>
131
- // device?.deviceId !== 'default' &&
57
+ device?.deviceId !== 'default' &&
132
58
  device?.deviceId !== '' &&
133
- (device.kind == 'audioinput' ||
134
- device.kind == 'videoinput' ||
135
- device.kind == 'audiooutput'),
59
+ (device.kind == 'audioinput' || device.kind == 'videoinput'),
136
60
  );
137
-
138
- log('Setting unique devices', updatedDeviceList);
139
- setDeviceList(updatedDeviceList);
61
+ console.log('DeviceTesting: set unique devices', uniqueDevices);
62
+ setDeviceList(uniqueDevices);
140
63
  });
141
-
142
- return updatedDeviceList;
143
64
  }, []);
144
65
 
145
- const getAgoraTrackDeviceId = (type: 'audio' | 'video') => {
146
- const mutedState =
147
- //@ts-ignore
148
- type === 'audio' ? !RtcEngine.isAudioEnabled : !RtcEngine.isVideoEnabled;
149
-
150
- let currentDevice: string;
151
-
152
- if (mutedState) {
153
- currentDevice =
154
- //@ts-ignore
155
- type === 'audio' ? RtcEngine.audioDeviceId : RtcEngine.videoDeviceId;
156
- log(`Agora ${type} Engine is using`, currentDevice);
157
- } else {
158
- currentDevice = localStream[type]
159
- ?.getMediaStreamTrack()
160
- .getSettings().deviceId;
161
- log(`Agora ${type} Track is using`, currentDevice);
162
- }
163
- return currentDevice ?? '';
164
- };
165
-
166
- /**
167
- * Retrieves the devices being used by agora tracks and
168
- * updates the selected Ui states with them.
169
- * Ignores for audioOutput since state acts as ground
170
- * truth.
171
- */
172
- const syncSelectedDeviceUi = (kind?: deviceKind) => {
173
- log('Refreshing', kind ?? 'all');
174
- switch (kind) {
175
- case 'audioinput':
176
- setUiSelectedMic(getAgoraTrackDeviceId('audio'));
177
- break;
178
- case 'videoinput':
179
- setUiSelectedCam(getAgoraTrackDeviceId('video'));
180
- break;
181
- case 'audiooutput':
182
- break;
183
- default:
184
- setUiSelectedMic(getAgoraTrackDeviceId('audio'));
185
- setUiSelectedCam(getAgoraTrackDeviceId('video'));
186
- }
187
- };
188
-
189
- /**
190
- * Sets the devices to the default device on chrome or
191
- * the first item on the devices list on other browsers
192
- * optionally takes device list to use that instead
193
- * of state which might be stale
194
- */
195
- const fallbackToDefaultDevice = (
196
- kind: deviceKind,
197
- uniqueDevices?: MediaDeviceInfo[],
198
- ) => {
199
- const deviceListLocal = uniqueDevices || deviceList;
200
- switch (kind) {
201
- case 'audioinput':
202
- const audioInputFallbackDeviceId = deviceListLocal.find(
203
- (device) =>
204
- device.kind === 'audioinput' &&
205
- (isChrome ? device.deviceId === 'default' : true),
206
- )?.deviceId;
207
- setSelectedMic(audioInputFallbackDeviceId);
208
- break;
209
- case 'videoinput':
210
- const videoInputFallbackDeviceId = deviceListLocal.find(
211
- (device) => device.kind === 'videoinput',
212
- )?.deviceId;
213
- setSelectedCam(videoInputFallbackDeviceId);
214
- break;
215
- case 'audiooutput':
216
- const audioOutputFallbackDeviceId = deviceListLocal.find(
217
- (device) =>
218
- device.kind === 'audiooutput' &&
219
- (isChrome ? device.deviceId === 'default' : true),
220
- )?.deviceId;
221
-
222
- setSelectedSpeaker(audioOutputFallbackDeviceId);
223
- break;
224
- }
225
- };
226
-
227
66
  useEffect(() => {
228
- const interval = setInterval(() => {
229
- navigator.mediaDevices.enumerateDevices();
230
- }, 2000);
231
- return () => {
232
- clearInterval(interval);
67
+ AgoraRTC.onMicrophoneChanged = async (changedDevice: changedDeviceInfo) => {
68
+ // When new audio device is plugged in ,refresh the devices list.
69
+ console.log('DeviceTesting: on-microphone-changed');
70
+ if (changedDevice && changedDevice.state === 'ACTIVE') {
71
+ if (changedDevice.device?.kind === 'audioinput') {
72
+ console.log('DeviceTesting: NEW audio device detected and selected');
73
+ setSelectedMic(changedDevice.device?.deviceId);
74
+ }
75
+ }
76
+ if (changedDevice && changedDevice.state === 'INACTIVE') {
77
+ if (changedDevice.device?.kind === 'audioinput') {
78
+ console.log('DeviceTesting: audio device inactive');
79
+ setSelectedMic('');
80
+ }
81
+ }
233
82
  };
234
- }, []);
235
-
236
- useEffect(() => {
237
- // Labels are empty in firefox when permission is granted first time
238
- // refresh device list if labels are empty
239
-
240
- const logTag = 'useEffect[rtc,store]';
241
-
242
- 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);
83
+ AgoraRTC.onCameraChanged = async (changedDevice: changedDeviceInfo) => {
84
+ // When new video device is plugged in ,refresh the devices list.
85
+ console.log('DeviceTesting: on-camera-changed');
86
+ if (changedDevice && changedDevice.state === 'ACTIVE') {
87
+ if (changedDevice.device?.kind === 'videoinput') {
88
+ console.log('DeviceTesting: NEW video device detected and selected');
89
+ setSelectedCam(changedDevice.device?.deviceId);
259
90
  }
260
91
  }
261
-
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);
92
+ if (changedDevice && changedDevice.state === 'INACTIVE') {
93
+ if (changedDevice.device?.kind === 'videoinput') {
94
+ console.log('DeviceTesting: video device inactive');
95
+ setSelectedCam('');
277
96
  }
278
97
  }
98
+ };
99
+ }, []);
279
100
 
280
- if (!selectedSpeaker || selectedSpeaker.trim().length == 0) {
281
- log(logTag, 'speaker: Device list populated but No selected speaker');
282
- const {audiooutput: storedAudioOutput} = activeDeviceId;
283
- const defaultSpeaker = deviceList.find(
284
- (device) =>
285
- device.deviceId === 'default' &&
286
- (isChrome ? device.deviceId === 'default' : true),
287
- )?.deviceId;
101
+ useEffect(() => {
102
+ refreshDevices();
103
+ }, [selectedCam, selectedMic]);
288
104
 
289
- if (
290
- defaultSpeaker &&
291
- storedAudioOutput &&
292
- defaultSpeaker !== storedAudioOutput &&
293
- deviceList.find((device) => device.deviceId === storedAudioOutput)
294
- ) {
295
- log(
296
- logTag,
297
- 'speaker: Setting speaker to active id',
298
- storedAudioOutput,
299
- );
300
- setSelectedSpeaker(storedAudioOutput);
301
- } else {
302
- setUiSelectedSpeaker(defaultSpeaker);
105
+ useEffect(() => {
106
+ if (!selectedMic || selectedMic.trim().length == 0) {
107
+ for (const i in deviceList) {
108
+ if (deviceList[i].kind === 'audioinput') {
109
+ console.log('DeviceTesting: set selected audio');
110
+ setSelectedMic(deviceList[i].deviceId);
111
+ break;
303
112
  }
304
113
  }
305
114
  }
306
-
307
- if (
308
- deviceList.length === 0 ||
309
- deviceList.find((device: MediaDeviceInfo) => device.label === '')
310
- ) {
311
- log(logTag, 'Empty device list');
312
- refreshDeviceList();
313
- }
314
- }, [rtc, store]);
315
-
316
- const commonOnChangedEvent = async (changedDeviceData: DeviceInfo) => {
317
- // Extracted devicelist because we want to perform fallback with
318
- // the most current version.
319
- const previousDeviceList = deviceList;
320
- const updatedDeviceList = await refreshDeviceList();
321
- const changedDevice = changedDeviceData.device;
322
-
323
- const {logTag, currentDevice, setCurrentDevice} = {
324
- audioinput: {
325
- logTag: 'mic: on-microphone-changed',
326
- currentDevice: selectedMic,
327
- setCurrentDevice: setSelectedMic,
328
- },
329
- audiooutput: {
330
- logTag: 'speaker: on-speaker-changed',
331
- currentDevice: selectedSpeaker,
332
- setCurrentDevice: setSelectedSpeaker,
333
- },
334
- videoinput: {
335
- logTag: 'cam: on-camera-changed',
336
- currentDevice: selectedCam,
337
- setCurrentDevice: setSelectedCam,
338
- },
339
- }[changedDevice.kind];
340
-
341
- log(logTag, changedDeviceData);
342
-
343
- if (currentDevice === 'default') {
344
- // const previousDefaultDevice = previousDeviceList.find(
345
- // (device) => device.deviceId === 'default',
346
- // );
347
- // const currentDefaultDevice = updatedDeviceList.find(
348
- // (device) => device.deviceId === 'default',
349
- // );
350
- // log(logTag, 'current Default device', {
351
- // changedDeviceData,
352
- // previousDeviceList,
353
- // updatedDeviceList,
354
- // previousDefaultDevice,
355
- // currentDefaultDevice,
356
- // });
357
- // if (previousDefaultDevice.groupId !== currentDefaultDevice.groupId) {
358
- // log(logTag, 'Default device changed', {
359
- // changedDeviceData,
360
- // previousDeviceList,
361
- // updatedDeviceList,
362
- // previousDefaultDevice,
363
- // currentDefaultDevice,
364
- // });
365
- // setCurrentDevice('default');
366
- // }
367
- setCurrentDevice('default');
368
- }
369
-
370
- const didChangeDeviceExistBefore = previousDeviceList.find(
371
- (device) => device.deviceId === changedDevice.deviceId,
372
- )
373
- ? true
374
- : false;
375
-
376
- if (changedDeviceData.state === 'ACTIVE' && !didChangeDeviceExistBefore) {
377
- const rememberedDevice =
378
- rememberedDevicesList[changedDevice.kind][changedDevice.deviceId];
379
-
380
- if (!rememberedDevice) {
381
- showNewDeviceDetectedToast(changedDevice);
382
- } else {
383
- if (rememberedDevice === 'switch-on-connect') {
384
- setCurrentDevice(changedDevice.deviceId);
385
- return;
115
+ if (!selectedCam || selectedCam.trim().length == 0) {
116
+ for (const i in deviceList) {
117
+ if (deviceList[i].kind === 'videoinput') {
118
+ console.log('DeviceTesting: set selected camera');
119
+ setSelectedCam(deviceList[i].deviceId);
120
+ break;
386
121
  }
387
122
  }
388
- } else if (changedDeviceData.state === 'INACTIVE') {
389
- if (changedDevice.deviceId === currentDevice) {
390
- fallbackToDefaultDevice(changedDevice.kind, updatedDeviceList);
391
- return;
392
- }
393
123
  }
394
- };
395
-
396
- // Port this to useEffectEvent(https://beta.reactjs.org/reference/react/useEffectEvent) when
397
- // released
398
- useEffect(() => {
399
- log('previous devicelist updated', deviceList);
400
- AgoraRTC.onMicrophoneChanged = commonOnChangedEvent;
401
- }, [selectedMic, deviceList]);
402
-
403
- useEffect(() => {
404
- AgoraRTC.onPlaybackDeviceChanged = commonOnChangedEvent;
405
- }, [selectedSpeaker, deviceList]);
124
+ }, [deviceList]);
406
125
 
407
126
  useEffect(() => {
408
- AgoraRTC.onCameraChanged = commonOnChangedEvent;
409
- }, [selectedCam, deviceList]);
410
-
411
- const setSelectedMic = (deviceId: deviceId) => {
412
- log('mic: setting to', deviceId);
413
- return new Promise((res, rej) => {
414
- RtcEngine.changeMic(
415
- 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
- );
426
- });
427
- };
428
-
429
- const setSelectedCam = (deviceId: deviceId) => {
430
- log('cam: setting to', deviceId);
431
- return new Promise((res, rej) => {
432
- RtcEngine.changeCamera(
433
- deviceId,
434
- () => {
435
- syncSelectedDeviceUi('videoinput');
436
- updateActiveDeviceId('videoinput', deviceId);
437
- res(null);
438
- },
439
- (e: any) => {
440
- console.error('Device Configure: Error setting webcam', e);
441
- rej(e);
442
- },
127
+ if (selectedCam.length !== 0) {
128
+ rtc.RtcEngine.changeCamera(
129
+ selectedCam,
130
+ () => {},
131
+ (e: any) => console.log(e),
443
132
  );
444
- });
445
- };
133
+ }
134
+ // eslint-disable-next-line react-hooks/exhaustive-deps
135
+ }, [selectedCam]);
446
136
 
447
- 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
- },
137
+ useEffect(() => {
138
+ if (selectedMic.length !== 0) {
139
+ rtc.RtcEngine.changeMic(
140
+ selectedMic,
141
+ () => {},
142
+ (e: any) => console.log(e),
461
143
  );
462
- });
463
- };
464
-
465
- const showNewDeviceDetectedToast = (device: MediaDeviceInfo) => {
466
- const {name, setAction} = {
467
- audioinput: {
468
- name: 'mic',
469
- setAction: setSelectedMic,
470
- },
471
- videoinput: {
472
- name: 'webcam',
473
- setAction: setSelectedCam,
474
- },
475
- audiooutput: {
476
- name: 'speaker',
477
- setAction: setSelectedSpeaker,
478
- },
479
- }[device.kind];
144
+ }
145
+ // eslint-disable-next-line react-hooks/exhaustive-deps
146
+ }, [selectedMic]);
480
147
 
481
- Toast.show({
482
- type: 'checked',
483
- // leadingIcon: <CustomIcon name={'mic-on'} />,
484
- text1: `New ${name} detected`,
485
- // @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
- ),
493
- visibilityTime: 6000,
494
- checkbox: {
495
- disabled: false,
496
- color: primaryColor,
497
- text: 'Remember my choice',
498
- },
499
- primaryBtn: {
500
- text: 'SWITCH DEVICE',
501
- onPress: (checked: boolean) => {
502
- setAction(device.deviceId);
503
- checked && updateRememberedDeviceList(device, true);
504
- Toast.hide();
505
- },
506
- },
507
- secondaryBtn: {
508
- text: 'IGNORE',
509
- onPress: (checked: boolean) => {
510
- checked && updateRememberedDeviceList(device, false);
511
- Toast.hide();
512
- },
513
- },
514
- });
515
- };
148
+ useEffect(() => {
149
+ // If stream exists and deviceList are empty, check for devices again
150
+ // Labels are empty in firefox when permission is grante first time, refresh device list if labels are empty
151
+ if (
152
+ deviceList.length === 0 ||
153
+ deviceList.find((device: MediaDeviceInfo) => device.label === '')
154
+ ) {
155
+ refreshDevices();
156
+ }
157
+ }, [rtc]);
516
158
 
517
159
  return (
518
160
  <DeviceContext.Provider
@@ -521,8 +163,6 @@ const DeviceConfigure: React.FC<Props> = (props: any) => {
521
163
  setSelectedCam,
522
164
  selectedMic,
523
165
  setSelectedMic,
524
- selectedSpeaker,
525
- setSelectedSpeaker,
526
166
  deviceList,
527
167
  setDeviceList,
528
168
  }}>
@@ -13,11 +13,9 @@ import {createContext} from 'react';
13
13
 
14
14
  interface DeviceContext {
15
15
  selectedCam: string;
16
- setSelectedCam: (cam: string) => Promise<any>;
16
+ setSelectedCam: (cam: string) => void;
17
17
  selectedMic: string;
18
- setSelectedMic: (mic: string) => Promise<any>;
19
- selectedSpeaker: string;
20
- setSelectedSpeaker: (speaker: string) => Promise<any>;
18
+ setSelectedMic: (mic: string) => void;
21
19
  deviceList: MediaDeviceInfo[];
22
20
  setDeviceList: (devices: MediaDeviceInfo[]) => void;
23
21
  }
@@ -25,11 +23,9 @@ interface DeviceContext {
25
23
  const DeviceContext = createContext<DeviceContext>({
26
24
  selectedCam: '',
27
25
  selectedMic: '',
28
- selectedSpeaker: '',
29
26
  deviceList: [],
30
- setSelectedCam: async () => {},
31
- setSelectedMic: async () => {},
32
- setSelectedSpeaker: async () => {},
27
+ setSelectedCam: () => {},
28
+ setSelectedMic: () => {},
33
29
  setDeviceList: () => {},
34
30
  });
35
31
  export default DeviceContext;