@stream-io/video-react-sdk 1.41.0 → 2.0.0-beta.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.
Files changed (313) hide show
  1. package/CHANGELOG.md +22 -6
  2. package/dist/{embedded-BackgroundFilters-folwWrgs.cjs.js → background-filters-DMStbSEg.cjs.js} +97 -71
  3. package/dist/background-filters-DMStbSEg.cjs.js.map +1 -0
  4. package/dist/{background-filters-folwWrgs.cjs.js → embedded-BackgroundFilters-DMStbSEg.cjs.js} +97 -71
  5. package/dist/embedded-BackgroundFilters-DMStbSEg.cjs.js.map +1 -0
  6. package/dist/embedded.cjs.js +2 -2
  7. package/dist/embedded.cjs.js.map +1 -1
  8. package/dist/esm/embedded.js +3 -0
  9. package/dist/esm/embedded.js.map +1 -0
  10. package/dist/esm/index.js +92 -0
  11. package/dist/esm/index.js.map +1 -0
  12. package/dist/esm/src/components/Avatar/Avatar.js +14 -0
  13. package/dist/esm/src/components/Avatar/Avatar.js.map +1 -0
  14. package/dist/{background-filters-D2U5UBbH.es.js → esm/src/components/BackgroundFilters/BackgroundFilters.js} +97 -71
  15. package/dist/esm/src/components/BackgroundFilters/BackgroundFilters.js.map +1 -0
  16. package/dist/esm/src/components/BackgroundFilters/BackgroundFiltersProvider.js +33 -0
  17. package/dist/esm/src/components/BackgroundFilters/BackgroundFiltersProvider.js.map +1 -0
  18. package/dist/esm/src/components/Button/CompositeButton.js +29 -0
  19. package/dist/esm/src/components/Button/CompositeButton.js.map +1 -0
  20. package/dist/esm/src/components/Button/IconButton.js +18 -0
  21. package/dist/esm/src/components/Button/IconButton.js.map +1 -0
  22. package/dist/esm/src/components/Button/TextButton.js +8 -0
  23. package/dist/esm/src/components/Button/TextButton.js.map +1 -0
  24. package/dist/esm/src/components/CallControls/AcceptCallButton.js +28 -0
  25. package/dist/esm/src/components/CallControls/AcceptCallButton.js.map +1 -0
  26. package/dist/esm/src/components/CallControls/CallControls.js +21 -0
  27. package/dist/esm/src/components/CallControls/CallControls.js.map +1 -0
  28. package/dist/esm/src/components/CallControls/CallStatsButton.js +18 -0
  29. package/dist/esm/src/components/CallControls/CallStatsButton.js.map +1 -0
  30. package/dist/esm/src/components/CallControls/CancelCallButton.js +78 -0
  31. package/dist/esm/src/components/CallControls/CancelCallButton.js.map +1 -0
  32. package/dist/esm/src/components/CallControls/ReactionsButton.js +61 -0
  33. package/dist/esm/src/components/CallControls/ReactionsButton.js.map +1 -0
  34. package/dist/esm/src/components/CallControls/RecordCallButton.js +64 -0
  35. package/dist/esm/src/components/CallControls/RecordCallButton.js.map +1 -0
  36. package/dist/esm/src/components/CallControls/ScreenShareButton.js +44 -0
  37. package/dist/esm/src/components/CallControls/ScreenShareButton.js.map +1 -0
  38. package/dist/esm/src/components/CallControls/ToggleAudioButton.js +72 -0
  39. package/dist/esm/src/components/CallControls/ToggleAudioButton.js.map +1 -0
  40. package/dist/esm/src/components/CallControls/ToggleAudioOutputButton.js +27 -0
  41. package/dist/esm/src/components/CallControls/ToggleAudioOutputButton.js.map +1 -0
  42. package/dist/esm/src/components/CallControls/ToggleVideoButton.js +81 -0
  43. package/dist/esm/src/components/CallControls/ToggleVideoButton.js.map +1 -0
  44. package/dist/esm/src/components/CallParticipantsList/BlockedUserListing.js +23 -0
  45. package/dist/esm/src/components/CallParticipantsList/BlockedUserListing.js.map +1 -0
  46. package/dist/esm/src/components/CallParticipantsList/CallParticipantListHeader.js +15 -0
  47. package/dist/esm/src/components/CallParticipantsList/CallParticipantListHeader.js.map +1 -0
  48. package/dist/esm/src/components/CallParticipantsList/CallParticipantListing.js +7 -0
  49. package/dist/esm/src/components/CallParticipantsList/CallParticipantListing.js.map +1 -0
  50. package/dist/esm/src/components/CallParticipantsList/CallParticipantListingItem.js +46 -0
  51. package/dist/esm/src/components/CallParticipantsList/CallParticipantListingItem.js.map +1 -0
  52. package/dist/esm/src/components/CallParticipantsList/CallParticipantsList.js +81 -0
  53. package/dist/esm/src/components/CallParticipantsList/CallParticipantsList.js.map +1 -0
  54. package/dist/esm/src/components/CallParticipantsList/EmptyParticipantSearchList.js +10 -0
  55. package/dist/esm/src/components/CallParticipantsList/EmptyParticipantSearchList.js.map +1 -0
  56. package/dist/esm/src/components/CallPreview/CallPreview.js +24 -0
  57. package/dist/esm/src/components/CallPreview/CallPreview.js.map +1 -0
  58. package/dist/esm/src/components/CallRecordingList/CallRecordingList.js +12 -0
  59. package/dist/esm/src/components/CallRecordingList/CallRecordingList.js.map +1 -0
  60. package/dist/esm/src/components/CallRecordingList/CallRecordingListHeader.js +12 -0
  61. package/dist/esm/src/components/CallRecordingList/CallRecordingListHeader.js.map +1 -0
  62. package/dist/esm/src/components/CallRecordingList/CallRecordingListItem.js +14 -0
  63. package/dist/esm/src/components/CallRecordingList/CallRecordingListItem.js.map +1 -0
  64. package/dist/esm/src/components/CallRecordingList/EmptyCallRecordingListing.js +8 -0
  65. package/dist/esm/src/components/CallRecordingList/EmptyCallRecordingListing.js.map +1 -0
  66. package/dist/esm/src/components/CallRecordingList/LoadingCallRecordingListing.js +10 -0
  67. package/dist/esm/src/components/CallRecordingList/LoadingCallRecordingListing.js.map +1 -0
  68. package/dist/esm/src/components/CallStats/CallStats.js +180 -0
  69. package/dist/esm/src/components/CallStats/CallStats.js.map +1 -0
  70. package/dist/{latency-chart-Bj5OSYzg.es.js → esm/src/components/CallStats/CallStatsLatencyChart.js} +1 -1
  71. package/dist/esm/src/components/CallStats/CallStatsLatencyChart.js.map +1 -0
  72. package/dist/esm/src/components/DeviceSettings/AudioVolumeIndicator.js +27 -0
  73. package/dist/esm/src/components/DeviceSettings/AudioVolumeIndicator.js.map +1 -0
  74. package/dist/esm/src/components/DeviceSettings/DeviceAudioPreviewItem.js +42 -0
  75. package/dist/esm/src/components/DeviceSettings/DeviceAudioPreviewItem.js.map +1 -0
  76. package/dist/esm/src/components/DeviceSettings/DeviceSelector.js +67 -0
  77. package/dist/esm/src/components/DeviceSettings/DeviceSelector.js.map +1 -0
  78. package/dist/esm/src/components/DeviceSettings/DeviceSelectorAudio.js +26 -0
  79. package/dist/esm/src/components/DeviceSettings/DeviceSelectorAudio.js.map +1 -0
  80. package/dist/esm/src/components/DeviceSettings/DeviceSelectorVideo.js +15 -0
  81. package/dist/esm/src/components/DeviceSettings/DeviceSelectorVideo.js.map +1 -0
  82. package/dist/esm/src/components/DeviceSettings/DeviceSettings.js +26 -0
  83. package/dist/esm/src/components/DeviceSettings/DeviceSettings.js.map +1 -0
  84. package/dist/esm/src/components/DeviceSettings/DeviceVideoPreviewItem.js +42 -0
  85. package/dist/esm/src/components/DeviceSettings/DeviceVideoPreviewItem.js.map +1 -0
  86. package/dist/esm/src/components/DeviceSettings/SpeakerTest.js +57 -0
  87. package/dist/esm/src/components/DeviceSettings/SpeakerTest.js.map +1 -0
  88. package/dist/esm/src/components/DropdownSelect/DropdownSelect.js +79 -0
  89. package/dist/esm/src/components/DropdownSelect/DropdownSelect.js.map +1 -0
  90. package/dist/esm/src/components/Icon/Icon.js +7 -0
  91. package/dist/esm/src/components/Icon/Icon.js.map +1 -0
  92. package/dist/esm/src/components/LoadingIndicator/LoadingIndicator.js +9 -0
  93. package/dist/esm/src/components/LoadingIndicator/LoadingIndicator.js.map +1 -0
  94. package/dist/esm/src/components/Menu/GenericMenu.js +19 -0
  95. package/dist/esm/src/components/Menu/GenericMenu.js.map +1 -0
  96. package/dist/esm/src/components/Menu/MenuToggle.js +75 -0
  97. package/dist/esm/src/components/Menu/MenuToggle.js.map +1 -0
  98. package/dist/esm/src/components/NoiseCancellation/NoiseCancellationProvider.js +96 -0
  99. package/dist/esm/src/components/NoiseCancellation/NoiseCancellationProvider.js.map +1 -0
  100. package/dist/esm/src/components/Notification/MicCaptureErrorNotification.js +23 -0
  101. package/dist/esm/src/components/Notification/MicCaptureErrorNotification.js.map +1 -0
  102. package/dist/esm/src/components/Notification/Notification.js +31 -0
  103. package/dist/esm/src/components/Notification/Notification.js.map +1 -0
  104. package/dist/esm/src/components/Notification/PermissionNotification.js +32 -0
  105. package/dist/esm/src/components/Notification/PermissionNotification.js.map +1 -0
  106. package/dist/esm/src/components/Notification/RecordingInProgressNotification.js +23 -0
  107. package/dist/esm/src/components/Notification/RecordingInProgressNotification.js.map +1 -0
  108. package/dist/esm/src/components/Notification/SpeakingWhileMutedNotification.js +14 -0
  109. package/dist/esm/src/components/Notification/SpeakingWhileMutedNotification.js.map +1 -0
  110. package/dist/esm/src/components/Permissions/PermissionRequests.js +99 -0
  111. package/dist/esm/src/components/Permissions/PermissionRequests.js.map +1 -0
  112. package/dist/esm/src/components/Reaction/Reaction.js +32 -0
  113. package/dist/esm/src/components/Reaction/Reaction.js.map +1 -0
  114. package/dist/esm/src/components/RingingCall/RingingCall.js +48 -0
  115. package/dist/esm/src/components/RingingCall/RingingCall.js.map +1 -0
  116. package/dist/esm/src/components/RingingCall/RingingCallControls.js +34 -0
  117. package/dist/esm/src/components/RingingCall/RingingCallControls.js.map +1 -0
  118. package/dist/esm/src/components/Search/SearchInput.js +27 -0
  119. package/dist/esm/src/components/Search/SearchInput.js.map +1 -0
  120. package/dist/esm/src/components/Search/SearchResults.js +15 -0
  121. package/dist/esm/src/components/Search/SearchResults.js.map +1 -0
  122. package/dist/esm/src/components/Search/hooks/useSearch.js +38 -0
  123. package/dist/esm/src/components/Search/hooks/useSearch.js.map +1 -0
  124. package/dist/esm/src/components/StreamTheme/StreamTheme.js +9 -0
  125. package/dist/esm/src/components/StreamTheme/StreamTheme.js.map +1 -0
  126. package/dist/esm/src/components/Tooltip/Tooltip.js +29 -0
  127. package/dist/esm/src/components/Tooltip/Tooltip.js.map +1 -0
  128. package/dist/esm/src/components/Tooltip/WithTooltip.js +15 -0
  129. package/dist/esm/src/components/Tooltip/WithTooltip.js.map +1 -0
  130. package/dist/esm/src/components/Tooltip/hooks/useEnterLeaveHandlers.js +17 -0
  131. package/dist/esm/src/components/Tooltip/hooks/useEnterLeaveHandlers.js.map +1 -0
  132. package/dist/esm/src/components/VideoPreview/VideoPreview.js +37 -0
  133. package/dist/esm/src/components/VideoPreview/VideoPreview.js.map +1 -0
  134. package/dist/esm/src/core/components/Audio/Audio.js +22 -0
  135. package/dist/esm/src/core/components/Audio/Audio.js.map +1 -0
  136. package/dist/esm/src/core/components/Audio/ParticipantsAudio.js +23 -0
  137. package/dist/esm/src/core/components/Audio/ParticipantsAudio.js.map +1 -0
  138. package/dist/esm/src/core/components/CallLayout/LivestreamLayout.js +150 -0
  139. package/dist/esm/src/core/components/CallLayout/LivestreamLayout.js.map +1 -0
  140. package/dist/esm/src/core/components/CallLayout/PaginatedGridLayout.js +79 -0
  141. package/dist/esm/src/core/components/CallLayout/PaginatedGridLayout.js.map +1 -0
  142. package/dist/esm/src/core/components/CallLayout/PipLayout/Grid.js +80 -0
  143. package/dist/esm/src/core/components/CallLayout/PipLayout/Grid.js.map +1 -0
  144. package/dist/esm/src/core/components/CallLayout/PipLayout/Host.js +13 -0
  145. package/dist/esm/src/core/components/CallLayout/PipLayout/Host.js.map +1 -0
  146. package/dist/esm/src/core/components/CallLayout/PipLayout/Pip.js +57 -0
  147. package/dist/esm/src/core/components/CallLayout/PipLayout/Pip.js.map +1 -0
  148. package/dist/esm/src/core/components/CallLayout/PipLayout/index.js +8 -0
  149. package/dist/esm/src/core/components/CallLayout/PipLayout/index.js.map +1 -0
  150. package/dist/esm/src/core/components/CallLayout/SpeakerLayout.js +103 -0
  151. package/dist/esm/src/core/components/CallLayout/SpeakerLayout.js.map +1 -0
  152. package/dist/esm/src/core/components/CallLayout/hooks.js +62 -0
  153. package/dist/esm/src/core/components/CallLayout/hooks.js.map +1 -0
  154. package/dist/esm/src/core/components/ParticipantView/DefaultParticipantViewUI.js +94 -0
  155. package/dist/esm/src/core/components/ParticipantView/DefaultParticipantViewUI.js.map +1 -0
  156. package/dist/esm/src/core/components/ParticipantView/ParticipantActionsContextMenu.js +97 -0
  157. package/dist/esm/src/core/components/ParticipantView/ParticipantActionsContextMenu.js.map +1 -0
  158. package/dist/esm/src/core/components/ParticipantView/ParticipantView.js +65 -0
  159. package/dist/esm/src/core/components/ParticipantView/ParticipantView.js.map +1 -0
  160. package/dist/esm/src/core/components/ParticipantView/ParticipantViewContext.js +7 -0
  161. package/dist/esm/src/core/components/ParticipantView/ParticipantViewContext.js.map +1 -0
  162. package/dist/esm/src/core/components/StreamCall/StreamCall.js +8 -0
  163. package/dist/esm/src/core/components/StreamCall/StreamCall.js.map +1 -0
  164. package/dist/esm/src/core/components/StreamVideo/StreamVideo.js +11 -0
  165. package/dist/esm/src/core/components/StreamVideo/StreamVideo.js.map +1 -0
  166. package/dist/esm/src/core/components/Video/BaseVideo.js +41 -0
  167. package/dist/esm/src/core/components/Video/BaseVideo.js.map +1 -0
  168. package/dist/esm/src/core/components/Video/BaseVideoPlaceholder.js +21 -0
  169. package/dist/esm/src/core/components/Video/BaseVideoPlaceholder.js.map +1 -0
  170. package/dist/esm/src/core/components/Video/DefaultPictureInPicturePlaceholder.js +12 -0
  171. package/dist/esm/src/core/components/Video/DefaultPictureInPicturePlaceholder.js.map +1 -0
  172. package/dist/esm/src/core/components/Video/DefaultVideoPlaceholder.js +12 -0
  173. package/dist/esm/src/core/components/Video/DefaultVideoPlaceholder.js.map +1 -0
  174. package/dist/esm/src/core/components/Video/Video.js +88 -0
  175. package/dist/esm/src/core/components/Video/Video.js.map +1 -0
  176. package/dist/esm/src/core/hooks/useCalculateHardLimit.js +59 -0
  177. package/dist/esm/src/core/hooks/useCalculateHardLimit.js.map +1 -0
  178. package/dist/esm/src/core/hooks/usePictureInPictureState.js +24 -0
  179. package/dist/esm/src/core/hooks/usePictureInPictureState.js.map +1 -0
  180. package/dist/esm/src/core/hooks/useTrackElementVisibility.js +14 -0
  181. package/dist/esm/src/core/hooks/useTrackElementVisibility.js.map +1 -0
  182. package/dist/esm/src/embedded/EmbeddedClientProvider.js +83 -0
  183. package/dist/esm/src/embedded/EmbeddedClientProvider.js.map +1 -0
  184. package/dist/esm/src/embedded/call/CallControls.js +65 -0
  185. package/dist/esm/src/embedded/call/CallControls.js.map +1 -0
  186. package/dist/esm/src/embedded/call/CallHeader.js +57 -0
  187. package/dist/esm/src/embedded/call/CallHeader.js.map +1 -0
  188. package/dist/esm/src/embedded/call/CallLayout.js +63 -0
  189. package/dist/esm/src/embedded/call/CallLayout.js.map +1 -0
  190. package/dist/esm/src/embedded/call/CallStateRouter.js +87 -0
  191. package/dist/esm/src/embedded/call/CallStateRouter.js.map +1 -0
  192. package/dist/esm/src/embedded/call/EmbeddedCall.js +12 -0
  193. package/dist/esm/src/embedded/call/EmbeddedCall.js.map +1 -0
  194. package/dist/esm/src/embedded/context/ConfigurationContext.js +21 -0
  195. package/dist/esm/src/embedded/context/ConfigurationContext.js.map +1 -0
  196. package/dist/esm/src/embedded/hooks/useCallDuration.js +32 -0
  197. package/dist/esm/src/embedded/hooks/useCallDuration.js.map +1 -0
  198. package/dist/esm/src/embedded/hooks/useEmbeddedClient.js +40 -0
  199. package/dist/esm/src/embedded/hooks/useEmbeddedClient.js.map +1 -0
  200. package/dist/esm/src/embedded/hooks/useInitializeCall.js +39 -0
  201. package/dist/esm/src/embedded/hooks/useInitializeCall.js.map +1 -0
  202. package/dist/esm/src/embedded/hooks/useInitializeVideoClient.js +93 -0
  203. package/dist/esm/src/embedded/hooks/useInitializeVideoClient.js.map +1 -0
  204. package/dist/esm/src/embedded/hooks/useIsLivestreamPaused.js +42 -0
  205. package/dist/esm/src/embedded/hooks/useIsLivestreamPaused.js.map +1 -0
  206. package/dist/esm/src/embedded/hooks/useLayout.js +122 -0
  207. package/dist/esm/src/embedded/hooks/useLayout.js.map +1 -0
  208. package/dist/esm/src/embedded/hooks/useNoiseCancellationLoader.js +48 -0
  209. package/dist/esm/src/embedded/hooks/useNoiseCancellationLoader.js.map +1 -0
  210. package/dist/esm/src/embedded/hooks/useWakeLock.js +34 -0
  211. package/dist/esm/src/embedded/hooks/useWakeLock.js.map +1 -0
  212. package/dist/esm/src/embedded/livestream/EmbeddedLivestream.js +11 -0
  213. package/dist/esm/src/embedded/livestream/EmbeddedLivestream.js.map +1 -0
  214. package/dist/esm/src/embedded/livestream/LivestreamUI.js +17 -0
  215. package/dist/esm/src/embedded/livestream/LivestreamUI.js.map +1 -0
  216. package/dist/esm/src/embedded/livestream/host/HostLayout.js +76 -0
  217. package/dist/esm/src/embedded/livestream/host/HostLayout.js.map +1 -0
  218. package/dist/esm/src/embedded/livestream/host/HostStateRouter.js +110 -0
  219. package/dist/esm/src/embedded/livestream/host/HostStateRouter.js.map +1 -0
  220. package/dist/esm/src/embedded/livestream/viewer/ViewerLayout.js +74 -0
  221. package/dist/esm/src/embedded/livestream/viewer/ViewerLayout.js.map +1 -0
  222. package/dist/esm/src/embedded/livestream/viewer/ViewerLobby.js +109 -0
  223. package/dist/esm/src/embedded/livestream/viewer/ViewerLobby.js.map +1 -0
  224. package/dist/esm/src/embedded/livestream/viewer/ViewerStateRouter.js +105 -0
  225. package/dist/esm/src/embedded/livestream/viewer/ViewerStateRouter.js.map +1 -0
  226. package/dist/esm/src/embedded/shared/BlurToggleButton/BlurToggleButton.js +65 -0
  227. package/dist/esm/src/embedded/shared/BlurToggleButton/BlurToggleButton.js.map +1 -0
  228. package/dist/esm/src/embedded/shared/CallFeedback/CallEndedScreen.js +34 -0
  229. package/dist/esm/src/embedded/shared/CallFeedback/CallEndedScreen.js.map +1 -0
  230. package/dist/esm/src/embedded/shared/CallFeedback/CallFeedback.js +35 -0
  231. package/dist/esm/src/embedded/shared/CallFeedback/CallFeedback.js.map +1 -0
  232. package/dist/esm/src/embedded/shared/CallFeedback/RatingScreen.js +18 -0
  233. package/dist/esm/src/embedded/shared/CallFeedback/RatingScreen.js.map +1 -0
  234. package/dist/esm/src/embedded/shared/CallFeedback/StarRating.js +37 -0
  235. package/dist/esm/src/embedded/shared/CallFeedback/StarRating.js.map +1 -0
  236. package/dist/esm/src/embedded/shared/CallFeedback/ThankYouScreen.js +34 -0
  237. package/dist/esm/src/embedded/shared/CallFeedback/ThankYouScreen.js.map +1 -0
  238. package/dist/esm/src/embedded/shared/ConnectionNotification/ConnectionNotification.js +56 -0
  239. package/dist/esm/src/embedded/shared/ConnectionNotification/ConnectionNotification.js.map +1 -0
  240. package/dist/esm/src/embedded/shared/EmbeddedParticipantViewUI/EmbeddedParticipantViewUI.js +42 -0
  241. package/dist/esm/src/embedded/shared/EmbeddedParticipantViewUI/EmbeddedParticipantViewUI.js.map +1 -0
  242. package/dist/esm/src/embedded/shared/JoinError/JoinError.js +34 -0
  243. package/dist/esm/src/embedded/shared/JoinError/JoinError.js.map +1 -0
  244. package/dist/esm/src/embedded/shared/Lobby/DeviceControls.js +44 -0
  245. package/dist/esm/src/embedded/shared/Lobby/DeviceControls.js.map +1 -0
  246. package/dist/esm/src/embedded/shared/Lobby/DisabledDeviceButton.js +31 -0
  247. package/dist/esm/src/embedded/shared/Lobby/DisabledDeviceButton.js.map +1 -0
  248. package/dist/esm/src/embedded/shared/Lobby/Lobby.js +45 -0
  249. package/dist/esm/src/embedded/shared/Lobby/Lobby.js.map +1 -0
  250. package/dist/esm/src/embedded/shared/Lobby/ToggleCameraButton.js +40 -0
  251. package/dist/esm/src/embedded/shared/Lobby/ToggleCameraButton.js.map +1 -0
  252. package/dist/esm/src/embedded/shared/Lobby/ToggleMicButton.js +41 -0
  253. package/dist/esm/src/embedded/shared/Lobby/ToggleMicButton.js.map +1 -0
  254. package/dist/esm/src/embedded/shared/Lobby/VideoPreviewFallbacks.js +50 -0
  255. package/dist/esm/src/embedded/shared/Lobby/VideoPreviewFallbacks.js.map +1 -0
  256. package/dist/esm/src/embedded/shared/ViewersCount/ViewersCount.js +31 -0
  257. package/dist/esm/src/embedded/shared/ViewersCount/ViewersCount.js.map +1 -0
  258. package/dist/esm/src/hooks/useDeviceList.js +40 -0
  259. package/dist/esm/src/hooks/useDeviceList.js.map +1 -0
  260. package/dist/esm/src/hooks/useDragToScroll.js +116 -0
  261. package/dist/esm/src/hooks/useDragToScroll.js.map +1 -0
  262. package/dist/esm/src/hooks/useFloatingUIPreset.js +34 -0
  263. package/dist/esm/src/hooks/useFloatingUIPreset.js.map +1 -0
  264. package/dist/esm/src/hooks/useLoopbackRecording.js +138 -0
  265. package/dist/esm/src/hooks/useLoopbackRecording.js.map +1 -0
  266. package/dist/esm/src/hooks/useModeration.js +135 -0
  267. package/dist/esm/src/hooks/useModeration.js.map +1 -0
  268. package/dist/esm/src/hooks/usePersistedDevicePreferences.js +16 -0
  269. package/dist/esm/src/hooks/usePersistedDevicePreferences.js.map +1 -0
  270. package/dist/esm/src/hooks/useRequestPermission.js +41 -0
  271. package/dist/esm/src/hooks/useRequestPermission.js.map +1 -0
  272. package/dist/esm/src/hooks/useScrollPosition.js +66 -0
  273. package/dist/esm/src/hooks/useScrollPosition.js.map +1 -0
  274. package/dist/esm/src/translations/en.json.js +177 -0
  275. package/dist/esm/src/translations/en.json.js.map +1 -0
  276. package/dist/esm/src/translations/index.js +6 -0
  277. package/dist/esm/src/translations/index.js.map +1 -0
  278. package/dist/esm/src/utilities/applyElementToRef.js +10 -0
  279. package/dist/esm/src/utilities/applyElementToRef.js.map +1 -0
  280. package/dist/esm/src/utilities/callControlHandler.js +29 -0
  281. package/dist/esm/src/utilities/callControlHandler.js.map +1 -0
  282. package/dist/esm/src/utilities/chunk.js +7 -0
  283. package/dist/esm/src/utilities/chunk.js.map +1 -0
  284. package/dist/esm/src/utilities/filter.js +94 -0
  285. package/dist/esm/src/utilities/filter.js.map +1 -0
  286. package/dist/esm/src/utilities/isComponentType.js +10 -0
  287. package/dist/esm/src/utilities/isComponentType.js.map +1 -0
  288. package/dist/esm/src/utilities/normalizeString.js +11 -0
  289. package/dist/esm/src/utilities/normalizeString.js.map +1 -0
  290. package/dist/esm/src/wrappers/LivestreamPlayer/LivestreamPlayer.js +105 -0
  291. package/dist/esm/src/wrappers/LivestreamPlayer/LivestreamPlayer.js.map +1 -0
  292. package/dist/index.cjs.js +136 -3
  293. package/dist/index.cjs.js.map +1 -1
  294. package/dist/index.d.ts +1 -1
  295. package/dist/src/hooks/index.d.ts +1 -0
  296. package/dist/src/hooks/useLoopbackRecording.d.ts +23 -0
  297. package/index.ts +4 -0
  298. package/package.json +15 -11
  299. package/src/components/BackgroundFilters/BackgroundFilters.tsx +139 -103
  300. package/src/hooks/index.ts +1 -0
  301. package/src/hooks/useLoopbackRecording.ts +207 -0
  302. package/dist/background-filters-D2U5UBbH.es.js.map +0 -1
  303. package/dist/background-filters-folwWrgs.cjs.js.map +0 -1
  304. package/dist/embedded-BackgroundFilters-D2U5UBbH.es.js +0 -420
  305. package/dist/embedded-BackgroundFilters-D2U5UBbH.es.js.map +0 -1
  306. package/dist/embedded-BackgroundFilters-folwWrgs.cjs.js.map +0 -1
  307. package/dist/embedded-CallStatsLatencyChart-Bj5OSYzg.es.js +0 -57
  308. package/dist/embedded-CallStatsLatencyChart-Bj5OSYzg.es.js.map +0 -1
  309. package/dist/embedded.es.js +0 -3536
  310. package/dist/embedded.es.js.map +0 -1
  311. package/dist/index.es.js +0 -3291
  312. package/dist/index.es.js.map +0 -1
  313. package/dist/latency-chart-Bj5OSYzg.es.js.map +0 -1
@@ -0,0 +1,103 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import clsx from 'clsx';
4
+ import { hasScreenShare } from '@stream-io/video-client';
5
+ import { useCall, useCallStateHooks, useSpeakerLayoutSortPreset } from '@stream-io/video-react-bindings';
6
+ import '../ParticipantView/ParticipantViewContext.js';
7
+ import '../../../components/Menu/MenuToggle.js';
8
+ import { ParticipantView } from '../ParticipantView/ParticipantView.js';
9
+ import { DefaultParticipantViewUI } from '../ParticipantView/DefaultParticipantViewUI.js';
10
+ import '../../../components/BackgroundFilters/BackgroundFiltersProvider.js';
11
+ import '../../../components/Button/CompositeButton.js';
12
+ import { IconButton } from '../../../components/Button/IconButton.js';
13
+ import '@floating-ui/react';
14
+ import { useVerticalScrollPosition, useHorizontalScrollPosition } from '../../../hooks/useScrollPosition.js';
15
+ import { useDragToScroll } from '../../../hooks/useDragToScroll.js';
16
+ import '../../../components/CallControls/RecordCallButton.js';
17
+ import '../../../components/CallControls/ReactionsButton.js';
18
+ import '../../../components/DeviceSettings/DeviceSettings.js';
19
+ import '../../../components/DropdownSelect/DropdownSelect.js';
20
+ import '../../../components/CallControls/CancelCallButton.js';
21
+ import '../../../components/CallControls/CallStatsButton.js';
22
+ import '../../../components/CallParticipantsList/CallParticipantsList.js';
23
+ import '../../../components/CallParticipantsList/CallParticipantListingItem.js';
24
+ import '../../../components/CallStats/CallStats.js';
25
+ import '../../../components/NoiseCancellation/NoiseCancellationProvider.js';
26
+ import '../../../components/RingingCall/RingingCall.js';
27
+ import '../../../components/Permissions/PermissionRequests.js';
28
+ import '../Video/Video.js';
29
+ import '../Video/BaseVideo.js';
30
+ import '../Video/DefaultVideoPlaceholder.js';
31
+ import { useRawRemoteParticipants, useFilteredParticipants } from './hooks.js';
32
+ import { useCalculateHardLimit } from '../../hooks/useCalculateHardLimit.js';
33
+ import '../Audio/Audio.js';
34
+ import { ParticipantsAudio } from '../Audio/ParticipantsAudio.js';
35
+
36
+ const DefaultParticipantViewUIBar = () => (jsx(DefaultParticipantViewUI, { menuPlacement: "top-end" }));
37
+ const SpeakerLayout = ({ ParticipantViewUIBar = DefaultParticipantViewUIBar, ParticipantViewUISpotlight = DefaultParticipantViewUI, VideoPlaceholder, PictureInPicturePlaceholder, participantsBarPosition = 'bottom', participantsBarLimit, mirrorLocalParticipantVideo = true, excludeLocalParticipant = false, filterParticipants, pageArrowsVisible = true, muted, enableDragToScroll = false, }) => {
38
+ const call = useCall();
39
+ const { useParticipants } = useCallStateHooks();
40
+ const allParticipants = useParticipants();
41
+ const remoteParticipants = useRawRemoteParticipants();
42
+ const [participantInSpotlight, ...otherParticipants] = useFilteredParticipants({ excludeLocalParticipant, filterParticipants });
43
+ const [participantsBarWrapperElement, setParticipantsBarWrapperElement] = useState(null);
44
+ const [participantsBarElement, setParticipantsBarElement] = useState(null);
45
+ const [buttonsWrapperElement, setButtonsWrapperElement] = useState(null);
46
+ const isSpeakerScreenSharing = participantInSpotlight && hasScreenShare(participantInSpotlight);
47
+ const hardLimit = useCalculateHardLimit(buttonsWrapperElement, participantsBarElement, participantsBarLimit);
48
+ const isVertical = participantsBarPosition === 'left' || participantsBarPosition === 'right';
49
+ const isHorizontal = participantsBarPosition === 'top' || participantsBarPosition === 'bottom';
50
+ useEffect(() => {
51
+ if (!participantsBarWrapperElement || !call)
52
+ return;
53
+ const cleanup = call.setViewport(participantsBarWrapperElement);
54
+ return () => cleanup?.();
55
+ }, [participantsBarWrapperElement, call]);
56
+ const isOneOnOneCall = allParticipants.length === 2;
57
+ useSpeakerLayoutSortPreset(call, isOneOnOneCall);
58
+ useDragToScroll(participantsBarWrapperElement, {
59
+ enabled: enableDragToScroll,
60
+ });
61
+ let participantsWithAppliedLimit = otherParticipants;
62
+ const hardLimitToApply = isVertical
63
+ ? hardLimit.vertical
64
+ : hardLimit.horizontal;
65
+ if (typeof participantsBarLimit !== 'undefined' &&
66
+ hardLimitToApply !== null) {
67
+ participantsWithAppliedLimit = otherParticipants.slice(0,
68
+ // subtract 1 if speaker is sharing screen as
69
+ // that one is rendered independently from otherParticipants array
70
+ hardLimitToApply - (isSpeakerScreenSharing ? 1 : 0));
71
+ }
72
+ const mirror = mirrorLocalParticipantVideo ? undefined : false;
73
+ if (!call)
74
+ return null;
75
+ const renderParticipantsBar = participantsBarPosition &&
76
+ (participantsWithAppliedLimit.length > 0 || isSpeakerScreenSharing);
77
+ return (jsxs("div", { className: "str-video__speaker-layout__wrapper", children: [!muted && jsx(ParticipantsAudio, { participants: remoteParticipants }), jsxs("div", { className: clsx('str-video__speaker-layout', participantsBarPosition &&
78
+ `str-video__speaker-layout--variant-${participantsBarPosition}`), children: [jsx("div", { className: "str-video__speaker-layout__spotlight", children: participantInSpotlight && (jsx(ParticipantView, { participant: participantInSpotlight, muteAudio: true, mirror: mirror, trackType: isSpeakerScreenSharing ? 'screenShareTrack' : 'videoTrack', ParticipantViewUI: ParticipantViewUISpotlight, VideoPlaceholder: VideoPlaceholder, PictureInPicturePlaceholder: PictureInPicturePlaceholder })) }), renderParticipantsBar && (jsxs("div", { ref: setButtonsWrapperElement, className: "str-video__speaker-layout__participants-bar-buttons-wrapper", children: [jsx("div", { className: "str-video__speaker-layout__participants-bar-wrapper", ref: setParticipantsBarWrapperElement, children: jsxs("div", { ref: setParticipantsBarElement, className: "str-video__speaker-layout__participants-bar", children: [isSpeakerScreenSharing && (jsx("div", { className: "str-video__speaker-layout__participant-tile", children: jsx(ParticipantView, { participant: participantInSpotlight, ParticipantViewUI: ParticipantViewUIBar, VideoPlaceholder: VideoPlaceholder, PictureInPicturePlaceholder: PictureInPicturePlaceholder, mirror: mirror, muteAudio: true }) }, participantInSpotlight.sessionId)), participantsWithAppliedLimit.map((participant) => (jsx("div", { className: "str-video__speaker-layout__participant-tile", children: jsx(ParticipantView, { participant: participant, ParticipantViewUI: ParticipantViewUIBar, VideoPlaceholder: VideoPlaceholder, PictureInPicturePlaceholder: PictureInPicturePlaceholder, mirror: mirror, muteAudio: true }) }, participant.sessionId)))] }) }), pageArrowsVisible && isVertical && (jsx(VerticalScrollButtons, { scrollWrapper: participantsBarWrapperElement })), pageArrowsVisible && isHorizontal && (jsx(HorizontalScrollButtons, { scrollWrapper: participantsBarWrapperElement }))] }))] })] }));
79
+ };
80
+ SpeakerLayout.displayName = 'SpeakerLayout';
81
+ const HorizontalScrollButtons = ({ scrollWrapper, }) => {
82
+ const scrollPosition = useHorizontalScrollPosition(scrollWrapper);
83
+ const scrollStartClickHandler = () => {
84
+ scrollWrapper?.scrollBy({ left: -150, behavior: 'smooth' });
85
+ };
86
+ const scrollEndClickHandler = () => {
87
+ scrollWrapper?.scrollBy({ left: 150, behavior: 'smooth' });
88
+ };
89
+ return (jsxs(Fragment, { children: [scrollPosition && scrollPosition !== 'start' && (jsx(IconButton, { onClick: scrollStartClickHandler, icon: "caret-left", className: "str-video__speaker-layout__participants-bar--button-left" })), scrollPosition && scrollPosition !== 'end' && (jsx(IconButton, { onClick: scrollEndClickHandler, icon: "caret-right", className: "str-video__speaker-layout__participants-bar--button-right" }))] }));
90
+ };
91
+ const VerticalScrollButtons = ({ scrollWrapper, }) => {
92
+ const scrollPosition = useVerticalScrollPosition(scrollWrapper);
93
+ const scrollTopClickHandler = () => {
94
+ scrollWrapper?.scrollBy({ top: -150, behavior: 'smooth' });
95
+ };
96
+ const scrollBottomClickHandler = () => {
97
+ scrollWrapper?.scrollBy({ top: 150, behavior: 'smooth' });
98
+ };
99
+ return (jsxs(Fragment, { children: [scrollPosition && scrollPosition !== 'top' && (jsx(IconButton, { onClick: scrollTopClickHandler, icon: "caret-up", className: "str-video__speaker-layout__participants-bar--button-top" })), scrollPosition && scrollPosition !== 'bottom' && (jsx(IconButton, { onClick: scrollBottomClickHandler, icon: "caret-down", className: "str-video__speaker-layout__participants-bar--button-bottom" }))] }));
100
+ };
101
+
102
+ export { SpeakerLayout };
103
+ //# sourceMappingURL=SpeakerLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpeakerLayout.js","sources":["../../../../../../../../src/core/components/CallLayout/SpeakerLayout.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport clsx from 'clsx';\nimport { hasScreenShare } from '@stream-io/video-client';\nimport {\n useCall,\n useCallStateHooks,\n useSpeakerLayoutSortPreset,\n} from '@stream-io/video-react-bindings';\n\nimport {\n DefaultParticipantViewUI,\n ParticipantView,\n ParticipantViewProps,\n} from '../ParticipantView';\nimport { IconButton } from '../../../components';\nimport {\n useDragToScroll,\n useHorizontalScrollPosition,\n useVerticalScrollPosition,\n} from '../../../hooks';\nimport {\n ParticipantFilter,\n ParticipantPredicate,\n useFilteredParticipants,\n useRawRemoteParticipants,\n} from './hooks';\nimport { useCalculateHardLimit } from '../../hooks/useCalculateHardLimit';\nimport { ParticipantsAudio } from '../Audio';\n\nexport type SpeakerLayoutProps = {\n /**\n * The UI to be used for the participant in the spotlight.\n */\n ParticipantViewUISpotlight?: ParticipantViewProps['ParticipantViewUI'];\n\n /**\n * The UI to be used for the participants in the participants bar.\n */\n ParticipantViewUIBar?: ParticipantViewProps['ParticipantViewUI'];\n\n /**\n * The position of the participants who are not in focus.\n * Providing `null` will hide the bar.\n */\n participantsBarPosition?: 'top' | 'bottom' | 'left' | 'right' | null;\n\n /**\n * Hard limits the number of the participants rendered in the participants bar.\n * Providing string `dynamic` will calculate hard limit based on screen width/height.\n */\n participantsBarLimit?: 'dynamic' | number;\n\n /**\n * When set to `true` will exclude the local participant from layout.\n * @default false\n */\n excludeLocalParticipant?: boolean;\n\n /**\n * Predicate to filter call participants or a filter object.\n * @example\n * // With a predicate:\n * <SpeakerLayout\n * filterParticipants={p => p.roles.includes('student')}\n * />\n * @example\n * // With a filter object:\n * <SpeakerLayout\n * filterParticipants={{\n * $or: [\n * { roles: { $contains: 'student' } },\n * { isPinned: true },\n * ],\n * }}\n * />\n */\n filterParticipants?: ParticipantPredicate | ParticipantFilter;\n\n /**\n * When set to `false` disables mirroring of the local participant's video.\n * @default true\n */\n mirrorLocalParticipantVideo?: boolean;\n\n /**\n * Turns on/off the pagination arrows.\n * @default true\n */\n pageArrowsVisible?: boolean;\n\n /**\n * Whether the layout is muted. Defaults to `false`.\n */\n muted?: boolean;\n\n /**\n * Whether to enable drag-to-scroll functionality on the participants bar.\n * @default false\n */\n enableDragToScroll?: boolean;\n} & Pick<\n ParticipantViewProps,\n 'VideoPlaceholder' | 'PictureInPicturePlaceholder'\n>;\n\nconst DefaultParticipantViewUIBar = () => (\n <DefaultParticipantViewUI menuPlacement=\"top-end\" />\n);\n\nexport const SpeakerLayout = ({\n ParticipantViewUIBar = DefaultParticipantViewUIBar,\n ParticipantViewUISpotlight = DefaultParticipantViewUI,\n VideoPlaceholder,\n PictureInPicturePlaceholder,\n participantsBarPosition = 'bottom',\n participantsBarLimit,\n mirrorLocalParticipantVideo = true,\n excludeLocalParticipant = false,\n filterParticipants,\n pageArrowsVisible = true,\n muted,\n enableDragToScroll = false,\n}: SpeakerLayoutProps) => {\n const call = useCall();\n const { useParticipants } = useCallStateHooks();\n const allParticipants = useParticipants();\n const remoteParticipants = useRawRemoteParticipants();\n const [participantInSpotlight, ...otherParticipants] =\n useFilteredParticipants({ excludeLocalParticipant, filterParticipants });\n const [participantsBarWrapperElement, setParticipantsBarWrapperElement] =\n useState<HTMLDivElement | null>(null);\n const [participantsBarElement, setParticipantsBarElement] =\n useState<HTMLDivElement | null>(null);\n const [buttonsWrapperElement, setButtonsWrapperElement] =\n useState<HTMLDivElement | null>(null);\n\n const isSpeakerScreenSharing =\n participantInSpotlight && hasScreenShare(participantInSpotlight);\n const hardLimit = useCalculateHardLimit(\n buttonsWrapperElement,\n participantsBarElement,\n participantsBarLimit,\n );\n\n const isVertical =\n participantsBarPosition === 'left' || participantsBarPosition === 'right';\n const isHorizontal =\n participantsBarPosition === 'top' || participantsBarPosition === 'bottom';\n\n useEffect(() => {\n if (!participantsBarWrapperElement || !call) return;\n\n const cleanup = call.setViewport(participantsBarWrapperElement);\n\n return () => cleanup?.();\n }, [participantsBarWrapperElement, call]);\n\n const isOneOnOneCall = allParticipants.length === 2;\n useSpeakerLayoutSortPreset(call, isOneOnOneCall);\n useDragToScroll(participantsBarWrapperElement, {\n enabled: enableDragToScroll,\n });\n\n let participantsWithAppliedLimit = otherParticipants;\n\n const hardLimitToApply = isVertical\n ? hardLimit.vertical\n : hardLimit.horizontal;\n\n if (\n typeof participantsBarLimit !== 'undefined' &&\n hardLimitToApply !== null\n ) {\n participantsWithAppliedLimit = otherParticipants.slice(\n 0,\n // subtract 1 if speaker is sharing screen as\n // that one is rendered independently from otherParticipants array\n hardLimitToApply - (isSpeakerScreenSharing ? 1 : 0),\n );\n }\n\n const mirror = mirrorLocalParticipantVideo ? undefined : false;\n\n if (!call) return null;\n\n const renderParticipantsBar =\n participantsBarPosition &&\n (participantsWithAppliedLimit.length > 0 || isSpeakerScreenSharing);\n return (\n <div className=\"str-video__speaker-layout__wrapper\">\n {!muted && <ParticipantsAudio participants={remoteParticipants} />}\n <div\n className={clsx(\n 'str-video__speaker-layout',\n participantsBarPosition &&\n `str-video__speaker-layout--variant-${participantsBarPosition}`,\n )}\n >\n <div className=\"str-video__speaker-layout__spotlight\">\n {participantInSpotlight && (\n <ParticipantView\n participant={participantInSpotlight}\n muteAudio={true}\n mirror={mirror}\n trackType={\n isSpeakerScreenSharing ? 'screenShareTrack' : 'videoTrack'\n }\n ParticipantViewUI={ParticipantViewUISpotlight}\n VideoPlaceholder={VideoPlaceholder}\n PictureInPicturePlaceholder={PictureInPicturePlaceholder}\n />\n )}\n </div>\n {renderParticipantsBar && (\n <div\n ref={setButtonsWrapperElement}\n className=\"str-video__speaker-layout__participants-bar-buttons-wrapper\"\n >\n <div\n className=\"str-video__speaker-layout__participants-bar-wrapper\"\n ref={setParticipantsBarWrapperElement}\n >\n <div\n ref={setParticipantsBarElement}\n className=\"str-video__speaker-layout__participants-bar\"\n >\n {isSpeakerScreenSharing && (\n <div\n className=\"str-video__speaker-layout__participant-tile\"\n key={participantInSpotlight.sessionId}\n >\n <ParticipantView\n participant={participantInSpotlight}\n ParticipantViewUI={ParticipantViewUIBar}\n VideoPlaceholder={VideoPlaceholder}\n PictureInPicturePlaceholder={PictureInPicturePlaceholder}\n mirror={mirror}\n muteAudio={true}\n />\n </div>\n )}\n {participantsWithAppliedLimit.map((participant) => (\n <div\n className=\"str-video__speaker-layout__participant-tile\"\n key={participant.sessionId}\n >\n <ParticipantView\n participant={participant}\n ParticipantViewUI={ParticipantViewUIBar}\n VideoPlaceholder={VideoPlaceholder}\n PictureInPicturePlaceholder={PictureInPicturePlaceholder}\n mirror={mirror}\n muteAudio={true}\n />\n </div>\n ))}\n </div>\n </div>\n {pageArrowsVisible && isVertical && (\n <VerticalScrollButtons\n scrollWrapper={participantsBarWrapperElement}\n />\n )}\n {pageArrowsVisible && isHorizontal && (\n <HorizontalScrollButtons\n scrollWrapper={participantsBarWrapperElement}\n />\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nSpeakerLayout.displayName = 'SpeakerLayout';\n\ntype ScrollButtonsProps<T extends HTMLElement> = {\n scrollWrapper: T | null;\n};\n\nconst HorizontalScrollButtons = <T extends HTMLElement>({\n scrollWrapper,\n}: ScrollButtonsProps<T>) => {\n const scrollPosition = useHorizontalScrollPosition(scrollWrapper);\n\n const scrollStartClickHandler = () => {\n scrollWrapper?.scrollBy({ left: -150, behavior: 'smooth' });\n };\n\n const scrollEndClickHandler = () => {\n scrollWrapper?.scrollBy({ left: 150, behavior: 'smooth' });\n };\n return (\n <>\n {scrollPosition && scrollPosition !== 'start' && (\n <IconButton\n onClick={scrollStartClickHandler}\n icon=\"caret-left\"\n className=\"str-video__speaker-layout__participants-bar--button-left\"\n />\n )}\n {scrollPosition && scrollPosition !== 'end' && (\n <IconButton\n onClick={scrollEndClickHandler}\n icon=\"caret-right\"\n className=\"str-video__speaker-layout__participants-bar--button-right\"\n />\n )}\n </>\n );\n};\n\nconst VerticalScrollButtons = <T extends HTMLElement>({\n scrollWrapper,\n}: ScrollButtonsProps<T>) => {\n const scrollPosition = useVerticalScrollPosition(scrollWrapper);\n\n const scrollTopClickHandler = () => {\n scrollWrapper?.scrollBy({ top: -150, behavior: 'smooth' });\n };\n\n const scrollBottomClickHandler = () => {\n scrollWrapper?.scrollBy({ top: 150, behavior: 'smooth' });\n };\n return (\n <>\n {scrollPosition && scrollPosition !== 'top' && (\n <IconButton\n onClick={scrollTopClickHandler}\n icon=\"caret-up\"\n className=\"str-video__speaker-layout__participants-bar--button-top\"\n />\n )}\n {scrollPosition && scrollPosition !== 'bottom' && (\n <IconButton\n onClick={scrollBottomClickHandler}\n icon=\"caret-down\"\n className=\"str-video__speaker-layout__participants-bar--button-bottom\"\n />\n )}\n </>\n );\n};\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { useMemo, useEffect } from 'react';
2
+ import { paginatedLayoutSortPreset, CallTypes, defaultSortPreset, hasScreenShare, hasAudio, hasVideo, isPinned } from '@stream-io/video-client';
3
+ import { useCallStateHooks } from '@stream-io/video-react-bindings';
4
+ import { applyFilter } from '../../../utilities/filter.js';
5
+
6
+ const useFilteredParticipants = ({ excludeLocalParticipant = false, filterParticipants, }) => {
7
+ const { useParticipants, useRemoteParticipants } = useCallStateHooks();
8
+ const allParticipants = useParticipants();
9
+ const remoteParticipants = useRemoteParticipants();
10
+ return useMemo(() => {
11
+ const unfilteredParticipants = excludeLocalParticipant
12
+ ? remoteParticipants
13
+ : allParticipants;
14
+ return filterParticipants
15
+ ? applyParticipantsFilter(unfilteredParticipants, filterParticipants)
16
+ : unfilteredParticipants;
17
+ }, [
18
+ allParticipants,
19
+ remoteParticipants,
20
+ excludeLocalParticipant,
21
+ filterParticipants,
22
+ ]);
23
+ };
24
+ const applyParticipantsFilter = (participants, filter) => {
25
+ const filterCallback = typeof filter === 'function'
26
+ ? filter
27
+ : (participant) => applyFilter({
28
+ userId: participant.userId,
29
+ isSpeaking: participant.isSpeaking,
30
+ isDominantSpeaker: participant.isDominantSpeaker,
31
+ name: participant.name,
32
+ roles: participant.roles,
33
+ isPinned: isPinned(participant),
34
+ hasVideo: hasVideo(participant),
35
+ hasAudio: hasAudio(participant),
36
+ hasScreenShare: hasScreenShare(participant),
37
+ }, filter);
38
+ return participants.filter(filterCallback);
39
+ };
40
+ const usePaginatedLayoutSortPreset = (call) => {
41
+ useEffect(() => {
42
+ if (!call)
43
+ return;
44
+ call.setSortParticipantsBy(paginatedLayoutSortPreset);
45
+ return () => {
46
+ resetSortPreset(call);
47
+ };
48
+ }, [call]);
49
+ };
50
+ const useRawRemoteParticipants = () => {
51
+ const { useRawParticipants } = useCallStateHooks();
52
+ const rawParticipants = useRawParticipants();
53
+ return useMemo(() => rawParticipants.filter((p) => !p.isLocalParticipant), [rawParticipants]);
54
+ };
55
+ const resetSortPreset = (call) => {
56
+ // reset the sorting to the default for the call type
57
+ const callConfig = CallTypes.get(call.type);
58
+ call.setSortParticipantsBy(callConfig.options.sortParticipantsBy || defaultSortPreset);
59
+ };
60
+
61
+ export { applyParticipantsFilter, useFilteredParticipants, usePaginatedLayoutSortPreset, useRawRemoteParticipants };
62
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sources":["../../../../../../../../src/core/components/CallLayout/hooks.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport {\n Call,\n CallTypes,\n defaultSortPreset,\n hasAudio,\n hasScreenShare,\n hasVideo,\n isPinned,\n paginatedLayoutSortPreset,\n StreamVideoParticipant,\n} from '@stream-io/video-client';\nimport { useCallStateHooks } from '@stream-io/video-react-bindings';\nimport { applyFilter, Filter } from '../../../utilities/filter';\n\nexport type FilterableParticipant = Pick<\n StreamVideoParticipant,\n 'userId' | 'isSpeaking' | 'isDominantSpeaker' | 'name' | 'roles'\n> & {\n isPinned: boolean;\n hasVideo: boolean;\n hasAudio: boolean;\n hasScreenShare: boolean;\n};\n\nexport type ParticipantFilter = Filter<FilterableParticipant>;\nexport type ParticipantPredicate = (\n participant: StreamVideoParticipant,\n) => boolean;\n\nexport const useFilteredParticipants = ({\n excludeLocalParticipant = false,\n filterParticipants,\n}: {\n excludeLocalParticipant?: boolean;\n filterParticipants?: ParticipantFilter | ParticipantPredicate;\n}) => {\n const { useParticipants, useRemoteParticipants } = useCallStateHooks();\n const allParticipants = useParticipants();\n const remoteParticipants = useRemoteParticipants();\n return useMemo(() => {\n const unfilteredParticipants = excludeLocalParticipant\n ? remoteParticipants\n : allParticipants;\n\n return filterParticipants\n ? applyParticipantsFilter(unfilteredParticipants, filterParticipants)\n : unfilteredParticipants;\n }, [\n allParticipants,\n remoteParticipants,\n excludeLocalParticipant,\n filterParticipants,\n ]);\n};\n\nexport const applyParticipantsFilter = (\n participants: StreamVideoParticipant[],\n filter: ParticipantPredicate | ParticipantFilter,\n) => {\n const filterCallback =\n typeof filter === 'function'\n ? filter\n : (participant: StreamVideoParticipant) =>\n applyFilter(\n {\n userId: participant.userId,\n isSpeaking: participant.isSpeaking,\n isDominantSpeaker: participant.isDominantSpeaker,\n name: participant.name,\n roles: participant.roles,\n isPinned: isPinned(participant),\n hasVideo: hasVideo(participant),\n hasAudio: hasAudio(participant),\n hasScreenShare: hasScreenShare(participant),\n },\n filter,\n );\n\n return participants.filter(filterCallback);\n};\n\nexport const usePaginatedLayoutSortPreset = (call: Call | undefined) => {\n useEffect(() => {\n if (!call) return;\n call.setSortParticipantsBy(paginatedLayoutSortPreset);\n return () => {\n resetSortPreset(call);\n };\n }, [call]);\n};\n\nexport const useRawRemoteParticipants = () => {\n const { useRawParticipants } = useCallStateHooks();\n const rawParticipants = useRawParticipants();\n return useMemo(\n () => rawParticipants.filter((p) => !p.isLocalParticipant),\n [rawParticipants],\n );\n};\n\nconst resetSortPreset = (call: Call) => {\n // reset the sorting to the default for the call type\n const callConfig = CallTypes.get(call.type);\n call.setSortParticipantsBy(\n callConfig.options.sortParticipantsBy || defaultSortPreset,\n );\n};\n"],"names":[],"mappings":";;;;;AA8BO,MAAM,uBAAuB,GAAG,CAAC,EACtC,uBAAuB,GAAG,KAAK,EAC/B,kBAAkB,GAInB,KAAI;IACH,MAAM,EAAE,eAAe,EAAE,qBAAqB,EAAE,GAAG,iBAAiB,EAAE;AACtE,IAAA,MAAM,eAAe,GAAG,eAAe,EAAE;AACzC,IAAA,MAAM,kBAAkB,GAAG,qBAAqB,EAAE;IAClD,OAAO,OAAO,CAAC,MAAK;QAClB,MAAM,sBAAsB,GAAG;AAC7B,cAAE;cACA,eAAe;AAEnB,QAAA,OAAO;AACL,cAAE,uBAAuB,CAAC,sBAAsB,EAAE,kBAAkB;cAClE,sBAAsB;AAC5B,IAAA,CAAC,EAAE;QACD,eAAe;QACf,kBAAkB;QAClB,uBAAuB;QACvB,kBAAkB;AACnB,KAAA,CAAC;AACJ;MAEa,uBAAuB,GAAG,CACrC,YAAsC,EACtC,MAAgD,KAC9C;AACF,IAAA,MAAM,cAAc,GAClB,OAAO,MAAM,KAAK;AAChB,UAAE;AACF,UAAE,CAAC,WAAmC,KAClC,WAAW,CACT;YACE,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,UAAU,EAAE,WAAW,CAAC,UAAU;YAClC,iBAAiB,EAAE,WAAW,CAAC,iBAAiB;YAChD,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,KAAK,EAAE,WAAW,CAAC,KAAK;AACxB,YAAA,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC;AAC/B,YAAA,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC;AAC/B,YAAA,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC;AAC/B,YAAA,cAAc,EAAE,cAAc,CAAC,WAAW,CAAC;SAC5C,EACD,MAAM,CACP;AAET,IAAA,OAAO,YAAY,CAAC,MAAM,CAAC,cAAc,CAAC;AAC5C;AAEO,MAAM,4BAA4B,GAAG,CAAC,IAAsB,KAAI;IACrE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,IAAI;YAAE;AACX,QAAA,IAAI,CAAC,qBAAqB,CAAC,yBAAyB,CAAC;AACrD,QAAA,OAAO,MAAK;YACV,eAAe,CAAC,IAAI,CAAC;AACvB,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACZ;AAEO,MAAM,wBAAwB,GAAG,MAAK;AAC3C,IAAA,MAAM,EAAE,kBAAkB,EAAE,GAAG,iBAAiB,EAAE;AAClD,IAAA,MAAM,eAAe,GAAG,kBAAkB,EAAE;IAC5C,OAAO,OAAO,CACZ,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAC1D,CAAC,eAAe,CAAC,CAClB;AACH;AAEA,MAAM,eAAe,GAAG,CAAC,IAAU,KAAI;;IAErC,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3C,IAAI,CAAC,qBAAqB,CACxB,UAAU,CAAC,OAAO,CAAC,kBAAkB,IAAI,iBAAiB,CAC3D;AACH,CAAC;;;;"}
@@ -0,0 +1,94 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { forwardRef } from 'react';
3
+ import { hasScreenShare, SfuModels, hasAudio, hasVideo, hasPausedTrack } from '@stream-io/video-client';
4
+ import { useCallStateHooks, useCall, useI18n, useIsAudioConnecting, useIsVideoConnecting } from '@stream-io/video-react-bindings';
5
+ import clsx from 'clsx';
6
+ import '../../../components/BackgroundFilters/BackgroundFiltersProvider.js';
7
+ import '../../../components/Button/CompositeButton.js';
8
+ import { IconButton } from '../../../components/Button/IconButton.js';
9
+ import { Notification } from '../../../components/Notification/Notification.js';
10
+ import '../../../components/CallControls/RecordCallButton.js';
11
+ import '../../../components/CallControls/ReactionsButton.js';
12
+ import '@floating-ui/react';
13
+ import { Icon } from '../../../components/Icon/Icon.js';
14
+ import '../../../components/DeviceSettings/DeviceSettings.js';
15
+ import '../../../components/DropdownSelect/DropdownSelect.js';
16
+ import { MenuToggle } from '../../../components/Menu/MenuToggle.js';
17
+ import '../../../components/CallControls/CancelCallButton.js';
18
+ import '../../../components/CallControls/CallStatsButton.js';
19
+ import '../../../components/CallParticipantsList/CallParticipantsList.js';
20
+ import '../../../components/CallParticipantsList/CallParticipantListingItem.js';
21
+ import { LoadingIndicator } from '../../../components/LoadingIndicator/LoadingIndicator.js';
22
+ import '../../../components/CallStats/CallStats.js';
23
+ import '../../../components/NoiseCancellation/NoiseCancellationProvider.js';
24
+ import { Reaction } from '../../../components/Reaction/Reaction.js';
25
+ import '../../../components/RingingCall/RingingCall.js';
26
+ import '../../../components/Permissions/PermissionRequests.js';
27
+ import '../Video/Video.js';
28
+ import '../Video/BaseVideo.js';
29
+ import '../Video/DefaultVideoPlaceholder.js';
30
+ import { ParticipantActionsContextMenu } from './ParticipantActionsContextMenu.js';
31
+ import { useParticipantViewContext } from './ParticipantViewContext.js';
32
+
33
+ const ToggleButton = forwardRef(function ToggleButtonRender(props, ref) {
34
+ return jsx(IconButton, { enabled: props.menuShown, icon: "ellipsis", ref: ref });
35
+ });
36
+ const DefaultScreenShareOverlay = () => {
37
+ const call = useCall();
38
+ const { t } = useI18n();
39
+ const stopScreenShare = () => {
40
+ call?.screenShare.disable().catch((err) => {
41
+ console.error('Failed to stop screen sharing:', err);
42
+ });
43
+ };
44
+ return (jsxs("div", { className: "str-video__screen-share-overlay", children: [jsx(Icon, { icon: "screen-share-off" }), jsx("span", { className: "str-video__screen-share-overlay__title", children: t('You are presenting your screen') }), jsxs("button", { onClick: stopScreenShare, type: "button", className: "str-video__screen-share-overlay__button", children: [jsx(Icon, { icon: "close" }), " ", t('Stop Screen Sharing')] })] }));
45
+ };
46
+ /**
47
+ * Rendered over a remote participant's tile when the browser's autoplay policy
48
+ * has blocked their audio. Selecting it calls `call.resumeAudio()`, unblocking
49
+ * every blocked element at once.
50
+ */
51
+ const DefaultAudioBlockedNotification = () => {
52
+ const call = useCall();
53
+ const { t } = useI18n();
54
+ return (jsx("button", { type: "button", className: "str-video__audio-blocked-notification", onClick: call?.resumeAudio, "aria-live": "polite", children: jsxs("span", { className: "str-video__audio-blocked-notification__message", children: [jsx(Icon, { icon: "speaker" }), jsxs("span", { className: "str-video__audio-blocked-notification__text", children: [jsx("span", { className: "str-video__audio-blocked-notification__title", children: t('Audio is blocked by your system') }), jsx("span", { className: "str-video__audio-blocked-notification__subtitle", children: t('Click or tap to play audio') })] })] }) }));
55
+ };
56
+ const DefaultParticipantViewUI = ({ indicatorsVisible = true, menuPlacement = 'bottom-start', showMenuButton = true, ParticipantActionsContextMenu: ParticipantActionsContextMenu$1 = ParticipantActionsContextMenu, AudioBlockedNotification = DefaultAudioBlockedNotification, }) => {
57
+ const { participant, trackType } = useParticipantViewContext();
58
+ const { useAutoplayBlockedSessionIds } = useCallStateHooks();
59
+ const blockedSessionIds = useAutoplayBlockedSessionIds();
60
+ const isScreenSharing = hasScreenShare(participant);
61
+ const shouldShowAudioBlockedNotification = !participant.isLocalParticipant &&
62
+ trackType !== 'screenShareTrack' &&
63
+ blockedSessionIds.includes(participant.sessionId);
64
+ if (participant.isLocalParticipant &&
65
+ isScreenSharing &&
66
+ trackType === 'screenShareTrack') {
67
+ return (jsxs(Fragment, { children: [jsx(DefaultScreenShareOverlay, {}), jsx(ParticipantDetails, { indicatorsVisible: indicatorsVisible })] }));
68
+ }
69
+ return (jsxs(Fragment, { children: [showMenuButton && (jsx(MenuToggle, { strategy: "fixed", placement: menuPlacement, ToggleButton: ToggleButton, children: jsx(ParticipantActionsContextMenu$1, {}) })), jsx(Reaction, { participant: participant }), jsx(ParticipantDetails, { indicatorsVisible: indicatorsVisible }), AudioBlockedNotification && shouldShowAudioBlockedNotification && (jsx(AudioBlockedNotification, {}))] }));
70
+ };
71
+ const ParticipantDetails = ({ indicatorsVisible = true, }) => {
72
+ const { participant, trackType } = useParticipantViewContext();
73
+ const { isLocalParticipant, connectionQuality, pin, sessionId, name, userId, } = participant;
74
+ const call = useCall();
75
+ const { t } = useI18n();
76
+ const connectionQualityAsString = !!connectionQuality &&
77
+ SfuModels.ConnectionQuality[connectionQuality].toLowerCase();
78
+ const hasAudioTrack = hasAudio(participant);
79
+ const hasVideoTrack = hasVideo(participant);
80
+ const canUnpin = !!pin && pin.isLocalPin;
81
+ const isTrackPaused = trackType !== 'none' ? hasPausedTrack(participant, trackType) : false;
82
+ const isAudioConnecting = useIsAudioConnecting(participant);
83
+ const isVideoConnecting = useIsVideoConnecting(participant);
84
+ return (jsxs(Fragment, { children: [jsx("div", { className: "str-video__participant-details", children: jsxs("div", { className: "str-video__participant-details__name", children: [name || userId, indicatorsVisible && isAudioConnecting && (jsx(LoadingIndicator, { className: "str-video__participant-details__name--audio-connecting", tooltip: t('Audio is connecting...') })), indicatorsVisible && !hasAudioTrack && (jsx("span", { className: "str-video__participant-details__name--audio-muted" })), indicatorsVisible && isVideoConnecting && (jsx(LoadingIndicator, { className: "str-video__participant-details__name--video-connecting", tooltip: t('Video is connecting...') })), indicatorsVisible && !hasVideoTrack && (jsx("span", { className: "str-video__participant-details__name--video-muted" })), indicatorsVisible && isTrackPaused && (jsx("span", { title: t('Video paused due to insufficient bandwidth'), className: "str-video__participant-details__name--track-paused" })), indicatorsVisible && pin && (jsx("span", { title: canUnpin ? t('Unpin') : t('Pinned'), onClick: canUnpin ? () => call?.unpin(sessionId) : undefined, className: "str-video__participant-details__name--pinned" })), indicatorsVisible && jsx(SpeechIndicator, {})] }) }), indicatorsVisible && (jsx(Notification, { isVisible: isLocalParticipant &&
85
+ connectionQuality === SfuModels.ConnectionQuality.POOR, message: t('Poor connection quality'), children: connectionQualityAsString && (jsx("span", { className: clsx('str-video__participant-details__connection-quality', `str-video__participant-details__connection-quality--${connectionQualityAsString}`), title: connectionQualityAsString })) }))] }));
86
+ };
87
+ const SpeechIndicator = () => {
88
+ const { participant } = useParticipantViewContext();
89
+ const { isSpeaking, isDominantSpeaker } = participant;
90
+ return (jsxs("span", { className: clsx('str-video__speech-indicator', isSpeaking && 'str-video__speech-indicator--speaking', isDominantSpeaker && 'str-video__speech-indicator--dominant'), children: [jsx("span", { className: "str-video__speech-indicator__bar" }), jsx("span", { className: "str-video__speech-indicator__bar" }), jsx("span", { className: "str-video__speech-indicator__bar" })] }));
91
+ };
92
+
93
+ export { DefaultAudioBlockedNotification, DefaultParticipantViewUI, DefaultScreenShareOverlay, ParticipantDetails, SpeechIndicator };
94
+ //# sourceMappingURL=DefaultParticipantViewUI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultParticipantViewUI.js","sources":["../../../../../../../../src/core/components/ParticipantView/DefaultParticipantViewUI.tsx"],"sourcesContent":["import { ComponentType, forwardRef } from 'react';\nimport { Placement } from '@floating-ui/react';\nimport {\n hasAudio,\n hasPausedTrack,\n hasScreenShare,\n hasVideo,\n SfuModels,\n} from '@stream-io/video-client';\nimport {\n useCall,\n useCallStateHooks,\n useI18n,\n useIsAudioConnecting,\n useIsVideoConnecting,\n} from '@stream-io/video-react-bindings';\nimport clsx from 'clsx';\n\nimport {\n Icon,\n IconButton,\n LoadingIndicator,\n MenuToggle,\n Notification,\n ToggleMenuButtonProps,\n} from '../../../components';\nimport { ParticipantActionsContextMenu as DefaultParticipantActionsContextMenu } from './ParticipantActionsContextMenu';\nimport { Reaction } from '../../../components/Reaction';\nimport { useParticipantViewContext } from './ParticipantViewContext';\n\nexport type DefaultParticipantViewUIProps = {\n /**\n * Turns on/off the status indicator icons (mute, connection quality, etc...).\n */\n indicatorsVisible?: boolean;\n /**\n * Placement of the context menu component when opened\n */\n menuPlacement?: Placement;\n /**\n * Option to show/hide menu button component\n */\n showMenuButton?: boolean;\n /**\n * Custom component to render the context menu\n */\n ParticipantActionsContextMenu?: ComponentType;\n /**\n * Rendered over the tile when this participant's audio is blocked by the\n * browser's autoplay policy. Selecting it calls {@link Call.resumeAudio} to\n * unblock audio. Defaults to\n * {@link DefaultAudioBlockedNotification}; pass `null` to disable.\n */\n AudioBlockedNotification?: ComponentType | null;\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\nexport const DefaultScreenShareOverlay = () => {\n const call = useCall();\n const { t } = useI18n();\n\n const stopScreenShare = () => {\n call?.screenShare.disable().catch((err) => {\n console.error('Failed to stop screen sharing:', err);\n });\n };\n\n return (\n <div className=\"str-video__screen-share-overlay\">\n <Icon icon=\"screen-share-off\" />\n <span className=\"str-video__screen-share-overlay__title\">\n {t('You are presenting your screen')}\n </span>\n <button\n onClick={stopScreenShare}\n type=\"button\"\n className=\"str-video__screen-share-overlay__button\"\n >\n <Icon icon=\"close\" /> {t('Stop Screen Sharing')}\n </button>\n </div>\n );\n};\n\n/**\n * Rendered over a remote participant's tile when the browser's autoplay policy\n * has blocked their audio. Selecting it calls `call.resumeAudio()`, unblocking\n * every blocked element at once.\n */\nexport const DefaultAudioBlockedNotification = () => {\n const call = useCall();\n const { t } = useI18n();\n\n return (\n <button\n type=\"button\"\n className=\"str-video__audio-blocked-notification\"\n onClick={call?.resumeAudio}\n aria-live=\"polite\"\n >\n <span className=\"str-video__audio-blocked-notification__message\">\n <Icon icon=\"speaker\" />\n <span className=\"str-video__audio-blocked-notification__text\">\n <span className=\"str-video__audio-blocked-notification__title\">\n {t('Audio is blocked by your system')}\n </span>\n <span className=\"str-video__audio-blocked-notification__subtitle\">\n {t('Click or tap to play audio')}\n </span>\n </span>\n </span>\n </button>\n );\n};\n\nexport const DefaultParticipantViewUI = ({\n indicatorsVisible = true,\n menuPlacement = 'bottom-start',\n showMenuButton = true,\n ParticipantActionsContextMenu = DefaultParticipantActionsContextMenu,\n AudioBlockedNotification = DefaultAudioBlockedNotification,\n}: DefaultParticipantViewUIProps) => {\n const { participant, trackType } = useParticipantViewContext();\n const { useAutoplayBlockedSessionIds } = useCallStateHooks();\n const blockedSessionIds = useAutoplayBlockedSessionIds();\n const isScreenSharing = hasScreenShare(participant);\n const shouldShowAudioBlockedNotification =\n !participant.isLocalParticipant &&\n trackType !== 'screenShareTrack' &&\n blockedSessionIds.includes(participant.sessionId);\n\n if (\n participant.isLocalParticipant &&\n isScreenSharing &&\n trackType === 'screenShareTrack'\n ) {\n return (\n <>\n <DefaultScreenShareOverlay />\n <ParticipantDetails indicatorsVisible={indicatorsVisible} />\n </>\n );\n }\n\n return (\n <>\n {showMenuButton && (\n <MenuToggle\n strategy=\"fixed\"\n placement={menuPlacement}\n ToggleButton={ToggleButton}\n >\n <ParticipantActionsContextMenu />\n </MenuToggle>\n )}\n <Reaction participant={participant} />\n <ParticipantDetails indicatorsVisible={indicatorsVisible} />\n {AudioBlockedNotification && shouldShowAudioBlockedNotification && (\n <AudioBlockedNotification />\n )}\n </>\n );\n};\n\nexport const ParticipantDetails = ({\n indicatorsVisible = true,\n}: Pick<DefaultParticipantViewUIProps, 'indicatorsVisible'>) => {\n const { participant, trackType } = useParticipantViewContext();\n const {\n isLocalParticipant,\n connectionQuality,\n pin,\n sessionId,\n name,\n userId,\n } = participant;\n const call = useCall();\n\n const { t } = useI18n();\n const connectionQualityAsString =\n !!connectionQuality &&\n SfuModels.ConnectionQuality[connectionQuality].toLowerCase();\n\n const hasAudioTrack = hasAudio(participant);\n const hasVideoTrack = hasVideo(participant);\n const canUnpin = !!pin && pin.isLocalPin;\n const isTrackPaused =\n trackType !== 'none' ? hasPausedTrack(participant, trackType) : false;\n\n const isAudioConnecting = useIsAudioConnecting(participant);\n const isVideoConnecting = useIsVideoConnecting(participant);\n\n return (\n <>\n <div className=\"str-video__participant-details\">\n <div className=\"str-video__participant-details__name\">\n {name || userId}\n {indicatorsVisible && isAudioConnecting && (\n <LoadingIndicator\n className=\"str-video__participant-details__name--audio-connecting\"\n tooltip={t('Audio is connecting...')}\n />\n )}\n {indicatorsVisible && !hasAudioTrack && (\n <span className=\"str-video__participant-details__name--audio-muted\" />\n )}\n {indicatorsVisible && isVideoConnecting && (\n <LoadingIndicator\n className=\"str-video__participant-details__name--video-connecting\"\n tooltip={t('Video is connecting...')}\n />\n )}\n {indicatorsVisible && !hasVideoTrack && (\n <span className=\"str-video__participant-details__name--video-muted\" />\n )}\n {indicatorsVisible && isTrackPaused && (\n <span\n title={t('Video paused due to insufficient bandwidth')}\n className=\"str-video__participant-details__name--track-paused\"\n />\n )}\n {indicatorsVisible && pin && (\n <span\n title={canUnpin ? t('Unpin') : t('Pinned')}\n onClick={canUnpin ? () => call?.unpin(sessionId) : undefined}\n className=\"str-video__participant-details__name--pinned\"\n />\n )}\n {indicatorsVisible && <SpeechIndicator />}\n </div>\n </div>\n {indicatorsVisible && (\n <Notification\n isVisible={\n isLocalParticipant &&\n connectionQuality === SfuModels.ConnectionQuality.POOR\n }\n message={t('Poor connection quality')}\n >\n {connectionQualityAsString && (\n <span\n className={clsx(\n 'str-video__participant-details__connection-quality',\n `str-video__participant-details__connection-quality--${connectionQualityAsString}`,\n )}\n title={connectionQualityAsString}\n />\n )}\n </Notification>\n )}\n </>\n );\n};\n\nexport const SpeechIndicator = () => {\n const { participant } = useParticipantViewContext();\n const { isSpeaking, isDominantSpeaker } = participant;\n return (\n <span\n className={clsx(\n 'str-video__speech-indicator',\n isSpeaking && 'str-video__speech-indicator--speaking',\n isDominantSpeaker && 'str-video__speech-indicator--dominant',\n )}\n >\n <span className=\"str-video__speech-indicator__bar\" />\n <span className=\"str-video__speech-indicator__bar\" />\n <span className=\"str-video__speech-indicator__bar\" />\n </span>\n );\n};\n"],"names":["_jsx","_jsxs","ParticipantActionsContextMenu","DefaultParticipantActionsContextMenu","_Fragment"],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import { useCall, useI18n, Restricted } from '@stream-io/video-react-bindings';
4
+ import { hasAudio, hasVideo, hasScreenShare, hasScreenShareAudio, OwnCapability } from '@stream-io/video-client';
5
+ import { useParticipantViewContext } from './ParticipantViewContext.js';
6
+ import { useMenuContext } from '../../../components/Menu/MenuToggle.js';
7
+ import { GenericMenu, GenericMenuButtonItem } from '../../../components/Menu/GenericMenu.js';
8
+ import { Icon } from '../../../components/Icon/Icon.js';
9
+ import { usePictureInPictureState } from '../../hooks/usePictureInPictureState.js';
10
+
11
+ const ParticipantActionsContextMenu = () => {
12
+ const { participant, participantViewElement, videoElement } = useParticipantViewContext();
13
+ const [fullscreenModeOn, setFullscreenModeOn] = useState(!!document.fullscreenElement);
14
+ const call = useCall();
15
+ const isPiP = usePictureInPictureState(videoElement ?? undefined);
16
+ const { t } = useI18n();
17
+ const { pin, sessionId, userId } = participant;
18
+ const hasAudioTrack = hasAudio(participant);
19
+ const hasVideoTrack = hasVideo(participant);
20
+ const hasScreenShareTrack = hasScreenShare(participant);
21
+ const hasScreenShareAudioTrack = hasScreenShareAudio(participant);
22
+ const blockUser = () => call?.blockUser(userId);
23
+ const kickUser = () => call?.kickUser({ user_id: userId });
24
+ const muteAudio = () => call?.muteUser(userId, 'audio');
25
+ const muteVideo = () => call?.muteUser(userId, 'video');
26
+ const muteScreenShare = () => call?.muteUser(userId, 'screenshare');
27
+ const muteScreenShareAudio = () => call?.muteUser(userId, 'screenshare_audio');
28
+ const grantPermission = (permission) => () => {
29
+ call?.updateUserPermissions({
30
+ user_id: userId,
31
+ grant_permissions: [permission],
32
+ });
33
+ };
34
+ const revokePermission = (permission) => () => {
35
+ call?.updateUserPermissions({
36
+ user_id: userId,
37
+ revoke_permissions: [permission],
38
+ });
39
+ };
40
+ const toggleParticipantPin = () => {
41
+ if (pin) {
42
+ call?.unpin(sessionId);
43
+ }
44
+ else {
45
+ call?.pin(sessionId);
46
+ }
47
+ };
48
+ const pinForEveryone = () => {
49
+ call
50
+ ?.pinForEveryone({ user_id: userId, session_id: sessionId })
51
+ .catch((err) => {
52
+ console.error(`Failed to pin participant ${userId}`, err);
53
+ });
54
+ };
55
+ const unpinForEveryone = () => {
56
+ call
57
+ ?.unpinForEveryone({ user_id: userId, session_id: sessionId })
58
+ .catch((err) => {
59
+ console.error(`Failed to unpin participant ${userId}`, err);
60
+ });
61
+ };
62
+ const toggleFullscreenMode = () => {
63
+ if (!fullscreenModeOn) {
64
+ return participantViewElement?.requestFullscreen().catch(console.error);
65
+ }
66
+ return document.exitFullscreen().catch(console.error);
67
+ };
68
+ useEffect(() => {
69
+ // handles the case when fullscreen mode is toggled externally,
70
+ // e.g., by pressing ESC key or some other keyboard shortcut
71
+ const handleFullscreenChange = () => {
72
+ setFullscreenModeOn(!!document.fullscreenElement);
73
+ };
74
+ document.addEventListener('fullscreenchange', handleFullscreenChange);
75
+ return () => {
76
+ document.removeEventListener('fullscreenchange', handleFullscreenChange);
77
+ };
78
+ }, []);
79
+ const togglePictureInPicture = () => {
80
+ if (videoElement && !isPiP) {
81
+ return videoElement
82
+ .requestPictureInPicture()
83
+ .catch(console.error);
84
+ }
85
+ return document.exitPictureInPicture().catch(console.error);
86
+ };
87
+ const { close } = useMenuContext() || {};
88
+ return (jsxs(GenericMenu, { onItemClick: close, children: [jsxs(GenericMenuButtonItem, { onClick: toggleParticipantPin, disabled: pin && !pin.isLocalPin, children: [jsx(Icon, { icon: "pin" }), pin ? t('Unpin') : t('Pin')] }), jsxs(Restricted, { requiredGrants: [OwnCapability.PIN_FOR_EVERYONE], children: [jsxs(GenericMenuButtonItem, { onClick: pinForEveryone, disabled: pin && !pin.isLocalPin, children: [jsx(Icon, { icon: "pin" }), t('Pin for everyone')] }), jsxs(GenericMenuButtonItem, { onClick: unpinForEveryone, disabled: !pin || pin.isLocalPin, children: [jsx(Icon, { icon: "pin" }), t('Unpin for everyone')] })] }), jsx(Restricted, { requiredGrants: [OwnCapability.BLOCK_USERS], children: jsxs(GenericMenuButtonItem, { onClick: blockUser, children: [jsx(Icon, { icon: "not-allowed" }), t('Block')] }) }), jsx(Restricted, { requiredGrants: [OwnCapability.KICK_USER], children: jsxs(GenericMenuButtonItem, { onClick: kickUser, children: [jsx(Icon, { icon: "kick-user" }), t('Kick')] }) }), jsxs(Restricted, { requiredGrants: [OwnCapability.MUTE_USERS], children: [hasVideoTrack && (jsxs(GenericMenuButtonItem, { onClick: muteVideo, children: [jsx(Icon, { icon: "camera-off-outline" }), t('Turn off video')] })), hasScreenShareTrack && (jsxs(GenericMenuButtonItem, { onClick: muteScreenShare, children: [jsx(Icon, { icon: "screen-share-off" }), t('Turn off screen share')] })), hasAudioTrack && (jsxs(GenericMenuButtonItem, { onClick: muteAudio, children: [jsx(Icon, { icon: "no-audio" }), t('Mute audio')] })), hasScreenShareAudioTrack && (jsxs(GenericMenuButtonItem, { onClick: muteScreenShareAudio, children: [jsx(Icon, { icon: "no-audio" }), t('Mute screen share audio')] }))] }), participantViewElement &&
89
+ typeof participantViewElement.requestFullscreen !== 'undefined' && (jsx(GenericMenuButtonItem, { onClick: toggleFullscreenMode, children: t('{{ direction }} fullscreen', {
90
+ direction: fullscreenModeOn ? t('Leave') : t('Enter'),
91
+ }) })), videoElement && document.pictureInPictureEnabled && (jsx(GenericMenuButtonItem, { onClick: togglePictureInPicture, children: t('{{ direction }} picture-in-picture', {
92
+ direction: isPiP ? t('Leave') : t('Enter'),
93
+ }) })), jsxs(Restricted, { requiredGrants: [OwnCapability.UPDATE_CALL_PERMISSIONS], children: [jsx(GenericMenuButtonItem, { onClick: grantPermission(OwnCapability.SEND_AUDIO), children: t('Allow audio') }), jsx(GenericMenuButtonItem, { onClick: grantPermission(OwnCapability.SEND_VIDEO), children: t('Allow video') }), jsx(GenericMenuButtonItem, { onClick: grantPermission(OwnCapability.SCREENSHARE), children: t('Allow screen sharing') }), jsx(GenericMenuButtonItem, { onClick: revokePermission(OwnCapability.SEND_AUDIO), children: t('Disable audio') }), jsx(GenericMenuButtonItem, { onClick: revokePermission(OwnCapability.SEND_VIDEO), children: t('Disable video') }), jsx(GenericMenuButtonItem, { onClick: revokePermission(OwnCapability.SCREENSHARE), children: t('Disable screen sharing') })] })] }));
94
+ };
95
+
96
+ export { ParticipantActionsContextMenu };
97
+ //# sourceMappingURL=ParticipantActionsContextMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParticipantActionsContextMenu.js","sources":["../../../../../../../../src/core/components/ParticipantView/ParticipantActionsContextMenu.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { Restricted, useCall, useI18n } from '@stream-io/video-react-bindings';\nimport {\n hasAudio,\n hasScreenShare,\n hasScreenShareAudio,\n hasVideo,\n OwnCapability,\n UpdateUserPermissionsRequestGrantPermissionsEnum,\n UpdateUserPermissionsRequestRevokePermissionsEnum,\n} from '@stream-io/video-client';\nimport { useParticipantViewContext } from './ParticipantViewContext';\nimport {\n GenericMenu,\n GenericMenuButtonItem,\n useMenuContext,\n} from '../../../components/Menu';\nimport { Icon } from '../../../components/Icon';\nimport { usePictureInPictureState } from '../../hooks/usePictureInPictureState';\n\nexport const ParticipantActionsContextMenu = () => {\n const { participant, participantViewElement, videoElement } =\n useParticipantViewContext();\n const [fullscreenModeOn, setFullscreenModeOn] = useState(\n !!document.fullscreenElement,\n );\n const call = useCall();\n const isPiP = usePictureInPictureState(videoElement ?? undefined);\n const { t } = useI18n();\n\n const { pin, sessionId, userId } = participant;\n\n const hasAudioTrack = hasAudio(participant);\n const hasVideoTrack = hasVideo(participant);\n const hasScreenShareTrack = hasScreenShare(participant);\n const hasScreenShareAudioTrack = hasScreenShareAudio(participant);\n\n const blockUser = () => call?.blockUser(userId);\n const kickUser = () => call?.kickUser({ user_id: userId });\n const muteAudio = () => call?.muteUser(userId, 'audio');\n const muteVideo = () => call?.muteUser(userId, 'video');\n const muteScreenShare = () => call?.muteUser(userId, 'screenshare');\n const muteScreenShareAudio = () =>\n call?.muteUser(userId, 'screenshare_audio');\n\n const grantPermission =\n (permission: UpdateUserPermissionsRequestGrantPermissionsEnum) => () => {\n call?.updateUserPermissions({\n user_id: userId,\n grant_permissions: [permission],\n });\n };\n\n const revokePermission =\n (permission: UpdateUserPermissionsRequestRevokePermissionsEnum) => () => {\n call?.updateUserPermissions({\n user_id: userId,\n revoke_permissions: [permission],\n });\n };\n\n const toggleParticipantPin = () => {\n if (pin) {\n call?.unpin(sessionId);\n } else {\n call?.pin(sessionId);\n }\n };\n\n const pinForEveryone = () => {\n call\n ?.pinForEveryone({ user_id: userId, session_id: sessionId })\n .catch((err) => {\n console.error(`Failed to pin participant ${userId}`, err);\n });\n };\n\n const unpinForEveryone = () => {\n call\n ?.unpinForEveryone({ user_id: userId, session_id: sessionId })\n .catch((err) => {\n console.error(`Failed to unpin participant ${userId}`, err);\n });\n };\n\n const toggleFullscreenMode = () => {\n if (!fullscreenModeOn) {\n return participantViewElement?.requestFullscreen().catch(console.error);\n }\n return document.exitFullscreen().catch(console.error);\n };\n\n useEffect(() => {\n // handles the case when fullscreen mode is toggled externally,\n // e.g., by pressing ESC key or some other keyboard shortcut\n const handleFullscreenChange = () => {\n setFullscreenModeOn(!!document.fullscreenElement);\n };\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n const togglePictureInPicture = () => {\n if (videoElement && !isPiP) {\n return videoElement\n .requestPictureInPicture()\n .catch(console.error) as Promise<void>;\n }\n\n return document.exitPictureInPicture().catch(console.error);\n };\n\n const { close } = useMenuContext() || {};\n return (\n <GenericMenu onItemClick={close}>\n <GenericMenuButtonItem\n onClick={toggleParticipantPin}\n disabled={pin && !pin.isLocalPin}\n >\n <Icon icon=\"pin\" />\n {pin ? t('Unpin') : t('Pin')}\n </GenericMenuButtonItem>\n <Restricted requiredGrants={[OwnCapability.PIN_FOR_EVERYONE]}>\n <GenericMenuButtonItem\n onClick={pinForEveryone}\n disabled={pin && !pin.isLocalPin}\n >\n <Icon icon=\"pin\" />\n {t('Pin for everyone')}\n </GenericMenuButtonItem>\n <GenericMenuButtonItem\n onClick={unpinForEveryone}\n disabled={!pin || pin.isLocalPin}\n >\n <Icon icon=\"pin\" />\n {t('Unpin for everyone')}\n </GenericMenuButtonItem>\n </Restricted>\n <Restricted requiredGrants={[OwnCapability.BLOCK_USERS]}>\n <GenericMenuButtonItem onClick={blockUser}>\n <Icon icon=\"not-allowed\" />\n {t('Block')}\n </GenericMenuButtonItem>\n </Restricted>\n <Restricted requiredGrants={[OwnCapability.KICK_USER]}>\n <GenericMenuButtonItem onClick={kickUser}>\n <Icon icon=\"kick-user\" />\n {t('Kick')}\n </GenericMenuButtonItem>\n </Restricted>\n <Restricted requiredGrants={[OwnCapability.MUTE_USERS]}>\n {hasVideoTrack && (\n <GenericMenuButtonItem onClick={muteVideo}>\n <Icon icon=\"camera-off-outline\" />\n {t('Turn off video')}\n </GenericMenuButtonItem>\n )}\n {hasScreenShareTrack && (\n <GenericMenuButtonItem onClick={muteScreenShare}>\n <Icon icon=\"screen-share-off\" />\n {t('Turn off screen share')}\n </GenericMenuButtonItem>\n )}\n {hasAudioTrack && (\n <GenericMenuButtonItem onClick={muteAudio}>\n <Icon icon=\"no-audio\" />\n {t('Mute audio')}\n </GenericMenuButtonItem>\n )}\n {hasScreenShareAudioTrack && (\n <GenericMenuButtonItem onClick={muteScreenShareAudio}>\n <Icon icon=\"no-audio\" />\n {t('Mute screen share audio')}\n </GenericMenuButtonItem>\n )}\n </Restricted>\n {participantViewElement &&\n typeof participantViewElement.requestFullscreen !== 'undefined' && (\n <GenericMenuButtonItem onClick={toggleFullscreenMode}>\n {t('{{ direction }} fullscreen', {\n direction: fullscreenModeOn ? t('Leave') : t('Enter'),\n })}\n </GenericMenuButtonItem>\n )}\n {videoElement && document.pictureInPictureEnabled && (\n <GenericMenuButtonItem onClick={togglePictureInPicture}>\n {t('{{ direction }} picture-in-picture', {\n direction: isPiP ? t('Leave') : t('Enter'),\n })}\n </GenericMenuButtonItem>\n )}\n <Restricted requiredGrants={[OwnCapability.UPDATE_CALL_PERMISSIONS]}>\n <GenericMenuButtonItem\n onClick={grantPermission(OwnCapability.SEND_AUDIO)}\n >\n {t('Allow audio')}\n </GenericMenuButtonItem>\n <GenericMenuButtonItem\n onClick={grantPermission(OwnCapability.SEND_VIDEO)}\n >\n {t('Allow video')}\n </GenericMenuButtonItem>\n <GenericMenuButtonItem\n onClick={grantPermission(OwnCapability.SCREENSHARE)}\n >\n {t('Allow screen sharing')}\n </GenericMenuButtonItem>\n\n <GenericMenuButtonItem\n onClick={revokePermission(OwnCapability.SEND_AUDIO)}\n >\n {t('Disable audio')}\n </GenericMenuButtonItem>\n <GenericMenuButtonItem\n onClick={revokePermission(OwnCapability.SEND_VIDEO)}\n >\n {t('Disable video')}\n </GenericMenuButtonItem>\n <GenericMenuButtonItem\n onClick={revokePermission(OwnCapability.SCREENSHARE)}\n >\n {t('Disable screen sharing')}\n </GenericMenuButtonItem>\n </Restricted>\n </GenericMenu>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { memo, forwardRef, useState, useMemo } from 'react';
3
+ import clsx from 'clsx';
4
+ import { hasAudio, hasVideo, hasScreenShareAudio } from '@stream-io/video-client';
5
+ import { useCallStateHooks } from '@stream-io/video-react-bindings';
6
+ import { Audio } from '../Audio/Audio.js';
7
+ import '../Audio/ParticipantsAudio.js';
8
+ import '../Video/BaseVideo.js';
9
+ import { Video } from '../Video/Video.js';
10
+ import { useTrackElementVisibility } from '../../hooks/useTrackElementVisibility.js';
11
+ import { DefaultParticipantViewUI } from './DefaultParticipantViewUI.js';
12
+ import { isComponentType } from '../../../utilities/isComponentType.js';
13
+ import { applyElementToRef } from '../../../utilities/applyElementToRef.js';
14
+ import { ParticipantViewContext } from './ParticipantViewContext.js';
15
+
16
+ const ParticipantView = memo(forwardRef(function ParticipantViewRender({ participant, trackType = 'videoTrack', mirror, muteAudio, refs: { setVideoElement, setVideoPlaceholderElement } = {}, className, VideoPlaceholder, PictureInPicturePlaceholder, ParticipantViewUI = DefaultParticipantViewUI, }, ref) {
17
+ const { isLocalParticipant, isSpeaking, isDominantSpeaker, sessionId } = participant;
18
+ const hasAudioTrack = hasAudio(participant);
19
+ const hasVideoTrack = hasVideo(participant);
20
+ const hasScreenShareAudioTrack = hasScreenShareAudio(participant);
21
+ const [trackedElement, setTrackedElement] = useState(null);
22
+ const [contextVideoElement, setContextVideoElement] = useState(null);
23
+ const [contextVideoPlaceholderElement, setContextVideoPlaceholderElement,] = useState(null);
24
+ useTrackElementVisibility({
25
+ sessionId,
26
+ trackedElement,
27
+ trackType,
28
+ });
29
+ const { useIncomingVideoSettings } = useCallStateHooks();
30
+ const { isParticipantVideoEnabled } = useIncomingVideoSettings();
31
+ const participantViewContextValue = useMemo(() => ({
32
+ participant,
33
+ participantViewElement: trackedElement,
34
+ videoElement: contextVideoElement,
35
+ videoPlaceholderElement: contextVideoPlaceholderElement,
36
+ trackType,
37
+ }), [
38
+ contextVideoElement,
39
+ contextVideoPlaceholderElement,
40
+ participant,
41
+ trackedElement,
42
+ trackType,
43
+ ]);
44
+ const videoRefs = useMemo(() => ({
45
+ setVideoElement: (element) => {
46
+ setVideoElement?.(element);
47
+ setContextVideoElement(element);
48
+ },
49
+ setVideoPlaceholderElement: (element) => {
50
+ setVideoPlaceholderElement?.(element);
51
+ setContextVideoPlaceholderElement(element);
52
+ },
53
+ }), [setVideoElement, setVideoPlaceholderElement]);
54
+ return (jsx("div", { "data-testid": "participant-view", ref: (element) => {
55
+ applyElementToRef(ref, element);
56
+ setTrackedElement(element);
57
+ }, className: clsx('str-video__participant-view', isDominantSpeaker &&
58
+ 'str-video__participant-view--dominant-speaker', isSpeaking && 'str-video__participant-view--speaking', !hasVideoTrack && 'str-video__participant-view--no-video', !hasAudioTrack && 'str-video__participant-view--no-audio', className), children: jsxs(ParticipantViewContext.Provider, { value: participantViewContextValue, children: [!isLocalParticipant && !muteAudio && (jsxs(Fragment, { children: [hasAudioTrack && (jsx(Audio, { participant: participant, trackType: "audioTrack" })), hasScreenShareAudioTrack && (jsx(Audio, { participant: participant, trackType: "screenShareAudioTrack" }))] })), jsx(Video, { VideoPlaceholder: VideoPlaceholder, PictureInPicturePlaceholder: PictureInPicturePlaceholder, participant: participant, trackType: trackType, refs: videoRefs, enabled: isLocalParticipant ||
59
+ trackType !== 'videoTrack' ||
60
+ isParticipantVideoEnabled(participant.sessionId), mirror: mirror, autoPlay: true }), isComponentType(ParticipantViewUI) ? (jsx(ParticipantViewUI, {})) : (ParticipantViewUI)] }) }));
61
+ }));
62
+ ParticipantView.displayName = 'ParticipantView';
63
+
64
+ export { ParticipantView };
65
+ //# sourceMappingURL=ParticipantView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParticipantView.js","sources":["../../../../../../../../src/core/components/ParticipantView/ParticipantView.tsx"],"sourcesContent":["import {\n ComponentType,\n forwardRef,\n memo,\n ReactElement,\n useMemo,\n useState,\n} from 'react';\nimport clsx from 'clsx';\nimport {\n hasAudio,\n hasScreenShareAudio,\n hasVideo,\n StreamVideoParticipant,\n VideoTrackType,\n} from '@stream-io/video-client';\nimport { useCallStateHooks } from '@stream-io/video-react-bindings';\n\nimport { Audio } from '../Audio';\nimport { Video, VideoProps } from '../Video';\nimport { useTrackElementVisibility } from '../../hooks';\nimport { DefaultParticipantViewUI } from './DefaultParticipantViewUI';\nimport { applyElementToRef, isComponentType } from '../../../utilities';\nimport { ParticipantViewContext } from './ParticipantViewContext';\n\nexport type ParticipantViewProps = {\n /**\n * The participant whose video/audio stream we want to play.\n */\n participant: StreamVideoParticipant;\n\n /**\n * Override the default UI for rendering participant information/actions.\n * pass `null` if you wish to not render anything\n * @default DefaultParticipantViewUI\n */\n ParticipantViewUI?: ComponentType | ReactElement | null;\n\n /**\n * The kind of video stream to play for the given participant.\n * The default value is `videoTrack`.\n * You can use `none` if you're building an audio-only call.\n */\n trackType?: VideoTrackType | 'none';\n\n /**\n * Forces participant's video to be mirrored or unmirrored. By default, video track\n * from the local participant is mirrored, and all other videos are not mirrored.\n */\n mirror?: boolean;\n\n /**\n * This prop is only useful for advanced use-cases (for example, building your own layout).\n * When set to `true` it will mute the give participant's audio stream on the client side.\n * The local participant is always muted.\n */\n muteAudio?: boolean;\n\n /**\n * An object with set functions meant for exposing the video\n * and video placeholder elements to the integrators.\n * It's useful when you want to attach custom event handlers to these elements.\n * - `refs.setVideoElement`\n * - `refs.setVideoPlaceholderElement`\n */\n refs?: VideoProps['refs'];\n\n /**\n * Custom class applied to the root DOM element.\n */\n className?: string;\n} & Pick<VideoProps, 'VideoPlaceholder' | 'PictureInPicturePlaceholder'>;\n\nexport const ParticipantView = memo(\n forwardRef<HTMLDivElement, ParticipantViewProps>(\n function ParticipantViewRender(\n {\n participant,\n trackType = 'videoTrack',\n mirror,\n muteAudio,\n refs: { setVideoElement, setVideoPlaceholderElement } = {},\n className,\n VideoPlaceholder,\n PictureInPicturePlaceholder,\n ParticipantViewUI = DefaultParticipantViewUI as ComponentType,\n },\n ref,\n ) {\n const { isLocalParticipant, isSpeaking, isDominantSpeaker, sessionId } =\n participant;\n\n const hasAudioTrack = hasAudio(participant);\n const hasVideoTrack = hasVideo(participant);\n const hasScreenShareAudioTrack = hasScreenShareAudio(participant);\n\n const [trackedElement, setTrackedElement] =\n useState<HTMLDivElement | null>(null);\n\n const [contextVideoElement, setContextVideoElement] =\n useState<HTMLVideoElement | null>(null);\n\n const [\n contextVideoPlaceholderElement,\n setContextVideoPlaceholderElement,\n ] = useState<HTMLDivElement | null>(null);\n\n useTrackElementVisibility({\n sessionId,\n trackedElement,\n trackType,\n });\n\n const { useIncomingVideoSettings } = useCallStateHooks();\n const { isParticipantVideoEnabled } = useIncomingVideoSettings();\n\n const participantViewContextValue = useMemo(\n () => ({\n participant,\n participantViewElement: trackedElement,\n videoElement: contextVideoElement,\n videoPlaceholderElement: contextVideoPlaceholderElement,\n trackType,\n }),\n [\n contextVideoElement,\n contextVideoPlaceholderElement,\n participant,\n trackedElement,\n trackType,\n ],\n );\n\n const videoRefs: VideoProps['refs'] = useMemo(\n () => ({\n setVideoElement: (element) => {\n setVideoElement?.(element);\n setContextVideoElement(element);\n },\n setVideoPlaceholderElement: (element) => {\n setVideoPlaceholderElement?.(element);\n setContextVideoPlaceholderElement(element);\n },\n }),\n [setVideoElement, setVideoPlaceholderElement],\n );\n\n return (\n <div\n data-testid=\"participant-view\"\n ref={(element) => {\n applyElementToRef(ref, element);\n setTrackedElement(element);\n }}\n className={clsx(\n 'str-video__participant-view',\n isDominantSpeaker &&\n 'str-video__participant-view--dominant-speaker',\n isSpeaking && 'str-video__participant-view--speaking',\n !hasVideoTrack && 'str-video__participant-view--no-video',\n !hasAudioTrack && 'str-video__participant-view--no-audio',\n className,\n )}\n >\n <ParticipantViewContext.Provider value={participantViewContextValue}>\n {/* mute the local participant, as we don't want to hear ourselves */}\n {!isLocalParticipant && !muteAudio && (\n <>\n {hasAudioTrack && (\n <Audio participant={participant} trackType=\"audioTrack\" />\n )}\n {hasScreenShareAudioTrack && (\n <Audio\n participant={participant}\n trackType=\"screenShareAudioTrack\"\n />\n )}\n </>\n )}\n <Video\n VideoPlaceholder={VideoPlaceholder}\n PictureInPicturePlaceholder={PictureInPicturePlaceholder}\n participant={participant}\n trackType={trackType}\n refs={videoRefs}\n enabled={\n isLocalParticipant ||\n trackType !== 'videoTrack' ||\n isParticipantVideoEnabled(participant.sessionId)\n }\n mirror={mirror}\n autoPlay\n />\n {isComponentType(ParticipantViewUI) ? (\n <ParticipantViewUI />\n ) : (\n ParticipantViewUI\n )}\n </ParticipantViewContext.Provider>\n </div>\n );\n },\n ),\n);\n\nParticipantView.displayName = 'ParticipantView';\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ const ParticipantViewContext = createContext(undefined);
4
+ const useParticipantViewContext = () => useContext(ParticipantViewContext);
5
+
6
+ export { ParticipantViewContext, useParticipantViewContext };
7
+ //# sourceMappingURL=ParticipantViewContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParticipantViewContext.js","sources":["../../../../../../../../src/core/components/ParticipantView/ParticipantViewContext.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport { ParticipantViewProps } from './ParticipantView';\n\nexport type ParticipantViewContextValue = Required<\n Pick<ParticipantViewProps, 'participant' | 'trackType'>\n> & {\n participantViewElement?: HTMLDivElement | null;\n videoElement?: HTMLVideoElement | null;\n videoPlaceholderElement?: HTMLDivElement | null;\n};\n\nexport const ParticipantViewContext = createContext<\n ParticipantViewContextValue | undefined\n>(undefined);\n\nexport const useParticipantViewContext = () =>\n useContext(ParticipantViewContext) as ParticipantViewContextValue;\n"],"names":[],"mappings":";;MAWa,sBAAsB,GAAG,aAAa,CAEjD,SAAS;AAEJ,MAAM,yBAAyB,GAAG,MACvC,UAAU,CAAC,sBAAsB;;;;"}
@@ -0,0 +1,8 @@
1
+ import { StreamCallProvider } from '@stream-io/video-react-bindings';
2
+
3
+ // re-exporting the StreamCallProvider as StreamCall
4
+ const StreamCall = StreamCallProvider;
5
+ StreamCall.displayName = 'StreamCall';
6
+
7
+ export { StreamCall };
8
+ //# sourceMappingURL=StreamCall.js.map