@stream-io/video-react-sdk 1.40.2 → 1.42.0
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/CHANGELOG.md +33 -4
- package/dist/embedded.cjs.js +4 -4
- package/dist/embedded.cjs.js.map +1 -1
- package/dist/esm/embedded.js +3 -0
- package/dist/esm/embedded.js.map +1 -0
- package/dist/esm/index.js +92 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/src/components/Avatar/Avatar.js +14 -0
- package/dist/esm/src/components/Avatar/Avatar.js.map +1 -0
- package/dist/{background-filters-D2U5UBbH.es.js → esm/src/components/BackgroundFilters/BackgroundFilters.js} +1 -1
- package/dist/esm/src/components/BackgroundFilters/BackgroundFilters.js.map +1 -0
- package/dist/esm/src/components/BackgroundFilters/BackgroundFiltersProvider.js +33 -0
- package/dist/esm/src/components/BackgroundFilters/BackgroundFiltersProvider.js.map +1 -0
- package/dist/esm/src/components/Button/CompositeButton.js +29 -0
- package/dist/esm/src/components/Button/CompositeButton.js.map +1 -0
- package/dist/esm/src/components/Button/IconButton.js +18 -0
- package/dist/esm/src/components/Button/IconButton.js.map +1 -0
- package/dist/esm/src/components/Button/TextButton.js +8 -0
- package/dist/esm/src/components/Button/TextButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/AcceptCallButton.js +28 -0
- package/dist/esm/src/components/CallControls/AcceptCallButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/CallControls.js +21 -0
- package/dist/esm/src/components/CallControls/CallControls.js.map +1 -0
- package/dist/esm/src/components/CallControls/CallStatsButton.js +18 -0
- package/dist/esm/src/components/CallControls/CallStatsButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/CancelCallButton.js +78 -0
- package/dist/esm/src/components/CallControls/CancelCallButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/ReactionsButton.js +61 -0
- package/dist/esm/src/components/CallControls/ReactionsButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/RecordCallButton.js +64 -0
- package/dist/esm/src/components/CallControls/RecordCallButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/ScreenShareButton.js +44 -0
- package/dist/esm/src/components/CallControls/ScreenShareButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/ToggleAudioButton.js +72 -0
- package/dist/esm/src/components/CallControls/ToggleAudioButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/ToggleAudioOutputButton.js +27 -0
- package/dist/esm/src/components/CallControls/ToggleAudioOutputButton.js.map +1 -0
- package/dist/esm/src/components/CallControls/ToggleVideoButton.js +81 -0
- package/dist/esm/src/components/CallControls/ToggleVideoButton.js.map +1 -0
- package/dist/esm/src/components/CallParticipantsList/BlockedUserListing.js +23 -0
- package/dist/esm/src/components/CallParticipantsList/BlockedUserListing.js.map +1 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantListHeader.js +15 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantListHeader.js.map +1 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantListing.js +7 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantListing.js.map +1 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantListingItem.js +46 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantListingItem.js.map +1 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantsList.js +81 -0
- package/dist/esm/src/components/CallParticipantsList/CallParticipantsList.js.map +1 -0
- package/dist/esm/src/components/CallParticipantsList/EmptyParticipantSearchList.js +10 -0
- package/dist/esm/src/components/CallParticipantsList/EmptyParticipantSearchList.js.map +1 -0
- package/dist/esm/src/components/CallPreview/CallPreview.js +24 -0
- package/dist/esm/src/components/CallPreview/CallPreview.js.map +1 -0
- package/dist/esm/src/components/CallRecordingList/CallRecordingList.js +12 -0
- package/dist/esm/src/components/CallRecordingList/CallRecordingList.js.map +1 -0
- package/dist/esm/src/components/CallRecordingList/CallRecordingListHeader.js +12 -0
- package/dist/esm/src/components/CallRecordingList/CallRecordingListHeader.js.map +1 -0
- package/dist/esm/src/components/CallRecordingList/CallRecordingListItem.js +14 -0
- package/dist/esm/src/components/CallRecordingList/CallRecordingListItem.js.map +1 -0
- package/dist/esm/src/components/CallRecordingList/EmptyCallRecordingListing.js +8 -0
- package/dist/esm/src/components/CallRecordingList/EmptyCallRecordingListing.js.map +1 -0
- package/dist/esm/src/components/CallRecordingList/LoadingCallRecordingListing.js +10 -0
- package/dist/esm/src/components/CallRecordingList/LoadingCallRecordingListing.js.map +1 -0
- package/dist/esm/src/components/CallStats/CallStats.js +180 -0
- package/dist/esm/src/components/CallStats/CallStats.js.map +1 -0
- package/dist/{latency-chart-Bj5OSYzg.es.js → esm/src/components/CallStats/CallStatsLatencyChart.js} +1 -1
- package/dist/esm/src/components/CallStats/CallStatsLatencyChart.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/AudioVolumeIndicator.js +27 -0
- package/dist/esm/src/components/DeviceSettings/AudioVolumeIndicator.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/DeviceAudioPreviewItem.js +42 -0
- package/dist/esm/src/components/DeviceSettings/DeviceAudioPreviewItem.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSelector.js +67 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSelector.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSelectorAudio.js +26 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSelectorAudio.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSelectorVideo.js +15 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSelectorVideo.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSettings.js +26 -0
- package/dist/esm/src/components/DeviceSettings/DeviceSettings.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/DeviceVideoPreviewItem.js +42 -0
- package/dist/esm/src/components/DeviceSettings/DeviceVideoPreviewItem.js.map +1 -0
- package/dist/esm/src/components/DeviceSettings/SpeakerTest.js +57 -0
- package/dist/esm/src/components/DeviceSettings/SpeakerTest.js.map +1 -0
- package/dist/esm/src/components/DropdownSelect/DropdownSelect.js +79 -0
- package/dist/esm/src/components/DropdownSelect/DropdownSelect.js.map +1 -0
- package/dist/esm/src/components/Icon/Icon.js +7 -0
- package/dist/esm/src/components/Icon/Icon.js.map +1 -0
- package/dist/esm/src/components/LoadingIndicator/LoadingIndicator.js +9 -0
- package/dist/esm/src/components/LoadingIndicator/LoadingIndicator.js.map +1 -0
- package/dist/esm/src/components/Menu/GenericMenu.js +19 -0
- package/dist/esm/src/components/Menu/GenericMenu.js.map +1 -0
- package/dist/esm/src/components/Menu/MenuToggle.js +75 -0
- package/dist/esm/src/components/Menu/MenuToggle.js.map +1 -0
- package/dist/esm/src/components/NoiseCancellation/NoiseCancellationProvider.js +96 -0
- package/dist/esm/src/components/NoiseCancellation/NoiseCancellationProvider.js.map +1 -0
- package/dist/esm/src/components/Notification/MicCaptureErrorNotification.js +23 -0
- package/dist/esm/src/components/Notification/MicCaptureErrorNotification.js.map +1 -0
- package/dist/esm/src/components/Notification/Notification.js +31 -0
- package/dist/esm/src/components/Notification/Notification.js.map +1 -0
- package/dist/esm/src/components/Notification/PermissionNotification.js +32 -0
- package/dist/esm/src/components/Notification/PermissionNotification.js.map +1 -0
- package/dist/esm/src/components/Notification/RecordingInProgressNotification.js +23 -0
- package/dist/esm/src/components/Notification/RecordingInProgressNotification.js.map +1 -0
- package/dist/esm/src/components/Notification/SpeakingWhileMutedNotification.js +14 -0
- package/dist/esm/src/components/Notification/SpeakingWhileMutedNotification.js.map +1 -0
- package/dist/esm/src/components/Permissions/PermissionRequests.js +99 -0
- package/dist/esm/src/components/Permissions/PermissionRequests.js.map +1 -0
- package/dist/esm/src/components/Reaction/Reaction.js +32 -0
- package/dist/esm/src/components/Reaction/Reaction.js.map +1 -0
- package/dist/esm/src/components/RingingCall/RingingCall.js +48 -0
- package/dist/esm/src/components/RingingCall/RingingCall.js.map +1 -0
- package/dist/esm/src/components/RingingCall/RingingCallControls.js +34 -0
- package/dist/esm/src/components/RingingCall/RingingCallControls.js.map +1 -0
- package/dist/esm/src/components/Search/SearchInput.js +27 -0
- package/dist/esm/src/components/Search/SearchInput.js.map +1 -0
- package/dist/esm/src/components/Search/SearchResults.js +15 -0
- package/dist/esm/src/components/Search/SearchResults.js.map +1 -0
- package/dist/esm/src/components/Search/hooks/useSearch.js +38 -0
- package/dist/esm/src/components/Search/hooks/useSearch.js.map +1 -0
- package/dist/esm/src/components/StreamTheme/StreamTheme.js +9 -0
- package/dist/esm/src/components/StreamTheme/StreamTheme.js.map +1 -0
- package/dist/esm/src/components/Tooltip/Tooltip.js +29 -0
- package/dist/esm/src/components/Tooltip/Tooltip.js.map +1 -0
- package/dist/esm/src/components/Tooltip/WithTooltip.js +15 -0
- package/dist/esm/src/components/Tooltip/WithTooltip.js.map +1 -0
- package/dist/esm/src/components/Tooltip/hooks/useEnterLeaveHandlers.js +17 -0
- package/dist/esm/src/components/Tooltip/hooks/useEnterLeaveHandlers.js.map +1 -0
- package/dist/esm/src/components/VideoPreview/VideoPreview.js +37 -0
- package/dist/esm/src/components/VideoPreview/VideoPreview.js.map +1 -0
- package/dist/esm/src/core/components/Audio/Audio.js +22 -0
- package/dist/esm/src/core/components/Audio/Audio.js.map +1 -0
- package/dist/esm/src/core/components/Audio/ParticipantsAudio.js +23 -0
- package/dist/esm/src/core/components/Audio/ParticipantsAudio.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/LivestreamLayout.js +150 -0
- package/dist/esm/src/core/components/CallLayout/LivestreamLayout.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/PaginatedGridLayout.js +79 -0
- package/dist/esm/src/core/components/CallLayout/PaginatedGridLayout.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/Grid.js +80 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/Grid.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/Host.js +13 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/Host.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/Pip.js +57 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/Pip.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/index.js +8 -0
- package/dist/esm/src/core/components/CallLayout/PipLayout/index.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/SpeakerLayout.js +103 -0
- package/dist/esm/src/core/components/CallLayout/SpeakerLayout.js.map +1 -0
- package/dist/esm/src/core/components/CallLayout/hooks.js +62 -0
- package/dist/esm/src/core/components/CallLayout/hooks.js.map +1 -0
- package/dist/esm/src/core/components/ParticipantView/DefaultParticipantViewUI.js +94 -0
- package/dist/esm/src/core/components/ParticipantView/DefaultParticipantViewUI.js.map +1 -0
- package/dist/esm/src/core/components/ParticipantView/ParticipantActionsContextMenu.js +97 -0
- package/dist/esm/src/core/components/ParticipantView/ParticipantActionsContextMenu.js.map +1 -0
- package/dist/esm/src/core/components/ParticipantView/ParticipantView.js +65 -0
- package/dist/esm/src/core/components/ParticipantView/ParticipantView.js.map +1 -0
- package/dist/esm/src/core/components/ParticipantView/ParticipantViewContext.js +7 -0
- package/dist/esm/src/core/components/ParticipantView/ParticipantViewContext.js.map +1 -0
- package/dist/esm/src/core/components/StreamCall/StreamCall.js +8 -0
- package/dist/esm/src/core/components/StreamCall/StreamCall.js.map +1 -0
- package/dist/esm/src/core/components/StreamVideo/StreamVideo.js +11 -0
- package/dist/esm/src/core/components/StreamVideo/StreamVideo.js.map +1 -0
- package/dist/esm/src/core/components/Video/BaseVideo.js +41 -0
- package/dist/esm/src/core/components/Video/BaseVideo.js.map +1 -0
- package/dist/esm/src/core/components/Video/BaseVideoPlaceholder.js +21 -0
- package/dist/esm/src/core/components/Video/BaseVideoPlaceholder.js.map +1 -0
- package/dist/esm/src/core/components/Video/DefaultPictureInPicturePlaceholder.js +12 -0
- package/dist/esm/src/core/components/Video/DefaultPictureInPicturePlaceholder.js.map +1 -0
- package/dist/esm/src/core/components/Video/DefaultVideoPlaceholder.js +12 -0
- package/dist/esm/src/core/components/Video/DefaultVideoPlaceholder.js.map +1 -0
- package/dist/esm/src/core/components/Video/Video.js +88 -0
- package/dist/esm/src/core/components/Video/Video.js.map +1 -0
- package/dist/esm/src/core/hooks/useCalculateHardLimit.js +59 -0
- package/dist/esm/src/core/hooks/useCalculateHardLimit.js.map +1 -0
- package/dist/esm/src/core/hooks/usePictureInPictureState.js +24 -0
- package/dist/esm/src/core/hooks/usePictureInPictureState.js.map +1 -0
- package/dist/esm/src/core/hooks/useTrackElementVisibility.js +14 -0
- package/dist/esm/src/core/hooks/useTrackElementVisibility.js.map +1 -0
- package/dist/esm/src/embedded/EmbeddedClientProvider.js +83 -0
- package/dist/esm/src/embedded/EmbeddedClientProvider.js.map +1 -0
- package/dist/esm/src/embedded/call/CallControls.js +65 -0
- package/dist/esm/src/embedded/call/CallControls.js.map +1 -0
- package/dist/esm/src/embedded/call/CallHeader.js +57 -0
- package/dist/esm/src/embedded/call/CallHeader.js.map +1 -0
- package/dist/esm/src/embedded/call/CallLayout.js +63 -0
- package/dist/esm/src/embedded/call/CallLayout.js.map +1 -0
- package/dist/esm/src/embedded/call/CallStateRouter.js +87 -0
- package/dist/esm/src/embedded/call/CallStateRouter.js.map +1 -0
- package/dist/esm/src/embedded/call/EmbeddedCall.js +12 -0
- package/dist/esm/src/embedded/call/EmbeddedCall.js.map +1 -0
- package/dist/esm/src/embedded/context/ConfigurationContext.js +21 -0
- package/dist/esm/src/embedded/context/ConfigurationContext.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useCallDuration.js +32 -0
- package/dist/esm/src/embedded/hooks/useCallDuration.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useEmbeddedClient.js +40 -0
- package/dist/esm/src/embedded/hooks/useEmbeddedClient.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useInitializeCall.js +39 -0
- package/dist/esm/src/embedded/hooks/useInitializeCall.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useInitializeVideoClient.js +93 -0
- package/dist/esm/src/embedded/hooks/useInitializeVideoClient.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useIsLivestreamPaused.js +42 -0
- package/dist/esm/src/embedded/hooks/useIsLivestreamPaused.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useLayout.js +122 -0
- package/dist/esm/src/embedded/hooks/useLayout.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useNoiseCancellationLoader.js +48 -0
- package/dist/esm/src/embedded/hooks/useNoiseCancellationLoader.js.map +1 -0
- package/dist/esm/src/embedded/hooks/useWakeLock.js +34 -0
- package/dist/esm/src/embedded/hooks/useWakeLock.js.map +1 -0
- package/dist/esm/src/embedded/livestream/EmbeddedLivestream.js +11 -0
- package/dist/esm/src/embedded/livestream/EmbeddedLivestream.js.map +1 -0
- package/dist/esm/src/embedded/livestream/LivestreamUI.js +17 -0
- package/dist/esm/src/embedded/livestream/LivestreamUI.js.map +1 -0
- package/dist/esm/src/embedded/livestream/host/HostLayout.js +76 -0
- package/dist/esm/src/embedded/livestream/host/HostLayout.js.map +1 -0
- package/dist/esm/src/embedded/livestream/host/HostStateRouter.js +110 -0
- package/dist/esm/src/embedded/livestream/host/HostStateRouter.js.map +1 -0
- package/dist/esm/src/embedded/livestream/viewer/ViewerLayout.js +74 -0
- package/dist/esm/src/embedded/livestream/viewer/ViewerLayout.js.map +1 -0
- package/dist/esm/src/embedded/livestream/viewer/ViewerLobby.js +109 -0
- package/dist/esm/src/embedded/livestream/viewer/ViewerLobby.js.map +1 -0
- package/dist/esm/src/embedded/livestream/viewer/ViewerStateRouter.js +105 -0
- package/dist/esm/src/embedded/livestream/viewer/ViewerStateRouter.js.map +1 -0
- package/dist/esm/src/embedded/shared/BlurToggleButton/BlurToggleButton.js +65 -0
- package/dist/esm/src/embedded/shared/BlurToggleButton/BlurToggleButton.js.map +1 -0
- package/dist/esm/src/embedded/shared/CallFeedback/CallEndedScreen.js +34 -0
- package/dist/esm/src/embedded/shared/CallFeedback/CallEndedScreen.js.map +1 -0
- package/dist/esm/src/embedded/shared/CallFeedback/CallFeedback.js +35 -0
- package/dist/esm/src/embedded/shared/CallFeedback/CallFeedback.js.map +1 -0
- package/dist/esm/src/embedded/shared/CallFeedback/RatingScreen.js +18 -0
- package/dist/esm/src/embedded/shared/CallFeedback/RatingScreen.js.map +1 -0
- package/dist/esm/src/embedded/shared/CallFeedback/StarRating.js +37 -0
- package/dist/esm/src/embedded/shared/CallFeedback/StarRating.js.map +1 -0
- package/dist/esm/src/embedded/shared/CallFeedback/ThankYouScreen.js +34 -0
- package/dist/esm/src/embedded/shared/CallFeedback/ThankYouScreen.js.map +1 -0
- package/dist/esm/src/embedded/shared/ConnectionNotification/ConnectionNotification.js +56 -0
- package/dist/esm/src/embedded/shared/ConnectionNotification/ConnectionNotification.js.map +1 -0
- package/dist/esm/src/embedded/shared/EmbeddedParticipantViewUI/EmbeddedParticipantViewUI.js +42 -0
- package/dist/esm/src/embedded/shared/EmbeddedParticipantViewUI/EmbeddedParticipantViewUI.js.map +1 -0
- package/dist/esm/src/embedded/shared/JoinError/JoinError.js +34 -0
- package/dist/esm/src/embedded/shared/JoinError/JoinError.js.map +1 -0
- package/dist/esm/src/embedded/shared/Lobby/DeviceControls.js +44 -0
- package/dist/esm/src/embedded/shared/Lobby/DeviceControls.js.map +1 -0
- package/dist/esm/src/embedded/shared/Lobby/DisabledDeviceButton.js +31 -0
- package/dist/esm/src/embedded/shared/Lobby/DisabledDeviceButton.js.map +1 -0
- package/dist/esm/src/embedded/shared/Lobby/Lobby.js +45 -0
- package/dist/esm/src/embedded/shared/Lobby/Lobby.js.map +1 -0
- package/dist/esm/src/embedded/shared/Lobby/ToggleCameraButton.js +40 -0
- package/dist/esm/src/embedded/shared/Lobby/ToggleCameraButton.js.map +1 -0
- package/dist/esm/src/embedded/shared/Lobby/ToggleMicButton.js +41 -0
- package/dist/esm/src/embedded/shared/Lobby/ToggleMicButton.js.map +1 -0
- package/dist/esm/src/embedded/shared/Lobby/VideoPreviewFallbacks.js +50 -0
- package/dist/esm/src/embedded/shared/Lobby/VideoPreviewFallbacks.js.map +1 -0
- package/dist/esm/src/embedded/shared/ViewersCount/ViewersCount.js +31 -0
- package/dist/esm/src/embedded/shared/ViewersCount/ViewersCount.js.map +1 -0
- package/dist/esm/src/hooks/useDeviceList.js +40 -0
- package/dist/esm/src/hooks/useDeviceList.js.map +1 -0
- package/dist/esm/src/hooks/useDragToScroll.js +116 -0
- package/dist/esm/src/hooks/useDragToScroll.js.map +1 -0
- package/dist/esm/src/hooks/useFloatingUIPreset.js +34 -0
- package/dist/esm/src/hooks/useFloatingUIPreset.js.map +1 -0
- package/dist/esm/src/hooks/useLoopbackRecording.js +138 -0
- package/dist/esm/src/hooks/useLoopbackRecording.js.map +1 -0
- package/dist/esm/src/hooks/useModeration.js +135 -0
- package/dist/esm/src/hooks/useModeration.js.map +1 -0
- package/dist/esm/src/hooks/usePersistedDevicePreferences.js +16 -0
- package/dist/esm/src/hooks/usePersistedDevicePreferences.js.map +1 -0
- package/dist/esm/src/hooks/useRequestPermission.js +41 -0
- package/dist/esm/src/hooks/useRequestPermission.js.map +1 -0
- package/dist/esm/src/hooks/useScrollPosition.js +66 -0
- package/dist/esm/src/hooks/useScrollPosition.js.map +1 -0
- package/dist/esm/src/translations/en.json.js +177 -0
- package/dist/esm/src/translations/en.json.js.map +1 -0
- package/dist/esm/src/translations/index.js +6 -0
- package/dist/esm/src/translations/index.js.map +1 -0
- package/dist/esm/src/utilities/applyElementToRef.js +10 -0
- package/dist/esm/src/utilities/applyElementToRef.js.map +1 -0
- package/dist/esm/src/utilities/callControlHandler.js +29 -0
- package/dist/esm/src/utilities/callControlHandler.js.map +1 -0
- package/dist/esm/src/utilities/chunk.js +7 -0
- package/dist/esm/src/utilities/chunk.js.map +1 -0
- package/dist/esm/src/utilities/filter.js +94 -0
- package/dist/esm/src/utilities/filter.js.map +1 -0
- package/dist/esm/src/utilities/isComponentType.js +10 -0
- package/dist/esm/src/utilities/isComponentType.js.map +1 -0
- package/dist/esm/src/utilities/normalizeString.js +11 -0
- package/dist/esm/src/utilities/normalizeString.js.map +1 -0
- package/dist/esm/src/wrappers/LivestreamPlayer/LivestreamPlayer.js +105 -0
- package/dist/esm/src/wrappers/LivestreamPlayer/LivestreamPlayer.js.map +1 -0
- package/dist/index.cjs.js +138 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/useLoopbackRecording.d.ts +23 -0
- package/dist/src/hooks/useRequestPermission.d.ts +2 -2
- package/index.ts +4 -0
- package/package.json +14 -10
- package/src/components/CallControls/ScreenShareButton.tsx +5 -2
- package/src/components/CallControls/ToggleAudioButton.tsx +6 -2
- package/src/components/CallControls/ToggleVideoButton.tsx +6 -2
- package/src/core/components/ParticipantView/ParticipantActionsContextMenu.tsx +16 -12
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useLoopbackRecording.ts +207 -0
- package/src/hooks/useRequestPermission.ts +4 -2
- package/dist/background-filters-D2U5UBbH.es.js.map +0 -1
- package/dist/embedded-BackgroundFilters-D2U5UBbH.es.js +0 -420
- package/dist/embedded-BackgroundFilters-D2U5UBbH.es.js.map +0 -1
- package/dist/embedded-CallStatsLatencyChart-Bj5OSYzg.es.js +0 -57
- package/dist/embedded-CallStatsLatencyChart-Bj5OSYzg.es.js.map +0 -1
- package/dist/embedded.es.js +0 -3536
- package/dist/embedded.es.js.map +0 -1
- package/dist/index.es.js +0 -3291
- package/dist/index.es.js.map +0 -1
- package/dist/latency-chart-Bj5OSYzg.es.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactionsButton.js","sources":["../../../../../../../src/components/CallControls/ReactionsButton.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport clsx from 'clsx';\n\nimport { OwnCapability, StreamReaction } from '@stream-io/video-client';\nimport { Restricted, useCall, useI18n } from '@stream-io/video-react-bindings';\n\nimport {\n MenuToggle,\n MenuVisualType,\n ToggleMenuButtonProps,\n useMenuContext,\n} from '../Menu';\nimport { CompositeButton } from '../Button';\nimport { defaultEmojiReactionMap } from '../Reaction';\nimport { Icon } from '../Icon';\nimport { WithTooltip } from '../Tooltip';\n\nexport const defaultReactions: StreamReaction[] = [\n {\n type: 'reaction',\n emoji_code: ':like:',\n },\n {\n // TODO OL: use `prompt` type?\n type: 'raised-hand',\n emoji_code: ':raise-hand:',\n },\n {\n type: 'reaction',\n emoji_code: ':fireworks:',\n },\n {\n type: 'reaction',\n emoji_code: ':dislike:',\n },\n {\n type: 'reaction',\n emoji_code: ':heart:',\n },\n {\n type: 'reaction',\n emoji_code: ':smile:',\n },\n];\n\nexport interface ReactionsButtonProps {\n reactions?: StreamReaction[];\n}\n\nexport const ReactionsButton = ({\n reactions = defaultReactions,\n}: ReactionsButtonProps) => {\n return (\n <Restricted requiredGrants={[OwnCapability.CREATE_REACTION]}>\n <MenuToggle\n placement=\"top\"\n ToggleButton={ToggleReactionsMenuButton}\n visualType={MenuVisualType.MENU}\n >\n <DefaultReactionsMenu reactions={reactions} />\n </MenuToggle>\n </Restricted>\n );\n};\n\nconst ToggleReactionsMenuButton = forwardRef<\n HTMLDivElement,\n ToggleMenuButtonProps\n>(function ToggleReactionsMenuButtonRender({ menuShown }, ref) {\n const { t } = useI18n();\n return (\n <WithTooltip title={t('Reactions')} tooltipDisabled={menuShown}>\n <CompositeButton ref={ref} active={menuShown} variant=\"primary\">\n <Icon icon=\"reactions\" />\n </CompositeButton>\n </WithTooltip>\n );\n});\n\nexport interface DefaultReactionsMenuProps {\n reactions: StreamReaction[];\n layout?: 'horizontal' | 'vertical';\n}\n\nexport const DefaultReactionsMenu = ({\n reactions,\n layout = 'horizontal',\n}: DefaultReactionsMenuProps) => {\n const call = useCall();\n const { close } = useMenuContext();\n return (\n <div\n className={clsx('str-video__reactions-menu', {\n 'str-video__reactions-menu--horizontal': layout === 'horizontal',\n 'str-video__reactions-menu--vertical': layout === 'vertical',\n })}\n >\n {reactions.map((reaction) => (\n <button\n key={reaction.emoji_code}\n type=\"button\"\n className=\"str-video__reactions-menu__button\"\n onClick={() => {\n call?.sendReaction(reaction);\n close?.();\n }}\n >\n {reaction.emoji_code && defaultEmojiReactionMap[reaction.emoji_code]}\n </button>\n ))}\n </div>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;;;;;;;AAiBO,MAAM,gBAAgB,GAAqB;AAChD,IAAA;AACE,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,UAAU,EAAE,QAAQ;AACrB,KAAA;AACD,IAAA;;AAEE,QAAA,IAAI,EAAE,aAAa;AACnB,QAAA,UAAU,EAAE,cAAc;AAC3B,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,UAAU,EAAE,aAAa;AAC1B,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,UAAU,EAAE,WAAW;AACxB,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,UAAU,EAAE,SAAS;AACtB,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,UAAU,EAAE,SAAS;AACtB,KAAA;;AAOI,MAAM,eAAe,GAAG,CAAC,EAC9B,SAAS,GAAG,gBAAgB,GACP,KAAI;AACzB,IAAA,QACEA,GAAA,CAAC,UAAU,EAAA,EAAC,cAAc,EAAE,CAAC,aAAa,CAAC,eAAe,CAAC,EAAA,QAAA,EACzDA,GAAA,CAAC,UAAU,EAAA,EACT,SAAS,EAAC,KAAK,EACf,YAAY,EAAE,yBAAyB,EACvC,UAAU,EAAE,cAAc,CAAC,IAAI,EAAA,QAAA,EAE/BA,GAAA,CAAC,oBAAoB,EAAA,EAAC,SAAS,EAAE,SAAS,GAAI,EAAA,CACnC,EAAA,CACF;AAEjB;AAEA,MAAM,yBAAyB,GAAG,UAAU,CAG1C,SAAS,+BAA+B,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,EAAA;AAC3D,IAAA,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE;AACvB,IAAA,QACEA,GAAA,CAAC,WAAW,IAAC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,eAAe,EAAE,SAAS,YAC5DA,GAAA,CAAC,eAAe,IAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAC,SAAS,EAAA,QAAA,EAC7DA,GAAA,CAAC,IAAI,EAAA,EAAC,IAAI,EAAC,WAAW,GAAG,EAAA,CACT,EAAA,CACN;AAElB,CAAC,CAAC;AAOK,MAAM,oBAAoB,GAAG,CAAC,EACnC,SAAS,EACT,MAAM,GAAG,YAAY,GACK,KAAI;AAC9B,IAAA,MAAM,IAAI,GAAG,OAAO,EAAE;AACtB,IAAA,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc,EAAE;AAClC,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,IAAI,CAAC,2BAA2B,EAAE;YAC3C,uCAAuC,EAAE,MAAM,KAAK,YAAY;YAChE,qCAAqC,EAAE,MAAM,KAAK,UAAU;SAC7D,CAAC,EAAA,QAAA,EAED,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,MACtBA,gBAEE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,mCAAmC,EAC7C,OAAO,EAAE,MAAK;AACZ,gBAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;gBAC5B,KAAK,IAAI;YACX,CAAC,EAAA,QAAA,EAEA,QAAQ,CAAC,UAAU,IAAI,uBAAuB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAA,EAR/D,QAAQ,CAAC,UAAU,CASjB,CACV,CAAC,EAAA,CACE;AAEV;;;;"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { OwnCapability } from '@stream-io/video-client';
|
|
4
|
+
import { useI18n, useToggleCallRecording, Restricted } from '@stream-io/video-react-bindings';
|
|
5
|
+
import { CompositeButton } from '../Button/CompositeButton.js';
|
|
6
|
+
import '../Button/IconButton.js';
|
|
7
|
+
import { Icon } from '../Icon/Icon.js';
|
|
8
|
+
import { MenuToggle, MenuVisualType, useMenuContext } from '../Menu/MenuToggle.js';
|
|
9
|
+
import { LoadingIndicator } from '../LoadingIndicator/LoadingIndicator.js';
|
|
10
|
+
import 'clsx';
|
|
11
|
+
import '@floating-ui/react';
|
|
12
|
+
import { WithTooltip } from '../Tooltip/WithTooltip.js';
|
|
13
|
+
import { createCallControlHandler } from '../../utilities/callControlHandler.js';
|
|
14
|
+
|
|
15
|
+
const RecordEndConfirmation = (props) => {
|
|
16
|
+
const { t } = useI18n();
|
|
17
|
+
const { toggleCallRecording, isAwaitingResponse } = useToggleCallRecording();
|
|
18
|
+
const { close } = useMenuContext();
|
|
19
|
+
const handleClick = createCallControlHandler(props, toggleCallRecording);
|
|
20
|
+
return (jsxs("div", { className: "str-video__end-recording__confirmation", children: [jsxs("div", { className: "str-video__end-recording__header", children: [jsx(Icon, { icon: "recording-on" }), jsx("h2", { className: "str-video__end-recording__heading", children: t('End recording') })] }), jsx("p", { className: "str-video__end-recording__description", children: t('Are you sure you want end the recording?') }), jsxs("div", { className: "str-video__end-recording__actions", children: [jsx(CompositeButton, { variant: "secondary", onClick: close, children: t('Cancel') }), jsx(CompositeButton, { variant: "primary", onClick: isAwaitingResponse ? undefined : handleClick, children: isAwaitingResponse ? jsx(LoadingIndicator, {}) : t('End recording') })] })] }));
|
|
21
|
+
};
|
|
22
|
+
const ToggleEndRecordingMenuButton = forwardRef(function ToggleEndRecordingMenuButtonRender(props, ref) {
|
|
23
|
+
return (jsx(CompositeButton, { ref: ref, active: true, variant: "secondary", "data-testid": "recording-stop-button", children: jsx(Icon, { icon: "recording-off" }) }));
|
|
24
|
+
});
|
|
25
|
+
const RecordCallConfirmationButton = (props) => {
|
|
26
|
+
const { caption } = props;
|
|
27
|
+
const { t } = useI18n();
|
|
28
|
+
const { toggleCallRecording, isAwaitingResponse, isCallRecordingInProgress } = useToggleCallRecording();
|
|
29
|
+
const handleClick = createCallControlHandler(props, toggleCallRecording);
|
|
30
|
+
if (isCallRecordingInProgress) {
|
|
31
|
+
return (jsx(Restricted, { requiredGrants: [
|
|
32
|
+
OwnCapability.START_RECORD_CALL,
|
|
33
|
+
OwnCapability.STOP_RECORD_CALL,
|
|
34
|
+
], children: jsx(MenuToggle, { ToggleButton: ToggleEndRecordingMenuButton, visualType: MenuVisualType.PORTAL, children: jsx(RecordEndConfirmation, { onError: props.onError }) }) }));
|
|
35
|
+
}
|
|
36
|
+
const title = isAwaitingResponse
|
|
37
|
+
? t('Waiting for recording to start...')
|
|
38
|
+
: (caption ?? t('Record call'));
|
|
39
|
+
return (jsx(Restricted, { requiredGrants: [
|
|
40
|
+
OwnCapability.START_RECORD_CALL,
|
|
41
|
+
OwnCapability.STOP_RECORD_CALL,
|
|
42
|
+
], children: jsx(WithTooltip, { title: title, children: jsx(CompositeButton, { active: isCallRecordingInProgress, caption: caption, variant: "secondary", "data-testid": "recording-start-button", onClick: isAwaitingResponse ? undefined : handleClick, children: isAwaitingResponse ? (jsx(LoadingIndicator, {})) : (jsx(Icon, { icon: "recording-off" })) }) }) }));
|
|
43
|
+
};
|
|
44
|
+
const RecordCallButton = (props) => {
|
|
45
|
+
const { caption } = props;
|
|
46
|
+
const { t } = useI18n();
|
|
47
|
+
const { toggleCallRecording, isAwaitingResponse, isCallRecordingInProgress } = useToggleCallRecording();
|
|
48
|
+
const handleClick = createCallControlHandler(props, toggleCallRecording);
|
|
49
|
+
let title = caption ?? t('Record call');
|
|
50
|
+
if (isAwaitingResponse) {
|
|
51
|
+
title = isCallRecordingInProgress
|
|
52
|
+
? t('Waiting for recording to stop...')
|
|
53
|
+
: t('Waiting for recording to start...');
|
|
54
|
+
}
|
|
55
|
+
return (jsx(Restricted, { requiredGrants: [
|
|
56
|
+
OwnCapability.START_RECORD_CALL,
|
|
57
|
+
OwnCapability.STOP_RECORD_CALL,
|
|
58
|
+
], children: jsx(CompositeButton, { active: isCallRecordingInProgress, caption: caption, variant: "secondary", "data-testid": isCallRecordingInProgress
|
|
59
|
+
? 'recording-stop-button'
|
|
60
|
+
: 'recording-start-button', title: title, onClick: isAwaitingResponse ? undefined : handleClick, children: isAwaitingResponse ? (jsx(LoadingIndicator, {})) : (jsx(Icon, { icon: isCallRecordingInProgress ? 'recording-on' : 'recording-off' })) }) }));
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export { RecordCallButton, RecordCallConfirmationButton };
|
|
64
|
+
//# sourceMappingURL=RecordCallButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordCallButton.js","sources":["../../../../../../../src/components/CallControls/RecordCallButton.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nimport { OwnCapability } from '@stream-io/video-client';\nimport {\n Restricted,\n useI18n,\n useToggleCallRecording,\n} from '@stream-io/video-react-bindings';\nimport { CompositeButton } from '../Button/';\nimport { Icon } from '../Icon';\nimport {\n MenuToggle,\n MenuVisualType,\n ToggleMenuButtonProps,\n useMenuContext,\n} from '../Menu';\nimport { LoadingIndicator } from '../LoadingIndicator';\nimport { WithTooltip } from '../Tooltip';\nimport {\n createCallControlHandler,\n PropsWithErrorHandler,\n} from '../../utilities/callControlHandler';\n\nexport type RecordCallButtonProps = PropsWithErrorHandler<{\n caption?: string;\n}>;\n\nconst RecordEndConfirmation = (props: PropsWithErrorHandler) => {\n const { t } = useI18n();\n const { toggleCallRecording, isAwaitingResponse } = useToggleCallRecording();\n\n const { close } = useMenuContext();\n\n const handleClick = createCallControlHandler(props, toggleCallRecording);\n\n return (\n <div className=\"str-video__end-recording__confirmation\">\n <div className=\"str-video__end-recording__header\">\n <Icon icon=\"recording-on\" />\n <h2 className=\"str-video__end-recording__heading\">\n {t('End recording')}\n </h2>\n </div>\n <p className=\"str-video__end-recording__description\">\n {t('Are you sure you want end the recording?')}\n </p>\n <div className=\"str-video__end-recording__actions\">\n <CompositeButton variant=\"secondary\" onClick={close}>\n {t('Cancel')}\n </CompositeButton>\n <CompositeButton\n variant=\"primary\"\n onClick={isAwaitingResponse ? undefined : handleClick}\n >\n {isAwaitingResponse ? <LoadingIndicator /> : t('End recording')}\n </CompositeButton>\n </div>\n </div>\n );\n};\n\nconst ToggleEndRecordingMenuButton = forwardRef<\n HTMLDivElement,\n ToggleMenuButtonProps\n>(function ToggleEndRecordingMenuButtonRender(props, ref) {\n return (\n <CompositeButton\n ref={ref}\n active={true}\n variant=\"secondary\"\n data-testid=\"recording-stop-button\"\n >\n <Icon icon=\"recording-off\" />\n </CompositeButton>\n );\n});\n\nexport const RecordCallConfirmationButton = (\n props: PropsWithErrorHandler<{ caption?: string }>,\n) => {\n const { caption } = props;\n const { t } = useI18n();\n const { toggleCallRecording, isAwaitingResponse, isCallRecordingInProgress } =\n useToggleCallRecording();\n\n const handleClick = createCallControlHandler(props, toggleCallRecording);\n\n if (isCallRecordingInProgress) {\n return (\n <Restricted\n requiredGrants={[\n OwnCapability.START_RECORD_CALL,\n OwnCapability.STOP_RECORD_CALL,\n ]}\n >\n <MenuToggle\n ToggleButton={ToggleEndRecordingMenuButton}\n visualType={MenuVisualType.PORTAL}\n >\n <RecordEndConfirmation onError={props.onError} />\n </MenuToggle>\n </Restricted>\n );\n }\n\n const title = isAwaitingResponse\n ? t('Waiting for recording to start...')\n : (caption ?? t('Record call'));\n\n return (\n <Restricted\n requiredGrants={[\n OwnCapability.START_RECORD_CALL,\n OwnCapability.STOP_RECORD_CALL,\n ]}\n >\n <WithTooltip title={title}>\n <CompositeButton\n active={isCallRecordingInProgress}\n caption={caption}\n variant=\"secondary\"\n data-testid=\"recording-start-button\"\n onClick={isAwaitingResponse ? undefined : handleClick}\n >\n {isAwaitingResponse ? (\n <LoadingIndicator />\n ) : (\n <Icon icon=\"recording-off\" />\n )}\n </CompositeButton>\n </WithTooltip>\n </Restricted>\n );\n};\n\nexport const RecordCallButton = (props: RecordCallButtonProps) => {\n const { caption } = props;\n const { t } = useI18n();\n const { toggleCallRecording, isAwaitingResponse, isCallRecordingInProgress } =\n useToggleCallRecording();\n\n const handleClick = createCallControlHandler(props, toggleCallRecording);\n\n let title = caption ?? t('Record call');\n\n if (isAwaitingResponse) {\n title = isCallRecordingInProgress\n ? t('Waiting for recording to stop...')\n : t('Waiting for recording to start...');\n }\n\n return (\n <Restricted\n requiredGrants={[\n OwnCapability.START_RECORD_CALL,\n OwnCapability.STOP_RECORD_CALL,\n ]}\n >\n <CompositeButton\n active={isCallRecordingInProgress}\n caption={caption}\n variant=\"secondary\"\n data-testid={\n isCallRecordingInProgress\n ? 'recording-stop-button'\n : 'recording-start-button'\n }\n title={title}\n onClick={isAwaitingResponse ? undefined : handleClick}\n >\n {isAwaitingResponse ? (\n <LoadingIndicator />\n ) : (\n <Icon\n icon={isCallRecordingInProgress ? 'recording-on' : 'recording-off'}\n />\n )}\n </CompositeButton>\n </Restricted>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { RequestPermissionRequestPermissionsEnum, OwnCapability } from '@stream-io/video-client';
|
|
3
|
+
import { useI18n, useCallStateHooks, Restricted } from '@stream-io/video-react-bindings';
|
|
4
|
+
import { CompositeButton } from '../Button/CompositeButton.js';
|
|
5
|
+
import '../Button/IconButton.js';
|
|
6
|
+
import 'react';
|
|
7
|
+
import 'clsx';
|
|
8
|
+
import '@floating-ui/react';
|
|
9
|
+
import { useRequestPermission } from '../../hooks/useRequestPermission.js';
|
|
10
|
+
import { PermissionNotification } from '../Notification/PermissionNotification.js';
|
|
11
|
+
import { Icon } from '../Icon/Icon.js';
|
|
12
|
+
import { WithTooltip } from '../Tooltip/WithTooltip.js';
|
|
13
|
+
import { createCallControlHandler } from '../../utilities/callControlHandler.js';
|
|
14
|
+
|
|
15
|
+
const ScreenShareButton = (props) => {
|
|
16
|
+
const { t } = useI18n();
|
|
17
|
+
const { caption, optimisticUpdates } = props;
|
|
18
|
+
const { useHasOngoingScreenShare, useScreenShareState, useCallSettings } = useCallStateHooks();
|
|
19
|
+
const isSomeoneScreenSharing = useHasOngoingScreenShare();
|
|
20
|
+
const { hasPermission, requestPermission, isAwaitingPermission } = useRequestPermission(RequestPermissionRequestPermissionsEnum.SCREENSHARE);
|
|
21
|
+
const callSettings = useCallSettings();
|
|
22
|
+
const isScreenSharingAllowed = callSettings?.screensharing.enabled;
|
|
23
|
+
const { screenShare, optionsAwareIsMute, isTogglePending } = useScreenShareState({
|
|
24
|
+
optimisticUpdates,
|
|
25
|
+
});
|
|
26
|
+
const amIScreenSharing = !optionsAwareIsMute;
|
|
27
|
+
const disableScreenShareButton = (!amIScreenSharing &&
|
|
28
|
+
(isSomeoneScreenSharing || isScreenSharingAllowed === false)) ||
|
|
29
|
+
(!optimisticUpdates && isTogglePending);
|
|
30
|
+
const handleClick = createCallControlHandler(props, async () => {
|
|
31
|
+
if (!hasPermission) {
|
|
32
|
+
await requestPermission();
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
await screenShare.toggle();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return (jsx(Restricted, { requiredGrants: [OwnCapability.SCREENSHARE], children: jsx(PermissionNotification, { permission: OwnCapability.SCREENSHARE, isAwaitingApproval: isAwaitingPermission, messageApproved: t('You can now share your screen.'), messageAwaitingApproval: t('Awaiting for an approval to share screen.'), messageRevoked: t('You can no longer share your screen.'), children: jsx(WithTooltip, { title: caption ?? t('Share screen'), children: jsx(CompositeButton, { active: isSomeoneScreenSharing || amIScreenSharing, caption: caption, variant: "primary", "data-testid": isSomeoneScreenSharing
|
|
39
|
+
? 'screen-share-stop-button'
|
|
40
|
+
: 'screen-share-start-button', disabled: disableScreenShareButton, onClick: handleClick, children: jsx(Icon, { icon: isSomeoneScreenSharing ? 'screen-share-on' : 'screen-share-off' }) }) }) }) }));
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export { ScreenShareButton };
|
|
44
|
+
//# sourceMappingURL=ScreenShareButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenShareButton.js","sources":["../../../../../../../src/components/CallControls/ScreenShareButton.tsx"],"sourcesContent":["import {\n OwnCapability,\n RequestPermissionRequestPermissionsEnum,\n} from '@stream-io/video-client';\nimport {\n Restricted,\n useCallStateHooks,\n useI18n,\n UseInputMediaDeviceOptions,\n} from '@stream-io/video-react-bindings';\nimport { CompositeButton } from '../Button/';\nimport { PermissionNotification } from '../Notification';\nimport { useRequestPermission } from '../../hooks';\nimport { Icon } from '../Icon';\nimport { WithTooltip } from '../Tooltip';\nimport {\n PropsWithErrorHandler,\n createCallControlHandler,\n} from '../../utilities/callControlHandler';\n\nexport type ScreenShareButtonProps = PropsWithErrorHandler<\n {\n caption?: string;\n } & UseInputMediaDeviceOptions\n>;\n\nexport const ScreenShareButton = (props: ScreenShareButtonProps) => {\n const { t } = useI18n();\n const { caption, optimisticUpdates } = props;\n\n const { useHasOngoingScreenShare, useScreenShareState, useCallSettings } =\n useCallStateHooks();\n const isSomeoneScreenSharing = useHasOngoingScreenShare();\n const { hasPermission, requestPermission, isAwaitingPermission } =\n useRequestPermission(RequestPermissionRequestPermissionsEnum.SCREENSHARE);\n\n const callSettings = useCallSettings();\n const isScreenSharingAllowed = callSettings?.screensharing.enabled;\n\n const { screenShare, optionsAwareIsMute, isTogglePending } =\n useScreenShareState({\n optimisticUpdates,\n });\n const amIScreenSharing = !optionsAwareIsMute;\n const disableScreenShareButton =\n (!amIScreenSharing &&\n (isSomeoneScreenSharing || isScreenSharingAllowed === false)) ||\n (!optimisticUpdates && isTogglePending);\n const handleClick = createCallControlHandler(props, async () => {\n if (!hasPermission) {\n await requestPermission();\n } else {\n await screenShare.toggle();\n }\n });\n\n return (\n <Restricted requiredGrants={[OwnCapability.SCREENSHARE]}>\n <PermissionNotification\n permission={OwnCapability.SCREENSHARE}\n isAwaitingApproval={isAwaitingPermission}\n messageApproved={t('You can now share your screen.')}\n messageAwaitingApproval={t('Awaiting for an approval to share screen.')}\n messageRevoked={t('You can no longer share your screen.')}\n >\n <WithTooltip title={caption ?? t('Share screen')}>\n <CompositeButton\n active={isSomeoneScreenSharing || amIScreenSharing}\n caption={caption}\n variant=\"primary\"\n data-testid={\n isSomeoneScreenSharing\n ? 'screen-share-stop-button'\n : 'screen-share-start-button'\n }\n disabled={disableScreenShareButton}\n onClick={handleClick}\n >\n <Icon\n icon={\n isSomeoneScreenSharing ? 'screen-share-on' : 'screen-share-off'\n }\n />\n </CompositeButton>\n </WithTooltip>\n </PermissionNotification>\n </Restricted>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;;;;;;;;AA0BO,MAAM,iBAAiB,GAAG,CAAC,KAA6B,KAAI;AACjE,IAAA,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE;AACvB,IAAA,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,GAAG,KAAK;IAE5C,MAAM,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,eAAe,EAAE,GACtE,iBAAiB,EAAE;AACrB,IAAA,MAAM,sBAAsB,GAAG,wBAAwB,EAAE;AACzD,IAAA,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,GAC9D,oBAAoB,CAAC,uCAAuC,CAAC,WAAW,CAAC;AAE3E,IAAA,MAAM,YAAY,GAAG,eAAe,EAAE;AACtC,IAAA,MAAM,sBAAsB,GAAG,YAAY,EAAE,aAAa,CAAC,OAAO;IAElE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,GACxD,mBAAmB,CAAC;QAClB,iBAAiB;AAClB,KAAA,CAAC;AACJ,IAAA,MAAM,gBAAgB,GAAG,CAAC,kBAAkB;AAC5C,IAAA,MAAM,wBAAwB,GAC5B,CAAC,CAAC,gBAAgB;AAChB,SAAC,sBAAsB,IAAI,sBAAsB,KAAK,KAAK,CAAC;AAC9D,SAAC,CAAC,iBAAiB,IAAI,eAAe,CAAC;IACzC,MAAM,WAAW,GAAG,wBAAwB,CAAC,KAAK,EAAE,YAAW;QAC7D,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,iBAAiB,EAAE;QAC3B;aAAO;AACL,YAAA,MAAM,WAAW,CAAC,MAAM,EAAE;QAC5B;AACF,IAAA,CAAC,CAAC;AAEF,IAAA,QACEA,GAAA,CAAC,UAAU,EAAA,EAAC,cAAc,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,EAAA,QAAA,EACrDA,GAAA,CAAC,sBAAsB,IACrB,UAAU,EAAE,aAAa,CAAC,WAAW,EACrC,kBAAkB,EAAE,oBAAoB,EACxC,eAAe,EAAE,CAAC,CAAC,gCAAgC,CAAC,EACpD,uBAAuB,EAAE,CAAC,CAAC,2CAA2C,CAAC,EACvE,cAAc,EAAE,CAAC,CAAC,sCAAsC,CAAC,EAAA,QAAA,EAEzDA,GAAA,CAAC,WAAW,EAAA,EAAC,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC,cAAc,CAAC,EAAA,QAAA,EAC9CA,GAAA,CAAC,eAAe,EAAA,EACd,MAAM,EAAE,sBAAsB,IAAI,gBAAgB,EAClD,OAAO,EAAE,OAAO,EAChB,OAAO,EAAC,SAAS,iBAEf;AACE,0BAAE;AACF,0BAAE,2BAA2B,EAEjC,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,WAAW,EAAA,QAAA,EAEpBA,GAAA,CAAC,IAAI,EAAA,EACH,IAAI,EACF,sBAAsB,GAAG,iBAAiB,GAAG,kBAAkB,EAAA,CAEjE,EAAA,CACc,EAAA,CACN,EAAA,CACS,EAAA,CACd;AAEjB;;;;"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { SfuModels, RequestPermissionRequestPermissionsEnum, OwnCapability } from '@stream-io/video-client';
|
|
3
|
+
import { useI18n, useCallStateHooks, Restricted } from '@stream-io/video-react-bindings';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import { CompositeButton } from '../Button/CompositeButton.js';
|
|
6
|
+
import '../Button/IconButton.js';
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
import { Icon } from '../Icon/Icon.js';
|
|
9
|
+
import '../DeviceSettings/DeviceSettings.js';
|
|
10
|
+
import '@floating-ui/react';
|
|
11
|
+
import { useRequestPermission } from '../../hooks/useRequestPermission.js';
|
|
12
|
+
import '../DropdownSelect/DropdownSelect.js';
|
|
13
|
+
import '../Menu/MenuToggle.js';
|
|
14
|
+
import { DeviceSelectorAudioInput } from '../DeviceSettings/DeviceSelectorAudio.js';
|
|
15
|
+
import { PermissionNotification } from '../Notification/PermissionNotification.js';
|
|
16
|
+
import { WithTooltip } from '../Tooltip/WithTooltip.js';
|
|
17
|
+
import { createCallControlHandler } from '../../utilities/callControlHandler.js';
|
|
18
|
+
|
|
19
|
+
const ToggleAudioPreviewButton = (props) => {
|
|
20
|
+
const { caption, Menu = DeviceSelectorAudioInput, menuPlacement = 'top', onMenuToggle, optimisticUpdates, ...restCompositeButtonProps } = props;
|
|
21
|
+
const { t } = useI18n();
|
|
22
|
+
const { useMicrophoneState, useLocalParticipant } = useCallStateHooks();
|
|
23
|
+
const { microphone, hasBrowserPermission, isPromptingPermission, optionsAwareIsMute, isTogglePending, } = useMicrophoneState({ optimisticUpdates });
|
|
24
|
+
const localParticipant = useLocalParticipant();
|
|
25
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(SfuModels.TrackType.AUDIO);
|
|
26
|
+
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
27
|
+
const handleClick = createCallControlHandler(props, () => microphone.toggle());
|
|
28
|
+
return (jsx(WithTooltip, { title: !hasBrowserPermission
|
|
29
|
+
? t('Check your browser audio permissions')
|
|
30
|
+
: isSystemMuted
|
|
31
|
+
? t('Microphone is paused by your system')
|
|
32
|
+
: (caption ?? t('Mic')), tooltipDisabled: tooltipDisabled, children: jsxs(CompositeButton, { active: optionsAwareIsMute, caption: caption, className: clsx(!hasBrowserPermission && 'str-video__device-unavailable'), variant: "secondary", disabled: !hasBrowserPermission || (!optimisticUpdates && isTogglePending), "data-testid": optionsAwareIsMute
|
|
33
|
+
? 'preview-audio-unmute-button'
|
|
34
|
+
: 'preview-audio-mute-button', onClick: handleClick, Menu: Menu, menuPlacement: menuPlacement, ...restCompositeButtonProps, onMenuToggle: (shown) => {
|
|
35
|
+
setTooltipDisabled(shown);
|
|
36
|
+
onMenuToggle?.(shown);
|
|
37
|
+
}, children: [jsx(Icon, { icon: !optionsAwareIsMute ? 'mic' : 'mic-off' }), !hasBrowserPermission && (jsx("span", { className: "str-video__no-media-permission", title: t('Check your browser audio permissions'), children: "!" })), isPromptingPermission && (jsx("span", { className: "str-video__pending-permission", title: t('Waiting for permission'), children: "?" })), isSystemMuted && hasBrowserPermission && (jsx("span", { className: "str-video__system-muted", title: t('Microphone is paused by your system'), children: "!" }))] }) }));
|
|
38
|
+
};
|
|
39
|
+
const ToggleAudioPublishingButton = (props) => {
|
|
40
|
+
const { t } = useI18n();
|
|
41
|
+
const { caption, Menu = jsx(DeviceSelectorAudioInput, { visualType: "list" }), menuPlacement = 'top', onMenuToggle, optimisticUpdates, ...restCompositeButtonProps } = props;
|
|
42
|
+
const { hasPermission, requestPermission, isAwaitingPermission } = useRequestPermission(RequestPermissionRequestPermissionsEnum.SEND_AUDIO);
|
|
43
|
+
const { useMicrophoneState, useLocalParticipant } = useCallStateHooks();
|
|
44
|
+
const { microphone, hasBrowserPermission, isPromptingPermission, isTogglePending, optionsAwareIsMute, } = useMicrophoneState({ optimisticUpdates });
|
|
45
|
+
const localParticipant = useLocalParticipant();
|
|
46
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(SfuModels.TrackType.AUDIO);
|
|
47
|
+
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
48
|
+
const handleClick = createCallControlHandler(props, async () => {
|
|
49
|
+
if (!hasPermission) {
|
|
50
|
+
await requestPermission();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
await microphone.toggle();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return (jsx(Restricted, { requiredGrants: [OwnCapability.SEND_AUDIO], children: jsx(PermissionNotification, { permission: OwnCapability.SEND_AUDIO, isAwaitingApproval: isAwaitingPermission, messageApproved: t('You can now speak.'), messageAwaitingApproval: t('Awaiting for an approval to speak.'), messageRevoked: t('You can no longer speak.'), children: jsx(WithTooltip, { title: !hasPermission
|
|
57
|
+
? t('You have no permission to share your audio')
|
|
58
|
+
: !hasBrowserPermission
|
|
59
|
+
? t('Check your browser mic permissions')
|
|
60
|
+
: isSystemMuted
|
|
61
|
+
? t('Microphone is paused by your system')
|
|
62
|
+
: (caption ?? t('Mic')), tooltipDisabled: tooltipDisabled, children: jsxs(CompositeButton, { active: optionsAwareIsMute, caption: caption, variant: "secondary", disabled: !hasBrowserPermission ||
|
|
63
|
+
!hasPermission ||
|
|
64
|
+
// disable button while the toggle action is pending when not using optimistic updates
|
|
65
|
+
(!optimisticUpdates && isTogglePending), "data-testid": optionsAwareIsMute ? 'audio-unmute-button' : 'audio-mute-button', onClick: handleClick, Menu: Menu, menuPlacement: menuPlacement, menuOffset: 16, ...restCompositeButtonProps, onMenuToggle: (shown) => {
|
|
66
|
+
setTooltipDisabled(shown);
|
|
67
|
+
onMenuToggle?.(shown);
|
|
68
|
+
}, children: [jsx(Icon, { icon: optionsAwareIsMute ? 'mic-off' : 'mic' }), (!hasBrowserPermission || !hasPermission) && (jsx("span", { className: "str-video__no-media-permission", children: "!" })), isPromptingPermission && (jsx("span", { className: "str-video__pending-permission", title: t('Waiting for permission'), children: "?" })), isSystemMuted && hasBrowserPermission && hasPermission && (jsx("span", { className: "str-video__system-muted", title: t('Microphone is paused by your system'), children: "!" }))] }) }) }) }));
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export { ToggleAudioPreviewButton, ToggleAudioPublishingButton };
|
|
72
|
+
//# sourceMappingURL=ToggleAudioButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleAudioButton.js","sources":["../../../../../../../src/components/CallControls/ToggleAudioButton.tsx"],"sourcesContent":["import {\n OwnCapability,\n RequestPermissionRequestPermissionsEnum,\n SfuModels,\n} from '@stream-io/video-client';\nimport {\n Restricted,\n useCallStateHooks,\n useI18n,\n type UseInputMediaDeviceOptions,\n} from '@stream-io/video-react-bindings';\nimport clsx from 'clsx';\nimport { CompositeButton, IconButtonWithMenuProps } from '../Button';\nimport { DeviceSelectorAudioInput } from '../DeviceSettings';\nimport { PermissionNotification } from '../Notification';\nimport { useRequestPermission } from '../../hooks';\nimport { Icon } from '../Icon';\nimport { WithTooltip } from '../Tooltip';\nimport { useState } from 'react';\nimport {\n createCallControlHandler,\n PropsWithErrorHandler,\n} from '../../utilities/callControlHandler';\n\nexport type ToggleAudioPreviewButtonProps = PropsWithErrorHandler<\n Pick<\n IconButtonWithMenuProps,\n 'caption' | 'Menu' | 'menuPlacement' | 'onMenuToggle'\n > &\n UseInputMediaDeviceOptions\n>;\n\nexport const ToggleAudioPreviewButton = (\n props: ToggleAudioPreviewButtonProps,\n) => {\n const {\n caption,\n Menu = DeviceSelectorAudioInput,\n menuPlacement = 'top',\n onMenuToggle,\n optimisticUpdates,\n ...restCompositeButtonProps\n } = props;\n const { t } = useI18n();\n const { useMicrophoneState, useLocalParticipant } = useCallStateHooks();\n const {\n microphone,\n hasBrowserPermission,\n isPromptingPermission,\n optionsAwareIsMute,\n isTogglePending,\n } = useMicrophoneState({ optimisticUpdates });\n const localParticipant = useLocalParticipant();\n const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(\n SfuModels.TrackType.AUDIO,\n );\n const [tooltipDisabled, setTooltipDisabled] = useState(false);\n const handleClick = createCallControlHandler(props, () =>\n microphone.toggle(),\n );\n\n return (\n <WithTooltip\n title={\n !hasBrowserPermission\n ? t('Check your browser audio permissions')\n : isSystemMuted\n ? t('Microphone is paused by your system')\n : (caption ?? t('Mic'))\n }\n tooltipDisabled={tooltipDisabled}\n >\n <CompositeButton\n active={optionsAwareIsMute}\n caption={caption}\n className={clsx(\n !hasBrowserPermission && 'str-video__device-unavailable',\n )}\n variant=\"secondary\"\n disabled={\n !hasBrowserPermission || (!optimisticUpdates && isTogglePending)\n }\n data-testid={\n optionsAwareIsMute\n ? 'preview-audio-unmute-button'\n : 'preview-audio-mute-button'\n }\n onClick={handleClick}\n Menu={Menu}\n menuPlacement={menuPlacement}\n {...restCompositeButtonProps}\n onMenuToggle={(shown) => {\n setTooltipDisabled(shown);\n onMenuToggle?.(shown);\n }}\n >\n <Icon icon={!optionsAwareIsMute ? 'mic' : 'mic-off'} />\n {!hasBrowserPermission && (\n <span\n className=\"str-video__no-media-permission\"\n title={t('Check your browser audio permissions')}\n children=\"!\"\n />\n )}\n {isPromptingPermission && (\n <span\n className=\"str-video__pending-permission\"\n title={t('Waiting for permission')}\n children=\"?\"\n />\n )}\n {isSystemMuted && hasBrowserPermission && (\n <span\n className=\"str-video__system-muted\"\n title={t('Microphone is paused by your system')}\n children=\"!\"\n />\n )}\n </CompositeButton>\n </WithTooltip>\n );\n};\n\nexport type ToggleAudioPublishingButtonProps = PropsWithErrorHandler<\n Pick<\n IconButtonWithMenuProps,\n 'caption' | 'Menu' | 'menuPlacement' | 'onMenuToggle'\n > &\n UseInputMediaDeviceOptions\n>;\n\nexport const ToggleAudioPublishingButton = (\n props: ToggleAudioPublishingButtonProps,\n) => {\n const { t } = useI18n();\n const {\n caption,\n Menu = <DeviceSelectorAudioInput visualType=\"list\" />,\n menuPlacement = 'top',\n onMenuToggle,\n optimisticUpdates,\n ...restCompositeButtonProps\n } = props;\n\n const { hasPermission, requestPermission, isAwaitingPermission } =\n useRequestPermission(RequestPermissionRequestPermissionsEnum.SEND_AUDIO);\n\n const { useMicrophoneState, useLocalParticipant } = useCallStateHooks();\n const {\n microphone,\n hasBrowserPermission,\n isPromptingPermission,\n isTogglePending,\n optionsAwareIsMute,\n } = useMicrophoneState({ optimisticUpdates });\n const localParticipant = useLocalParticipant();\n const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(\n SfuModels.TrackType.AUDIO,\n );\n\n const [tooltipDisabled, setTooltipDisabled] = useState(false);\n const handleClick = createCallControlHandler(props, async () => {\n if (!hasPermission) {\n await requestPermission();\n } else {\n await microphone.toggle();\n }\n });\n\n return (\n <Restricted requiredGrants={[OwnCapability.SEND_AUDIO]}>\n <PermissionNotification\n permission={OwnCapability.SEND_AUDIO}\n isAwaitingApproval={isAwaitingPermission}\n messageApproved={t('You can now speak.')}\n messageAwaitingApproval={t('Awaiting for an approval to speak.')}\n messageRevoked={t('You can no longer speak.')}\n >\n <WithTooltip\n title={\n !hasPermission\n ? t('You have no permission to share your audio')\n : !hasBrowserPermission\n ? t('Check your browser mic permissions')\n : isSystemMuted\n ? t('Microphone is paused by your system')\n : (caption ?? t('Mic'))\n }\n tooltipDisabled={tooltipDisabled}\n >\n <CompositeButton\n active={optionsAwareIsMute}\n caption={caption}\n variant=\"secondary\"\n disabled={\n !hasBrowserPermission ||\n !hasPermission ||\n // disable button while the toggle action is pending when not using optimistic updates\n (!optimisticUpdates && isTogglePending)\n }\n data-testid={\n optionsAwareIsMute ? 'audio-unmute-button' : 'audio-mute-button'\n }\n onClick={handleClick}\n Menu={Menu}\n menuPlacement={menuPlacement}\n menuOffset={16}\n {...restCompositeButtonProps}\n onMenuToggle={(shown) => {\n setTooltipDisabled(shown);\n onMenuToggle?.(shown);\n }}\n >\n <Icon icon={optionsAwareIsMute ? 'mic-off' : 'mic'} />\n {(!hasBrowserPermission || !hasPermission) && (\n <span className=\"str-video__no-media-permission\">!</span>\n )}\n {isPromptingPermission && (\n <span\n className=\"str-video__pending-permission\"\n title={t('Waiting for permission')}\n >\n ?\n </span>\n )}\n {isSystemMuted && hasBrowserPermission && hasPermission && (\n <span\n className=\"str-video__system-muted\"\n title={t('Microphone is paused by your system')}\n >\n !\n </span>\n )}\n </CompositeButton>\n </WithTooltip>\n </PermissionNotification>\n </Restricted>\n );\n};\n"],"names":["_jsx","_jsxs"],"mappings":";;;;;;;;;;;;;;;;;;AAgCO,MAAM,wBAAwB,GAAG,CACtC,KAAoC,KAClC;IACF,MAAM,EACJ,OAAO,EACP,IAAI,GAAG,wBAAwB,EAC/B,aAAa,GAAG,KAAK,EACrB,YAAY,EACZ,iBAAiB,EACjB,GAAG,wBAAwB,EAC5B,GAAG,KAAK;AACT,IAAA,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE;IACvB,MAAM,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,GAAG,iBAAiB,EAAE;AACvE,IAAA,MAAM,EACJ,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,GAChB,GAAG,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;AAC7C,IAAA,MAAM,gBAAgB,GAAG,mBAAmB,EAAE;AAC9C,IAAA,MAAM,aAAa,GAAG,CAAC,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,CACnE,SAAS,CAAC,SAAS,CAAC,KAAK,CAC1B;IACD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AAC7D,IAAA,MAAM,WAAW,GAAG,wBAAwB,CAAC,KAAK,EAAE,MAClD,UAAU,CAAC,MAAM,EAAE,CACpB;AAED,IAAA,QACEA,GAAA,CAAC,WAAW,IACV,KAAK,EACH,CAAC;AACC,cAAE,CAAC,CAAC,sCAAsC;AAC1C,cAAE;AACA,kBAAE,CAAC,CAAC,qCAAqC;mBACtC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAE7B,eAAe,EAAE,eAAe,EAAA,QAAA,EAEhCC,IAAA,CAAC,eAAe,EAAA,EACd,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,IAAI,CACb,CAAC,oBAAoB,IAAI,+BAA+B,CACzD,EACD,OAAO,EAAC,WAAW,EACnB,QAAQ,EACN,CAAC,oBAAoB,KAAK,CAAC,iBAAiB,IAAI,eAAe,CAAC,EAAA,aAAA,EAGhE;AACE,kBAAE;kBACA,2BAA2B,EAEjC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,KACxB,wBAAwB,EAC5B,YAAY,EAAE,CAAC,KAAK,KAAI;gBACtB,kBAAkB,CAAC,KAAK,CAAC;AACzB,gBAAA,YAAY,GAAG,KAAK,CAAC;AACvB,YAAA,CAAC,aAEDD,GAAA,CAAC,IAAI,IAAC,IAAI,EAAE,CAAC,kBAAkB,GAAG,KAAK,GAAG,SAAS,EAAA,CAAI,EACtD,CAAC,oBAAoB,KACpBA,cACE,SAAS,EAAC,gCAAgC,EAC1C,KAAK,EAAE,CAAC,CAAC,sCAAsC,CAAC,EAChD,QAAQ,EAAC,GAAG,GACZ,CACH,EACA,qBAAqB,KACpBA,GAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAC,+BAA+B,EACzC,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC,EAClC,QAAQ,EAAC,GAAG,EAAA,CACZ,CACH,EACA,aAAa,IAAI,oBAAoB,KACpCA,GAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAC,yBAAyB,EACnC,KAAK,EAAE,CAAC,CAAC,qCAAqC,CAAC,EAC/C,QAAQ,EAAC,GAAG,EAAA,CACZ,CACH,CAAA,EAAA,CACe,EAAA,CACN;AAElB;AAUO,MAAM,2BAA2B,GAAG,CACzC,KAAuC,KACrC;AACF,IAAA,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE;IACvB,MAAM,EACJ,OAAO,EACP,IAAI,GAAGA,GAAA,CAAC,wBAAwB,EAAA,EAAC,UAAU,EAAC,MAAM,EAAA,CAAG,EACrD,aAAa,GAAG,KAAK,EACrB,YAAY,EACZ,iBAAiB,EACjB,GAAG,wBAAwB,EAC5B,GAAG,KAAK;AAET,IAAA,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,GAC9D,oBAAoB,CAAC,uCAAuC,CAAC,UAAU,CAAC;IAE1E,MAAM,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,GAAG,iBAAiB,EAAE;AACvE,IAAA,MAAM,EACJ,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,GAAG,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;AAC7C,IAAA,MAAM,gBAAgB,GAAG,mBAAmB,EAAE;AAC9C,IAAA,MAAM,aAAa,GAAG,CAAC,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,CACnE,SAAS,CAAC,SAAS,CAAC,KAAK,CAC1B;IAED,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC7D,MAAM,WAAW,GAAG,wBAAwB,CAAC,KAAK,EAAE,YAAW;QAC7D,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,iBAAiB,EAAE;QAC3B;aAAO;AACL,YAAA,MAAM,UAAU,CAAC,MAAM,EAAE;QAC3B;AACF,IAAA,CAAC,CAAC;IAEF,QACEA,GAAA,CAAC,UAAU,EAAA,EAAC,cAAc,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,EAAA,QAAA,EACpDA,IAAC,sBAAsB,EAAA,EACrB,UAAU,EAAE,aAAa,CAAC,UAAU,EACpC,kBAAkB,EAAE,oBAAoB,EACxC,eAAe,EAAE,CAAC,CAAC,oBAAoB,CAAC,EACxC,uBAAuB,EAAE,CAAC,CAAC,oCAAoC,CAAC,EAChE,cAAc,EAAE,CAAC,CAAC,0BAA0B,CAAC,EAAA,QAAA,EAE7CA,GAAA,CAAC,WAAW,EAAA,EACV,KAAK,EACH,CAAC;AACC,sBAAE,CAAC,CAAC,4CAA4C;sBAC9C,CAAC;AACD,0BAAE,CAAC,CAAC,oCAAoC;AACxC,0BAAE;AACA,8BAAE,CAAC,CAAC,qCAAqC;AACzC,+BAAG,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAE/B,eAAe,EAAE,eAAe,YAEhCC,IAAA,CAAC,eAAe,EAAA,EACd,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAC,WAAW,EACnB,QAAQ,EACN,CAAC,oBAAoB;AACrB,wBAAA,CAAC,aAAa;;AAEd,yBAAC,CAAC,iBAAiB,IAAI,eAAe,CAAC,iBAGvC,kBAAkB,GAAG,qBAAqB,GAAG,mBAAmB,EAElE,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,EAAE,EAAA,GACV,wBAAwB,EAC5B,YAAY,EAAE,CAAC,KAAK,KAAI;wBACtB,kBAAkB,CAAC,KAAK,CAAC;AACzB,wBAAA,YAAY,GAAG,KAAK,CAAC;AACvB,oBAAA,CAAC,EAAA,QAAA,EAAA,CAEDD,GAAA,CAAC,IAAI,EAAA,EAAC,IAAI,EAAE,kBAAkB,GAAG,SAAS,GAAG,KAAK,EAAA,CAAI,EACrD,CAAC,CAAC,oBAAoB,IAAI,CAAC,aAAa,MACvCA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,gCAAgC,EAAA,QAAA,EAAA,GAAA,EAAA,CAAS,CAC1D,EACA,qBAAqB,KACpBA,GAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAC,+BAA+B,EACzC,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC,EAAA,QAAA,EAAA,GAAA,EAAA,CAG7B,CACR,EACA,aAAa,IAAI,oBAAoB,IAAI,aAAa,KACrDA,GAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAC,yBAAyB,EACnC,KAAK,EAAE,CAAC,CAAC,qCAAqC,CAAC,EAAA,QAAA,EAAA,GAAA,EAAA,CAG1C,CACR,CAAA,EAAA,CACe,EAAA,CACN,EAAA,CACS,EAAA,CACd;AAEjB;;;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { CompositeButton } from '../Button/CompositeButton.js';
|
|
3
|
+
import '../Button/IconButton.js';
|
|
4
|
+
import { useI18n } from '@stream-io/video-react-bindings';
|
|
5
|
+
import { Icon } from '../Icon/Icon.js';
|
|
6
|
+
import { useState } from 'react';
|
|
7
|
+
import '@stream-io/video-client';
|
|
8
|
+
import '../DeviceSettings/DeviceSettings.js';
|
|
9
|
+
import 'clsx';
|
|
10
|
+
import '@floating-ui/react';
|
|
11
|
+
import '../DropdownSelect/DropdownSelect.js';
|
|
12
|
+
import '../Menu/MenuToggle.js';
|
|
13
|
+
import { DeviceSelectorAudioOutput } from '../DeviceSettings/DeviceSelectorAudio.js';
|
|
14
|
+
import { WithTooltip } from '../Tooltip/WithTooltip.js';
|
|
15
|
+
|
|
16
|
+
const ToggleAudioOutputButton = (props) => {
|
|
17
|
+
const { t } = useI18n();
|
|
18
|
+
const { caption, Menu = DeviceSelectorAudioOutput, menuPlacement = 'top', onMenuToggle, } = props;
|
|
19
|
+
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
20
|
+
return (jsx(WithTooltip, { title: caption || t('Speakers'), tooltipDisabled: tooltipDisabled, children: jsx(CompositeButton, { Menu: Menu, menuPlacement: menuPlacement, caption: caption, "data-testid": "audio-output-button", onMenuToggle: (shown) => {
|
|
21
|
+
setTooltipDisabled(shown);
|
|
22
|
+
onMenuToggle?.(shown);
|
|
23
|
+
}, children: jsx(Icon, { icon: "speaker" }) }) }));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { ToggleAudioOutputButton };
|
|
27
|
+
//# sourceMappingURL=ToggleAudioOutputButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleAudioOutputButton.js","sources":["../../../../../../../src/components/CallControls/ToggleAudioOutputButton.tsx"],"sourcesContent":["import { CompositeButton, IconButtonWithMenuProps } from '../Button';\nimport { useI18n } from '@stream-io/video-react-bindings';\nimport { Icon } from '../Icon';\nimport { DeviceSelectorAudioOutput } from '../DeviceSettings';\nimport { WithTooltip } from '../Tooltip';\nimport { useState } from 'react';\n\nexport type ToggleAudioOutputButtonProps = Pick<\n IconButtonWithMenuProps,\n 'caption' | 'Menu' | 'menuPlacement' | 'onMenuToggle'\n>;\n\nexport const ToggleAudioOutputButton = (\n props: ToggleAudioOutputButtonProps,\n) => {\n const { t } = useI18n();\n const {\n caption,\n Menu = DeviceSelectorAudioOutput,\n menuPlacement = 'top',\n onMenuToggle,\n } = props;\n const [tooltipDisabled, setTooltipDisabled] = useState(false);\n\n return (\n <WithTooltip\n title={caption || t('Speakers')}\n tooltipDisabled={tooltipDisabled}\n >\n <CompositeButton\n Menu={Menu}\n menuPlacement={menuPlacement}\n caption={caption}\n data-testid=\"audio-output-button\"\n onMenuToggle={(shown) => {\n setTooltipDisabled(shown);\n onMenuToggle?.(shown);\n }}\n >\n <Icon icon=\"speaker\" />\n </CompositeButton>\n </WithTooltip>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;;;;;;;;;AAYO,MAAM,uBAAuB,GAAG,CACrC,KAAmC,KACjC;AACF,IAAA,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE;AACvB,IAAA,MAAM,EACJ,OAAO,EACP,IAAI,GAAG,yBAAyB,EAChC,aAAa,GAAG,KAAK,EACrB,YAAY,GACb,GAAG,KAAK;IACT,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AAE7D,IAAA,QACEA,GAAA,CAAC,WAAW,EAAA,EACV,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC,UAAU,CAAC,EAC/B,eAAe,EAAE,eAAe,YAEhCA,GAAA,CAAC,eAAe,EAAA,EACd,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,OAAO,EAAA,aAAA,EACJ,qBAAqB,EACjC,YAAY,EAAE,CAAC,KAAK,KAAI;gBACtB,kBAAkB,CAAC,KAAK,CAAC;AACzB,gBAAA,YAAY,GAAG,KAAK,CAAC;YACvB,CAAC,EAAA,QAAA,EAEDA,GAAA,CAAC,IAAI,EAAA,EAAC,IAAI,EAAC,SAAS,EAAA,CAAG,EAAA,CACP,EAAA,CACN;AAElB;;;;"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useI18n, useCallStateHooks, Restricted } from '@stream-io/video-react-bindings';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import { SfuModels, RequestPermissionRequestPermissionsEnum, OwnCapability } from '@stream-io/video-client';
|
|
5
|
+
import { CompositeButton } from '../Button/CompositeButton.js';
|
|
6
|
+
import '../Button/IconButton.js';
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
import { Icon } from '../Icon/Icon.js';
|
|
9
|
+
import '../DeviceSettings/DeviceSettings.js';
|
|
10
|
+
import '@floating-ui/react';
|
|
11
|
+
import { useRequestPermission } from '../../hooks/useRequestPermission.js';
|
|
12
|
+
import '../DropdownSelect/DropdownSelect.js';
|
|
13
|
+
import '../Menu/MenuToggle.js';
|
|
14
|
+
import { DeviceSelectorVideo } from '../DeviceSettings/DeviceSelectorVideo.js';
|
|
15
|
+
import { PermissionNotification } from '../Notification/PermissionNotification.js';
|
|
16
|
+
import { WithTooltip } from '../Tooltip/WithTooltip.js';
|
|
17
|
+
import { createCallControlHandler } from '../../utilities/callControlHandler.js';
|
|
18
|
+
|
|
19
|
+
const ToggleVideoPreviewButton = (props) => {
|
|
20
|
+
const { caption, Menu = DeviceSelectorVideo, menuPlacement = 'top', onMenuToggle, optimisticUpdates, ...restCompositeButtonProps } = props;
|
|
21
|
+
const { t } = useI18n();
|
|
22
|
+
const { useCameraState, useLocalParticipant } = useCallStateHooks();
|
|
23
|
+
const { camera, hasBrowserPermission, isPromptingPermission, isTogglePending, optionsAwareIsMute, } = useCameraState({ optimisticUpdates });
|
|
24
|
+
const localParticipant = useLocalParticipant();
|
|
25
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(SfuModels.TrackType.VIDEO);
|
|
26
|
+
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
27
|
+
const handleClick = createCallControlHandler(props, () => camera.toggle());
|
|
28
|
+
return (jsx(WithTooltip, { title: !hasBrowserPermission
|
|
29
|
+
? t('Check your browser video permissions')
|
|
30
|
+
: isSystemMuted
|
|
31
|
+
? t('Camera is paused by your system')
|
|
32
|
+
: (caption ?? t('Video')), tooltipDisabled: tooltipDisabled, children: jsxs(CompositeButton, { active: optionsAwareIsMute, caption: caption, className: clsx(!hasBrowserPermission && 'str-video__device-unavailable'), variant: "secondary", "data-testid": optionsAwareIsMute
|
|
33
|
+
? 'preview-video-unmute-button'
|
|
34
|
+
: 'preview-video-mute-button', onClick: handleClick, disabled: !hasBrowserPermission || (!optimisticUpdates && isTogglePending), Menu: Menu, menuPlacement: menuPlacement, ...restCompositeButtonProps, onMenuToggle: (shown) => {
|
|
35
|
+
setTooltipDisabled(shown);
|
|
36
|
+
onMenuToggle?.(shown);
|
|
37
|
+
}, children: [jsx(Icon, { icon: !optionsAwareIsMute ? 'camera' : 'camera-off' }), !hasBrowserPermission && (jsx("span", { className: "str-video__no-media-permission", title: t('Check your browser video permissions'), children: "!" })), isPromptingPermission && (jsx("span", { className: "str-video__pending-permission", title: t('Waiting for permission'), children: "?" })), isSystemMuted && hasBrowserPermission && (jsx("span", { className: "str-video__system-muted", title: t('Camera is paused by your system'), children: "!" }))] }) }));
|
|
38
|
+
};
|
|
39
|
+
const ToggleVideoPublishingButton = (props) => {
|
|
40
|
+
const { t } = useI18n();
|
|
41
|
+
const { caption, Menu = jsx(DeviceSelectorVideo, { visualType: "list" }), menuPlacement = 'top', onMenuToggle, optimisticUpdates, ...restCompositeButtonProps } = props;
|
|
42
|
+
const { hasPermission, requestPermission, isAwaitingPermission } = useRequestPermission(RequestPermissionRequestPermissionsEnum.SEND_VIDEO);
|
|
43
|
+
const { useCameraState, useCallSettings, useLocalParticipant } = useCallStateHooks();
|
|
44
|
+
const { camera, optionsAwareIsMute, hasBrowserPermission, isPromptingPermission, isTogglePending, } = useCameraState({ optimisticUpdates });
|
|
45
|
+
const localParticipant = useLocalParticipant();
|
|
46
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(SfuModels.TrackType.VIDEO);
|
|
47
|
+
const callSettings = useCallSettings();
|
|
48
|
+
const isPublishingVideoAllowed = callSettings?.video.enabled;
|
|
49
|
+
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
50
|
+
const handleClick = createCallControlHandler(props, async () => {
|
|
51
|
+
if (!hasPermission) {
|
|
52
|
+
await requestPermission();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
await camera.toggle();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return (jsx(Restricted, { requiredGrants: [OwnCapability.SEND_VIDEO], children: jsx(PermissionNotification, { permission: OwnCapability.SEND_VIDEO, isAwaitingApproval: isAwaitingPermission, messageApproved: t('You can now share your video.'), messageAwaitingApproval: t('Awaiting for an approval to share your video.'), messageRevoked: t('You can no longer share your video.'), children: jsx(WithTooltip, { title: !hasPermission
|
|
59
|
+
? t('You have no permission to share your video')
|
|
60
|
+
: !hasBrowserPermission
|
|
61
|
+
? t('Check your browser video permissions')
|
|
62
|
+
: !isPublishingVideoAllowed
|
|
63
|
+
? t('Video publishing is disabled by the system')
|
|
64
|
+
: isSystemMuted
|
|
65
|
+
? t('Camera is paused by your system')
|
|
66
|
+
: caption || t('Video'), tooltipDisabled: tooltipDisabled, children: jsxs(CompositeButton, { active: optionsAwareIsMute, caption: caption, variant: "secondary", disabled: !hasBrowserPermission ||
|
|
67
|
+
!hasPermission ||
|
|
68
|
+
!isPublishingVideoAllowed ||
|
|
69
|
+
(!optimisticUpdates && isTogglePending), "data-testid": optionsAwareIsMute ? 'video-unmute-button' : 'video-mute-button', onClick: handleClick, Menu: Menu, menuPlacement: menuPlacement, menuOffset: 16, ...restCompositeButtonProps, onMenuToggle: (shown) => {
|
|
70
|
+
setTooltipDisabled(shown);
|
|
71
|
+
onMenuToggle?.(shown);
|
|
72
|
+
}, children: [jsx(Icon, { icon: optionsAwareIsMute ? 'camera-off' : 'camera' }), (!hasBrowserPermission ||
|
|
73
|
+
!hasPermission ||
|
|
74
|
+
!isPublishingVideoAllowed) && (jsx("span", { className: "str-video__no-media-permission", children: "!" })), isPromptingPermission && (jsx("span", { className: "str-video__pending-permission", title: t('Waiting for permission'), children: "?" })), isSystemMuted &&
|
|
75
|
+
hasBrowserPermission &&
|
|
76
|
+
hasPermission &&
|
|
77
|
+
isPublishingVideoAllowed && (jsx("span", { className: "str-video__system-muted", title: t('Camera is paused by your system'), children: "!" }))] }) }) }) }));
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export { ToggleVideoPreviewButton, ToggleVideoPublishingButton };
|
|
81
|
+
//# sourceMappingURL=ToggleVideoButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleVideoButton.js","sources":["../../../../../../../src/components/CallControls/ToggleVideoButton.tsx"],"sourcesContent":["import {\n Restricted,\n useCallStateHooks,\n useI18n,\n UseInputMediaDeviceOptions,\n} from '@stream-io/video-react-bindings';\nimport clsx from 'clsx';\nimport {\n OwnCapability,\n RequestPermissionRequestPermissionsEnum,\n SfuModels,\n} from '@stream-io/video-client';\nimport { CompositeButton, IconButtonWithMenuProps } from '../Button/';\nimport { DeviceSelectorVideo } from '../DeviceSettings';\nimport { PermissionNotification } from '../Notification';\nimport { useRequestPermission } from '../../hooks';\nimport { Icon } from '../Icon';\nimport { WithTooltip } from '../Tooltip';\nimport { useState } from 'react';\nimport {\n createCallControlHandler,\n PropsWithErrorHandler,\n} from '../../utilities/callControlHandler';\n\nexport type ToggleVideoPreviewButtonProps = PropsWithErrorHandler<\n Pick<\n IconButtonWithMenuProps,\n 'caption' | 'Menu' | 'menuPlacement' | 'onMenuToggle'\n > &\n UseInputMediaDeviceOptions\n>;\n\nexport const ToggleVideoPreviewButton = (\n props: ToggleVideoPreviewButtonProps,\n) => {\n const {\n caption,\n Menu = DeviceSelectorVideo,\n menuPlacement = 'top',\n onMenuToggle,\n optimisticUpdates,\n ...restCompositeButtonProps\n } = props;\n const { t } = useI18n();\n const { useCameraState, useLocalParticipant } = useCallStateHooks();\n const {\n camera,\n hasBrowserPermission,\n isPromptingPermission,\n isTogglePending,\n optionsAwareIsMute,\n } = useCameraState({ optimisticUpdates });\n const localParticipant = useLocalParticipant();\n const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(\n SfuModels.TrackType.VIDEO,\n );\n const [tooltipDisabled, setTooltipDisabled] = useState(false);\n const handleClick = createCallControlHandler(props, () => camera.toggle());\n\n return (\n <WithTooltip\n title={\n !hasBrowserPermission\n ? t('Check your browser video permissions')\n : isSystemMuted\n ? t('Camera is paused by your system')\n : (caption ?? t('Video'))\n }\n tooltipDisabled={tooltipDisabled}\n >\n <CompositeButton\n active={optionsAwareIsMute}\n caption={caption}\n className={clsx(\n !hasBrowserPermission && 'str-video__device-unavailable',\n )}\n variant=\"secondary\"\n data-testid={\n optionsAwareIsMute\n ? 'preview-video-unmute-button'\n : 'preview-video-mute-button'\n }\n onClick={handleClick}\n disabled={\n !hasBrowserPermission || (!optimisticUpdates && isTogglePending)\n }\n Menu={Menu}\n menuPlacement={menuPlacement}\n {...restCompositeButtonProps}\n onMenuToggle={(shown) => {\n setTooltipDisabled(shown);\n onMenuToggle?.(shown);\n }}\n >\n <Icon icon={!optionsAwareIsMute ? 'camera' : 'camera-off'} />\n {!hasBrowserPermission && (\n <span\n className=\"str-video__no-media-permission\"\n title={t('Check your browser video permissions')}\n children=\"!\"\n />\n )}\n {isPromptingPermission && (\n <span\n className=\"str-video__pending-permission\"\n title={t('Waiting for permission')}\n children=\"?\"\n />\n )}\n {isSystemMuted && hasBrowserPermission && (\n <span\n className=\"str-video__system-muted\"\n title={t('Camera is paused by your system')}\n children=\"!\"\n />\n )}\n </CompositeButton>\n </WithTooltip>\n );\n};\n\ntype ToggleVideoPublishingButtonProps = PropsWithErrorHandler<\n Pick<\n IconButtonWithMenuProps,\n 'caption' | 'Menu' | 'menuPlacement' | 'onMenuToggle'\n > &\n UseInputMediaDeviceOptions\n>;\n\nexport const ToggleVideoPublishingButton = (\n props: ToggleVideoPublishingButtonProps,\n) => {\n const { t } = useI18n();\n const {\n caption,\n Menu = <DeviceSelectorVideo visualType=\"list\" />,\n menuPlacement = 'top',\n onMenuToggle,\n optimisticUpdates,\n ...restCompositeButtonProps\n } = props;\n\n const { hasPermission, requestPermission, isAwaitingPermission } =\n useRequestPermission(RequestPermissionRequestPermissionsEnum.SEND_VIDEO);\n\n const { useCameraState, useCallSettings, useLocalParticipant } =\n useCallStateHooks();\n const {\n camera,\n optionsAwareIsMute,\n hasBrowserPermission,\n isPromptingPermission,\n isTogglePending,\n } = useCameraState({ optimisticUpdates });\n const localParticipant = useLocalParticipant();\n const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(\n SfuModels.TrackType.VIDEO,\n );\n const callSettings = useCallSettings();\n const isPublishingVideoAllowed = callSettings?.video.enabled;\n const [tooltipDisabled, setTooltipDisabled] = useState(false);\n const handleClick = createCallControlHandler(props, async () => {\n if (!hasPermission) {\n await requestPermission();\n } else {\n await camera.toggle();\n }\n });\n\n return (\n <Restricted requiredGrants={[OwnCapability.SEND_VIDEO]}>\n <PermissionNotification\n permission={OwnCapability.SEND_VIDEO}\n isAwaitingApproval={isAwaitingPermission}\n messageApproved={t('You can now share your video.')}\n messageAwaitingApproval={t(\n 'Awaiting for an approval to share your video.',\n )}\n messageRevoked={t('You can no longer share your video.')}\n >\n <WithTooltip\n title={\n !hasPermission\n ? t('You have no permission to share your video')\n : !hasBrowserPermission\n ? t('Check your browser video permissions')\n : !isPublishingVideoAllowed\n ? t('Video publishing is disabled by the system')\n : isSystemMuted\n ? t('Camera is paused by your system')\n : caption || t('Video')\n }\n tooltipDisabled={tooltipDisabled}\n >\n <CompositeButton\n active={optionsAwareIsMute}\n caption={caption}\n variant=\"secondary\"\n disabled={\n !hasBrowserPermission ||\n !hasPermission ||\n !isPublishingVideoAllowed ||\n (!optimisticUpdates && isTogglePending)\n }\n data-testid={\n optionsAwareIsMute ? 'video-unmute-button' : 'video-mute-button'\n }\n onClick={handleClick}\n Menu={Menu}\n menuPlacement={menuPlacement}\n menuOffset={16}\n {...restCompositeButtonProps}\n onMenuToggle={(shown) => {\n setTooltipDisabled(shown);\n onMenuToggle?.(shown);\n }}\n >\n <Icon icon={optionsAwareIsMute ? 'camera-off' : 'camera'} />\n {(!hasBrowserPermission ||\n !hasPermission ||\n !isPublishingVideoAllowed) && (\n <span className=\"str-video__no-media-permission\">!</span>\n )}\n {isPromptingPermission && (\n <span\n className=\"str-video__pending-permission\"\n title={t('Waiting for permission')}\n >\n ?\n </span>\n )}\n {isSystemMuted &&\n hasBrowserPermission &&\n hasPermission &&\n isPublishingVideoAllowed && (\n <span\n className=\"str-video__system-muted\"\n title={t('Camera is paused by your system')}\n >\n !\n </span>\n )}\n </CompositeButton>\n </WithTooltip>\n </PermissionNotification>\n </Restricted>\n );\n};\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useCall, Restricted } from '@stream-io/video-react-bindings';
|
|
3
|
+
import { OwnCapability } from '@stream-io/video-client';
|
|
4
|
+
import '../Button/CompositeButton.js';
|
|
5
|
+
import '../Button/IconButton.js';
|
|
6
|
+
import { TextButton } from '../Button/TextButton.js';
|
|
7
|
+
|
|
8
|
+
const BlockedUserListing = ({ data }) => {
|
|
9
|
+
if (!data.length)
|
|
10
|
+
return null;
|
|
11
|
+
return (jsx(Fragment, { children: jsx("div", { className: "str-video__participant-listing", children: data.map((userId) => (jsx(BlockedUserListingItem, { userId: userId }, userId))) }) }));
|
|
12
|
+
};
|
|
13
|
+
const BlockedUserListingItem = ({ userId }) => {
|
|
14
|
+
const call = useCall();
|
|
15
|
+
const unblockUserClickHandler = () => {
|
|
16
|
+
if (userId)
|
|
17
|
+
call?.unblockUser(userId);
|
|
18
|
+
};
|
|
19
|
+
return (jsxs("div", { className: "str-video__participant-listing-item", children: [jsx("div", { className: "str-video__participant-listing-item__display-name", children: userId }), jsx(Restricted, { requiredGrants: [OwnCapability.BLOCK_USERS], children: jsx(TextButton, { onClick: unblockUserClickHandler, children: "Unblock" }) })] }));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { BlockedUserListing };
|
|
23
|
+
//# sourceMappingURL=BlockedUserListing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockedUserListing.js","sources":["../../../../../../../src/components/CallParticipantsList/BlockedUserListing.tsx"],"sourcesContent":["import { Restricted, useCall } from '@stream-io/video-react-bindings';\nimport { OwnCapability } from '@stream-io/video-client';\n\nimport { TextButton } from '../Button';\n\nexport const BlockedUserListing = ({ data }: { data: string[] }) => {\n if (!data.length) return null;\n\n return (\n <>\n <div className=\"str-video__participant-listing\">\n {data.map((userId) => (\n <BlockedUserListingItem key={userId} userId={userId} />\n ))}\n </div>\n </>\n );\n};\n\nconst BlockedUserListingItem = ({ userId }: { userId: string }) => {\n const call = useCall();\n\n const unblockUserClickHandler = () => {\n if (userId) call?.unblockUser(userId);\n };\n\n return (\n <div className=\"str-video__participant-listing-item\">\n <div className=\"str-video__participant-listing-item__display-name\">\n {userId}\n </div>\n <Restricted requiredGrants={[OwnCapability.BLOCK_USERS]}>\n <TextButton onClick={unblockUserClickHandler}>Unblock</TextButton>\n </Restricted>\n </div>\n );\n};\n"],"names":["_jsx","_Fragment","_jsxs"],"mappings":";;;;;;;MAKa,kBAAkB,GAAG,CAAC,EAAE,IAAI,EAAsB,KAAI;IACjE,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,IAAI;AAE7B,IAAA,QACEA,GAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EACED,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,gCAAgC,EAAA,QAAA,EAC5C,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,MACfA,GAAA,CAAC,sBAAsB,EAAA,EAAc,MAAM,EAAE,MAAM,EAAA,EAAtB,MAAM,CAAoB,CACxD,CAAC,EAAA,CACE,EAAA,CACL;AAEP;AAEA,MAAM,sBAAsB,GAAG,CAAC,EAAE,MAAM,EAAsB,KAAI;AAChE,IAAA,MAAM,IAAI,GAAG,OAAO,EAAE;IAEtB,MAAM,uBAAuB,GAAG,MAAK;AACnC,QAAA,IAAI,MAAM;AAAE,YAAA,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC;AACvC,IAAA,CAAC;AAED,IAAA,QACEE,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,qCAAqC,EAAA,QAAA,EAAA,CAClDF,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,mDAAmD,EAAA,QAAA,EAC/D,MAAM,EAAA,CACH,EACNA,IAAC,UAAU,EAAA,EAAC,cAAc,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,YACrDA,GAAA,CAAC,UAAU,EAAA,EAAC,OAAO,EAAE,uBAAuB,EAAA,QAAA,EAAA,SAAA,EAAA,CAAsB,EAAA,CACvD,CAAA,EAAA,CACT;AAEV,CAAC;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useCallStateHooks, useI18n } from '@stream-io/video-react-bindings';
|
|
3
|
+
import '../Button/CompositeButton.js';
|
|
4
|
+
import { IconButton } from '../Button/IconButton.js';
|
|
5
|
+
|
|
6
|
+
const CallParticipantListHeader = ({ onClose, }) => {
|
|
7
|
+
const { useParticipants, useAnonymousParticipantCount } = useCallStateHooks();
|
|
8
|
+
const participants = useParticipants();
|
|
9
|
+
const anonymousParticipantCount = useAnonymousParticipantCount();
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
return (jsxs("div", { className: "str-video__participant-list-header", children: [jsxs("div", { className: "str-video__participant-list-header__title", children: [t('Participants'), ' ', jsxs("span", { className: "str-video__participant-list-header__title-count", children: ["[", participants.length, "]"] }), anonymousParticipantCount > 0 && (jsx("span", { className: "str-video__participant-list-header__title-anonymous", children: t('Anonymous', { count: anonymousParticipantCount }) }))] }), jsx(IconButton, { onClick: onClose, className: "str-video__participant-list-header__close-button", icon: "close" })] }));
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { CallParticipantListHeader };
|
|
15
|
+
//# sourceMappingURL=CallParticipantListHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallParticipantListHeader.js","sources":["../../../../../../../src/components/CallParticipantsList/CallParticipantListHeader.tsx"],"sourcesContent":["import { useCallStateHooks, useI18n } from '@stream-io/video-react-bindings';\n\nimport { IconButton } from '../Button';\n\nexport type CallParticipantListHeaderProps = {\n /**\n * Click event listener function to be invoked to dismiss / hide the CallParticipantsList from the UI.\n */\n onClose: () => void;\n};\n\nexport const CallParticipantListHeader = ({\n onClose,\n}: CallParticipantListHeaderProps) => {\n const { useParticipants, useAnonymousParticipantCount } = useCallStateHooks();\n const participants = useParticipants();\n const anonymousParticipantCount = useAnonymousParticipantCount();\n const { t } = useI18n();\n\n return (\n <div className=\"str-video__participant-list-header\">\n <div className=\"str-video__participant-list-header__title\">\n {t('Participants')}{' '}\n <span className=\"str-video__participant-list-header__title-count\">\n [{participants.length}]\n </span>\n {anonymousParticipantCount > 0 && (\n <span className=\"str-video__participant-list-header__title-anonymous\">\n {t('Anonymous', { count: anonymousParticipantCount })}\n </span>\n )}\n </div>\n <IconButton\n onClick={onClose}\n className=\"str-video__participant-list-header__close-button\"\n icon=\"close\"\n />\n </div>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;MAWa,yBAAyB,GAAG,CAAC,EACxC,OAAO,GACwB,KAAI;IACnC,MAAM,EAAE,eAAe,EAAE,4BAA4B,EAAE,GAAG,iBAAiB,EAAE;AAC7E,IAAA,MAAM,YAAY,GAAG,eAAe,EAAE;AACtC,IAAA,MAAM,yBAAyB,GAAG,4BAA4B,EAAE;AAChE,IAAA,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE;AAEvB,IAAA,QACEA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,oCAAoC,EAAA,QAAA,EAAA,CACjDA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,2CAA2C,EAAA,QAAA,EAAA,CACvD,CAAC,CAAC,cAAc,CAAC,EAAE,GAAG,EACvBA,IAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,iDAAiD,kBAC7D,YAAY,CAAC,MAAM,EAAA,GAAA,CAAA,EAAA,CAChB,EACN,yBAAyB,GAAG,CAAC,KAC5BC,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,qDAAqD,EAAA,QAAA,EAClE,CAAC,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,EAAA,CAChD,CACR,CAAA,EAAA,CACG,EACNA,GAAA,CAAC,UAAU,EAAA,EACT,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,kDAAkD,EAC5D,IAAI,EAAC,OAAO,EAAA,CACZ,CAAA,EAAA,CACE;AAEV;;;;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { CallParticipantListingItem } from './CallParticipantListingItem.js';
|
|
3
|
+
|
|
4
|
+
const CallParticipantListing = ({ data, }) => (jsx("div", { className: "str-video__participant-listing", children: data.map((participant) => (jsx(CallParticipantListingItem, { participant: participant }, participant.sessionId))) }));
|
|
5
|
+
|
|
6
|
+
export { CallParticipantListing };
|
|
7
|
+
//# sourceMappingURL=CallParticipantListing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallParticipantListing.js","sources":["../../../../../../../src/components/CallParticipantsList/CallParticipantListing.tsx"],"sourcesContent":["import { ComponentType } from 'react';\nimport { StreamVideoParticipant } from '@stream-io/video-client';\nimport { CallParticipantListingItem } from './CallParticipantListingItem';\n\nexport type CallParticipantListingProps = {\n /** Array of participant objects to be rendered */\n data: StreamVideoParticipant[];\n Header?: ComponentType;\n};\n\nexport const CallParticipantListing = ({\n data,\n}: CallParticipantListingProps) => (\n <div className=\"str-video__participant-listing\">\n {data.map((participant) => (\n <CallParticipantListingItem\n key={participant.sessionId}\n participant={participant}\n />\n ))}\n </div>\n);\n"],"names":["_jsx"],"mappings":";;;AAUO,MAAM,sBAAsB,GAAG,CAAC,EACrC,IAAI,GACwB,MAC5BA,aAAK,SAAS,EAAC,gCAAgC,EAAA,QAAA,EAC5C,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,MACpBA,GAAA,CAAC,0BAA0B,IAEzB,WAAW,EAAE,WAAW,EAAA,EADnB,WAAW,CAAC,SAAS,CAE1B,CACH,CAAC,EAAA,CACE;;;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { memo, forwardRef } from 'react';
|
|
4
|
+
import { useI18n, useConnectedUser } from '@stream-io/video-react-bindings';
|
|
5
|
+
import { hasAudio, hasVideo, isPinned } from '@stream-io/video-client';
|
|
6
|
+
import '../Button/CompositeButton.js';
|
|
7
|
+
import { IconButton } from '../Button/IconButton.js';
|
|
8
|
+
import { MenuToggle } from '../Menu/MenuToggle.js';
|
|
9
|
+
import '@floating-ui/react';
|
|
10
|
+
import { WithTooltip } from '../Tooltip/WithTooltip.js';
|
|
11
|
+
import { Avatar } from '../Avatar/Avatar.js';
|
|
12
|
+
import { ParticipantActionsContextMenu } from '../../core/components/ParticipantView/ParticipantActionsContextMenu.js';
|
|
13
|
+
import { ParticipantViewContext } from '../../core/components/ParticipantView/ParticipantViewContext.js';
|
|
14
|
+
|
|
15
|
+
const CallParticipantListingItem = memo(function CallParticipantListingItemRender({ participant, DisplayName = DefaultDisplayName, }) {
|
|
16
|
+
const isAudioOn = hasAudio(participant);
|
|
17
|
+
const isVideoOn = hasVideo(participant);
|
|
18
|
+
const isPinnedOn = isPinned(participant);
|
|
19
|
+
const { t } = useI18n();
|
|
20
|
+
return (jsxs("div", { className: "str-video__participant-listing-item", children: [jsx(Avatar, { name: participant.name, imageSrc: participant.image }), jsx(DisplayName, { participant: participant }), jsxs("div", { className: "str-video__participant-listing-item__media-indicator-group", children: [jsx(MediaIndicator, { title: isAudioOn ? t('Microphone on') : t('Microphone off'), className: clsx('str-video__participant-listing-item__icon', `str-video__participant-listing-item__icon-${isAudioOn ? 'mic' : 'mic-off'}`) }), jsx(MediaIndicator, { title: isVideoOn ? t('Camera on') : t('Camera off'), className: clsx('str-video__participant-listing-item__icon', `str-video__participant-listing-item__icon-${isVideoOn ? 'camera' : 'camera-off'}`) }), isPinnedOn && (jsx(MediaIndicator, { title: t('Pinned'), className: clsx('str-video__participant-listing-item__icon', 'str-video__participant-listing-item__icon-pinned') })), jsx(MenuToggle, { placement: "bottom-end", ToggleButton: ToggleButton, children: jsx(ParticipantViewContext.Provider, { value: { participant, trackType: 'none' }, children: jsx(ParticipantActionsContextMenu, {}) }) })] })] }));
|
|
21
|
+
});
|
|
22
|
+
CallParticipantListingItem.displayName = 'CallParticipantListingItem';
|
|
23
|
+
const MediaIndicator = (props) => (jsx(WithTooltip, { ...props }));
|
|
24
|
+
const DefaultDisplayName = ({ participant }) => {
|
|
25
|
+
const connectedUser = useConnectedUser();
|
|
26
|
+
const { t } = useI18n();
|
|
27
|
+
const meFlag = participant.userId === connectedUser?.id ? t('Me') : '';
|
|
28
|
+
const nameOrId = participant.name || participant.userId || t('Unknown');
|
|
29
|
+
let displayName;
|
|
30
|
+
if (!participant.name) {
|
|
31
|
+
displayName = meFlag || nameOrId || t('Unknown');
|
|
32
|
+
}
|
|
33
|
+
else if (meFlag) {
|
|
34
|
+
displayName = `${nameOrId} (${meFlag})`;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
displayName = nameOrId;
|
|
38
|
+
}
|
|
39
|
+
return (jsx(WithTooltip, { className: "str-video__participant-listing-item__display-name", title: displayName, children: displayName }));
|
|
40
|
+
};
|
|
41
|
+
const ToggleButton = forwardRef(function ToggleButtonRender(props, ref) {
|
|
42
|
+
return jsx(IconButton, { enabled: props.menuShown, icon: "ellipsis", ref: ref });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export { CallParticipantListingItem };
|
|
46
|
+
//# sourceMappingURL=CallParticipantListingItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallParticipantListingItem.js","sources":["../../../../../../../src/components/CallParticipantsList/CallParticipantListingItem.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport { ComponentProps, ComponentType, forwardRef, memo } from 'react';\nimport { useConnectedUser, useI18n } from '@stream-io/video-react-bindings';\nimport {\n hasAudio,\n hasVideo,\n isPinned,\n StreamVideoParticipant,\n} from '@stream-io/video-client';\nimport { IconButton } from '../Button';\nimport { MenuToggle, ToggleMenuButtonProps } from '../Menu';\nimport { WithTooltip } from '../Tooltip';\nimport { Avatar } from '../Avatar';\nimport { ParticipantActionsContextMenu } from '../../core/components/ParticipantView/ParticipantActionsContextMenu';\nimport { ParticipantViewContext } from '../../core/components/ParticipantView/ParticipantViewContext';\n\ntype CallParticipantListingItemProps = {\n /** Participant object be rendered */\n participant: StreamVideoParticipant;\n /** Custom component used to display participant's name */\n DisplayName?: ComponentType<{ participant: StreamVideoParticipant }>;\n};\nexport const CallParticipantListingItem = memo(\n function CallParticipantListingItemRender({\n participant,\n DisplayName = DefaultDisplayName,\n }: CallParticipantListingItemProps) {\n const isAudioOn = hasAudio(participant);\n const isVideoOn = hasVideo(participant);\n const isPinnedOn = isPinned(participant);\n\n const { t } = useI18n();\n\n return (\n <div className=\"str-video__participant-listing-item\">\n <Avatar name={participant.name} imageSrc={participant.image} />\n <DisplayName participant={participant} />\n <div className=\"str-video__participant-listing-item__media-indicator-group\">\n <MediaIndicator\n title={isAudioOn ? t('Microphone on') : t('Microphone off')}\n className={clsx(\n 'str-video__participant-listing-item__icon',\n `str-video__participant-listing-item__icon-${\n isAudioOn ? 'mic' : 'mic-off'\n }`,\n )}\n />\n <MediaIndicator\n title={isVideoOn ? t('Camera on') : t('Camera off')}\n className={clsx(\n 'str-video__participant-listing-item__icon',\n `str-video__participant-listing-item__icon-${\n isVideoOn ? 'camera' : 'camera-off'\n }`,\n )}\n />\n {isPinnedOn && (\n <MediaIndicator\n title={t('Pinned')}\n className={clsx(\n 'str-video__participant-listing-item__icon',\n 'str-video__participant-listing-item__icon-pinned',\n )}\n />\n )}\n\n <MenuToggle placement=\"bottom-end\" ToggleButton={ToggleButton}>\n <ParticipantViewContext.Provider\n value={{ participant, trackType: 'none' }}\n >\n <ParticipantActionsContextMenu />\n </ParticipantViewContext.Provider>\n </MenuToggle>\n </div>\n </div>\n );\n },\n);\n\nCallParticipantListingItem.displayName = 'CallParticipantListingItem';\n\nconst MediaIndicator = (props: ComponentProps<'div'>) => (\n <WithTooltip {...props} />\n);\n\ntype DisplayNameProps = {\n /** Participant object that provides the data from which display name can be generated */\n participant: StreamVideoParticipant;\n};\n\nconst DefaultDisplayName = ({ participant }: DisplayNameProps) => {\n const connectedUser = useConnectedUser();\n const { t } = useI18n();\n\n const meFlag = participant.userId === connectedUser?.id ? t('Me') : '';\n const nameOrId = participant.name || participant.userId || t('Unknown');\n let displayName;\n if (!participant.name) {\n displayName = meFlag || nameOrId || t('Unknown');\n } else if (meFlag) {\n displayName = `${nameOrId} (${meFlag})`;\n } else {\n displayName = nameOrId;\n }\n\n return (\n <WithTooltip\n className=\"str-video__participant-listing-item__display-name\"\n title={displayName}\n >\n {displayName}\n </WithTooltip>\n );\n};\n\nconst ToggleButton = forwardRef<HTMLButtonElement, ToggleMenuButtonProps>(\n function ToggleButtonRender(props, ref) {\n return <IconButton enabled={props.menuShown} icon=\"ellipsis\" ref={ref} />;\n },\n);\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|