agora-appbuilder-core 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/template/.bundle/config +2 -0
- package/template/Gemfile +4 -0
- package/template/Gulpfile.js +29 -29
- package/template/_eslintrc.js +3 -3
- package/template/_gitignore +12 -11
- package/template/_package-lock.json +28491 -23647
- package/template/_prettierrc.js +2 -2
- package/template/agora-rn-uikit/.eslintrc.js +5 -0
- package/template/agora-rn-uikit/package.json +14 -14
- package/template/agora-rn-uikit/src/AgoraUIKit.tsx +6 -6
- package/template/agora-rn-uikit/src/Contexts/ContentContext.tsx +10 -0
- package/template/agora-rn-uikit/src/Contexts/DispatchContext.tsx +22 -0
- package/template/agora-rn-uikit/src/Contexts/LocalUserContext.tsx +6 -6
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +79 -38
- package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +26 -17
- package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +1 -0
- package/template/agora-rn-uikit/src/Controls/Icons.ts +45 -0
- package/template/agora-rn-uikit/src/Controls/Local/EndCall.tsx +6 -4
- package/template/agora-rn-uikit/src/Controls/Local/FullScreen.tsx +3 -1
- package/template/agora-rn-uikit/src/Controls/Local/LocalAudioMute.tsx +5 -2
- package/template/agora-rn-uikit/src/Controls/Local/LocalVideoMute.tsx +5 -2
- package/template/agora-rn-uikit/src/Controls/Local/Recording.tsx +0 -2
- package/template/agora-rn-uikit/src/Controls/Local/SwitchCamera.tsx +7 -6
- package/template/agora-rn-uikit/src/Controls/LocalControls.tsx +5 -5
- package/template/agora-rn-uikit/src/Controls/Remote/RemoteAudioMute.tsx +5 -4
- package/template/agora-rn-uikit/src/Controls/Remote/RemoteSwap.tsx +3 -1
- package/template/agora-rn-uikit/src/Controls/Remote/RemoteVideoMute.tsx +5 -4
- package/template/agora-rn-uikit/src/Controls/RemoteControls.tsx +2 -2
- package/template/agora-rn-uikit/src/Reducer/ActiveSpeaker.ts +30 -0
- package/template/agora-rn-uikit/src/Reducer/LocalMuteAudio.ts +8 -7
- package/template/agora-rn-uikit/src/Reducer/LocalMuteVideo.ts +8 -7
- package/template/agora-rn-uikit/src/Reducer/LocalPermissionState.ts +6 -7
- package/template/agora-rn-uikit/src/Reducer/RemoteAudioStateChanged.ts +7 -8
- package/template/agora-rn-uikit/src/Reducer/RemoteVideoStateChanged.ts +9 -9
- package/template/agora-rn-uikit/src/Reducer/UpdateDualStreamMode.ts +7 -8
- package/template/agora-rn-uikit/src/Reducer/UserJoined.ts +14 -13
- package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteAudio.ts +6 -7
- package/template/agora-rn-uikit/src/Reducer/UserMuteRemoteVideo.ts +6 -7
- package/template/agora-rn-uikit/src/Reducer/UserOffline.ts +5 -6
- package/template/agora-rn-uikit/src/Reducer/UserPin.ts +20 -3
- package/template/agora-rn-uikit/src/Reducer/UserSecondaryPin.ts +23 -0
- package/template/agora-rn-uikit/src/Reducer/index.ts +2 -1
- package/template/agora-rn-uikit/src/Rtc/Create.tsx +138 -100
- package/template/agora-rn-uikit/src/Rtc/Join.tsx +55 -28
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +177 -77
- package/template/agora-rn-uikit/src/Utils/isBotUser.ts +15 -0
- package/template/agora-rn-uikit/src/Utils/quality.tsx +8 -0
- package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +56 -12
- package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +47 -17
- package/template/agora-rn-uikit/src/Views/MinVideoView.tsx +19 -11
- package/template/agora-rn-uikit/src/index.ts +15 -9
- package/template/android/app/build.gradle +59 -156
- package/template/android/app/src/debug/AndroidManifest.xml +6 -1
- package/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java +7 -4
- package/template/android/app/src/main/AndroidManifest.xml +6 -19
- package/template/android/app/src/main/assets/fonts/icomoon.ttf +0 -0
- package/template/android/app/src/main/java/com/helloworld/MainActivity.java +17 -0
- package/template/android/app/src/main/java/com/helloworld/MainApplication.java +22 -36
- package/template/android/app/src/main/java/com/helloworld/SSLPinningFactory.java +30 -0
- package/template/android/app/src/main/res/values/strings.xml +3 -0
- package/template/android/app/src/release/java/com/helloworld/ReactNativeFlipper.java +20 -0
- package/template/android/build.gradle +19 -33
- package/template/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/template/android/gradle/wrapper/gradle-wrapper.properties +3 -2
- package/template/android/gradle.properties +18 -4
- package/template/android/gradlew +165 -104
- package/template/android/gradlew.bat +12 -23
- package/template/android/settings.gradle +1 -0
- package/template/bridge/rtc/webNg/RtcEngine.ts +200 -70
- package/template/bridge/rtc/webNg/{SurfaceView.tsx → RtcSurfaceView.tsx} +20 -26
- package/template/bridge/rtc/webNg/Types.ts +20 -5
- package/template/bridge/rtc/webNg/index.ts +81 -14
- package/template/bridge/rtm/web/index.ts +5 -3
- package/template/configTransform.js +16 -1
- package/template/customization-api/action-library.ts +4 -16
- package/template/customization-api/app-state.ts +15 -8
- package/template/customization-api/customEvents.ts +7 -2
- package/template/customization-api/customize.ts +1 -1
- package/template/customization-api/index.ts +4 -0
- package/template/customization-api/sub-components.ts +17 -16
- package/template/customization-api/temp.ts +52 -0
- package/template/customization-api/typeDefinition.ts +34 -46
- package/template/customization-api/types.ts +26 -0
- package/template/customization-api/utils.ts +4 -0
- package/template/customization-implementation/createHook.ts +24 -6
- package/template/customization-implementation/index.ts +1 -2
- package/template/customization-implementation/useCustomization.tsx +5 -7
- package/template/defaultConfig.js +72 -0
- package/template/global.d.ts +14 -1
- package/template/index.js +1 -4
- package/template/index.web.js +0 -5
- package/template/index.wsdk.tsx +1 -12
- package/template/ios/.xcode.env +11 -0
- package/template/ios/HelloWorld/AppDelegate.h +2 -4
- package/template/ios/HelloWorld/AppDelegate.mm +64 -0
- package/template/ios/HelloWorld/HelloWorldDebug.entitlements +10 -0
- package/template/ios/HelloWorld/Info.plist +8 -2
- package/template/ios/HelloWorld/main.m +2 -1
- package/template/ios/HelloWorld.xcodeproj/project.pbxproj +533 -17
- package/template/ios/HelloWorld.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/template/ios/HelloWorld.xcworkspace/contents.xcworkspacedata +10 -0
- package/template/ios/HelloWorld.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/template/ios/HelloWorldTests/HelloWorldTests.m +14 -13
- package/template/ios/HelloWorldTests/Info.plist +2 -2
- package/template/ios/Podfile +54 -20
- package/template/ios/Podfile.lock +809 -0
- package/template/ios/ScreenSharing/Info.plist +15 -0
- package/template/ios/ScreenSharing/SampleHandler.h +9 -0
- package/template/ios/ScreenSharing/SampleHandler.m +70 -0
- package/template/jest.config.js +4 -0
- package/template/metro.config.js +7 -32
- package/template/package.json +53 -39
- package/template/react-native-toast-message/index.d.ts +3 -1
- package/template/react-native-toast-message/index.js +1 -0
- package/template/react-native-toast-message/src/components/base/index.js +20 -32
- package/template/react-native-toast-message/src/components/base/styles.js +18 -21
- package/template/react-native-toast-message/src/components/checkbox.js +24 -19
- package/template/react-native-toast-message/src/index.js +3 -1
- package/template/react-native-toast-message/src/index.sdk.tsx +4 -1
- package/template/src/App.tsx +53 -69
- package/template/src/AppRoutes.tsx +90 -0
- package/template/src/AppWrapper.tsx +42 -25
- package/template/src/SDKAppWrapper.tsx +90 -57
- package/template/src/app-state/useLocalUserInfo.ts +3 -3
- package/template/src/app-state/useNoiseSupression.native.tsx +67 -0
- package/template/src/app-state/useNoiseSupression.tsx +107 -0
- package/template/src/app-state/useVideoQuality.tsx +39 -0
- package/template/src/assets/font-styles.css +175 -3
- package/template/src/assets/fonts/icomoon.ttf +0 -0
- package/template/src/assets/selection.json +1 -1
- package/template/src/atoms/ActionMenu.tsx +50 -11
- package/template/src/atoms/Avatar.tsx +51 -0
- package/template/src/atoms/Card.tsx +21 -8
- package/template/src/atoms/Carousel.native.tsx +105 -0
- package/template/src/atoms/Carousel.tsx +103 -0
- package/template/src/atoms/Checkbox.tsx +98 -0
- package/template/src/atoms/CircularProgress.tsx +0 -1
- package/template/src/atoms/ClipboardIconButton.tsx +91 -0
- package/template/src/atoms/CustomIcon.tsx +46 -0
- package/template/src/atoms/DropDownMulti.tsx +349 -0
- package/template/src/atoms/Dropdown.tsx +3 -3
- package/template/src/atoms/IconButton.tsx +52 -9
- package/template/src/atoms/ImageIcon.tsx +18 -5
- package/template/src/atoms/InlineNotification.tsx +81 -0
- package/template/src/atoms/InviteInfo.tsx +4 -4
- package/template/src/atoms/MeetingLink.tsx +160 -0
- package/template/src/atoms/ParticipantsCount.tsx +20 -8
- package/template/src/atoms/Popup.tsx +49 -27
- package/template/src/atoms/PrimaryButton.tsx +19 -5
- package/template/src/atoms/RecordingInfo.tsx +8 -5
- package/template/src/atoms/SecondaryButton.tsx +2 -0
- package/template/src/atoms/Spacer.tsx +1 -0
- package/template/src/atoms/TertiaryButton.tsx +35 -5
- package/template/src/atoms/TextInput.tsx +2 -1
- package/template/src/atoms/Toolbar.tsx +102 -0
- package/template/src/atoms/ToolbarItem.tsx +85 -0
- package/template/src/atoms/ToolbarMenu.tsx +40 -0
- package/template/src/atoms/ToolbarMenuItem.tsx +104 -0
- package/template/src/atoms/ToolbarPreset.tsx +71 -0
- package/template/src/atoms/Tooltip.tsx +30 -13
- package/template/src/atoms/pagination/Pagination.tsx +127 -0
- package/template/src/atoms/pagination/usePagination.tsx +88 -0
- package/template/src/auth/AuthProvider.tsx +500 -0
- package/template/src/auth/AuthRoute.tsx +94 -0
- package/template/src/auth/IDPAuth.electron.tsx +31 -0
- package/template/src/auth/IDPAuth.tsx +67 -0
- package/template/src/auth/IDPLogoutComponent.tsx +158 -0
- package/template/src/auth/UserCancelPopup.tsx +115 -0
- package/template/src/auth/config.ts +52 -0
- package/template/src/auth/openIDPURL.electron.tsx +39 -0
- package/template/src/auth/openIDPURL.native.tsx +51 -0
- package/template/src/auth/openIDPURL.tsx +20 -0
- package/template/src/auth/useIDPAuth.electron.tsx +65 -0
- package/template/src/auth/useIDPAuth.native.tsx +70 -0
- package/template/src/auth/useIDPAuth.tsx +63 -0
- package/template/src/auth/useTokenAuth.tsx +194 -0
- package/template/src/components/Chat.tsx +92 -72
- package/template/src/components/ChatContext.ts +2 -0
- package/template/src/components/ColorConfigure.tsx +0 -1
- package/template/src/components/CommonStyles.ts +9 -2
- package/template/src/components/Controls.tsx +914 -182
- package/template/src/components/Controls1.native.tsx +9 -5
- package/template/src/components/DeviceConfigure.native.tsx +2 -2
- package/template/src/components/DeviceConfigure.tsx +400 -149
- package/template/src/components/DeviceContext.tsx +2 -0
- package/template/src/components/EventsConfigure.tsx +722 -82
- package/template/src/components/GraphQLProvider.tsx +82 -39
- package/template/src/components/GridVideo.tsx +30 -16
- package/template/src/components/HostControlView.tsx +11 -14
- package/template/src/components/JoinPhrase.tsx +0 -1
- package/template/src/components/Leftbar.tsx +110 -0
- package/template/src/components/Navbar.tsx +305 -147
- package/template/src/components/NavbarMobile.tsx +119 -0
- package/template/src/components/Navigation.native.tsx +1 -15
- package/template/src/components/{Settings.native.tsx → Navigation.sdk.tsx} +17 -6
- package/template/src/components/NetworkQualityContext.tsx +12 -6
- package/template/src/components/ParticipantsView.tsx +63 -56
- package/template/src/components/PinnedVideo.tsx +191 -119
- package/template/src/components/Precall.native.tsx +177 -72
- package/template/src/components/Precall.tsx +247 -78
- package/template/src/components/RTMConfigure.tsx +205 -67
- package/template/src/components/Rightbar.tsx +112 -0
- package/template/src/components/Router.electron.ts +1 -0
- package/template/src/components/Router.native.ts +1 -0
- package/template/src/components/Router.sdk.ts +1 -0
- package/template/src/components/Router.ts +1 -0
- package/template/src/components/SdkApiContext.tsx +313 -0
- package/template/src/components/SdkMuteToggleListener.tsx +88 -0
- package/template/src/components/SessionContext.tsx +0 -1
- package/template/src/components/Settings.tsx +33 -4
- package/template/src/components/SettingsView.tsx +44 -9
- package/template/src/components/Share.tsx +152 -74
- package/template/src/components/StorageContext.tsx +23 -6
- package/template/src/components/ToastComponent.tsx +10 -1
- package/template/src/components/WhiteboardLayout.tsx +291 -0
- package/template/src/components/chat-messages/useChatMessages.tsx +454 -239
- package/template/src/components/chat-ui/{useChatUIControl.tsx → useChatUIControls.tsx} +29 -29
- package/template/src/components/common/Error.tsx +2 -0
- package/template/src/components/common/Logo.tsx +2 -2
- package/template/src/components/contexts/LiveStreamDataContext.tsx +13 -12
- package/template/src/components/contexts/ScreenShareContext.tsx +15 -1
- package/template/src/components/contexts/VideoMeetingDataContext.tsx +6 -6
- package/template/src/components/contexts/WaitingRoomContext.tsx +50 -0
- package/template/src/components/contexts/WhiteboardContext.tsx +54 -54
- package/template/src/components/disable-chat/useDisableChat.tsx +32 -0
- package/template/src/components/livestream/LiveStreamContext.tsx +314 -220
- package/template/src/components/livestream/Types.ts +36 -20
- package/template/src/components/livestream/views/LiveStreamAttendeeLandingTile.tsx +295 -0
- package/template/src/components/livestream/views/LiveStreamControls.tsx +5 -10
- package/template/src/components/meeting-info-invite/MeetingInfo.tsx +82 -0
- package/template/src/components/meeting-info-invite/MeetingInfoCardHeader.tsx +86 -0
- package/template/src/components/meeting-info-invite/MeetingInfoGridTile.tsx +218 -0
- package/template/src/components/meeting-info-invite/MeetingInfoLinks.tsx +122 -0
- package/template/src/components/participants/AllAudienceParticipants.tsx +19 -20
- package/template/src/components/participants/AllHostParticipants.tsx +20 -19
- package/template/src/components/participants/Participant.tsx +45 -16
- package/template/src/components/participants/ParticipantSectionTitle.tsx +5 -2
- package/template/src/components/participants/ScreenshareParticipants.tsx +17 -19
- package/template/src/components/participants/UserActionMenuOptions.tsx +173 -62
- package/template/src/components/participants/WaitingRoomParticipants.tsx +74 -0
- package/template/src/components/popups/InvitePopup.tsx +110 -45
- package/template/src/components/popups/StartScreenSharePopup.native.tsx +182 -0
- package/template/src/components/popups/StartScreenSharePopup.tsx +6 -0
- package/template/src/components/popups/StopRecordingPopup.tsx +11 -5
- package/template/src/components/popups/StopScreenSharePopup.native.tsx +135 -0
- package/template/src/components/popups/StopScreenSharePopup.tsx +6 -0
- package/template/src/components/popups/WhiteboardClearAllPopup.tsx +123 -0
- package/template/src/components/precall/LocalMute.tsx +69 -45
- package/template/src/components/precall/PermissionHelper.tsx +56 -28
- package/template/src/components/precall/PreCallSettings.tsx +1 -0
- package/template/src/components/precall/VideoFallback.tsx +173 -0
- package/template/src/components/precall/VideoPreview.native.tsx +19 -53
- package/template/src/components/precall/VideoPreview.tsx +29 -164
- package/template/src/components/precall/index.tsx +2 -0
- package/template/src/components/precall/joinCallBtn.native.tsx +12 -5
- package/template/src/components/precall/joinCallBtn.tsx +13 -4
- package/template/src/components/precall/joinWaitingRoomBtn.native.tsx +210 -0
- package/template/src/components/precall/joinWaitingRoomBtn.tsx +250 -0
- package/template/src/components/precall/meetingTitle.tsx +37 -11
- package/template/src/components/precall/selectDevice.tsx +5 -5
- package/template/src/components/precall/textInput.tsx +17 -19
- package/template/src/components/precall/usePreCall.tsx +33 -1
- package/template/src/components/recording-bot/RecordingBotRoute.tsx +42 -0
- package/template/src/components/recordings/RecordingsDateTable.tsx +62 -0
- package/template/src/components/recordings/RecordingsModal.tsx +135 -0
- package/template/src/components/recordings/ViewRecordingsModal.tsx +51 -0
- package/template/src/components/recordings/recording-table.tsx +154 -0
- package/template/src/components/recordings/style.ts +183 -0
- package/template/src/components/recordings/utils.ts +80 -0
- package/template/src/components/room-info/useRoomInfo.tsx +128 -0
- package/template/src/components/{meeting-info/useSetMeetingInfo.tsx → room-info/useSetRoomInfo.tsx} +12 -12
- package/template/src/components/useShareLink.tsx +28 -63
- package/template/src/components/useUserPreference.tsx +82 -16
- package/template/src/components/useVideoCall.tsx +93 -1
- package/template/src/components/virtual-background/VBButton.tsx +64 -0
- package/template/src/components/virtual-background/VBCard.native.tsx +282 -0
- package/template/src/components/virtual-background/VBCard.tsx +272 -0
- package/template/src/components/virtual-background/VBPanel.tsx +279 -0
- package/template/src/components/virtual-background/VButils.native.ts +37 -0
- package/template/src/components/virtual-background/VButils.ts +104 -0
- package/template/src/components/virtual-background/VideoPreview.native.tsx +43 -0
- package/template/src/components/virtual-background/VideoPreview.tsx +106 -0
- package/template/src/components/virtual-background/imagePaths.ts +87 -0
- package/template/src/components/virtual-background/images/beachImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/bedroomImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/bookImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/earthImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/index.ts +37 -0
- package/template/src/components/virtual-background/images/lampImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/mountainsImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/office1ImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/officeImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/plantsImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/skyImageBase64.ts +1 -0
- package/template/src/components/virtual-background/images/wallImageBase64.ts +1 -0
- package/template/src/components/virtual-background/useVB.native.tsx +185 -0
- package/template/src/components/virtual-background/useVB.tsx +267 -0
- package/template/src/components/whiteboard/StrokeWidthTool.tsx +137 -0
- package/template/src/components/whiteboard/WhiteboardButton.tsx +93 -0
- package/template/src/components/whiteboard/WhiteboardCanvas.tsx +99 -0
- package/template/src/components/whiteboard/WhiteboardConfigure.native.tsx +148 -0
- package/template/src/components/whiteboard/WhiteboardConfigure.tsx +446 -0
- package/template/src/components/whiteboard/WhiteboardCursor.tsx +152 -0
- package/template/src/components/whiteboard/WhiteboardToolBox.tsx +1246 -0
- package/template/src/components/whiteboard/WhiteboardView.native.tsx +188 -0
- package/template/src/components/whiteboard/WhiteboardView.tsx +81 -0
- package/template/src/components/whiteboard/WhiteboardWidget.tsx +685 -0
- package/template/src/components/whiteboard/WhiteboardWrapper.tsx +38 -0
- package/template/src/language/default-labels/commonLabels.ts +51 -14
- package/template/src/language/default-labels/createScreenLabels.ts +97 -17
- package/template/src/language/default-labels/joinScreenLabels.ts +45 -6
- package/template/src/language/default-labels/precallScreenLabels.ts +149 -25
- package/template/src/language/default-labels/shareLinkScreenLabels.ts +85 -37
- package/template/src/language/default-labels/videoCallScreenLabels.ts +1195 -158
- package/template/src/pages/Create.tsx +136 -106
- package/template/src/pages/Endcall.tsx +2 -2
- package/template/src/pages/Join.tsx +82 -40
- package/template/src/pages/Login.tsx +26 -0
- package/template/src/pages/VideoCall.tsx +329 -127
- package/template/src/pages/video-call/ActionSheet.native.tsx +54 -6
- package/template/src/pages/video-call/ActionSheet.tsx +55 -15
- package/template/src/pages/video-call/ActionSheetContent.tsx +498 -308
- package/template/src/pages/video-call/ActionSheetHandle.tsx +7 -1
- package/template/src/pages/video-call/DefaultLayouts.ts +20 -8
- package/template/src/pages/video-call/NameWithMicIcon.tsx +41 -64
- package/template/src/pages/video-call/PinchableView.tsx +119 -0
- package/template/src/pages/video-call/RenderComponent.tsx +14 -30
- package/template/src/pages/video-call/SidePanelHeader.tsx +227 -29
- package/template/src/pages/video-call/VideoCallMobileView.tsx +231 -89
- package/template/src/pages/video-call/VideoCallScreen.native.tsx +3 -2
- package/template/src/pages/video-call/VideoCallScreen.tsx +233 -84
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +41 -0
- package/template/src/pages/video-call/VideoComponent.tsx +60 -8
- package/template/src/pages/video-call/VideoRenderer.tsx +343 -57
- package/template/src/pages/video-call/VisibilitySensor.tsx +104 -0
- package/template/src/pages/video-call/ZoomableWrapper.native.tsx +34 -0
- package/template/src/pages/video-call/ZoomableWrapper.tsx +5 -0
- package/template/src/pages/video-call/index.ts +42 -8
- package/template/src/rtm/RTMEngine.ts +17 -4
- package/template/src/rtm-events/constants.ts +21 -3
- package/template/src/rtm-events-api/Events.ts +7 -4
- package/template/src/rtm-events-api/LocalEvents.ts +14 -0
- package/template/src/rtm-events-api/types.ts +5 -5
- package/template/src/selection.json +1 -0
- package/template/src/subComponents/ChatBubble.tsx +87 -67
- package/template/src/subComponents/ChatContainer.tsx +70 -49
- package/template/src/subComponents/ChatInput.ios.tsx +32 -85
- package/template/src/subComponents/ChatInput.tsx +31 -80
- package/template/src/subComponents/Checkbox.native.tsx +46 -46
- package/template/src/subComponents/Checkbox.tsx +7 -6
- package/template/src/subComponents/CopyJoinInfo.tsx +31 -11
- package/template/src/subComponents/EndcallPopup.tsx +83 -12
- package/template/src/subComponents/FallbackLogo.tsx +2 -2
- package/template/src/subComponents/LanguageSelector.tsx +34 -30
- package/template/src/subComponents/LayoutIconButton.tsx +34 -17
- package/template/src/subComponents/LayoutIconDropdown.tsx +21 -8
- package/template/src/subComponents/Loading.tsx +60 -0
- package/template/src/subComponents/LocalAudioMute.tsx +87 -34
- package/template/src/subComponents/LocalEndCall.tsx +61 -24
- package/template/src/subComponents/LocalSwitchCamera.tsx +57 -13
- package/template/src/subComponents/LocalVideoMute.tsx +105 -36
- package/template/src/subComponents/LogoutButton.tsx +1 -1
- package/template/src/subComponents/NetworkQualityPill.tsx +22 -38
- package/template/src/subComponents/Recording.tsx +29 -9
- package/template/src/subComponents/RemoteAudioMute.tsx +5 -5
- package/template/src/subComponents/RemoteMutePopup.tsx +55 -14
- package/template/src/subComponents/RemoteVideoMute.tsx +5 -5
- package/template/src/subComponents/RemoveMeetingPopup.tsx +19 -6
- package/template/src/subComponents/RemoveScreensharePopup.tsx +20 -5
- package/template/src/subComponents/ScreenShareNotice.tsx +11 -6
- package/template/src/subComponents/SelectDevice.tsx +103 -34
- package/template/src/subComponents/SelectDeviceSettings.backup.tsx +9 -6
- package/template/src/subComponents/SidePanelButtons.ts +0 -3
- package/template/src/subComponents/SidePanelEnum.tsx +2 -0
- package/template/src/subComponents/SidePanelHeader.tsx +97 -63
- package/template/src/subComponents/ToastConfig.tsx +70 -61
- package/template/src/subComponents/caption/Caption.tsx +132 -0
- package/template/src/subComponents/caption/CaptionContainer.tsx +302 -0
- package/template/src/subComponents/caption/CaptionIcon.tsx +111 -0
- package/template/src/subComponents/caption/CaptionText.tsx +182 -0
- package/template/src/subComponents/caption/DownloadTranscriptBtn.tsx +65 -0
- package/template/src/subComponents/caption/LanguageSelectorPopup.tsx +192 -0
- package/template/src/subComponents/caption/Transcript.tsx +452 -0
- package/template/src/subComponents/caption/TranscriptIcon.tsx +123 -0
- package/template/src/subComponents/caption/TranscriptText.tsx +98 -0
- package/template/src/subComponents/caption/index.ts +3 -0
- package/template/src/subComponents/caption/proto/ptoto.js +91 -0
- package/template/src/subComponents/caption/proto/test.proto +23 -0
- package/template/src/subComponents/caption/useCaption.tsx +123 -0
- package/template/src/subComponents/caption/useCaptionWidth.ts +27 -0
- package/template/src/subComponents/caption/useSTTAPI.tsx +179 -0
- package/template/src/subComponents/caption/useStreamMessageUtils.native.ts +211 -0
- package/template/src/subComponents/caption/useStreamMessageUtils.ts +235 -0
- package/template/src/subComponents/caption/useTranscriptDownload.native.ts +63 -0
- package/template/src/subComponents/caption/useTranscriptDownload.ts +52 -0
- package/template/src/subComponents/caption/utils.ts +126 -0
- package/template/src/subComponents/chat/ChatParticipants.tsx +60 -24
- package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +2 -2
- package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +19 -20
- package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +66 -35
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +3 -2
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +10 -6
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +28 -19
- package/template/src/subComponents/recording/useIsRecordingBot.tsx +38 -0
- package/template/src/subComponents/recording/useRecording.tsx +251 -138
- package/template/src/subComponents/recording/useRecordingLayoutQuery.tsx +0 -1
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +39 -15
- package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +275 -69
- package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +193 -124
- package/template/src/subComponents/screenshare/useScreenshare.tsx +2 -0
- package/template/src/subComponents/waiting-rooms/WaitingRoomControls.tsx +85 -0
- package/template/src/subComponents/waiting-rooms/useWaitingRoomAPI.ts +75 -0
- package/template/src/theme/index.ts +13 -0
- package/template/src/utils/SdkEvents.ts +37 -14
- package/template/src/utils/SdkMethodEvents.ts +101 -0
- package/template/src/utils/axiomLogger.ts +117 -0
- package/template/src/utils/book.jpg +0 -0
- package/template/src/utils/common.tsx +118 -6
- package/template/src/utils/constants.ts +4 -0
- package/template/src/utils/getCustomRoute.ts +7 -0
- package/template/src/utils/index.tsx +34 -0
- package/template/src/utils/useActionSheet.tsx +50 -0
- package/template/src/utils/useActiveSpeaker.ts +38 -0
- package/template/src/utils/useAppState.ts +17 -0
- package/template/src/utils/useAsyncEffect.ts +138 -0
- package/template/src/utils/{useCreateMeeting.ts → useCreateRoom.ts} +27 -26
- package/template/src/utils/useEndCall.ts +65 -0
- package/template/src/utils/useFindActiveSpeaker.native.ts +4 -0
- package/template/src/utils/useFindActiveSpeaker.ts +335 -0
- package/template/src/utils/useGetMeetingPhrase.ts +10 -10
- package/template/src/utils/useIsAudioEnabled.ts +3 -3
- package/template/src/utils/useIsLocalUserSpeaking.native.ts +4 -0
- package/template/src/utils/useIsLocalUserSpeaking.ts +103 -0
- package/template/src/utils/useIsPSTN.ts +3 -3
- package/template/src/utils/useIsVideoEnabled.ts +3 -3
- package/template/src/utils/useJoinRoom.ts +199 -0
- package/template/src/utils/{useIsActiveSpeaker.ts → useLocalAudio.ts} +23 -12
- package/template/src/{components/OAuth.tsx → utils/useMenu.tsx} +16 -15
- package/template/src/utils/useModal.tsx +8 -0
- package/template/src/utils/useMutePSTN.ts +2 -2
- package/template/src/utils/useMuteToggleLocal.ts +121 -96
- package/template/src/utils/useRemoteEndCall.ts +4 -4
- package/template/src/utils/useRemoteEndScreenshare.ts +4 -4
- package/template/src/utils/useRemoteMute.ts +7 -7
- package/template/src/utils/useRemoteRequest.ts +7 -7
- package/template/src/utils/useSearchParams.tsx +28 -0
- package/template/src/utils/useString.ts +13 -3
- package/template/src/utils/useSwitchCamera.native.tsx +25 -0
- package/template/src/{subComponents/screenshare/ScreenshareButton.native.tsx → utils/useSwitchCamera.tsx} +12 -11
- package/template/src/utils/useToolbar.tsx +59 -0
- package/template/src/wasms/agora-virtual-background.wasm +0 -0
- package/template/static.d.ts +42 -0
- package/template/tsconfig_rsdk_index.json +3 -3
- package/template/tsconfig_wsdk_index.json +1 -1
- package/template/web/index.html +20 -0
- package/template/webpack.commons.js +21 -10
- package/template/webpack.rsdk.config.js +1 -2
- package/template/webpack.web.config.js +7 -3
- package/template/_buckconfig +0 -6
- package/template/_gitattributes +0 -1
- package/template/agora-rn-uikit/src/Contexts/RenderContext.tsx +0 -10
- package/template/agora-rn-uikit/src/Reducer/ActiveSpeakerDetected.ts +0 -11
- package/template/android/app/_BUCK +0 -55
- package/template/android/app/build_defs.bzl +0 -19
- package/template/bridge/rtc/webNg/LocalView.tsx +0 -20
- package/template/ios/HelloWorld/AppDelegate.m +0 -74
- package/template/src/components/OAuth.electron.tsx +0 -41
- package/template/src/components/OAuth.native.tsx +0 -55
- package/template/src/components/OAuthConfig.ts +0 -77
- package/template/src/components/StoreToken.tsx +0 -39
- package/template/src/components/meeting-info/useMeetingInfo.tsx +0 -70
- package/template/src/pages/video-call/CustomUserContextHolder.tsx +0 -20
- package/template/src/utils/useButtonTemplate.tsx +0 -44
- package/template/src/utils/useJoinMeeting.ts +0 -132
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {useCaption} from './useCaption';
|
|
3
|
+
import protoRoot from './proto/ptoto';
|
|
4
|
+
|
|
5
|
+
type StreamMessageCallback = (args: [number, Uint8Array]) => void;
|
|
6
|
+
type FinalListType = {
|
|
7
|
+
[key: string]: string[];
|
|
8
|
+
};
|
|
9
|
+
type TranscriptItem = {
|
|
10
|
+
uid: string;
|
|
11
|
+
time: number;
|
|
12
|
+
text: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const useStreamMessageUtils = (): {
|
|
16
|
+
streamMessageCallback: StreamMessageCallback;
|
|
17
|
+
} => {
|
|
18
|
+
const {
|
|
19
|
+
setCaptionObj,
|
|
20
|
+
setMeetingTranscript,
|
|
21
|
+
activeSpeakerRef,
|
|
22
|
+
prevSpeakerRef,
|
|
23
|
+
} = useCaption();
|
|
24
|
+
|
|
25
|
+
let captionStartTime: number = 0;
|
|
26
|
+
const finalList: FinalListType = {};
|
|
27
|
+
const finalTranscriptList: FinalListType = {};
|
|
28
|
+
|
|
29
|
+
const streamMessageCallback: StreamMessageCallback = args => {
|
|
30
|
+
/* uid - bot which sends stream message in channel
|
|
31
|
+
payload - stream message in Uint8Array format
|
|
32
|
+
*/
|
|
33
|
+
const [uid, payload] = args;
|
|
34
|
+
let nonFinalText = ''; // holds intermediate results
|
|
35
|
+
let finalText = ''; // holds final strings
|
|
36
|
+
let currentFinalText = ''; // holds current caption
|
|
37
|
+
let isInterjecting = false;
|
|
38
|
+
|
|
39
|
+
const textstream = protoRoot
|
|
40
|
+
.lookupType('Text')
|
|
41
|
+
.decode(payload as Uint8Array) as any;
|
|
42
|
+
|
|
43
|
+
console.log('STT - Parsed Textstream : ', textstream);
|
|
44
|
+
|
|
45
|
+
// Identifing Current & Prev Speakers for the Captions
|
|
46
|
+
/*
|
|
47
|
+
t0 A : Hi All!
|
|
48
|
+
t1 B : Hi A
|
|
49
|
+
t2 A : Hi B
|
|
50
|
+
t3 C : What's Plan
|
|
51
|
+
t4 B : Goal Planning
|
|
52
|
+
t5 C : Yes Agree
|
|
53
|
+
|
|
54
|
+
Screen:
|
|
55
|
+
Time : t0 | t1 | t2 | t3 | t4 | t5
|
|
56
|
+
Prev Speaker : | A:Hi All! | B: Hi A | A: Hi B | C: What's Plan | B: Goal Planning
|
|
57
|
+
Active Speaker : A:Hi All! | B: Hi A | A: Hi B | C: What's Plan | B: Goal Planning | C: Yes Agree
|
|
58
|
+
Clearing Required: A B A C
|
|
59
|
+
|
|
60
|
+
Logic:
|
|
61
|
+
time : t0 t1 t2 t3 t4 t5
|
|
62
|
+
textstream.uid : A B A C B C
|
|
63
|
+
(B)prevSpeaker : - - A B A C
|
|
64
|
+
(B)activeSpeake: - A B A C B
|
|
65
|
+
Prev Data clear: - - A B A C
|
|
66
|
+
################## CHANGE ######################
|
|
67
|
+
(A)prevSpeaker : - A B A C B
|
|
68
|
+
(A)activeSpeake: A B A C B C
|
|
69
|
+
|
|
70
|
+
Clear when textStream.uid == prevSpeakerRef.current
|
|
71
|
+
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
const finalWord = textstream.words.filter(word => word.isFinal === true);
|
|
75
|
+
// when we only get final word for the previous speaker then don't flip previous speaker as active but update in place.
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
textstream.uid !== activeSpeakerRef.current &&
|
|
79
|
+
!(finalWord.length > 0 && textstream.uid === prevSpeakerRef.current)
|
|
80
|
+
) {
|
|
81
|
+
// we have a speaker change so clear the context for prev speaker
|
|
82
|
+
if (prevSpeakerRef.current !== '') {
|
|
83
|
+
finalList[prevSpeakerRef.current] = [];
|
|
84
|
+
isInterjecting = true;
|
|
85
|
+
}
|
|
86
|
+
prevSpeakerRef.current = activeSpeakerRef.current;
|
|
87
|
+
activeSpeakerRef.current = textstream.uid;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* creating [] for each user to store their complete transcripts
|
|
91
|
+
initializing captions state for cuurent speaker
|
|
92
|
+
ex: {282190954:[]}
|
|
93
|
+
*/
|
|
94
|
+
if (!finalList[textstream.uid]) {
|
|
95
|
+
finalList[textstream.uid] = [];
|
|
96
|
+
finalTranscriptList[textstream.uid] = [];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const words = textstream.words; //[Word,Word]
|
|
100
|
+
|
|
101
|
+
/* categorize words into final & nonFinal objects per uid
|
|
102
|
+
Final Word Ex : {
|
|
103
|
+
"text": "Hello, are you doing?",
|
|
104
|
+
"durationMs": 960,
|
|
105
|
+
"isFinal": true,
|
|
106
|
+
"confidence": 0.8549408316612244
|
|
107
|
+
}
|
|
108
|
+
*/
|
|
109
|
+
for (const word of words) {
|
|
110
|
+
if (word.isFinal) {
|
|
111
|
+
finalText = finalText + word.text;
|
|
112
|
+
} else {
|
|
113
|
+
nonFinalText =
|
|
114
|
+
word.text !== '.' ? nonFinalText + word.text : nonFinalText;
|
|
115
|
+
if (!captionStartTime) {
|
|
116
|
+
captionStartTime = performance.now();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (finalText) {
|
|
121
|
+
finalList[textstream.uid].push(finalText);
|
|
122
|
+
finalTranscriptList[textstream.uid].push(finalText);
|
|
123
|
+
currentFinalText = finalText;
|
|
124
|
+
// log info to show measure the duration of passes in which a sentence gets finalized
|
|
125
|
+
const duration = performance.now() - captionStartTime;
|
|
126
|
+
console.log(
|
|
127
|
+
`stt-Time taken to finalize caption ${currentFinalText}: ${duration}ms`,
|
|
128
|
+
);
|
|
129
|
+
captionStartTime = null; // Reset start time
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Updating Meeting Transcript */
|
|
133
|
+
if (currentFinalText.length) {
|
|
134
|
+
setMeetingTranscript(prevTranscript => {
|
|
135
|
+
const lastTranscriptIndex = prevTranscript.length - 1;
|
|
136
|
+
const lastTranscript =
|
|
137
|
+
lastTranscriptIndex >= 0 ? prevTranscript[lastTranscriptIndex] : null;
|
|
138
|
+
|
|
139
|
+
/*
|
|
140
|
+
checking if the last item transcript matches with current uid
|
|
141
|
+
If yes then updating the last transcript msg with current text
|
|
142
|
+
If no then adding a new entry in the transcript
|
|
143
|
+
*/
|
|
144
|
+
if (lastTranscript && lastTranscript.uid === textstream.uid) {
|
|
145
|
+
const updatedTranscript = {
|
|
146
|
+
...lastTranscript,
|
|
147
|
+
//text: lastTranscript.text + ' ' + currentFinalText, // missing few updates with reading prev values
|
|
148
|
+
text: finalTranscriptList[textstream.uid].join(' '),
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
return [
|
|
152
|
+
...prevTranscript.slice(0, lastTranscriptIndex),
|
|
153
|
+
updatedTranscript,
|
|
154
|
+
];
|
|
155
|
+
} else {
|
|
156
|
+
const isLangUpdate =
|
|
157
|
+
lastTranscript?.uid.toString().indexOf('langUpdate') > -1;
|
|
158
|
+
|
|
159
|
+
finalTranscriptList[textstream.uid] = [currentFinalText];
|
|
160
|
+
|
|
161
|
+
return [
|
|
162
|
+
...prevTranscript,
|
|
163
|
+
{
|
|
164
|
+
uid: textstream.uid,
|
|
165
|
+
time: new Date().getTime(),
|
|
166
|
+
text: currentFinalText,
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/*
|
|
174
|
+
Previous final words of the uid are prepended and
|
|
175
|
+
then current non final words so that context of speech is not lost
|
|
176
|
+
*/
|
|
177
|
+
const existingStringBuffer = isInterjecting
|
|
178
|
+
? ''
|
|
179
|
+
: finalList[textstream.uid]?.join(' ');
|
|
180
|
+
const latestString = nonFinalText;
|
|
181
|
+
const captionText =
|
|
182
|
+
existingStringBuffer.length > 0
|
|
183
|
+
? existingStringBuffer + ' ' + latestString
|
|
184
|
+
: latestString;
|
|
185
|
+
|
|
186
|
+
// updating the captions
|
|
187
|
+
captionText &&
|
|
188
|
+
setCaptionObj(prevState => {
|
|
189
|
+
return {
|
|
190
|
+
...prevState,
|
|
191
|
+
[textstream.uid]: {
|
|
192
|
+
text: captionText,
|
|
193
|
+
lastUpdated: new Date().getTime(),
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
console.group('STT-logs');
|
|
199
|
+
console.log('Recived uid =>', textstream.uid);
|
|
200
|
+
console.log('PrevSpeaker uid =>', prevSpeakerRef.current);
|
|
201
|
+
console.log('ActiveSpeaker uid=>', activeSpeakerRef.current);
|
|
202
|
+
console.log('final List =>', finalList);
|
|
203
|
+
console.groupEnd();
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
streamMessageCallback,
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export default useStreamMessageUtils;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {useCaption} from './useCaption';
|
|
3
|
+
import protoRoot from './proto/ptoto';
|
|
4
|
+
import PQueue from 'p-queue';
|
|
5
|
+
|
|
6
|
+
type StreamMessageCallback = (args: [number, Uint8Array]) => void;
|
|
7
|
+
type FinalListType = {
|
|
8
|
+
[key: string]: string[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const useStreamMessageUtils = (): {
|
|
12
|
+
streamMessageCallback: StreamMessageCallback;
|
|
13
|
+
} => {
|
|
14
|
+
const {
|
|
15
|
+
setCaptionObj,
|
|
16
|
+
setMeetingTranscript,
|
|
17
|
+
activeSpeakerRef,
|
|
18
|
+
prevSpeakerRef,
|
|
19
|
+
} = useCaption();
|
|
20
|
+
|
|
21
|
+
let captionStartTime: number = 0;
|
|
22
|
+
const finalList: FinalListType = {};
|
|
23
|
+
const finalTranscriptList: FinalListType = {};
|
|
24
|
+
const queue = new PQueue({concurrency: 1});
|
|
25
|
+
let counter = 0;
|
|
26
|
+
let lastOfftime = 0;
|
|
27
|
+
|
|
28
|
+
const streamMessageCallback: StreamMessageCallback = args => {
|
|
29
|
+
const queueCallback = (args1: [number, Uint8Array]) => {
|
|
30
|
+
/* uid - bot which sends stream message in channel
|
|
31
|
+
payload - stream message in Uint8Array format
|
|
32
|
+
*/
|
|
33
|
+
const [, payload] = args1;
|
|
34
|
+
let nonFinalText = ''; // holds intermediate results
|
|
35
|
+
let finalText = ''; // holds final strings
|
|
36
|
+
let currentFinalText = ''; // holds current caption
|
|
37
|
+
let isInterjecting = false;
|
|
38
|
+
|
|
39
|
+
const textstream = protoRoot
|
|
40
|
+
.lookupType('Text')
|
|
41
|
+
.decode(payload as Uint8Array) as any;
|
|
42
|
+
|
|
43
|
+
//console.log('STT - Parsed Textstream : ', textstream);
|
|
44
|
+
// console.log(
|
|
45
|
+
// `STT-callback(${++counter}): %c${textstream.uid} %c${textstream.words
|
|
46
|
+
// .map(word =>
|
|
47
|
+
// word.text === '.'
|
|
48
|
+
// ? ''
|
|
49
|
+
// : word.isFinal
|
|
50
|
+
// ? word.text + ' --Final--'
|
|
51
|
+
// : word.text,
|
|
52
|
+
// )
|
|
53
|
+
// .join(' ')}`,
|
|
54
|
+
// 'color:red',
|
|
55
|
+
// 'color:blue',
|
|
56
|
+
// );
|
|
57
|
+
|
|
58
|
+
// Identifing Current & Prev Speakers for the Captions
|
|
59
|
+
/*
|
|
60
|
+
t0 A : Hi All!
|
|
61
|
+
t1 B : Hi A
|
|
62
|
+
t2 A : Hi B
|
|
63
|
+
t3 C : What's Plan
|
|
64
|
+
t4 B : Goal Planning
|
|
65
|
+
t5 C : Yes Agree
|
|
66
|
+
|
|
67
|
+
Screen:
|
|
68
|
+
Time : t0 | t1 | t2 | t3 | t4 | t5
|
|
69
|
+
Prev Speaker : | A:Hi All! | B: Hi A | A: Hi B | C: What's Plan | B: Goal Planning
|
|
70
|
+
Active Speaker : A:Hi All! | B: Hi A | A: Hi B | C: What's Plan | B: Goal Planning | C: Yes Agree
|
|
71
|
+
Clearing Required: A B A C
|
|
72
|
+
|
|
73
|
+
Logic:
|
|
74
|
+
time : t0 t1 t2 t3 t4 t5
|
|
75
|
+
textstream.uid : A B A C B C
|
|
76
|
+
(B)prevSpeaker : - - A B A C
|
|
77
|
+
(B)activeSpeake: - A B A C B
|
|
78
|
+
Prev Data clear: - - A B A C
|
|
79
|
+
################## CHANGE ######################
|
|
80
|
+
(A)prevSpeaker : - A B A C B
|
|
81
|
+
(A)activeSpeake: A B A C B C
|
|
82
|
+
|
|
83
|
+
Clear when textStream.uid == prevSpeakerRef.current
|
|
84
|
+
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
const finalWord = textstream.words.filter(word => word.isFinal === true);
|
|
88
|
+
// when we only get final word for the previous speaker then don't flip previous speaker as active but update in place.
|
|
89
|
+
|
|
90
|
+
if (
|
|
91
|
+
textstream.uid !== activeSpeakerRef.current &&
|
|
92
|
+
!(finalWord.length > 0 && textstream.uid === prevSpeakerRef.current)
|
|
93
|
+
) {
|
|
94
|
+
// we have a speaker change so clear the context for prev speaker
|
|
95
|
+
if (prevSpeakerRef.current !== '') {
|
|
96
|
+
finalList[prevSpeakerRef.current] = [];
|
|
97
|
+
isInterjecting = true;
|
|
98
|
+
// console.log(
|
|
99
|
+
// '%cSTT-callback%c Interjection! ',
|
|
100
|
+
// 'color:#fff',
|
|
101
|
+
// 'background: #222; color: #bada55',
|
|
102
|
+
// );
|
|
103
|
+
}
|
|
104
|
+
prevSpeakerRef.current = activeSpeakerRef.current;
|
|
105
|
+
activeSpeakerRef.current = textstream.uid;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* creating [] for each user to store their complete transcripts
|
|
109
|
+
initializing captions state for cuurent speaker
|
|
110
|
+
ex: {282190954:[]}
|
|
111
|
+
*/
|
|
112
|
+
if (!finalList[textstream.uid]) {
|
|
113
|
+
finalList[textstream.uid] = [];
|
|
114
|
+
finalTranscriptList[textstream.uid] = [];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const words = textstream.words; //[Word,Word]
|
|
118
|
+
|
|
119
|
+
/* categorize words into final & nonFinal objects per uid
|
|
120
|
+
Final Word Ex : {
|
|
121
|
+
"text": "Hello, are you doing?",
|
|
122
|
+
"durationMs": 960,
|
|
123
|
+
"isFinal": true,
|
|
124
|
+
"confidence": 0.8549408316612244
|
|
125
|
+
}
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
for (const word of words) {
|
|
129
|
+
if (word.isFinal) {
|
|
130
|
+
finalText = finalText + word.text;
|
|
131
|
+
} else {
|
|
132
|
+
nonFinalText =
|
|
133
|
+
word.text !== '.' ? nonFinalText + word.text : nonFinalText;
|
|
134
|
+
if (!captionStartTime) {
|
|
135
|
+
captionStartTime = performance.now();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (finalText) {
|
|
141
|
+
finalList[textstream.uid].push(finalText);
|
|
142
|
+
finalTranscriptList[textstream.uid].push(finalText);
|
|
143
|
+
currentFinalText = finalText;
|
|
144
|
+
// log info to show measure the duration of passes in which a sentence gets finalized
|
|
145
|
+
const duration = performance.now() - captionStartTime;
|
|
146
|
+
console.log(
|
|
147
|
+
`stt-Time taken to finalize caption ${currentFinalText}: ${duration}ms`,
|
|
148
|
+
);
|
|
149
|
+
captionStartTime = null; // Reset start time
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Updating Meeting Transcript */
|
|
153
|
+
if (currentFinalText.length) {
|
|
154
|
+
setMeetingTranscript(prevTranscript => {
|
|
155
|
+
const lastTranscriptIndex = prevTranscript.length - 1;
|
|
156
|
+
const lastTranscript =
|
|
157
|
+
lastTranscriptIndex >= 0
|
|
158
|
+
? prevTranscript[lastTranscriptIndex]
|
|
159
|
+
: null;
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
checking if the last item transcript matches with current uid
|
|
163
|
+
If yes then updating the last transcript msg with current text
|
|
164
|
+
If no then adding a new entry in the transcript
|
|
165
|
+
*/
|
|
166
|
+
if (lastTranscript && lastTranscript.uid === textstream.uid) {
|
|
167
|
+
const updatedTranscript = {
|
|
168
|
+
...lastTranscript,
|
|
169
|
+
//text: lastTranscript.text + ' ' + currentFinalText, // missing few updates with reading prev values
|
|
170
|
+
text: finalTranscriptList[textstream.uid].join(' '),
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return [
|
|
174
|
+
...prevTranscript.slice(0, lastTranscriptIndex),
|
|
175
|
+
updatedTranscript,
|
|
176
|
+
];
|
|
177
|
+
} else {
|
|
178
|
+
finalTranscriptList[textstream.uid] = [currentFinalText];
|
|
179
|
+
|
|
180
|
+
return [
|
|
181
|
+
...prevTranscript,
|
|
182
|
+
{
|
|
183
|
+
uid: textstream.uid,
|
|
184
|
+
time: new Date().getTime(),
|
|
185
|
+
text: currentFinalText,
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/*
|
|
193
|
+
Previous final words of the uid are prepended and
|
|
194
|
+
then current non final words so that context of speech is not lost
|
|
195
|
+
*/
|
|
196
|
+
const existingStringBuffer = isInterjecting
|
|
197
|
+
? ''
|
|
198
|
+
: finalList[textstream.uid]?.join(' ');
|
|
199
|
+
const latestString = nonFinalText;
|
|
200
|
+
const captionText =
|
|
201
|
+
existingStringBuffer.length > 0
|
|
202
|
+
? existingStringBuffer + ' ' + latestString
|
|
203
|
+
: latestString;
|
|
204
|
+
|
|
205
|
+
// updating the captions
|
|
206
|
+
captionText &&
|
|
207
|
+
setCaptionObj(prevState => {
|
|
208
|
+
return {
|
|
209
|
+
...prevState,
|
|
210
|
+
[textstream.uid]: {
|
|
211
|
+
text: captionText,
|
|
212
|
+
lastUpdated: new Date().getTime(),
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// console.group('STT-logs');
|
|
218
|
+
// console.log('Recived uid =>', textstream.uid);
|
|
219
|
+
// console.log('PrevSpeaker uid =>', prevSpeakerRef.current);
|
|
220
|
+
// console.log('ActiveSpeaker uid=>', activeSpeakerRef.current);
|
|
221
|
+
// console.log('final List =>', finalList);
|
|
222
|
+
// console.groupEnd();
|
|
223
|
+
};
|
|
224
|
+
(async () => {
|
|
225
|
+
await queue.add(() => queueCallback(args));
|
|
226
|
+
console.log('stt- using pq queue');
|
|
227
|
+
})();
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
streamMessageCallback,
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
export default useStreamMessageUtils;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {formatTranscriptContent} from './utils';
|
|
2
|
+
import {useCaption} from './useCaption';
|
|
3
|
+
import RNFetchBlob from 'rn-fetch-blob';
|
|
4
|
+
import {isAndroid, isIOS, useRoomInfo, useContent} from 'customization-api';
|
|
5
|
+
import Share from 'react-native-share';
|
|
6
|
+
|
|
7
|
+
const useTranscriptDownload = (): {
|
|
8
|
+
downloadTranscript: () => Promise<string | null>;
|
|
9
|
+
} => {
|
|
10
|
+
const {meetingTranscript} = useCaption();
|
|
11
|
+
const {defaultContent} = useContent();
|
|
12
|
+
const {
|
|
13
|
+
data: {meetingTitle},
|
|
14
|
+
} = useRoomInfo();
|
|
15
|
+
|
|
16
|
+
const downloadTranscript = (): Promise<string | null> => {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
try {
|
|
19
|
+
const [finalContent, fileName] = formatTranscriptContent(
|
|
20
|
+
meetingTranscript,
|
|
21
|
+
meetingTitle,
|
|
22
|
+
defaultContent,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
// get path to the Documents directory, don't have access to Downloads folder so saving in documents 1
|
|
26
|
+
const documentsDir = RNFetchBlob.fs.dirs.DocumentDir;
|
|
27
|
+
|
|
28
|
+
// setting file path
|
|
29
|
+
const filePath = `${documentsDir}/${fileName}`;
|
|
30
|
+
|
|
31
|
+
// Writing content to the file
|
|
32
|
+
RNFetchBlob.fs
|
|
33
|
+
.writeFile(filePath, finalContent, 'utf8')
|
|
34
|
+
.then(() => {
|
|
35
|
+
console.warn('Content downloaded successfully on native.');
|
|
36
|
+
// need to show the preview of downloaded file
|
|
37
|
+
Share.open({url: `file://${filePath}`, type: 'text/plain'})
|
|
38
|
+
.then(res => {
|
|
39
|
+
// console.warn('File shared successfully:', res);
|
|
40
|
+
resolve(filePath);
|
|
41
|
+
})
|
|
42
|
+
.catch(error => {
|
|
43
|
+
// console.error('Error sharing file:', error);
|
|
44
|
+
reject(error);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
resolve(filePath);
|
|
48
|
+
})
|
|
49
|
+
.catch(error => {
|
|
50
|
+
console.error('Error downloading content:', error);
|
|
51
|
+
reject(error);
|
|
52
|
+
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('Error downloading content:', error);
|
|
55
|
+
reject(error);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return {downloadTranscript};
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default useTranscriptDownload;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {formatTranscriptContent} from './utils';
|
|
2
|
+
import {useCaption} from './useCaption';
|
|
3
|
+
import {useRoomInfo, useContent} from 'customization-api';
|
|
4
|
+
|
|
5
|
+
const useTranscriptDownload = (): {
|
|
6
|
+
downloadTranscript: () => Promise<string | null>;
|
|
7
|
+
} => {
|
|
8
|
+
const {meetingTranscript} = useCaption();
|
|
9
|
+
|
|
10
|
+
const {defaultContent} = useContent();
|
|
11
|
+
const {
|
|
12
|
+
data: {meetingTitle},
|
|
13
|
+
} = useRoomInfo();
|
|
14
|
+
|
|
15
|
+
const downloadTranscript = (): Promise<string | null> => {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
try {
|
|
18
|
+
const [finalContent, fileName] = formatTranscriptContent(
|
|
19
|
+
meetingTranscript,
|
|
20
|
+
meetingTitle,
|
|
21
|
+
defaultContent,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// blob with required content
|
|
25
|
+
const blob = new Blob([finalContent], {type: 'text/plain'});
|
|
26
|
+
|
|
27
|
+
// url to download content
|
|
28
|
+
const downloadUrl = URL.createObjectURL(blob);
|
|
29
|
+
|
|
30
|
+
// anchor ele to download
|
|
31
|
+
const anchor = document.createElement('a');
|
|
32
|
+
anchor.href = downloadUrl;
|
|
33
|
+
anchor.download = fileName;
|
|
34
|
+
|
|
35
|
+
// click to dowload the file
|
|
36
|
+
anchor.click();
|
|
37
|
+
|
|
38
|
+
// revoke download url
|
|
39
|
+
URL.revokeObjectURL(downloadUrl);
|
|
40
|
+
console.log('Content downloaded successfully.');
|
|
41
|
+
resolve(downloadUrl);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error('Error downloading content:', error);
|
|
44
|
+
reject(error);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return {downloadTranscript};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default useTranscriptDownload;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {ContentObjects} from '../../../agora-rn-uikit/src/Contexts/RtcContext';
|
|
2
|
+
import {TranscriptItem} from './useCaption';
|
|
3
|
+
|
|
4
|
+
export function formatTime(timestamp: number): string {
|
|
5
|
+
const d = new Date(timestamp);
|
|
6
|
+
const h = d.getHours();
|
|
7
|
+
const m = d.getMinutes().toString().padStart(2, '0');
|
|
8
|
+
//const s = d.getSeconds().toString().padStart(2, '0');
|
|
9
|
+
const suffix = h >= 12 ? 'PM' : 'AM';
|
|
10
|
+
const H = h % 12 || 12;
|
|
11
|
+
return `${H}:${m} ${suffix}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type LanguageType =
|
|
15
|
+
| 'en-US'
|
|
16
|
+
| 'hi-IN'
|
|
17
|
+
| 'zh-CN'
|
|
18
|
+
| 'zh-HK'
|
|
19
|
+
| 'fr-FR'
|
|
20
|
+
| 'de-DE'
|
|
21
|
+
| 'ko-KR'
|
|
22
|
+
| 'en-IN'
|
|
23
|
+
| 'ar'
|
|
24
|
+
| 'ja-JP'
|
|
25
|
+
| 'pt-PT'
|
|
26
|
+
| 'es-ES'
|
|
27
|
+
| 'it-IT'
|
|
28
|
+
| 'id-ID'
|
|
29
|
+
| '';
|
|
30
|
+
|
|
31
|
+
interface LanguageData {
|
|
32
|
+
label: string;
|
|
33
|
+
value: LanguageType;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const langData: LanguageData[] = [
|
|
37
|
+
{label: 'English (US)', value: 'en-US'},
|
|
38
|
+
{label: 'English (India)', value: 'en-IN'},
|
|
39
|
+
{label: 'Hindi', value: 'hi-IN'},
|
|
40
|
+
{label: 'Chinese (Simplified)', value: 'zh-CN'},
|
|
41
|
+
{label: 'Chinese (Traditional)', value: 'zh-HK'},
|
|
42
|
+
{label: 'Arabic', value: 'ar'},
|
|
43
|
+
{label: 'French', value: 'fr-FR'},
|
|
44
|
+
{label: 'German', value: 'de-DE'},
|
|
45
|
+
{label: 'Japanese', value: 'ja-JP'},
|
|
46
|
+
{label: 'Korean', value: 'ko-KR'},
|
|
47
|
+
{label: 'Portuguese', value: 'pt-PT'},
|
|
48
|
+
{label: 'Spanish', value: 'es-ES'},
|
|
49
|
+
{label: 'Italian', value: 'it-IT'},
|
|
50
|
+
{label: 'Indonesian', value: 'id-ID'},
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
export function getLanguageLabel(
|
|
54
|
+
languageCode: LanguageType[],
|
|
55
|
+
): string | undefined {
|
|
56
|
+
const langLabels = languageCode.map(langCode => {
|
|
57
|
+
return langData.find(data => data.value === langCode).label;
|
|
58
|
+
});
|
|
59
|
+
return langLabels ? langLabels.join(', ') : undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function formatDateWithTimeZone(date: Date): string {
|
|
63
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
64
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
65
|
+
const year = date.getUTCFullYear();
|
|
66
|
+
|
|
67
|
+
const hours = String(date.getUTCHours()).padStart(2, '0');
|
|
68
|
+
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
|
|
69
|
+
|
|
70
|
+
const timeZoneOffset = 5.5 * 60; // Offset in minutes for GMT +5:30
|
|
71
|
+
const offsetHours = Math.floor(timeZoneOffset / 60);
|
|
72
|
+
const offsetMinutes = timeZoneOffset % 60;
|
|
73
|
+
const offsetSign = '+';
|
|
74
|
+
|
|
75
|
+
return `${day}/${month}/${year} ${hours}:${minutes} GMT ${offsetSign}${offsetHours}:${String(
|
|
76
|
+
offsetMinutes,
|
|
77
|
+
).padStart(2, '0')}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const formatTranscriptContent = (
|
|
81
|
+
meetingTranscript: TranscriptItem[],
|
|
82
|
+
meetingTitle: string,
|
|
83
|
+
defaultContent: ContentObjects,
|
|
84
|
+
) => {
|
|
85
|
+
const formattedContent = meetingTranscript
|
|
86
|
+
.map(item => {
|
|
87
|
+
if (item.uid.toString().indexOf('langUpdate') !== -1) {
|
|
88
|
+
return `${defaultContent[item?.uid?.split('-')[1]]?.name} ${item.text}`;
|
|
89
|
+
}
|
|
90
|
+
return `${defaultContent[item.uid].name} ${formatTime(
|
|
91
|
+
Number(item?.time),
|
|
92
|
+
)}:\n${item.text}`;
|
|
93
|
+
})
|
|
94
|
+
.join('\n\n');
|
|
95
|
+
|
|
96
|
+
const startTime = formatDateWithTimeZone(
|
|
97
|
+
new Date(meetingTranscript[0]?.time),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const attendees = Object.entries(defaultContent)
|
|
101
|
+
.filter(
|
|
102
|
+
arr =>
|
|
103
|
+
arr[1].type === 'rtc' &&
|
|
104
|
+
arr[0] !== '100000' && // exclude recording bot
|
|
105
|
+
(arr[1]?.isInWaitingRoom === true ? false : true),
|
|
106
|
+
)
|
|
107
|
+
.map(arr => arr[1].name)
|
|
108
|
+
.join(',');
|
|
109
|
+
|
|
110
|
+
const info =
|
|
111
|
+
'This editable transcript was computer generated and might contain errors. People can also change\nthe text after it was created.';
|
|
112
|
+
const finalContent = `${meetingTitle} (${startTime}) - Transcript \n\nParticipants\n${attendees} \n\nTranscript\n${info} \n\n${formattedContent}`;
|
|
113
|
+
|
|
114
|
+
// to give unique file name
|
|
115
|
+
const currentDate = new Date();
|
|
116
|
+
const formattedDate = currentDate.toISOString().slice(0, 10);
|
|
117
|
+
const formattedTime = currentDate
|
|
118
|
+
.toTimeString()
|
|
119
|
+
.slice(0, 8)
|
|
120
|
+
.replace(/:/g, '');
|
|
121
|
+
|
|
122
|
+
// adding the filename
|
|
123
|
+
const fileName = `MeetingTranscript_${formattedDate}_${formattedTime}.txt`;
|
|
124
|
+
|
|
125
|
+
return [finalContent, fileName];
|
|
126
|
+
};
|