@werxt/livekit-components-react 2.9.20
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/LICENSE +201 -0
- package/README.md +36 -0
- package/dist/assets/icons/CameraDisabledIcon.d.ts +11 -0
- package/dist/assets/icons/CameraDisabledIcon.d.ts.map +1 -0
- package/dist/assets/icons/CameraIcon.d.ts +11 -0
- package/dist/assets/icons/CameraIcon.d.ts.map +1 -0
- package/dist/assets/icons/ChatCloseIcon.d.ts +11 -0
- package/dist/assets/icons/ChatCloseIcon.d.ts.map +1 -0
- package/dist/assets/icons/ChatIcon.d.ts +11 -0
- package/dist/assets/icons/ChatIcon.d.ts.map +1 -0
- package/dist/assets/icons/Chevron.d.ts +11 -0
- package/dist/assets/icons/Chevron.d.ts.map +1 -0
- package/dist/assets/icons/FocusToggleIcon.d.ts +11 -0
- package/dist/assets/icons/FocusToggleIcon.d.ts.map +1 -0
- package/dist/assets/icons/GearIcon.d.ts +11 -0
- package/dist/assets/icons/GearIcon.d.ts.map +1 -0
- package/dist/assets/icons/LeaveIcon.d.ts +11 -0
- package/dist/assets/icons/LeaveIcon.d.ts.map +1 -0
- package/dist/assets/icons/LockLockedIcon.d.ts +11 -0
- package/dist/assets/icons/LockLockedIcon.d.ts.map +1 -0
- package/dist/assets/icons/MicDisabledIcon.d.ts +11 -0
- package/dist/assets/icons/MicDisabledIcon.d.ts.map +1 -0
- package/dist/assets/icons/MicIcon.d.ts +11 -0
- package/dist/assets/icons/MicIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityExcellentIcon.d.ts +11 -0
- package/dist/assets/icons/QualityExcellentIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityGoodIcon.d.ts +11 -0
- package/dist/assets/icons/QualityGoodIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityPoorIcon.d.ts +11 -0
- package/dist/assets/icons/QualityPoorIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityUnknownIcon.d.ts +11 -0
- package/dist/assets/icons/QualityUnknownIcon.d.ts.map +1 -0
- package/dist/assets/icons/ScreenShareIcon.d.ts +11 -0
- package/dist/assets/icons/ScreenShareIcon.d.ts.map +1 -0
- package/dist/assets/icons/ScreenShareStopIcon.d.ts +11 -0
- package/dist/assets/icons/ScreenShareStopIcon.d.ts.map +1 -0
- package/dist/assets/icons/SpinnerIcon.d.ts +11 -0
- package/dist/assets/icons/SpinnerIcon.d.ts.map +1 -0
- package/dist/assets/icons/UnfocusToggleIcon.d.ts +11 -0
- package/dist/assets/icons/UnfocusToggleIcon.d.ts.map +1 -0
- package/dist/assets/icons/index.d.ts +20 -0
- package/dist/assets/icons/index.d.ts.map +1 -0
- package/dist/assets/icons/util.d.ts +11 -0
- package/dist/assets/icons/util.d.ts.map +1 -0
- package/dist/assets/images/ParticipantPlaceholder.d.ts +11 -0
- package/dist/assets/images/ParticipantPlaceholder.d.ts.map +1 -0
- package/dist/assets/images/index.d.ts +2 -0
- package/dist/assets/images/index.d.ts.map +1 -0
- package/dist/components/ChatEntry.d.ts +35 -0
- package/dist/components/ChatEntry.d.ts.map +1 -0
- package/dist/components/ConnectionState.d.ts +23 -0
- package/dist/components/ConnectionState.d.ts.map +1 -0
- package/dist/components/ConnectionStateToast.d.ts +13 -0
- package/dist/components/ConnectionStateToast.d.ts.map +1 -0
- package/dist/components/LiveKitRoom.d.ts +92 -0
- package/dist/components/LiveKitRoom.d.ts.map +1 -0
- package/dist/components/ParticipantLoop.d.ts +28 -0
- package/dist/components/ParticipantLoop.d.ts.map +1 -0
- package/dist/components/RoomAudioRenderer.d.ts +29 -0
- package/dist/components/RoomAudioRenderer.d.ts.map +1 -0
- package/dist/components/RoomName.d.ts +20 -0
- package/dist/components/RoomName.d.ts.map +1 -0
- package/dist/components/SessionProvider.d.ts +13 -0
- package/dist/components/SessionProvider.d.ts.map +1 -0
- package/dist/components/Toast.d.ts +14 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/TrackLoop.d.ts +26 -0
- package/dist/components/TrackLoop.d.ts.map +1 -0
- package/dist/components/controls/ChatToggle.d.ts +19 -0
- package/dist/components/controls/ChatToggle.d.ts.map +1 -0
- package/dist/components/controls/ClearPinButton.d.ts +20 -0
- package/dist/components/controls/ClearPinButton.d.ts.map +1 -0
- package/dist/components/controls/DisconnectButton.d.ts +19 -0
- package/dist/components/controls/DisconnectButton.d.ts.map +1 -0
- package/dist/components/controls/FocusToggle.d.ts +21 -0
- package/dist/components/controls/FocusToggle.d.ts.map +1 -0
- package/dist/components/controls/MediaDeviceSelect.d.ts +40 -0
- package/dist/components/controls/MediaDeviceSelect.d.ts.map +1 -0
- package/dist/components/controls/PaginationControl.d.ts +9 -0
- package/dist/components/controls/PaginationControl.d.ts.map +1 -0
- package/dist/components/controls/PaginationIndicator.d.ts +7 -0
- package/dist/components/controls/PaginationIndicator.d.ts.map +1 -0
- package/dist/components/controls/SettingsMenuToggle.d.ts +13 -0
- package/dist/components/controls/SettingsMenuToggle.d.ts.map +1 -0
- package/dist/components/controls/StartAudio.d.ts +24 -0
- package/dist/components/controls/StartAudio.d.ts.map +1 -0
- package/dist/components/controls/StartMediaButton.d.ts +22 -0
- package/dist/components/controls/StartMediaButton.d.ts.map +1 -0
- package/dist/components/controls/TrackToggle.d.ts +32 -0
- package/dist/components/controls/TrackToggle.d.ts.map +1 -0
- package/dist/components/index.d.ts +30 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/layout/CarouselLayout.d.ts +27 -0
- package/dist/components/layout/CarouselLayout.d.ts.map +1 -0
- package/dist/components/layout/FocusLayout.d.ts +25 -0
- package/dist/components/layout/FocusLayout.d.ts.map +1 -0
- package/dist/components/layout/GridLayout.d.ts +26 -0
- package/dist/components/layout/GridLayout.d.ts.map +1 -0
- package/dist/components/layout/LayoutContextProvider.d.ts +12 -0
- package/dist/components/layout/LayoutContextProvider.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts +4 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/participant/AudioTrack.d.ts +33 -0
- package/dist/components/participant/AudioTrack.d.ts.map +1 -0
- package/dist/components/participant/AudioVisualizer.d.ts +22 -0
- package/dist/components/participant/AudioVisualizer.d.ts.map +1 -0
- package/dist/components/participant/BarVisualizer.d.ts +77 -0
- package/dist/components/participant/BarVisualizer.d.ts.map +1 -0
- package/dist/components/participant/ConnectionQualityIndicator.d.ts +16 -0
- package/dist/components/participant/ConnectionQualityIndicator.d.ts.map +1 -0
- package/dist/components/participant/ParticipantAudioTile.d.ts +14 -0
- package/dist/components/participant/ParticipantAudioTile.d.ts.map +1 -0
- package/dist/components/participant/ParticipantName.d.ts +17 -0
- package/dist/components/participant/ParticipantName.d.ts.map +1 -0
- package/dist/components/participant/ParticipantTile.d.ts +49 -0
- package/dist/components/participant/ParticipantTile.d.ts.map +1 -0
- package/dist/components/participant/TrackMutedIndicator.d.ts +19 -0
- package/dist/components/participant/TrackMutedIndicator.d.ts.map +1 -0
- package/dist/components/participant/VideoTrack.d.ts +23 -0
- package/dist/components/participant/VideoTrack.d.ts.map +1 -0
- package/dist/components/participant/animationSequences/connectingSequence.d.ts +2 -0
- package/dist/components/participant/animationSequences/connectingSequence.d.ts.map +1 -0
- package/dist/components/participant/animationSequences/listeningSequence.d.ts +2 -0
- package/dist/components/participant/animationSequences/listeningSequence.d.ts.map +1 -0
- package/dist/components/participant/animationSequences/thinkingSequence.d.ts +2 -0
- package/dist/components/participant/animationSequences/thinkingSequence.d.ts.map +1 -0
- package/dist/components/participant/animators/useBarAnimator.d.ts +3 -0
- package/dist/components/participant/animators/useBarAnimator.d.ts.map +1 -0
- package/dist/components-lNrIMTWQ.mjs +1051 -0
- package/dist/components-lNrIMTWQ.mjs.map +1 -0
- package/dist/context/chat-context.d.ts +23 -0
- package/dist/context/chat-context.d.ts.map +1 -0
- package/dist/context/feature-context.d.ts +14 -0
- package/dist/context/feature-context.d.ts.map +1 -0
- package/dist/context/index.d.ts +10 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/layout-context.d.ts +32 -0
- package/dist/context/layout-context.d.ts.map +1 -0
- package/dist/context/participant-context.d.ts +22 -0
- package/dist/context/participant-context.d.ts.map +1 -0
- package/dist/context/pin-context.d.ts +17 -0
- package/dist/context/pin-context.d.ts.map +1 -0
- package/dist/context/room-context.d.ts +22 -0
- package/dist/context/room-context.d.ts.map +1 -0
- package/dist/context/session-context.d.ts +22 -0
- package/dist/context/session-context.d.ts.map +1 -0
- package/dist/context/track-reference-context.d.ts +25 -0
- package/dist/context/track-reference-context.d.ts.map +1 -0
- package/dist/contexts-D4V9wQRc.mjs +4026 -0
- package/dist/contexts-D4V9wQRc.mjs.map +1 -0
- package/dist/hooks/cloud/krisp/useKrispNoiseFilter.d.ts +42 -0
- package/dist/hooks/cloud/krisp/useKrispNoiseFilter.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +54 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/internal/index.d.ts +10 -0
- package/dist/hooks/internal/index.d.ts.map +1 -0
- package/dist/hooks/internal/useMediaQuery.d.ts +7 -0
- package/dist/hooks/internal/useMediaQuery.d.ts.map +1 -0
- package/dist/hooks/internal/useObservableState.d.ts +6 -0
- package/dist/hooks/internal/useObservableState.d.ts.map +1 -0
- package/dist/hooks/internal/useResizeObserver.d.ts +14 -0
- package/dist/hooks/internal/useResizeObserver.d.ts.map +1 -0
- package/dist/hooks/useAgent.d.ts +219 -0
- package/dist/hooks/useAgent.d.ts.map +1 -0
- package/dist/hooks/useAudioPlayback.d.ts +15 -0
- package/dist/hooks/useAudioPlayback.d.ts.map +1 -0
- package/dist/hooks/useChat.d.ts +43 -0
- package/dist/hooks/useChat.d.ts.map +1 -0
- package/dist/hooks/useChatToggle.d.ts +21 -0
- package/dist/hooks/useChatToggle.d.ts.map +1 -0
- package/dist/hooks/useClearPinButton.d.ts +15 -0
- package/dist/hooks/useClearPinButton.d.ts.map +1 -0
- package/dist/hooks/useConnectionQualityIndicator.d.ts +20 -0
- package/dist/hooks/useConnectionQualityIndicator.d.ts.map +1 -0
- package/dist/hooks/useConnectionStatus.d.ts +12 -0
- package/dist/hooks/useConnectionStatus.d.ts.map +1 -0
- package/dist/hooks/useDataChannel.d.ts +38 -0
- package/dist/hooks/useDataChannel.d.ts.map +1 -0
- package/dist/hooks/useDisconnectButton.d.ts +21 -0
- package/dist/hooks/useDisconnectButton.d.ts.map +1 -0
- package/dist/hooks/useEvents.d.ts +9 -0
- package/dist/hooks/useEvents.d.ts.map +1 -0
- package/dist/hooks/useFacingMode.d.ts +10 -0
- package/dist/hooks/useFacingMode.d.ts.map +1 -0
- package/dist/hooks/useFocusToggle.d.ts +26 -0
- package/dist/hooks/useFocusToggle.d.ts.map +1 -0
- package/dist/hooks/useGridLayout.d.ts +27 -0
- package/dist/hooks/useGridLayout.d.ts.map +1 -0
- package/dist/hooks/useIsEncrypted.d.ts +12 -0
- package/dist/hooks/useIsEncrypted.d.ts.map +1 -0
- package/dist/hooks/useIsMuted.d.ts +22 -0
- package/dist/hooks/useIsMuted.d.ts.map +1 -0
- package/dist/hooks/useIsRecording.d.ts +11 -0
- package/dist/hooks/useIsRecording.d.ts.map +1 -0
- package/dist/hooks/useIsSpeaking.d.ts +11 -0
- package/dist/hooks/useIsSpeaking.d.ts.map +1 -0
- package/dist/hooks/useLiveKitRoom.d.ts +19 -0
- package/dist/hooks/useLiveKitRoom.d.ts.map +1 -0
- package/dist/hooks/useLocalParticipant.d.ts +29 -0
- package/dist/hooks/useLocalParticipant.d.ts.map +1 -0
- package/dist/hooks/useLocalParticipantPermissions.d.ts +12 -0
- package/dist/hooks/useLocalParticipantPermissions.d.ts.map +1 -0
- package/dist/hooks/useMediaDeviceSelect.d.ts +41 -0
- package/dist/hooks/useMediaDeviceSelect.d.ts.map +1 -0
- package/dist/hooks/useMediaDevices.d.ts +15 -0
- package/dist/hooks/useMediaDevices.d.ts.map +1 -0
- package/dist/hooks/useMediaTrackBySourceOrName.d.ts +18 -0
- package/dist/hooks/useMediaTrackBySourceOrName.d.ts.map +1 -0
- package/dist/hooks/usePagination.d.ts +24 -0
- package/dist/hooks/usePagination.d.ts.map +1 -0
- package/dist/hooks/useParticipantAttributes.d.ts +30 -0
- package/dist/hooks/useParticipantAttributes.d.ts.map +1 -0
- package/dist/hooks/useParticipantInfo.d.ts +21 -0
- package/dist/hooks/useParticipantInfo.d.ts.map +1 -0
- package/dist/hooks/useParticipantPermissions.d.ts +17 -0
- package/dist/hooks/useParticipantPermissions.d.ts.map +1 -0
- package/dist/hooks/useParticipantTile.d.ts +22 -0
- package/dist/hooks/useParticipantTile.d.ts.map +1 -0
- package/dist/hooks/useParticipantTracks.d.ts +14 -0
- package/dist/hooks/useParticipantTracks.d.ts.map +1 -0
- package/dist/hooks/useParticipants.d.ts +30 -0
- package/dist/hooks/useParticipants.d.ts.map +1 -0
- package/dist/hooks/usePersistentUserChoices.d.ts +35 -0
- package/dist/hooks/usePersistentUserChoices.d.ts.map +1 -0
- package/dist/hooks/usePinnedTracks.d.ts +14 -0
- package/dist/hooks/usePinnedTracks.d.ts.map +1 -0
- package/dist/hooks/useRemoteParticipant.d.ts +35 -0
- package/dist/hooks/useRemoteParticipant.d.ts.map +1 -0
- package/dist/hooks/useRemoteParticipants.d.ts +30 -0
- package/dist/hooks/useRemoteParticipants.d.ts.map +1 -0
- package/dist/hooks/useRoomInfo.d.ts +21 -0
- package/dist/hooks/useRoomInfo.d.ts.map +1 -0
- package/dist/hooks/useSequentialRoomConnectDisconnect.d.ts +27 -0
- package/dist/hooks/useSequentialRoomConnectDisconnect.d.ts.map +1 -0
- package/dist/hooks/useSession.d.ts +130 -0
- package/dist/hooks/useSession.d.ts.map +1 -0
- package/dist/hooks/useSessionMessages.d.ts +29 -0
- package/dist/hooks/useSessionMessages.d.ts.map +1 -0
- package/dist/hooks/useSettingsToggle.d.ts +20 -0
- package/dist/hooks/useSettingsToggle.d.ts.map +1 -0
- package/dist/hooks/useSortedParticipants.d.ts +7 -0
- package/dist/hooks/useSortedParticipants.d.ts.map +1 -0
- package/dist/hooks/useSpeakingParticipants.d.ts +16 -0
- package/dist/hooks/useSpeakingParticipants.d.ts.map +1 -0
- package/dist/hooks/useStartAudio.d.ts +27 -0
- package/dist/hooks/useStartAudio.d.ts.map +1 -0
- package/dist/hooks/useStartVideo.d.ts +26 -0
- package/dist/hooks/useStartVideo.d.ts.map +1 -0
- package/dist/hooks/useSwipe.d.ts +24 -0
- package/dist/hooks/useSwipe.d.ts.map +1 -0
- package/dist/hooks/useTextStream.d.ts +20 -0
- package/dist/hooks/useTextStream.d.ts.map +1 -0
- package/dist/hooks/useToken.d.ts +20 -0
- package/dist/hooks/useToken.d.ts.map +1 -0
- package/dist/hooks/useTrack.d.ts +4 -0
- package/dist/hooks/useTrack.d.ts.map +1 -0
- package/dist/hooks/useTrackByName.d.ts +10 -0
- package/dist/hooks/useTrackByName.d.ts.map +1 -0
- package/dist/hooks/useTrackMutedIndicator.d.ts +18 -0
- package/dist/hooks/useTrackMutedIndicator.d.ts.map +1 -0
- package/dist/hooks/useTrackRefBySourceOrName.d.ts +7 -0
- package/dist/hooks/useTrackRefBySourceOrName.d.ts.map +1 -0
- package/dist/hooks/useTrackSyncTime.d.ts +10 -0
- package/dist/hooks/useTrackSyncTime.d.ts.map +1 -0
- package/dist/hooks/useTrackToggle.d.ts +27 -0
- package/dist/hooks/useTrackToggle.d.ts.map +1 -0
- package/dist/hooks/useTrackTranscription.d.ts +26 -0
- package/dist/hooks/useTrackTranscription.d.ts.map +1 -0
- package/dist/hooks/useTrackVolume.d.ts +49 -0
- package/dist/hooks/useTrackVolume.d.ts.map +1 -0
- package/dist/hooks/useTracks.d.ts +29 -0
- package/dist/hooks/useTracks.d.ts.map +1 -0
- package/dist/hooks/useTranscriptions.d.ts +21 -0
- package/dist/hooks/useTranscriptions.d.ts.map +1 -0
- package/dist/hooks/useVisualStableUpdate.d.ts +27 -0
- package/dist/hooks/useVisualStableUpdate.d.ts.map +1 -0
- package/dist/hooks/useVoiceAssistant.d.ts +43 -0
- package/dist/hooks/useVoiceAssistant.d.ts.map +1 -0
- package/dist/hooks/useWarnAboutMissingStyles.d.ts +5 -0
- package/dist/hooks/useWarnAboutMissingStyles.d.ts.map +1 -0
- package/dist/hooks-hQJmeINB.mjs +1992 -0
- package/dist/hooks-hQJmeINB.mjs.map +1 -0
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hooks.mjs +64 -0
- package/dist/hooks.mjs.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.docs.d.ts +6 -0
- package/dist/index.docs.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +157 -0
- package/dist/index.mjs.map +1 -0
- package/dist/krisp.d.ts +2 -0
- package/dist/krisp.js +2 -0
- package/dist/krisp.js.map +1 -0
- package/dist/krisp.mjs +45 -0
- package/dist/krisp.mjs.map +1 -0
- package/dist/mergeProps.d.ts +25 -0
- package/dist/mergeProps.d.ts.map +1 -0
- package/dist/prefabs/AudioConference.d.ts +22 -0
- package/dist/prefabs/AudioConference.d.ts.map +1 -0
- package/dist/prefabs/Chat.d.ts +35 -0
- package/dist/prefabs/Chat.d.ts.map +1 -0
- package/dist/prefabs/ControlBar.d.ts +45 -0
- package/dist/prefabs/ControlBar.d.ts.map +1 -0
- package/dist/prefabs/MediaDeviceMenu.d.ts +36 -0
- package/dist/prefabs/MediaDeviceMenu.d.ts.map +1 -0
- package/dist/prefabs/PreJoin.d.ts +59 -0
- package/dist/prefabs/PreJoin.d.ts.map +1 -0
- package/dist/prefabs/VideoConference.d.ts +35 -0
- package/dist/prefabs/VideoConference.d.ts.map +1 -0
- package/dist/prefabs/VoiceAssistantControlBar.d.ts +32 -0
- package/dist/prefabs/VoiceAssistantControlBar.d.ts.map +1 -0
- package/dist/prefabs/index.d.ts +8 -0
- package/dist/prefabs/index.d.ts.map +1 -0
- package/dist/prefabs.d.ts +2 -0
- package/dist/prefabs.js +2 -0
- package/dist/prefabs.js.map +1 -0
- package/dist/prefabs.mjs +579 -0
- package/dist/prefabs.mjs.map +1 -0
- package/dist/room-BP3SCCCd.mjs +191 -0
- package/dist/room-BP3SCCCd.mjs.map +1 -0
- package/dist/shared-88J2fzv7.js +2 -0
- package/dist/shared-88J2fzv7.js.map +1 -0
- package/dist/shared-BDr0qLg4.js +4 -0
- package/dist/shared-BDr0qLg4.js.map +1 -0
- package/dist/shared-CjI_UuOX.js +2 -0
- package/dist/shared-CjI_UuOX.js.map +1 -0
- package/dist/shared-DTHOl3uJ.js +2 -0
- package/dist/shared-DTHOl3uJ.js.map +1 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +104 -0
- package/src/assets/icons/CameraDisabledIcon.tsx +15 -0
- package/src/assets/icons/CameraIcon.tsx +14 -0
- package/src/assets/icons/ChatCloseIcon.tsx +17 -0
- package/src/assets/icons/ChatIcon.tsx +25 -0
- package/src/assets/icons/Chevron.tsx +19 -0
- package/src/assets/icons/FocusToggleIcon.tsx +16 -0
- package/src/assets/icons/GearIcon.tsx +19 -0
- package/src/assets/icons/LeaveIcon.tsx +25 -0
- package/src/assets/icons/LockLockedIcon.tsx +19 -0
- package/src/assets/icons/MicDisabledIcon.tsx +15 -0
- package/src/assets/icons/MicIcon.tsx +19 -0
- package/src/assets/icons/QualityExcellentIcon.tsx +15 -0
- package/src/assets/icons/QualityGoodIcon.tsx +19 -0
- package/src/assets/icons/QualityPoorIcon.tsx +20 -0
- package/src/assets/icons/QualityUnknownIcon.tsx +17 -0
- package/src/assets/icons/ScreenShareIcon.tsx +25 -0
- package/src/assets/icons/ScreenShareStopIcon.tsx +21 -0
- package/src/assets/icons/SpinnerIcon.tsx +93 -0
- package/src/assets/icons/UnfocusToggleIcon.tsx +16 -0
- package/src/assets/icons/index.ts +19 -0
- package/src/assets/icons/util.tsx +47 -0
- package/src/assets/images/ParticipantPlaceholder.tsx +31 -0
- package/src/assets/images/index.ts +1 -0
- package/src/assets/template.js +21 -0
- package/src/components/ChatEntry.tsx +112 -0
- package/src/components/ConnectionState.tsx +36 -0
- package/src/components/ConnectionStateToast.tsx +47 -0
- package/src/components/LiveKitRoom.tsx +122 -0
- package/src/components/ParticipantLoop.tsx +41 -0
- package/src/components/RoomAudioRenderer.tsx +57 -0
- package/src/components/RoomName.tsx +36 -0
- package/src/components/SessionProvider.tsx +22 -0
- package/src/components/Toast.tsx +18 -0
- package/src/components/TrackLoop.tsx +45 -0
- package/src/components/controls/ChatToggle.tsx +32 -0
- package/src/components/controls/ClearPinButton.tsx +32 -0
- package/src/components/controls/DisconnectButton.tsx +32 -0
- package/src/components/controls/FocusToggle.tsx +54 -0
- package/src/components/controls/MediaDeviceSelect.tsx +144 -0
- package/src/components/controls/PaginationControl.tsx +51 -0
- package/src/components/controls/PaginationIndicator.tsx +26 -0
- package/src/components/controls/SettingsMenuToggle.tsx +26 -0
- package/src/components/controls/StartAudio.tsx +40 -0
- package/src/components/controls/StartMediaButton.tsx +41 -0
- package/src/components/controls/TrackToggle.tsx +54 -0
- package/src/components/index.ts +34 -0
- package/src/components/layout/CarouselLayout.tsx +80 -0
- package/src/components/layout/FocusLayout.tsx +37 -0
- package/src/components/layout/GridLayout.tsx +63 -0
- package/src/components/layout/LayoutContextProvider.tsx +36 -0
- package/src/components/layout/index.ts +3 -0
- package/src/components/participant/AudioTrack.tsx +89 -0
- package/src/components/participant/AudioVisualizer.tsx +67 -0
- package/src/components/participant/BarVisualizer.tsx +164 -0
- package/src/components/participant/ConnectionQualityIndicator.tsx +36 -0
- package/src/components/participant/ParticipantAudioTile.tsx +67 -0
- package/src/components/participant/ParticipantName.tsx +50 -0
- package/src/components/participant/ParticipantTile.tsx +192 -0
- package/src/components/participant/TrackMutedIndicator.tsx +53 -0
- package/src/components/participant/VideoTrack.tsx +92 -0
- package/src/components/participant/animationSequences/connectingSequence.ts +9 -0
- package/src/components/participant/animationSequences/listeningSequence.ts +6 -0
- package/src/components/participant/animationSequences/thinkingSequence.ts +12 -0
- package/src/components/participant/animators/useBarAnimator.ts +55 -0
- package/src/context/chat-context.ts +37 -0
- package/src/context/feature-context.ts +28 -0
- package/src/context/index.ts +27 -0
- package/src/context/layout-context.ts +72 -0
- package/src/context/participant-context.ts +44 -0
- package/src/context/pin-context.ts +27 -0
- package/src/context/room-context.ts +42 -0
- package/src/context/session-context.ts +43 -0
- package/src/context/track-reference-context.ts +47 -0
- package/src/hooks/cloud/krisp/useKrispNoiseFilter.ts +110 -0
- package/src/hooks/index.ts +72 -0
- package/src/hooks/internal/index.ts +10 -0
- package/src/hooks/internal/useMediaQuery.ts +46 -0
- package/src/hooks/internal/useObservableState.ts +24 -0
- package/src/hooks/internal/useResizeObserver.ts +124 -0
- package/src/hooks/useAgent.ts +945 -0
- package/src/hooks/useAudioPlayback.ts +34 -0
- package/src/hooks/useChat.ts +57 -0
- package/src/hooks/useChatToggle.ts +38 -0
- package/src/hooks/useClearPinButton.ts +29 -0
- package/src/hooks/useConnectionQualityIndicator.ts +33 -0
- package/src/hooks/useConnectionStatus.ts +22 -0
- package/src/hooks/useDataChannel.ts +73 -0
- package/src/hooks/useDisconnectButton.ts +36 -0
- package/src/hooks/useEvents.ts +39 -0
- package/src/hooks/useFacingMode.ts +22 -0
- package/src/hooks/useFocusToggle.ts +59 -0
- package/src/hooks/useGridLayout.ts +44 -0
- package/src/hooks/useIsEncrypted.ts +29 -0
- package/src/hooks/useIsMuted.ts +51 -0
- package/src/hooks/useIsRecording.ts +23 -0
- package/src/hooks/useIsSpeaking.ts +21 -0
- package/src/hooks/useLiveKitRoom.ts +186 -0
- package/src/hooks/useLocalParticipant.ts +73 -0
- package/src/hooks/useLocalParticipantPermissions.ts +24 -0
- package/src/hooks/useMediaDeviceSelect.ts +81 -0
- package/src/hooks/useMediaDevices.ts +28 -0
- package/src/hooks/useMediaTrackBySourceOrName.ts +97 -0
- package/src/hooks/usePagination.test.ts +77 -0
- package/src/hooks/usePagination.ts +67 -0
- package/src/hooks/useParticipantAttributes.ts +69 -0
- package/src/hooks/useParticipantInfo.ts +35 -0
- package/src/hooks/useParticipantPermissions.ts +29 -0
- package/src/hooks/useParticipantTile.ts +81 -0
- package/src/hooks/useParticipantTracks.ts +54 -0
- package/src/hooks/useParticipants.ts +42 -0
- package/src/hooks/usePersistentUserChoices.ts +64 -0
- package/src/hooks/usePinnedTracks.ts +24 -0
- package/src/hooks/useRemoteParticipant.ts +79 -0
- package/src/hooks/useRemoteParticipants.ts +45 -0
- package/src/hooks/useRoomInfo.ts +32 -0
- package/src/hooks/useSequentialRoomConnectDisconnect.ts +171 -0
- package/src/hooks/useSession.ts +642 -0
- package/src/hooks/useSessionMessages.ts +158 -0
- package/src/hooks/useSettingsToggle.ts +32 -0
- package/src/hooks/useSortedParticipants.ts +20 -0
- package/src/hooks/useSpeakingParticipants.ts +27 -0
- package/src/hooks/useStartAudio.ts +50 -0
- package/src/hooks/useStartVideo.ts +49 -0
- package/src/hooks/useSwipe.ts +68 -0
- package/src/hooks/useTextStream.ts +35 -0
- package/src/hooks/useToken.ts +54 -0
- package/src/hooks/useTrack.ts +11 -0
- package/src/hooks/useTrackByName.ts +15 -0
- package/src/hooks/useTrackMutedIndicator.ts +44 -0
- package/src/hooks/useTrackRefBySourceOrName.ts +30 -0
- package/src/hooks/useTrackSyncTime.ts +18 -0
- package/src/hooks/useTrackToggle.ts +93 -0
- package/src/hooks/useTrackTranscription.ts +75 -0
- package/src/hooks/useTrackVolume.ts +283 -0
- package/src/hooks/useTracks.test.ts +60 -0
- package/src/hooks/useTracks.ts +154 -0
- package/src/hooks/useTranscriptions.ts +48 -0
- package/src/hooks/useVisualStableUpdate.ts +63 -0
- package/src/hooks/useVoiceAssistant.ts +109 -0
- package/src/hooks/useWarnAboutMissingStyles.ts +11 -0
- package/src/index.docs.ts +12 -0
- package/src/index.ts +32 -0
- package/src/mergeProps.ts +87 -0
- package/src/prefabs/AudioConference.tsx +57 -0
- package/src/prefabs/Chat.tsx +153 -0
- package/src/prefabs/ControlBar.tsx +227 -0
- package/src/prefabs/MediaDeviceMenu.tsx +159 -0
- package/src/prefabs/PreJoin.tsx +439 -0
- package/src/prefabs/VideoConference.tsx +184 -0
- package/src/prefabs/VoiceAssistantControlBar.tsx +109 -0
- package/src/prefabs/index.ts +11 -0
- package/src/utils.ts +78 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { log, setupLiveKitRoom } from '@livekit/components-core';
|
|
2
|
+
import type { DisconnectReason } from 'livekit-client';
|
|
3
|
+
import { Room, MediaDeviceFailure, RoomEvent } from 'livekit-client';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import type { HTMLAttributes } from 'react';
|
|
6
|
+
|
|
7
|
+
import type { LiveKitRoomProps } from '../components';
|
|
8
|
+
import { mergeProps } from '../mergeProps';
|
|
9
|
+
import { roomOptionsStringifyReplacer } from '../utils';
|
|
10
|
+
|
|
11
|
+
const defaultRoomProps: Partial<LiveKitRoomProps> = {
|
|
12
|
+
connect: true,
|
|
13
|
+
audio: false,
|
|
14
|
+
video: false,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The `useLiveKitRoom` hook is used to implement the `LiveKitRoom` or your custom implementation of it.
|
|
19
|
+
* It returns a `Room` instance and HTML props that should be applied to the root element of the component.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* const { room, htmlProps } = useLiveKitRoom();
|
|
24
|
+
* return <div {...htmlProps}>...</div>;
|
|
25
|
+
* ```
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export function useLiveKitRoom<T extends HTMLElement>(
|
|
29
|
+
props: LiveKitRoomProps,
|
|
30
|
+
): {
|
|
31
|
+
room: Room | undefined;
|
|
32
|
+
htmlProps: HTMLAttributes<T>;
|
|
33
|
+
} {
|
|
34
|
+
const {
|
|
35
|
+
token,
|
|
36
|
+
serverUrl,
|
|
37
|
+
options,
|
|
38
|
+
room: passedRoom,
|
|
39
|
+
connectOptions,
|
|
40
|
+
connect,
|
|
41
|
+
audio,
|
|
42
|
+
video,
|
|
43
|
+
screen,
|
|
44
|
+
onConnected,
|
|
45
|
+
onDisconnected,
|
|
46
|
+
onError,
|
|
47
|
+
onMediaDeviceFailure,
|
|
48
|
+
onEncryptionError,
|
|
49
|
+
simulateParticipants,
|
|
50
|
+
...rest
|
|
51
|
+
} = { ...defaultRoomProps, ...props };
|
|
52
|
+
if (options && passedRoom) {
|
|
53
|
+
log.warn(
|
|
54
|
+
'when using a manually created room, the options object will be ignored. set the desired options directly when creating the room instead.',
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const [room, setRoom] = React.useState<Room | undefined>();
|
|
59
|
+
|
|
60
|
+
const shouldConnect = React.useRef(connect);
|
|
61
|
+
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
setRoom(passedRoom ?? new Room(options));
|
|
64
|
+
}, [passedRoom, JSON.stringify(options, roomOptionsStringifyReplacer)]);
|
|
65
|
+
|
|
66
|
+
const htmlProps = React.useMemo(() => {
|
|
67
|
+
const { className } = setupLiveKitRoom();
|
|
68
|
+
return mergeProps(rest, { className }) as HTMLAttributes<T>;
|
|
69
|
+
}, [rest]);
|
|
70
|
+
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
if (!room) return;
|
|
73
|
+
const onSignalConnected = () => {
|
|
74
|
+
const localP = room.localParticipant;
|
|
75
|
+
|
|
76
|
+
log.debug('trying to publish local tracks');
|
|
77
|
+
Promise.all([
|
|
78
|
+
localP.setMicrophoneEnabled(!!audio, typeof audio !== 'boolean' ? audio : undefined),
|
|
79
|
+
localP.setCameraEnabled(!!video, typeof video !== 'boolean' ? video : undefined),
|
|
80
|
+
localP.setScreenShareEnabled(!!screen, typeof screen !== 'boolean' ? screen : undefined),
|
|
81
|
+
]).catch((e) => {
|
|
82
|
+
log.warn(e);
|
|
83
|
+
onError?.(e as Error);
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleMediaDeviceError = (e: Error, kind?: MediaDeviceKind) => {
|
|
88
|
+
const mediaDeviceFailure = MediaDeviceFailure.getFailure(e);
|
|
89
|
+
onMediaDeviceFailure?.(mediaDeviceFailure, kind);
|
|
90
|
+
};
|
|
91
|
+
const handleEncryptionError = (e: Error) => {
|
|
92
|
+
onEncryptionError?.(e);
|
|
93
|
+
};
|
|
94
|
+
const handleDisconnected = (reason?: DisconnectReason) => {
|
|
95
|
+
onDisconnected?.(reason);
|
|
96
|
+
};
|
|
97
|
+
const handleConnected = () => {
|
|
98
|
+
onConnected?.();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
room
|
|
102
|
+
.on(RoomEvent.SignalConnected, onSignalConnected)
|
|
103
|
+
.on(RoomEvent.MediaDevicesError, handleMediaDeviceError)
|
|
104
|
+
.on(RoomEvent.EncryptionError, handleEncryptionError)
|
|
105
|
+
.on(RoomEvent.Disconnected, handleDisconnected)
|
|
106
|
+
.on(RoomEvent.Connected, handleConnected);
|
|
107
|
+
|
|
108
|
+
return () => {
|
|
109
|
+
room
|
|
110
|
+
.off(RoomEvent.SignalConnected, onSignalConnected)
|
|
111
|
+
.off(RoomEvent.MediaDevicesError, handleMediaDeviceError)
|
|
112
|
+
.off(RoomEvent.EncryptionError, handleEncryptionError)
|
|
113
|
+
.off(RoomEvent.Disconnected, handleDisconnected)
|
|
114
|
+
.off(RoomEvent.Connected, handleConnected);
|
|
115
|
+
};
|
|
116
|
+
}, [
|
|
117
|
+
room,
|
|
118
|
+
audio,
|
|
119
|
+
video,
|
|
120
|
+
screen,
|
|
121
|
+
onError,
|
|
122
|
+
onEncryptionError,
|
|
123
|
+
onMediaDeviceFailure,
|
|
124
|
+
onConnected,
|
|
125
|
+
onDisconnected,
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
React.useEffect(() => {
|
|
129
|
+
if (!room) return;
|
|
130
|
+
|
|
131
|
+
if (simulateParticipants) {
|
|
132
|
+
room.simulateParticipants({
|
|
133
|
+
participants: {
|
|
134
|
+
count: simulateParticipants,
|
|
135
|
+
},
|
|
136
|
+
publish: {
|
|
137
|
+
audio: true,
|
|
138
|
+
useRealTracks: true,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (connect) {
|
|
145
|
+
shouldConnect.current = true;
|
|
146
|
+
log.debug('connecting');
|
|
147
|
+
if (!token) {
|
|
148
|
+
log.debug('no token yet');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (!serverUrl) {
|
|
152
|
+
log.warn('no livekit url provided');
|
|
153
|
+
onError?.(Error('no livekit url provided'));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
room.connect(serverUrl, token, connectOptions).catch((e) => {
|
|
157
|
+
log.warn(e);
|
|
158
|
+
if (shouldConnect.current === true) {
|
|
159
|
+
onError?.(e as Error);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
log.debug('disconnecting because connect is false');
|
|
164
|
+
shouldConnect.current = false;
|
|
165
|
+
room.disconnect();
|
|
166
|
+
}
|
|
167
|
+
}, [
|
|
168
|
+
connect,
|
|
169
|
+
token,
|
|
170
|
+
JSON.stringify(connectOptions),
|
|
171
|
+
room,
|
|
172
|
+
onError,
|
|
173
|
+
serverUrl,
|
|
174
|
+
simulateParticipants,
|
|
175
|
+
]);
|
|
176
|
+
|
|
177
|
+
React.useEffect(() => {
|
|
178
|
+
if (!room) return;
|
|
179
|
+
return () => {
|
|
180
|
+
log.info('disconnecting on onmount');
|
|
181
|
+
room.disconnect();
|
|
182
|
+
};
|
|
183
|
+
}, [room]);
|
|
184
|
+
|
|
185
|
+
return { room, htmlProps };
|
|
186
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { ParticipantMedia } from '@livekit/components-core';
|
|
2
|
+
import { observeParticipantMedia } from '@livekit/components-core';
|
|
3
|
+
import type { TrackPublication, LocalParticipant, Room } from 'livekit-client';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { useEnsureRoom } from '../context';
|
|
6
|
+
|
|
7
|
+
/** @public */
|
|
8
|
+
export interface UseLocalParticipantOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The room to use. If not provided, the hook will use the room from the context.
|
|
11
|
+
*/
|
|
12
|
+
room?: Room;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The `useLocalParticipant` hook returns the local participant and the associated state
|
|
17
|
+
* around the participant.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* const { localParticipant } = useLocalParticipant();
|
|
22
|
+
* ```
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export function useLocalParticipant(options: UseLocalParticipantOptions = {}) {
|
|
26
|
+
const room = useEnsureRoom(options.room);
|
|
27
|
+
const [localParticipant, setLocalParticipant] = React.useState(room.localParticipant);
|
|
28
|
+
|
|
29
|
+
const [isMicrophoneEnabled, setIsMicrophoneEnabled] = React.useState(
|
|
30
|
+
localParticipant.isMicrophoneEnabled,
|
|
31
|
+
);
|
|
32
|
+
const [isCameraEnabled, setIsCameraEnabled] = React.useState(localParticipant.isCameraEnabled);
|
|
33
|
+
const [isScreenShareEnabled, setIsScreenShareEnabled] = React.useState(
|
|
34
|
+
localParticipant.isScreenShareEnabled,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const [lastMicrophoneError, setLastMicrophoneError] = React.useState(
|
|
38
|
+
localParticipant.lastMicrophoneError,
|
|
39
|
+
);
|
|
40
|
+
const [lastCameraError, setLastCameraError] = React.useState(localParticipant.lastCameraError);
|
|
41
|
+
|
|
42
|
+
const [microphoneTrack, setMicrophoneTrack] = React.useState<TrackPublication | undefined>(
|
|
43
|
+
undefined,
|
|
44
|
+
);
|
|
45
|
+
const [cameraTrack, setCameraTrack] = React.useState<TrackPublication | undefined>(undefined);
|
|
46
|
+
|
|
47
|
+
const handleUpdate = (media: ParticipantMedia<LocalParticipant>) => {
|
|
48
|
+
setIsCameraEnabled(media.isCameraEnabled);
|
|
49
|
+
setIsMicrophoneEnabled(media.isMicrophoneEnabled);
|
|
50
|
+
setIsScreenShareEnabled(media.isScreenShareEnabled);
|
|
51
|
+
setCameraTrack(media.cameraTrack);
|
|
52
|
+
setMicrophoneTrack(media.microphoneTrack);
|
|
53
|
+
setLastMicrophoneError(media.participant.lastMicrophoneError);
|
|
54
|
+
setLastCameraError(media.participant.lastCameraError);
|
|
55
|
+
setLocalParticipant(media.participant);
|
|
56
|
+
};
|
|
57
|
+
React.useEffect(() => {
|
|
58
|
+
const listener = observeParticipantMedia(room.localParticipant).subscribe(handleUpdate);
|
|
59
|
+
// TODO also listen to permission and metadata etc. events
|
|
60
|
+
return () => listener.unsubscribe();
|
|
61
|
+
}, [room]);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
isMicrophoneEnabled,
|
|
65
|
+
isScreenShareEnabled,
|
|
66
|
+
isCameraEnabled,
|
|
67
|
+
microphoneTrack,
|
|
68
|
+
cameraTrack,
|
|
69
|
+
lastMicrophoneError,
|
|
70
|
+
lastCameraError,
|
|
71
|
+
localParticipant,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { participantPermissionObserver } from '@livekit/components-core';
|
|
2
|
+
import type { ParticipantPermission } from '@livekit/protocol';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useRoomContext } from '../context';
|
|
5
|
+
import { useObservableState } from './internal';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The `useLocalParticipantPermissions` hook returns the local participant's permissions.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const { canPublish, canPublishData } = useLocalParticipantPermissions();
|
|
13
|
+
* ```
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export function useLocalParticipantPermissions(): ParticipantPermission | undefined {
|
|
17
|
+
const room = useRoomContext();
|
|
18
|
+
const permissionObserver = React.useMemo(
|
|
19
|
+
() => participantPermissionObserver(room.localParticipant),
|
|
20
|
+
[room],
|
|
21
|
+
);
|
|
22
|
+
const permissions = useObservableState(permissionObserver, room.localParticipant.permissions);
|
|
23
|
+
return permissions;
|
|
24
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createMediaDeviceObserver, setupDeviceSelector, log } from '@livekit/components-core';
|
|
2
|
+
import { Room, type LocalAudioTrack, type LocalVideoTrack } from 'livekit-client';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useMaybeRoomContext } from '../context';
|
|
5
|
+
import { useObservableState } from './internal';
|
|
6
|
+
|
|
7
|
+
/** @public */
|
|
8
|
+
export interface UseMediaDeviceSelectProps {
|
|
9
|
+
kind: MediaDeviceKind;
|
|
10
|
+
room?: Room;
|
|
11
|
+
track?: LocalAudioTrack | LocalVideoTrack;
|
|
12
|
+
/**
|
|
13
|
+
* this will call getUserMedia if the permissions are not yet given to enumerate the devices with device labels.
|
|
14
|
+
* in some browsers multiple calls to getUserMedia result in multiple permission prompts.
|
|
15
|
+
* It's generally advised only flip this to true, once a (preview) track has been acquired successfully with the
|
|
16
|
+
* appropriate permissions.
|
|
17
|
+
*
|
|
18
|
+
* @see {@link MediaDeviceMenu}
|
|
19
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices | MDN enumerateDevices}
|
|
20
|
+
*/
|
|
21
|
+
requestPermissions?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* this callback gets called if an error is thrown when failing to select a device and also if a user
|
|
24
|
+
* denied permissions, eventhough the `requestPermissions` option is set to `true`.
|
|
25
|
+
* Most commonly this will emit a MediaDeviceError
|
|
26
|
+
*/
|
|
27
|
+
onError?: (e: Error) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The `useMediaDeviceSelect` hook is used to implement the `MediaDeviceSelect` component and
|
|
32
|
+
* returns o.a. the list of devices of a given kind (audioinput or videoinput), the currently active device
|
|
33
|
+
* and a function to set the the active device.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* const { devices, activeDeviceId, setActiveMediaDevice } = useMediaDeviceSelect({kind: 'audioinput'});
|
|
38
|
+
* ```
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export function useMediaDeviceSelect({
|
|
42
|
+
kind,
|
|
43
|
+
room,
|
|
44
|
+
track,
|
|
45
|
+
requestPermissions,
|
|
46
|
+
onError,
|
|
47
|
+
}: UseMediaDeviceSelectProps) {
|
|
48
|
+
const roomContext = useMaybeRoomContext();
|
|
49
|
+
|
|
50
|
+
const roomFallback = React.useMemo(() => room ?? roomContext ?? new Room(), [room, roomContext]);
|
|
51
|
+
|
|
52
|
+
// List of all devices.
|
|
53
|
+
const deviceObserver = React.useMemo(
|
|
54
|
+
() => createMediaDeviceObserver(kind, onError, requestPermissions),
|
|
55
|
+
[kind, requestPermissions, onError],
|
|
56
|
+
);
|
|
57
|
+
const devices = useObservableState(deviceObserver, [] as MediaDeviceInfo[]);
|
|
58
|
+
// Active device management.
|
|
59
|
+
const [currentDeviceId, setCurrentDeviceId] = React.useState<string>(
|
|
60
|
+
roomFallback?.getActiveDevice(kind) ?? 'default',
|
|
61
|
+
);
|
|
62
|
+
const { className, activeDeviceObservable, setActiveMediaDevice } = React.useMemo(
|
|
63
|
+
() => setupDeviceSelector(kind, roomFallback),
|
|
64
|
+
[kind, roomFallback, track],
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
React.useEffect(() => {
|
|
68
|
+
const listener = activeDeviceObservable.subscribe((deviceId) => {
|
|
69
|
+
if (!deviceId) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
log.info('setCurrentDeviceId', deviceId);
|
|
73
|
+
setCurrentDeviceId(deviceId);
|
|
74
|
+
});
|
|
75
|
+
return () => {
|
|
76
|
+
listener?.unsubscribe();
|
|
77
|
+
};
|
|
78
|
+
}, [activeDeviceObservable]);
|
|
79
|
+
|
|
80
|
+
return { devices, className, activeDeviceId: currentDeviceId, setActiveMediaDevice };
|
|
81
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useObservableState } from './internal';
|
|
3
|
+
import { createMediaDeviceObserver } from '@livekit/components-core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `useMediaDevices` hook returns the list of media devices of a given kind.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* const videoDevices = useMediaDevices({ kind: 'videoinput' });
|
|
11
|
+
* const audioDevices = useMediaDevices({ kind: 'audioinput' });
|
|
12
|
+
* ```
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export function useMediaDevices({
|
|
16
|
+
kind,
|
|
17
|
+
onError,
|
|
18
|
+
}: {
|
|
19
|
+
kind: MediaDeviceKind;
|
|
20
|
+
onError?: (e: Error) => void;
|
|
21
|
+
}) {
|
|
22
|
+
const deviceObserver = React.useMemo(
|
|
23
|
+
() => createMediaDeviceObserver(kind, onError),
|
|
24
|
+
[kind, onError],
|
|
25
|
+
);
|
|
26
|
+
const devices = useObservableState(deviceObserver, [] as MediaDeviceInfo[]);
|
|
27
|
+
return devices;
|
|
28
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { TrackIdentifier } from '@livekit/components-core';
|
|
2
|
+
import {
|
|
3
|
+
getTrackByIdentifier,
|
|
4
|
+
isTrackReference,
|
|
5
|
+
log,
|
|
6
|
+
setupMediaTrack,
|
|
7
|
+
} from '@livekit/components-core';
|
|
8
|
+
import * as React from 'react';
|
|
9
|
+
import { mergeProps } from '../utils';
|
|
10
|
+
|
|
11
|
+
/** @public */
|
|
12
|
+
export interface UseMediaTrackOptions {
|
|
13
|
+
element?: React.RefObject<HTMLMediaElement> | null;
|
|
14
|
+
props?: React.HTMLAttributes<HTMLVideoElement | HTMLAudioElement>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export function useMediaTrackBySourceOrName(
|
|
21
|
+
observerOptions: TrackIdentifier,
|
|
22
|
+
options: UseMediaTrackOptions = {},
|
|
23
|
+
) {
|
|
24
|
+
const [publication, setPublication] = React.useState(getTrackByIdentifier(observerOptions));
|
|
25
|
+
|
|
26
|
+
const [isMuted, setMuted] = React.useState(publication?.isMuted);
|
|
27
|
+
const [isSubscribed, setSubscribed] = React.useState(publication?.isSubscribed);
|
|
28
|
+
|
|
29
|
+
const [track, setTrack] = React.useState(publication?.track);
|
|
30
|
+
const [orientation, setOrientation] = React.useState<'landscape' | 'portrait'>('landscape');
|
|
31
|
+
const previousElement = React.useRef<HTMLMediaElement | undefined | null>();
|
|
32
|
+
|
|
33
|
+
const { className, trackObserver } = React.useMemo(() => {
|
|
34
|
+
return setupMediaTrack(observerOptions);
|
|
35
|
+
}, [
|
|
36
|
+
observerOptions.participant.sid ?? observerOptions.participant.identity,
|
|
37
|
+
observerOptions.source,
|
|
38
|
+
isTrackReference(observerOptions) && observerOptions.publication.trackSid,
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
const subscription = trackObserver.subscribe((publication) => {
|
|
43
|
+
log.debug('update track', publication);
|
|
44
|
+
setPublication(publication);
|
|
45
|
+
setMuted(publication?.isMuted);
|
|
46
|
+
setSubscribed(publication?.isSubscribed);
|
|
47
|
+
setTrack(publication?.track);
|
|
48
|
+
});
|
|
49
|
+
return () => subscription?.unsubscribe();
|
|
50
|
+
}, [trackObserver]);
|
|
51
|
+
|
|
52
|
+
React.useEffect(() => {
|
|
53
|
+
if (track) {
|
|
54
|
+
if (previousElement.current) {
|
|
55
|
+
track.detach(previousElement.current);
|
|
56
|
+
}
|
|
57
|
+
if (
|
|
58
|
+
options.element?.current &&
|
|
59
|
+
!(observerOptions.participant.isLocal && track?.kind === 'audio')
|
|
60
|
+
) {
|
|
61
|
+
track.attach(options.element.current);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
previousElement.current = options.element?.current;
|
|
65
|
+
return () => {
|
|
66
|
+
if (previousElement.current) {
|
|
67
|
+
track?.detach(previousElement.current);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}, [track, options.element]);
|
|
71
|
+
|
|
72
|
+
React.useEffect(() => {
|
|
73
|
+
// Set the orientation of the video track.
|
|
74
|
+
// TODO: This does not handle changes in orientation after a track got published (e.g when rotating a phone camera from portrait to landscape).
|
|
75
|
+
if (
|
|
76
|
+
typeof publication?.dimensions?.width === 'number' &&
|
|
77
|
+
typeof publication?.dimensions?.height === 'number'
|
|
78
|
+
) {
|
|
79
|
+
const orientation_ =
|
|
80
|
+
publication.dimensions.width > publication.dimensions.height ? 'landscape' : 'portrait';
|
|
81
|
+
setOrientation(orientation_);
|
|
82
|
+
}
|
|
83
|
+
}, [publication]);
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
publication,
|
|
87
|
+
isMuted,
|
|
88
|
+
isSubscribed,
|
|
89
|
+
track,
|
|
90
|
+
elementProps: mergeProps(options.props, {
|
|
91
|
+
className,
|
|
92
|
+
'data-lk-local-participant': observerOptions.participant.isLocal,
|
|
93
|
+
'data-lk-source': publication?.source,
|
|
94
|
+
...(publication?.kind === 'video' && { 'data-lk-orientation': orientation }),
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, test, expect } from 'vitest';
|
|
2
|
+
import { renderHook } from '@testing-library/react';
|
|
3
|
+
import usePagination from './usePagination';
|
|
4
|
+
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core';
|
|
5
|
+
|
|
6
|
+
describe('Test hook', () => {
|
|
7
|
+
test('Test basic assumptions of the usePagination hook return values.', () => {
|
|
8
|
+
const itemPerPage = 4;
|
|
9
|
+
const totalTrackRefs = new Array(12) as TrackReferenceOrPlaceholder[];
|
|
10
|
+
const { result } = renderHook(() => usePagination(itemPerPage, totalTrackRefs));
|
|
11
|
+
|
|
12
|
+
expect(result.current.currentPage).toBe(1);
|
|
13
|
+
expect(result.current.totalPageCount).toBe(3);
|
|
14
|
+
expect(result.current.firstItemIndex).toBe(0);
|
|
15
|
+
expect(result.current.lastItemIndex).toBe(4);
|
|
16
|
+
expect(result.current.prevPage).toBeTypeOf('function');
|
|
17
|
+
expect(result.current.nextPage).toBeTypeOf('function');
|
|
18
|
+
});
|
|
19
|
+
test('Test moving to pages works as expected.', () => {
|
|
20
|
+
const itemPerPage = 4;
|
|
21
|
+
const totalTrackRefs = new Array(12) as TrackReferenceOrPlaceholder[];
|
|
22
|
+
const { result, rerender } = renderHook(() => usePagination(itemPerPage, totalTrackRefs));
|
|
23
|
+
|
|
24
|
+
expect(result.current.currentPage).toBe(1);
|
|
25
|
+
|
|
26
|
+
result.current.nextPage();
|
|
27
|
+
rerender();
|
|
28
|
+
expect(result.current.currentPage).toBe(2);
|
|
29
|
+
|
|
30
|
+
result.current.nextPage();
|
|
31
|
+
rerender();
|
|
32
|
+
expect(result.current.currentPage).toBe(3);
|
|
33
|
+
|
|
34
|
+
// Check top limit is working.
|
|
35
|
+
result.current.nextPage();
|
|
36
|
+
rerender();
|
|
37
|
+
expect(result.current.currentPage).toBe(3);
|
|
38
|
+
|
|
39
|
+
result.current.prevPage();
|
|
40
|
+
rerender();
|
|
41
|
+
expect(result.current.currentPage).toBe(2);
|
|
42
|
+
|
|
43
|
+
result.current.prevPage();
|
|
44
|
+
rerender();
|
|
45
|
+
expect(result.current.currentPage).toBe(1);
|
|
46
|
+
|
|
47
|
+
// Test bottom limit is working.
|
|
48
|
+
result.current.prevPage();
|
|
49
|
+
rerender();
|
|
50
|
+
expect(result.current.currentPage).toBe(1);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('Test jumping to pages works as expected.', () => {
|
|
54
|
+
const itemPerPage = 4;
|
|
55
|
+
const totalTrackRefs = new Array(12) as TrackReferenceOrPlaceholder[];
|
|
56
|
+
const { result, rerender } = renderHook(() => usePagination(itemPerPage, totalTrackRefs));
|
|
57
|
+
expect(result.current.currentPage).toBe(1);
|
|
58
|
+
|
|
59
|
+
result.current.setPage(3);
|
|
60
|
+
rerender();
|
|
61
|
+
expect(result.current.currentPage).toBe(3);
|
|
62
|
+
|
|
63
|
+
result.current.setPage(2);
|
|
64
|
+
rerender();
|
|
65
|
+
expect(result.current.currentPage).toBe(2);
|
|
66
|
+
|
|
67
|
+
// Jumping to a index that is lower than 1 jumps to page 1.
|
|
68
|
+
result.current.setPage(0);
|
|
69
|
+
rerender();
|
|
70
|
+
expect(result.current.currentPage).toBe(1);
|
|
71
|
+
|
|
72
|
+
// Jumping to a index that is higher than the last page jumps to last page.
|
|
73
|
+
result.current.setPage(999999);
|
|
74
|
+
rerender();
|
|
75
|
+
expect(result.current.currentPage).toBe(3);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useVisualStableUpdate } from './useVisualStableUpdate';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The `usePagination` hook implements simple pagination logic for use with arrays.
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* const tracks = useTracks();
|
|
10
|
+
* const pagination = usePagination(4, tracks);
|
|
11
|
+
*
|
|
12
|
+
* <TrackLoop tracks={pagination.tracks} />
|
|
13
|
+
* ```
|
|
14
|
+
* @alpha
|
|
15
|
+
*/
|
|
16
|
+
export function usePagination(itemPerPage: number, trackReferences: TrackReferenceOrPlaceholder[]) {
|
|
17
|
+
const [currentPage, setCurrentPage] = React.useState(1);
|
|
18
|
+
const totalPageCount = Math.max(Math.ceil(trackReferences.length / itemPerPage), 1);
|
|
19
|
+
if (currentPage > totalPageCount) {
|
|
20
|
+
setCurrentPage(totalPageCount);
|
|
21
|
+
}
|
|
22
|
+
const lastItemIndex = currentPage * itemPerPage;
|
|
23
|
+
const firstItemIndex = lastItemIndex - itemPerPage;
|
|
24
|
+
|
|
25
|
+
const changePage = (direction: 'next' | 'previous') => {
|
|
26
|
+
setCurrentPage((state) => {
|
|
27
|
+
if (direction === 'next') {
|
|
28
|
+
if (state === totalPageCount) {
|
|
29
|
+
return state;
|
|
30
|
+
}
|
|
31
|
+
return state + 1;
|
|
32
|
+
} else {
|
|
33
|
+
if (state === 1) {
|
|
34
|
+
return state;
|
|
35
|
+
}
|
|
36
|
+
return state - 1;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const goToPage = (num: number) => {
|
|
42
|
+
if (num > totalPageCount) {
|
|
43
|
+
setCurrentPage(totalPageCount);
|
|
44
|
+
} else if (num < 1) {
|
|
45
|
+
setCurrentPage(1);
|
|
46
|
+
} else {
|
|
47
|
+
setCurrentPage(num);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const updatedTrackReferences = useVisualStableUpdate(trackReferences, itemPerPage);
|
|
52
|
+
|
|
53
|
+
const tracksOnPage = updatedTrackReferences.slice(firstItemIndex, lastItemIndex);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
totalPageCount,
|
|
57
|
+
nextPage: () => changePage('next'),
|
|
58
|
+
prevPage: () => changePage('previous'),
|
|
59
|
+
setPage: goToPage,
|
|
60
|
+
firstItemIndex,
|
|
61
|
+
lastItemIndex,
|
|
62
|
+
tracks: tracksOnPage,
|
|
63
|
+
currentPage,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default usePagination;
|