agora-appbuilder-core 3.0.9 → 3.0.10

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 (248) hide show
  1. package/Readme.md +6 -0
  2. package/package.json +2 -2
  3. package/template/_package-lock.json +5871 -4728
  4. package/template/agora-rn-uikit/src/Contexts/LocalUserContext.tsx +4 -0
  5. package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +18 -0
  6. package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +2 -0
  7. package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +30 -26
  8. package/template/agora-rn-uikit/src/Controls/Icons.ts +30 -83
  9. package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +6 -6
  10. package/template/agora-rn-uikit/src/Reducer/ActiveSpeakerDetected.ts +11 -0
  11. package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +1 -0
  12. package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +1 -0
  13. package/template/agora-rn-uikit/src/Reducer/LocalPermissionState.ts +24 -0
  14. package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +1 -0
  15. package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +1 -0
  16. package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +1 -0
  17. package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +2 -0
  18. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +1 -0
  19. package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +1 -0
  20. package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +1 -0
  21. package/template/agora-rn-uikit/src/Reducer/UserPin.ts +11 -0
  22. package/template/agora-rn-uikit/src/Reducer/index.ts +3 -0
  23. package/template/agora-rn-uikit/src/Rtc/Create.tsx +89 -1
  24. package/template/agora-rn-uikit/src/RtcConfigure.tsx +39 -2
  25. package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +15 -5
  26. package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +15 -9
  27. package/template/agora-rn-uikit/src/index.ts +3 -1
  28. package/template/android/app/build.gradle +1 -0
  29. package/template/android/app/src/main/AndroidManifest.xml +22 -15
  30. package/template/android/app/src/main/assets/fonts/SourceSansPro-Regular.ttf +0 -0
  31. package/template/android/app/src/main/assets/fonts/icomoon.ttf +0 -0
  32. package/template/android/app/src/main/java/com/helloworld/MainActivity.java +50 -0
  33. package/template/android/app/src/main/res/values/colors.xml +7 -0
  34. package/template/android/build.gradle +3 -3
  35. package/template/babel.config.js +1 -0
  36. package/template/bridge/rtc/webNg/RtcEngine.ts +110 -17
  37. package/template/customization-api/sub-components.ts +1 -1
  38. package/template/customization-api/typeDefinition.ts +2 -1
  39. package/template/electron/index.html +27 -27
  40. package/template/electron/renderer/index.js +1 -0
  41. package/template/global.d.ts +25 -4
  42. package/template/index.rsdk.tsx +1 -0
  43. package/template/index.web.js +2 -1
  44. package/template/index.wsdk.tsx +1 -1
  45. package/template/ios/HelloWorld/Info.plist +14 -1
  46. package/template/ios/HelloWorld.xcodeproj/project.pbxproj +17 -0
  47. package/template/metro.config.js +1 -1
  48. package/template/package.json +18 -7
  49. package/template/react-native-toast-message/index.d.ts +43 -43
  50. package/template/react-native-toast-message/src/colors/index.js +3 -2
  51. package/template/react-native-toast-message/src/components/base/index.js +46 -59
  52. package/template/react-native-toast-message/src/components/base/styles.js +16 -32
  53. package/template/react-native-toast-message/src/components/checkbox.js +178 -0
  54. package/template/react-native-toast-message/src/components/error.js +3 -2
  55. package/template/react-native-toast-message/src/components/info.js +3 -2
  56. package/template/react-native-toast-message/src/components/success.js +3 -2
  57. package/template/react-native-toast-message/src/index.js +122 -31
  58. package/template/react-native-toast-message/src/index.sdk.tsx +125 -35
  59. package/template/react-native-toast-message/src/styles.js +3 -4
  60. package/template/react-native-toast-message/src/styles.sdk.ts +3 -4
  61. package/template/react-native.config.js +7 -0
  62. package/template/src/App.tsx +6 -0
  63. package/template/src/AppWrapper.tsx +63 -28
  64. package/template/src/assets/font-styles.css +329 -0
  65. package/template/src/assets/fonts/SourceSansPro-Regular.ttf +0 -0
  66. package/template/src/assets/fonts/icomoon.ttf +0 -0
  67. package/template/src/assets/permission.png +0 -0
  68. package/template/src/assets/selection.json +1 -0
  69. package/template/src/atoms/ActionMenu.tsx +236 -0
  70. package/template/src/atoms/AnimatedActiveSpeaker.native.tsx +71 -0
  71. package/template/src/atoms/AnimatedActiveSpeaker.tsx +84 -0
  72. package/template/src/atoms/AnimatedRings.native.tsx +68 -0
  73. package/template/src/atoms/AnimatedRings.tsx +70 -0
  74. package/template/src/atoms/Card.tsx +61 -0
  75. package/template/src/atoms/CircularProgress.native.tsx +121 -0
  76. package/template/src/atoms/CircularProgress.tsx +102 -0
  77. package/template/src/atoms/CustomIcon.tsx +88 -0
  78. package/template/src/atoms/CustomSwitch.tsx +287 -0
  79. package/template/src/atoms/Dropdown.tsx +306 -0
  80. package/template/src/atoms/HorizontalRule.tsx +3 -1
  81. package/template/src/atoms/IconButton.tsx +162 -0
  82. package/template/src/atoms/ImageIcon.tsx +98 -0
  83. package/template/src/atoms/InfoBubble.tsx +291 -0
  84. package/template/src/atoms/Input.tsx +87 -0
  85. package/template/src/atoms/InviteInfo.tsx +166 -0
  86. package/template/src/atoms/LinkButton.tsx +28 -0
  87. package/template/src/atoms/OutlineButton.tsx +61 -0
  88. package/template/src/atoms/ParticipantsCount.tsx +73 -0
  89. package/template/src/atoms/Popup.tsx +147 -0
  90. package/template/src/atoms/PrimaryButton.tsx +51 -26
  91. package/template/src/atoms/RecordingInfo.tsx +49 -0
  92. package/template/src/atoms/SecondaryButton.tsx +8 -5
  93. package/template/src/atoms/Spacer.tsx +22 -0
  94. package/template/src/atoms/TertiaryButton.tsx +78 -0
  95. package/template/src/atoms/TextInput.tsx +12 -14
  96. package/template/src/atoms/Toggle.tsx +47 -0
  97. package/template/src/atoms/Tooltip.native.tsx +65 -0
  98. package/template/src/atoms/Tooltip.tsx +94 -0
  99. package/template/src/atoms/UserAvatar.tsx +60 -0
  100. package/template/src/components/Chat.tsx +86 -214
  101. package/template/src/components/ChatContext.ts +8 -1
  102. package/template/src/components/ColorConfigure.tsx +1 -1
  103. package/template/src/components/ColorContext.ts +1 -1
  104. package/template/src/components/CommonStyles.ts +44 -0
  105. package/template/src/components/Controls.tsx +342 -42
  106. package/template/src/components/{Controls.native.tsx → Controls1.native.tsx} +6 -4
  107. package/template/src/components/DeviceConfigure.tsx +461 -101
  108. package/template/src/components/DeviceContext.tsx +8 -4
  109. package/template/src/components/EventsConfigure.tsx +144 -7
  110. package/template/src/components/GraphQLProvider.tsx +1 -1
  111. package/template/src/components/GridVideo.tsx +59 -44
  112. package/template/src/components/HostControlView.tsx +114 -35
  113. package/template/src/components/Navbar.tsx +216 -398
  114. package/template/src/components/NetworkQualityContext.tsx +20 -20
  115. package/template/src/components/ParticipantsView.tsx +177 -154
  116. package/template/src/components/PinnedVideo.tsx +207 -120
  117. package/template/src/components/Precall.native.tsx +358 -119
  118. package/template/src/components/Precall.tsx +269 -135
  119. package/template/src/components/RTMConfigure.tsx +27 -4
  120. package/template/src/components/Router.electron.ts +1 -0
  121. package/template/src/components/Router.native.ts +1 -0
  122. package/template/src/components/Router.sdk.ts +1 -0
  123. package/template/src/components/Router.ts +1 -0
  124. package/template/src/components/Settings.tsx +26 -95
  125. package/template/src/components/SettingsView.tsx +251 -56
  126. package/template/src/components/Share.tsx +302 -273
  127. package/template/src/components/StorageContext.tsx +30 -3
  128. package/template/src/components/ToastComponent.tsx +8 -0
  129. package/template/src/components/chat-messages/useChatMessages.tsx +69 -23
  130. package/template/src/components/chat-ui/useChatUIControl.tsx +7 -0
  131. package/template/src/components/common/Error.tsx +20 -6
  132. package/template/src/components/common/Logo.tsx +16 -15
  133. package/template/src/components/contexts/LiveStreamDataContext.tsx +10 -5
  134. package/template/src/components/contexts/VideoMeetingDataContext.tsx +37 -7
  135. package/template/src/components/livestream/LiveStreamContext.tsx +270 -36
  136. package/template/src/components/livestream/Types.ts +39 -14
  137. package/template/src/components/livestream/index.ts +1 -0
  138. package/template/src/components/livestream/views/LiveStreamControls.tsx +12 -4
  139. package/template/src/components/participants/AllAudienceParticipants.tsx +101 -30
  140. package/template/src/components/participants/AllHostParticipants.tsx +103 -34
  141. package/template/src/components/participants/Participant.tsx +302 -0
  142. package/template/src/components/participants/ParticipantName.tsx +13 -7
  143. package/template/src/components/participants/ParticipantSectionTitle.tsx +35 -10
  144. package/template/src/components/participants/ScreenshareParticipants.tsx +144 -12
  145. package/template/src/components/participants/UserActionMenuOptions.tsx +398 -0
  146. package/template/src/components/popups/InvitePopup.tsx +115 -0
  147. package/template/src/components/popups/StopRecordingPopup.tsx +114 -0
  148. package/template/src/components/precall/LocalMute.tsx +84 -14
  149. package/template/src/components/precall/{LocalMute.native.tsx → LocalMute1.native.tsx} +21 -5
  150. package/template/src/components/precall/PermissionHelper.native.tsx +5 -0
  151. package/template/src/components/precall/PermissionHelper.tsx +126 -0
  152. package/template/src/components/precall/PreCallSettings.tsx +52 -0
  153. package/template/src/components/precall/VideoPreview.native.tsx +48 -3
  154. package/template/src/components/precall/VideoPreview.tsx +163 -7
  155. package/template/src/components/precall/joinCallBtn.tsx +15 -2
  156. package/template/src/components/precall/meetingTitle.tsx +15 -12
  157. package/template/src/components/precall/selectDevice.tsx +1 -21
  158. package/template/src/components/precall/textInput.tsx +32 -4
  159. package/template/src/components/precall/usePreCall.tsx +16 -0
  160. package/template/src/components/styles.ts +42 -21
  161. package/template/src/components/useShareLink.tsx +12 -14
  162. package/template/src/components/useToast.tsx +41 -0
  163. package/template/src/components/useVideoCall.tsx +65 -0
  164. package/template/src/language/default-labels/precallScreenLabels.ts +3 -3
  165. package/template/src/pages/Authenticate.tsx +5 -15
  166. package/template/src/pages/Create.tsx +293 -165
  167. package/template/src/pages/Endcall.tsx +148 -0
  168. package/template/src/pages/Join.tsx +93 -67
  169. package/template/src/pages/VideoCall.tsx +89 -64
  170. package/template/src/pages/video-call/ActionSheet.native.tsx +215 -0
  171. package/template/src/pages/video-call/ActionSheet.tsx +226 -0
  172. package/template/src/pages/video-call/ActionSheetContent.tsx +479 -0
  173. package/template/src/pages/video-call/ActionSheetHandle.tsx +38 -0
  174. package/template/src/pages/video-call/ActionSheetStyles.css +138 -0
  175. package/template/src/pages/video-call/DefaultLayouts.ts +4 -4
  176. package/template/src/pages/video-call/NameWithMicIcon.tsx +120 -44
  177. package/template/src/pages/video-call/RenderComponent.tsx +3 -2
  178. package/template/src/pages/video-call/SidePanelHeader.tsx +190 -0
  179. package/template/src/pages/video-call/VideoCallMobileView.tsx +139 -0
  180. package/template/src/pages/video-call/VideoCallScreen.native.tsx +37 -0
  181. package/template/src/pages/video-call/VideoCallScreen.tsx +45 -9
  182. package/template/src/pages/video-call/VideoComponent.tsx +18 -3
  183. package/template/src/pages/video-call/VideoRenderer.tsx +218 -60
  184. package/template/src/rtm-events/constants.ts +2 -0
  185. package/template/src/subComponents/ChatBubble.tsx +123 -83
  186. package/template/src/subComponents/ChatContainer.tsx +257 -84
  187. package/template/src/subComponents/ChatInput.ios.tsx +237 -0
  188. package/template/src/subComponents/ChatInput.tsx +61 -46
  189. package/template/src/subComponents/Checkbox.native.tsx +16 -5
  190. package/template/src/subComponents/Checkbox.tsx +2 -2
  191. package/template/src/subComponents/CopyJoinInfo.tsx +36 -58
  192. package/template/src/subComponents/EndcallPopup.tsx +107 -0
  193. package/template/src/subComponents/FallbackLogo.tsx +122 -40
  194. package/template/src/subComponents/LanguageSelector.tsx +1 -1
  195. package/template/src/subComponents/LayoutIconButton.tsx +201 -0
  196. package/template/src/subComponents/LayoutIconDropdown.tsx +131 -134
  197. package/template/src/subComponents/{LayoutIconDropdown.native.tsx → LayoutIconDropdown1.native.tsx} +4 -18
  198. package/template/src/subComponents/LocalAudioMute.tsx +119 -27
  199. package/template/src/subComponents/LocalEndCall.tsx +71 -33
  200. package/template/src/subComponents/LocalSwitchCamera.tsx +17 -30
  201. package/template/src/subComponents/LocalVideoMute.tsx +117 -27
  202. package/template/src/subComponents/Logo.tsx +3 -4
  203. package/template/src/subComponents/LogoutButton.tsx +1 -1
  204. package/template/src/subComponents/NetworkQualityPill.tsx +60 -63
  205. package/template/src/subComponents/OpenInNativeButton.tsx +3 -3
  206. package/template/src/subComponents/Recording.tsx +28 -29
  207. package/template/src/subComponents/RemoteAudioMute.tsx +83 -29
  208. package/template/src/subComponents/RemoteEndCall.tsx +8 -5
  209. package/template/src/subComponents/RemoteMutePopup.tsx +193 -0
  210. package/template/src/subComponents/RemoteVideoMute.tsx +74 -21
  211. package/template/src/subComponents/RemoveMeetingPopup.tsx +109 -0
  212. package/template/src/subComponents/RemoveScreensharePopup.tsx +109 -0
  213. package/template/src/subComponents/ScreenShareNotice.tsx +83 -8
  214. package/template/src/subComponents/SelectDevice.tsx +404 -61
  215. package/template/src/subComponents/SelectDeviceSettings.backup.tsx +207 -0
  216. package/template/src/subComponents/SelectOAuth.tsx +9 -8
  217. package/template/src/subComponents/SidePanelHeader.tsx +112 -0
  218. package/template/src/subComponents/ToastConfig.tsx +150 -10
  219. package/template/src/subComponents/chat/ChatParticipants.tsx +187 -78
  220. package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +95 -32
  221. package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +29 -33
  222. package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +6 -6
  223. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +24 -11
  224. package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +17 -10
  225. package/template/src/subComponents/recording/useRecording.tsx +79 -27
  226. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +52 -70
  227. package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +11 -2
  228. package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +26 -4
  229. package/template/src/theme/index.ts +46 -0
  230. package/template/src/utils/PlatformWrapper.tsx +21 -0
  231. package/template/src/utils/common.tsx +155 -1
  232. package/template/src/utils/hexadecimalTransparency.ts +108 -0
  233. package/template/src/utils/index.tsx +19 -0
  234. package/template/src/utils/isMobileOrTablet.ts +7 -2
  235. package/template/src/utils/pendingStateUpdateHelper.ts +19 -0
  236. package/template/src/utils/useButtonTemplate.tsx +1 -0
  237. package/template/src/utils/useFocus.tsx +46 -0
  238. package/template/src/utils/useIsActiveSpeaker.ts +27 -0
  239. package/template/src/utils/useIsHandRaised.ts +13 -0
  240. package/template/src/utils/useMuteToggleLocal.ts +54 -3
  241. package/template/src/utils/useRemoteEndScreenshare.ts +26 -0
  242. package/template/src/utils/useRemoteRequest.ts +84 -0
  243. package/template/web/index.html +5 -0
  244. package/template/webpack.commons.js +13 -8
  245. package/template/webpack.web.config.js +1 -0
  246. package/template/src/assets/icons.ts +0 -102
  247. package/template/src/components/participants/MeParticipant.tsx +0 -38
  248. package/template/src/components/participants/RemoteParticipants.tsx +0 -71
@@ -2,13 +2,28 @@ import React, {useEffect, useState} from 'react';
2
2
  import useLayoutsData from './useLayoutsData';
3
3
  import {isArray, isValidReactComponent} from '../../utils/common';
4
4
  import {useLayout} from '../../utils/useLayout';
5
- import {useRender} from 'customization-api';
5
+ import {useRender, useRtc} from 'customization-api';
6
+ import {getGridLayoutName} from './DefaultLayouts';
6
7
 
7
8
  const VideoComponent = () => {
9
+ const {dispatch} = useRtc();
8
10
  const [layout, setLayoutIndex] = useState(0);
9
11
  const layoutsData = useLayoutsData();
10
- const {currentLayout} = useLayout();
11
- const {activeUids} = useRender();
12
+ const {currentLayout, setLayout} = useLayout();
13
+ const {activeUids, pinnedUid} = useRender();
14
+
15
+ useEffect(() => {
16
+ if (activeUids && activeUids.length === 1) {
17
+ if (pinnedUid) {
18
+ dispatch({type: 'UserPin', value: [0]});
19
+ }
20
+ const gridLayoutName = getGridLayoutName();
21
+ if (currentLayout !== gridLayoutName) {
22
+ setLayout(gridLayoutName);
23
+ }
24
+ }
25
+ }, [activeUids]);
26
+
12
27
  useEffect(() => {
13
28
  if (isArray(layoutsData)) {
14
29
  let index = layoutsData.findIndex((item) => item.name === currentLayout);
@@ -1,85 +1,243 @@
1
- import React, {useContext} from 'react';
2
- import {View, StyleSheet} from 'react-native';
3
- import {RenderInterface, UidType} from '../../../agora-rn-uikit';
1
+ import React, {useState, useRef, useContext, useEffect} from 'react';
2
+ import {View, StyleSheet, Platform} from 'react-native';
3
+ import {PropsContext, RenderInterface, UidType} from '../../../agora-rn-uikit';
4
4
  import ScreenShareNotice from '../../subComponents/ScreenShareNotice';
5
5
  import {MaxVideoView} from '../../../agora-rn-uikit';
6
6
  import FallbackLogo from '../../subComponents/FallbackLogo';
7
- import ColorContext from '../../components/ColorContext';
8
7
  import NetworkQualityPill from '../../subComponents/NetworkQualityPill';
9
8
  import NameWithMicIcon from './NameWithMicIcon';
9
+ import useIsActiveSpeaker from '../../utils/useIsActiveSpeaker';
10
+ import {useLayout, useRender, useRtc} from 'customization-api';
11
+ import {getGridLayoutName, getPinnedLayoutName} from './DefaultLayouts';
12
+ import IconButton from '../../atoms/IconButton';
13
+ import UserActionMenuOptionsOptions from '../../components/participants/UserActionMenuOptions';
14
+ import {isMobileUA, isWebInternal} from '../../utils/common';
15
+ import ThemeConfig from '../../theme';
10
16
 
11
17
  interface VideoRendererProps {
12
18
  user: RenderInterface;
19
+ isMax?: boolean;
13
20
  }
14
- const VideoRenderer: React.FC<VideoRendererProps> = ({user}) => {
15
- const {primaryColor} = useContext(ColorContext);
21
+ const VideoRenderer: React.FC<VideoRendererProps> = ({user, isMax = false}) => {
22
+ const {dispatch} = useRtc();
23
+ const isActiveSpeaker = useIsActiveSpeaker();
24
+ const {pinnedUid, activeUids} = useRender();
25
+ const activeSpeaker = isActiveSpeaker(user.uid);
26
+ const [isHovered, setIsHovered] = useState(false);
27
+ const {rtcProps} = useContext(PropsContext);
28
+ const {currentLayout} = useLayout();
29
+ const showReplacePin =
30
+ pinnedUid && !isMax && isHovered && currentLayout === getPinnedLayoutName();
31
+ const showPinForMe =
32
+ !pinnedUid &&
33
+ !isMax &&
34
+ isHovered &&
35
+ currentLayout === getPinnedLayoutName();
36
+ const [videoTileWidth, setVideoTileWidth] = useState(0);
37
+ const [avatarSize, setAvatarSize] = useState(100);
38
+ const videoMoreMenuRef = useRef(null);
39
+ const [actionMenuVisible, setActionMenuVisible] = React.useState(false);
16
40
  return (
17
- <View style={maxStyle.container}>
18
- <ScreenShareNotice uid={user.uid} />
19
- <NetworkQualityPill
20
- user={user}
21
- primaryColor={primaryColor}
22
- rootStyle={{
23
- marginLeft: 25,
24
- top: 8,
25
- right: 10,
26
- }}
27
- small
28
- />
29
- <MaxVideoView
30
- fallback={() => {
31
- return FallbackLogo(user?.name);
41
+ <>
42
+ <UserActionMenuOptionsOptions
43
+ actionMenuVisible={actionMenuVisible}
44
+ setActionMenuVisible={(flag) => {
45
+ //once user clicks action menu item -> hide the action menu and set parent isHovered false
46
+ if (!flag) {
47
+ setIsHovered(false);
48
+ }
49
+ setActionMenuVisible(flag);
32
50
  }}
33
51
  user={user}
34
- key={user.uid}
52
+ btnRef={videoMoreMenuRef}
53
+ from={'video-tile'}
35
54
  />
36
- <View style={maxStyle.nameHolder}>
37
- <NameWithMicIcon user={user} />
55
+ <PlatformWrapper isHovered={isHovered} setIsHovered={setIsHovered}>
56
+ <View
57
+ onLayout={({
58
+ nativeEvent: {
59
+ layout: {x, y, width, height},
60
+ },
61
+ }) => {
62
+ setVideoTileWidth(width);
63
+ setAvatarSize(Math.floor(width * 0.35));
64
+ }}
65
+ style={[
66
+ maxStyle.container,
67
+ activeSpeaker
68
+ ? maxStyle.activeContainerStyle
69
+ : user.video
70
+ ? maxStyle.noVideoStyle
71
+ : maxStyle.nonActiveContainerStyle,
72
+ ]}>
73
+ {!showReplacePin && !showPinForMe && (
74
+ <ScreenShareNotice uid={user.uid} isMax={isMax} />
75
+ )}
76
+ <NetworkQualityPill user={user} />
77
+ <MaxVideoView
78
+ fallback={() => {
79
+ return FallbackLogo(
80
+ user?.name,
81
+ activeSpeaker,
82
+ (showReplacePin || showPinForMe) && !isMobileUA()
83
+ ? true
84
+ : false,
85
+ isMax,
86
+ avatarSize,
87
+ );
88
+ }}
89
+ user={user}
90
+ containerStyle={{
91
+ width: '100%',
92
+ height: '100%',
93
+ }}
94
+ key={user.uid}
95
+ />
96
+ <NameWithMicIcon
97
+ videoTileWidth={videoTileWidth}
98
+ user={user}
99
+ isMax={isMax}
100
+ />
101
+ {user.uid !== rtcProps?.screenShareUid &&
102
+ (isHovered || actionMenuVisible || isMobileUA()) ? (
103
+ <MoreMenu
104
+ videoMoreMenuRef={videoMoreMenuRef}
105
+ setActionMenuVisible={setActionMenuVisible}
106
+ />
107
+ ) : (
108
+ <></>
109
+ )}
110
+ {(showReplacePin || showPinForMe) && !isMobileUA() ? (
111
+ <IconButton
112
+ onPress={() => {
113
+ dispatch({type: 'UserPin', value: [user.uid]});
114
+ }}
115
+ containerStyle={maxStyle.replacePinContainer}
116
+ btnTextProps={{
117
+ text: showReplacePin ? 'Replace Pin' : 'Pin for me',
118
+ textColor: $config.VIDEO_AUDIO_TILE_TEXT_COLOR,
119
+ textStyle: {
120
+ marginTop: 0,
121
+ fontWeight: '700',
122
+ marginLeft: 6,
123
+ },
124
+ }}
125
+ iconProps={{
126
+ name: 'pin-filled',
127
+ iconSize: 20,
128
+ iconType: 'plain',
129
+ tintColor: $config.VIDEO_AUDIO_TILE_TEXT_COLOR,
130
+ }}
131
+ />
132
+ ) : (
133
+ <></>
134
+ )}
135
+ </View>
136
+ </PlatformWrapper>
137
+ </>
138
+ );
139
+ };
140
+
141
+ interface MoreMenuProps {
142
+ setActionMenuVisible: (f: boolean) => void;
143
+ videoMoreMenuRef: any;
144
+ }
145
+ const MoreMenu = ({setActionMenuVisible, videoMoreMenuRef}: MoreMenuProps) => {
146
+ const {activeUids} = useRender();
147
+ const {currentLayout} = useLayout();
148
+ const reduceSpace =
149
+ isMobileUA() &&
150
+ activeUids.length > 4 &&
151
+ currentLayout === getGridLayoutName();
152
+ return (
153
+ <>
154
+ <View
155
+ ref={videoMoreMenuRef}
156
+ collapsable={false}
157
+ style={{
158
+ position: 'absolute',
159
+ right: reduceSpace ? 2 : 8,
160
+ bottom: reduceSpace ? 2 : 8,
161
+ zIndex: 999,
162
+ }}>
163
+ <IconButton
164
+ onPress={() => {
165
+ setActionMenuVisible(true);
166
+ }}
167
+ iconProps={{
168
+ iconContainerStyle: {
169
+ padding: reduceSpace && activeUids.length > 12 ? 2 : 8,
170
+ backgroundColor: $config.VIDEO_AUDIO_TILE_OVERLAY_COLOR,
171
+ },
172
+ name: 'more-menu',
173
+ iconSize: 20,
174
+ tintColor: $config.SECONDARY_ACTION_COLOR,
175
+ }}
176
+ />
38
177
  </View>
39
- </View>
178
+ </>
179
+ );
180
+ };
181
+
182
+ const PlatformWrapper = ({children, setIsHovered, isHovered}) => {
183
+ return isWebInternal() && !isMobileUA() ? (
184
+ <div
185
+ style={{width: '100%', height: '100%'}}
186
+ /**
187
+ * why onMouseOver is used instead of onMouseEnter
188
+ * when user clicks close icon the participant then video tile will expand and
189
+ * cursor will directly land on child elements. so onhover kabab menu icon is not displayed
190
+ *
191
+ * As per doc
192
+ * The mouseover event triggers when the mouse pointer enters the div element, and its child elements.
193
+ * The mouseenter event is only triggered when the mouse pointer enters the div element.
194
+ * */
195
+ onMouseOver={() => {
196
+ !isHovered && setIsHovered(true);
197
+ }}
198
+ onMouseLeave={() => {
199
+ setIsHovered(false);
200
+ }}>
201
+ {children}
202
+ </div>
203
+ ) : (
204
+ <>{children}</>
40
205
  );
41
206
  };
42
207
 
43
208
  const maxStyle = StyleSheet.create({
44
- container: {width: '100%', height: '100%'},
45
- width80: {width: '80%'},
46
- width100: {width: '100%'},
47
- flex2: {flex: 2},
48
- flex4: {flex: 4, backgroundColor: '#ffffff00'},
49
- flex1: {flex: 1},
50
- nameHolder: {
51
- marginTop: -25,
52
- backgroundColor: $config.SECONDARY_FONT_COLOR + 'aa',
53
- alignSelf: 'flex-end',
54
- paddingHorizontal: 8,
55
- height: 25,
56
- borderTopLeftRadius: 15,
57
- borderBottomRightRadius: 15,
209
+ replacePinContainer: {
210
+ zIndex: 999,
211
+ paddingHorizontal: 12,
212
+ paddingVertical: 10,
213
+ backgroundColor: $config.VIDEO_AUDIO_TILE_OVERLAY_COLOR,
214
+ borderRadius: 8,
58
215
  flexDirection: 'row',
59
- zIndex: 5,
60
- maxWidth: '100%',
216
+ position: 'absolute',
217
+ left: 0,
218
+ right: 0,
219
+ top: 0,
220
+ bottom: 0,
221
+ margin: 'auto',
222
+ maxWidth: 120,
223
+ maxHeight: 32,
224
+ },
225
+ container: {
226
+ width: '100%',
227
+ height: '100%',
228
+ position: 'relative',
229
+ overflow: 'hidden',
230
+ borderRadius: ThemeConfig.BorderRadius.small,
231
+ borderWidth: 2,
61
232
  },
62
- name: {
63
- color: $config.PRIMARY_FONT_COLOR,
64
- lineHeight: 25,
65
- fontWeight: '700',
66
- flexShrink: 1,
233
+ activeContainerStyle: {
234
+ borderColor: $config.PRIMARY_ACTION_BRAND_COLOR,
67
235
  },
68
- MicBackdrop: {
69
- width: 20,
70
- height: 20,
71
- borderRadius: 15,
72
- marginHorizontal: 10,
73
- backgroundColor: $config.SECONDARY_FONT_COLOR,
74
- display: 'flex',
75
- alignSelf: 'center',
76
- justifyContent: 'center',
236
+ nonActiveContainerStyle: {
237
+ borderColor: 'transparent',
77
238
  },
78
- MicIcon: {
79
- width: '80%',
80
- height: '80%',
81
- alignSelf: 'center',
82
- resizeMode: 'contain',
239
+ noVideoStyle: {
240
+ borderColor: 'transparent',
83
241
  },
84
242
  });
85
243
 
@@ -2,6 +2,7 @@
2
2
  // 1. RECORDING
3
3
  const RECORDING_STARTED = 'RECORDING_STARTED';
4
4
  const RECORDING_STOPPED = 'RECORDING_STOPPED';
5
+ const RECORDING_STOP_REQUEST = 'RECORDING_STOP_REQUEST';
5
6
  // 2. SCREENSHARE
6
7
  const SCREENSHARE_STARTED = 'SCREENSHARE_STARTED';
7
8
  const SCREENSHARE_STOPPED = 'SCREENSHARE_STOPPED';
@@ -9,6 +10,7 @@ const SCREENSHARE_STOPPED = 'SCREENSHARE_STOPPED';
9
10
  const EventActions = {
10
11
  RECORDING_STARTED,
11
12
  RECORDING_STOPPED,
13
+ RECORDING_STOP_REQUEST,
12
14
  SCREENSHARE_STARTED,
13
15
  SCREENSHARE_STOPPED,
14
16
  };
@@ -16,13 +16,19 @@ import {useString} from '../utils/useString';
16
16
  import {ChatBubbleProps} from '../components/ChatContext';
17
17
  import ColorContext from '../components/ColorContext';
18
18
  import {isWebInternal} from '../utils/common';
19
- import {useRender} from 'customization-api';
19
+ import {useChatUIControl, useRender} from 'customization-api';
20
+ import ThemeConfig from '../theme';
21
+ import hexadecimalTransparency from '../utils/hexadecimalTransparency';
22
+ import Spacer from '../atoms/Spacer';
23
+ import {formatAMPM} from '../utils';
20
24
 
21
25
  const ChatBubble = (props: ChatBubbleProps) => {
22
26
  const {renderList} = useRender();
23
27
  const {primaryColor} = useContext(ColorContext);
28
+ const {privateActive, selectedChatUserId} = useChatUIControl();
24
29
  let {
25
30
  isLocal,
31
+ isSameUser,
26
32
  message,
27
33
  createdTimestamp,
28
34
  uid,
@@ -30,10 +36,8 @@ const ChatBubble = (props: ChatBubbleProps) => {
30
36
  msgId,
31
37
  updatedTimestamp,
32
38
  } = props;
33
- let time =
34
- new Date(parseInt(createdTimestamp)).getHours() +
35
- ':' +
36
- new Date(parseInt(createdTimestamp)).getMinutes();
39
+ let time = formatAMPM(new Date(parseInt(createdTimestamp)));
40
+
37
41
  const handleUrl = (url: string) => {
38
42
  if (isWebInternal()) {
39
43
  window.open(url, '_blank');
@@ -44,6 +48,7 @@ const ChatBubble = (props: ChatBubbleProps) => {
44
48
  //commented for v1 release
45
49
  //const remoteUserDefaultLabel = useString('remoteUserDefaultLabel')();
46
50
  const remoteUserDefaultLabel = 'User';
51
+
47
52
  return props?.render ? (
48
53
  props.render(
49
54
  isLocal,
@@ -53,106 +58,141 @@ const ChatBubble = (props: ChatBubbleProps) => {
53
58
  msgId,
54
59
  isDeleted,
55
60
  updatedTimestamp,
61
+ isSameUser,
56
62
  )
57
63
  ) : (
58
- <View>
59
- <View style={isLocal ? style.chatSenderViewLocal : style.chatSenderView}>
60
- <Text style={isLocal ? style.timestampTextLocal : style.timestampText}>
61
- {renderList[uid] ? renderList[uid].name : remoteUserDefaultLabel} |{' '}
62
- {time + ' '}
64
+ <>
65
+ {!isSameUser && !(privateActive && selectedChatUserId) ? (
66
+ <Text
67
+ style={
68
+ isLocal ? style.localUsernameStyle : style.remoteUsernameStyle
69
+ }>
70
+ {isLocal
71
+ ? 'You'
72
+ : renderList[uid]
73
+ ? renderList[uid].name
74
+ : remoteUserDefaultLabel}
63
75
  </Text>
64
- </View>
76
+ ) : (
77
+ <></>
78
+ )}
65
79
  <View
66
80
  style={
67
- isLocal
68
- ? [style.chatBubbleLocal, {backgroundColor: primaryColor}]
69
- : style.chatBubble
81
+ isLocal ? style.chatBubbleLocalView : style.chatBubbleRemoteView
70
82
  }>
71
- <Hyperlink
72
- onPress={handleUrl}
73
- linkStyle={{
74
- color: !isLocal
75
- ? $config.PRIMARY_FONT_COLOR
76
- : $config.SECONDARY_FONT_COLOR,
77
- textDecorationLine: 'underline',
78
- }}>
79
- <Text
80
- style={isLocal ? style.whiteText : style.blackText}
81
- selectable={true}>
82
- {message}
83
- </Text>
84
- </Hyperlink>
83
+ <View
84
+ style={
85
+ isLocal
86
+ ? style.chatBubbleLocalViewLayer2
87
+ : style.chatBubbleRemoteViewLayer2
88
+ }>
89
+ <Hyperlink
90
+ onPress={handleUrl}
91
+ linkStyle={{
92
+ color: $config.FONT_COLOR,
93
+ textDecorationLine: 'underline',
94
+ }}>
95
+ <Text style={style.messageStyle} selectable={true}>
96
+ {message}
97
+ </Text>
98
+ </Hyperlink>
99
+ {/* <Spacer size={5} /> */}
100
+ <Text style={style.timestampStyle}>{time}</Text>
101
+ </View>
85
102
  </View>
86
- </View>
103
+ </>
87
104
  );
88
105
  };
89
106
 
90
107
  const style = StyleSheet.create({
91
- full: {
92
- flex: 1,
93
- },
94
- chatSenderViewLocal: {
95
- // flex: 2,
96
- marginVertical: 2,
97
- flexDirection: 'row',
98
- marginRight: 15,
99
- // marginLeft: 30,
100
- justifyContent: 'flex-end',
101
- },
102
- chatSenderView: {
103
- // flex: 2,
104
- marginVertical: 2,
105
- flexDirection: 'row',
106
- marginRight: 30,
107
- marginLeft: 15,
108
+ remoteUsernameStyle: {
109
+ fontFamily: ThemeConfig.FontFamily.sansPro,
110
+ fontWeight: '600',
111
+ fontSize: ThemeConfig.FontSize.small,
112
+ textAlign: 'left',
113
+ color: $config.FONT_COLOR + ThemeConfig.EmphasisPlus.medium,
114
+ alignSelf: 'flex-start',
115
+ marginTop: 20,
116
+ marginBottom: 8,
117
+ marginHorizontal: 20,
108
118
  },
109
- timestampText: {
110
- color: $config.PRIMARY_FONT_COLOR + '60',
111
- fontWeight: '500',
112
- fontSize: 12,
113
- flex: 1,
119
+ localUsernameStyle: {
120
+ fontFamily: ThemeConfig.FontFamily.sansPro,
121
+ fontWeight: '600',
122
+ fontSize: ThemeConfig.FontSize.small,
114
123
  textAlign: 'left',
124
+ color: $config.FONT_COLOR + ThemeConfig.EmphasisPlus.medium,
125
+ alignSelf: 'flex-end',
126
+ marginTop: 20,
127
+ marginBottom: 8,
128
+ marginHorizontal: 20,
115
129
  },
116
- timestampTextLocal: {
117
- color: $config.PRIMARY_FONT_COLOR + '60',
118
- fontWeight: '500',
119
- fontSize: 12,
120
- flex: 1,
130
+ timestampStyle: {
131
+ // position: 'absolute',
132
+ // bottom: 0,
133
+ // right: 12,
134
+ fontFamily: ThemeConfig.FontFamily.sansPro,
135
+ fontWeight: '400',
136
+ fontSize: ThemeConfig.FontSize.tiny,
121
137
  textAlign: 'right',
138
+ color: $config.FONT_COLOR + ThemeConfig.EmphasisPlus.disabled,
139
+ marginTop: 4,
140
+ marginBottom: 6,
122
141
  },
123
- chatBubble: {
124
- backgroundColor: $config.PRIMARY_FONT_COLOR + '20',
125
- flex: 1,
126
- // width: 'max-content',
142
+ chatBubbleRemoteView: {
143
+ backgroundColor: $config.CARD_LAYER_2_COLOR,
144
+ minWidth: '30%',
127
145
  maxWidth: '80%',
128
146
  alignSelf: 'flex-start',
129
- display: 'flex',
130
- marginVertical: 5,
131
- padding: 8,
132
- marginRight: 30,
133
- marginLeft: 15,
134
- borderRadius: 10,
147
+ marginVertical: 2,
148
+ marginHorizontal: 20,
149
+ borderBottomLeftRadius: 12,
150
+ borderBottomRightRadius: 12,
151
+ borderTopLeftRadius: 0,
152
+ borderTopRightRadius: 12,
153
+ },
154
+ chatBubbleRemoteViewLayer2: {
155
+ backgroundColor: 'transparent',
156
+ // width: '100%',
157
+ // height: '100%',
158
+ paddingVertical: 8,
159
+ paddingHorizontal: 12,
160
+ borderBottomLeftRadius: 12,
161
+ borderBottomRightRadius: 12,
162
+ borderTopLeftRadius: 12,
163
+ borderTopRightRadius: 0,
135
164
  },
136
- chatBubbleLocal: {
137
- backgroundColor: $config.PRIMARY_COLOR,
165
+ chatBubbleLocalViewLayer2: {
166
+ //width: '100%',
167
+ //height: '100%',
168
+ paddingVertical: 8,
169
+ paddingHorizontal: 12,
170
+ borderBottomLeftRadius: 12,
171
+ borderBottomRightRadius: 12,
172
+ borderTopLeftRadius: 12,
173
+ borderTopRightRadius: 0,
174
+ backgroundColor:
175
+ $config.PRIMARY_ACTION_BRAND_COLOR + hexadecimalTransparency['10%'],
176
+ },
177
+ chatBubbleLocalView: {
178
+ backgroundColor:
179
+ $config.CARD_LAYER_5_COLOR + hexadecimalTransparency['20%'],
180
+ minWidth: '30%',
138
181
  maxWidth: '80%',
139
- flex: 1,
140
- display: 'flex',
141
182
  alignSelf: 'flex-end',
142
- marginVertical: 5,
143
- padding: 8,
144
- marginRight: 15,
145
- marginLeft: 30,
146
- borderRadius: 10,
147
- },
148
- whiteText: {
149
- color: $config.SECONDARY_FONT_COLOR,
150
- fontWeight: '500',
183
+ marginVertical: 2,
184
+ marginHorizontal: 20,
185
+ borderBottomLeftRadius: 12,
186
+ borderBottomRightRadius: 12,
187
+ borderTopLeftRadius: 12,
188
+ borderTopRightRadius: 0,
151
189
  },
152
- blackText: {
153
- color: $config.PRIMARY_FONT_COLOR,
154
- opacity: 1,
155
- fontWeight: '500',
190
+ messageStyle: {
191
+ fontFamily: ThemeConfig.FontFamily.sansPro,
192
+ fontWeight: '400',
193
+ fontSize: ThemeConfig.FontSize.small,
194
+ lineHeight: ThemeConfig.FontSize.small * 1.4,
195
+ color: $config.FONT_COLOR,
156
196
  },
157
197
  });
158
198