@stream-io/video-react-sdk 0.0.1-alpha.9 → 0.0.1-alpha.91

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 (249) hide show
  1. package/CHANGELOG.md +22 -150
  2. package/README.md +1 -1
  3. package/dist/css/styles.css +273 -407
  4. package/dist/css/styles.css.map +1 -1
  5. package/dist/src/components/Button/CompositeButton.js +2 -4
  6. package/dist/src/components/Button/CompositeButton.js.map +1 -1
  7. package/dist/src/components/CallControls/AcceptCallButton.d.ts +7 -0
  8. package/dist/src/components/CallControls/AcceptCallButton.js +27 -0
  9. package/dist/src/components/CallControls/AcceptCallButton.js.map +1 -0
  10. package/dist/src/components/CallControls/CallControls.d.ts +1 -3
  11. package/dist/src/components/CallControls/CallControls.js +2 -5
  12. package/dist/src/components/CallControls/CallControls.js.map +1 -1
  13. package/dist/src/components/CallControls/CallStatsButton.d.ts +1 -5
  14. package/dist/src/components/CallControls/CallStatsButton.js +2 -4
  15. package/dist/src/components/CallControls/CallStatsButton.js.map +1 -1
  16. package/dist/src/components/CallControls/CancelCallButton.d.ts +2 -3
  17. package/dist/src/components/CallControls/CancelCallButton.js +4 -2
  18. package/dist/src/components/CallControls/CancelCallButton.js.map +1 -1
  19. package/dist/src/components/CallControls/ReactionsButton.js +1 -2
  20. package/dist/src/components/CallControls/ReactionsButton.js.map +1 -1
  21. package/dist/src/components/CallControls/RecordCallButton.d.ts +1 -3
  22. package/dist/src/components/CallControls/RecordCallButton.js +10 -6
  23. package/dist/src/components/CallControls/RecordCallButton.js.map +1 -1
  24. package/dist/src/components/CallControls/ScreenShareButton.d.ts +1 -3
  25. package/dist/src/components/CallControls/ScreenShareButton.js +7 -7
  26. package/dist/src/components/CallControls/ScreenShareButton.js.map +1 -1
  27. package/dist/src/components/CallControls/ToggleAudioButton.d.ts +1 -1
  28. package/dist/src/components/CallControls/ToggleAudioButton.js +17 -10
  29. package/dist/src/components/CallControls/ToggleAudioButton.js.map +1 -1
  30. package/dist/src/components/CallControls/ToggleVideoButton.d.ts +10 -0
  31. package/dist/src/components/CallControls/{ToggleCameraButton.js → ToggleVideoButton.js} +17 -11
  32. package/dist/src/components/CallControls/ToggleVideoButton.js.map +1 -0
  33. package/dist/src/components/CallControls/index.d.ts +2 -2
  34. package/dist/src/components/CallControls/index.js +2 -2
  35. package/dist/src/components/CallControls/index.js.map +1 -1
  36. package/dist/src/components/CallParticipantsList/BlockedUserListing.js +1 -2
  37. package/dist/src/components/CallParticipantsList/BlockedUserListing.js.map +1 -1
  38. package/dist/src/components/CallParticipantsList/CallParticipantListingItem.d.ts +2 -1
  39. package/dist/src/components/CallParticipantsList/CallParticipantListingItem.js +13 -5
  40. package/dist/src/components/CallParticipantsList/CallParticipantListingItem.js.map +1 -1
  41. package/dist/src/components/CallParticipantsList/CallParticipantsList.js +1 -2
  42. package/dist/src/components/CallParticipantsList/CallParticipantsList.js.map +1 -1
  43. package/dist/src/components/CallStats/CallStats.d.ts +6 -0
  44. package/dist/src/components/{StreamCall → CallStats}/CallStats.js +3 -3
  45. package/dist/src/components/CallStats/CallStats.js.map +1 -0
  46. package/dist/src/components/CallStats/CallStatsLatencyChart.js.map +1 -0
  47. package/dist/src/components/CallStats/index.d.ts +2 -0
  48. package/dist/src/components/CallStats/index.js +3 -0
  49. package/dist/src/components/CallStats/index.js.map +1 -0
  50. package/dist/src/components/Debug/DebugStatsView.d.ts +1 -1
  51. package/dist/src/components/Debug/DebugStatsView.js +32 -7
  52. package/dist/src/components/Debug/DebugStatsView.js.map +1 -1
  53. package/dist/src/components/DeviceSettings/DeviceSelectorAudio.js +5 -3
  54. package/dist/src/components/DeviceSettings/DeviceSelectorAudio.js.map +1 -1
  55. package/dist/src/components/DeviceSettings/DeviceSelectorVideo.js +3 -2
  56. package/dist/src/components/DeviceSettings/DeviceSelectorVideo.js.map +1 -1
  57. package/dist/src/components/Notification/SpeakingWhileMutedNotification.js +4 -2
  58. package/dist/src/components/Notification/SpeakingWhileMutedNotification.js.map +1 -1
  59. package/dist/src/components/PendingCallPanel/PendingCallControls.d.ts +2 -0
  60. package/dist/src/components/PendingCallPanel/PendingCallControls.js +13 -0
  61. package/dist/src/components/PendingCallPanel/PendingCallControls.js.map +1 -0
  62. package/dist/src/components/PendingCallPanel/PendingCallPanel.d.ts +2 -0
  63. package/dist/src/components/PendingCallPanel/PendingCallPanel.js +34 -0
  64. package/dist/src/components/PendingCallPanel/PendingCallPanel.js.map +1 -0
  65. package/dist/src/components/PendingCallPanel/index.d.ts +2 -0
  66. package/dist/src/components/PendingCallPanel/index.js +3 -0
  67. package/dist/src/components/PendingCallPanel/index.js.map +1 -0
  68. package/dist/src/components/Permissions/PermissionRequests.js +2 -8
  69. package/dist/src/components/Permissions/PermissionRequests.js.map +1 -1
  70. package/dist/src/components/StreamCall/CallParticipantsScreenView.js +3 -3
  71. package/dist/src/components/StreamCall/CallParticipantsScreenView.js.map +1 -1
  72. package/dist/src/components/StreamCall/CallParticipantsView.js +2 -3
  73. package/dist/src/components/StreamCall/CallParticipantsView.js.map +1 -1
  74. package/dist/src/components/StreamTheme/StreamTheme.d.ts +5 -0
  75. package/dist/src/components/StreamTheme/StreamTheme.js +18 -0
  76. package/dist/src/components/StreamTheme/StreamTheme.js.map +1 -0
  77. package/dist/src/components/StreamTheme/index.d.ts +1 -0
  78. package/dist/src/components/StreamTheme/index.js +2 -0
  79. package/dist/src/components/StreamTheme/index.js.map +1 -0
  80. package/dist/src/components/Video/VideoPreview.js +10 -5
  81. package/dist/src/components/Video/VideoPreview.js.map +1 -1
  82. package/dist/src/components/Video/index.d.ts +1 -1
  83. package/dist/src/components/Video/index.js +1 -1
  84. package/dist/src/components/Video/index.js.map +1 -1
  85. package/dist/src/components/index.d.ts +2 -2
  86. package/dist/src/components/index.js +2 -2
  87. package/dist/src/components/index.js.map +1 -1
  88. package/dist/src/core/components/CallLayout/PaginatedGridLayout.d.ts +3 -7
  89. package/dist/src/core/components/CallLayout/PaginatedGridLayout.js +13 -14
  90. package/dist/src/core/components/CallLayout/PaginatedGridLayout.js.map +1 -1
  91. package/dist/src/core/components/CallLayout/SpeakerLayout.d.ts +6 -1
  92. package/dist/src/core/components/CallLayout/SpeakerLayout.js +13 -7
  93. package/dist/src/core/components/CallLayout/SpeakerLayout.js.map +1 -1
  94. package/dist/src/core/components/ParticipantView/DefaultParticipantViewUI.d.ts +18 -0
  95. package/dist/src/core/components/ParticipantView/DefaultParticipantViewUI.js +36 -0
  96. package/dist/src/core/components/ParticipantView/DefaultParticipantViewUI.js.map +1 -0
  97. package/dist/src/core/components/ParticipantView/ParticipantView.d.ts +79 -0
  98. package/dist/src/core/components/ParticipantView/ParticipantView.js +33 -0
  99. package/dist/src/core/components/ParticipantView/ParticipantView.js.map +1 -0
  100. package/dist/src/core/components/ParticipantView/index.d.ts +2 -0
  101. package/dist/src/core/components/ParticipantView/index.js +3 -0
  102. package/dist/src/core/components/ParticipantView/index.js.map +1 -0
  103. package/dist/src/core/components/StreamCall/StreamCall.d.ts +73 -0
  104. package/dist/src/core/components/StreamCall/StreamCall.js +60 -0
  105. package/dist/src/core/components/StreamCall/StreamCall.js.map +1 -0
  106. package/dist/src/core/components/StreamCall/index.d.ts +1 -0
  107. package/dist/src/core/components/StreamCall/index.js +2 -0
  108. package/dist/src/core/components/StreamCall/index.js.map +1 -0
  109. package/dist/src/core/components/Video/BaseVideo.d.ts +3 -3
  110. package/dist/src/core/components/Video/BaseVideo.js +6 -12
  111. package/dist/src/core/components/Video/BaseVideo.js.map +1 -1
  112. package/dist/src/core/components/Video/DefaultVideoPlaceholder.d.ts +6 -0
  113. package/dist/src/core/components/Video/DefaultVideoPlaceholder.js +9 -0
  114. package/dist/src/core/components/Video/DefaultVideoPlaceholder.js.map +1 -0
  115. package/dist/src/core/components/Video/Video.d.ts +11 -6
  116. package/dist/src/core/components/Video/Video.js +31 -28
  117. package/dist/src/core/components/Video/Video.js.map +1 -1
  118. package/dist/src/core/components/index.d.ts +3 -2
  119. package/dist/src/core/components/index.js +2 -1
  120. package/dist/src/core/components/index.js.map +1 -1
  121. package/dist/src/core/contexts/MediaDevicesContext.d.ts +117 -19
  122. package/dist/src/core/contexts/MediaDevicesContext.js +52 -90
  123. package/dist/src/core/contexts/MediaDevicesContext.js.map +1 -1
  124. package/dist/src/core/hooks/index.d.ts +2 -0
  125. package/dist/src/core/hooks/index.js +2 -0
  126. package/dist/src/core/hooks/index.js.map +1 -1
  127. package/dist/src/core/hooks/useAudioPublisher.js +9 -3
  128. package/dist/src/core/hooks/useAudioPublisher.js.map +1 -1
  129. package/dist/src/core/hooks/useDevices.d.ts +80 -0
  130. package/dist/src/core/hooks/useDevices.js +113 -0
  131. package/dist/src/core/hooks/useDevices.js.map +1 -0
  132. package/dist/src/core/hooks/useTrackElementVisibility.d.ts +6 -0
  133. package/dist/src/core/hooks/useTrackElementVisibility.js +27 -0
  134. package/dist/src/core/hooks/useTrackElementVisibility.js.map +1 -0
  135. package/dist/src/core/hooks/useVideoPublisher.js +35 -6
  136. package/dist/src/core/hooks/useVideoPublisher.js.map +1 -1
  137. package/dist/src/hooks/index.d.ts +0 -1
  138. package/dist/src/hooks/index.js +0 -1
  139. package/dist/src/hooks/index.js.map +1 -1
  140. package/dist/src/utilities/applyElementToRef.d.ts +2 -0
  141. package/dist/src/utilities/applyElementToRef.js +8 -0
  142. package/dist/src/utilities/applyElementToRef.js.map +1 -0
  143. package/dist/src/utilities/chunk.d.ts +1 -0
  144. package/dist/src/utilities/chunk.js +5 -0
  145. package/dist/src/utilities/chunk.js.map +1 -0
  146. package/dist/src/utilities/index.d.ts +3 -0
  147. package/dist/src/utilities/index.js +4 -0
  148. package/dist/src/utilities/index.js.map +1 -0
  149. package/dist/src/utilities/isComponentType.d.ts +2 -0
  150. package/dist/src/utilities/isComponentType.js +7 -0
  151. package/dist/src/utilities/isComponentType.js.map +1 -0
  152. package/package.json +12 -10
  153. package/src/components/Button/CompositeButton.tsx +4 -13
  154. package/src/components/CallControls/AcceptCallButton.tsx +36 -0
  155. package/src/components/CallControls/CallControls.tsx +13 -19
  156. package/src/components/CallControls/CallStatsButton.tsx +6 -14
  157. package/src/components/CallControls/CancelCallButton.tsx +12 -4
  158. package/src/components/CallControls/ReactionsButton.tsx +1 -2
  159. package/src/components/CallControls/RecordCallButton.tsx +12 -7
  160. package/src/components/CallControls/ScreenShareButton.tsx +7 -8
  161. package/src/components/CallControls/ToggleAudioButton.tsx +23 -12
  162. package/src/components/CallControls/{ToggleCameraButton.tsx → ToggleVideoButton.tsx} +20 -13
  163. package/src/components/CallControls/index.ts +2 -2
  164. package/src/components/CallParticipantsList/BlockedUserListing.tsx +1 -2
  165. package/src/components/CallParticipantsList/CallParticipantListingItem.tsx +27 -3
  166. package/src/components/CallParticipantsList/CallParticipantsList.tsx +1 -1
  167. package/src/components/{StreamCall → CallStats}/CallStats.tsx +3 -3
  168. package/src/components/CallStats/index.ts +2 -0
  169. package/src/components/Debug/DebugStatsView.tsx +60 -7
  170. package/src/components/DeviceSettings/DeviceSelectorAudio.tsx +9 -4
  171. package/src/components/DeviceSettings/DeviceSelectorVideo.tsx +3 -3
  172. package/src/components/Notification/SpeakingWhileMutedNotification.tsx +9 -8
  173. package/src/components/PendingCallPanel/PendingCallControls.tsx +27 -0
  174. package/src/components/PendingCallPanel/PendingCallPanel.tsx +71 -0
  175. package/src/components/PendingCallPanel/index.ts +2 -0
  176. package/src/components/Permissions/PermissionRequests.tsx +2 -8
  177. package/src/components/StreamCall/CallParticipantsScreenView.tsx +3 -4
  178. package/src/components/StreamCall/CallParticipantsView.tsx +3 -4
  179. package/src/components/StreamTheme/StreamTheme.tsx +19 -0
  180. package/src/components/StreamTheme/index.ts +1 -0
  181. package/src/components/Video/VideoPreview.tsx +16 -6
  182. package/src/components/Video/index.ts +1 -1
  183. package/src/components/index.ts +2 -2
  184. package/src/core/components/CallLayout/PaginatedGridLayout.tsx +32 -36
  185. package/src/core/components/CallLayout/SpeakerLayout.tsx +48 -25
  186. package/src/core/components/ParticipantView/DefaultParticipantViewUI.tsx +160 -0
  187. package/src/core/components/ParticipantView/ParticipantView.tsx +156 -0
  188. package/src/core/components/ParticipantView/index.ts +2 -0
  189. package/src/core/components/StreamCall/StreamCall.tsx +157 -0
  190. package/src/core/components/StreamCall/index.ts +1 -0
  191. package/src/core/components/Video/BaseVideo.tsx +9 -24
  192. package/src/core/components/Video/DefaultVideoPlaceholder.tsx +36 -0
  193. package/src/core/components/Video/Video.tsx +62 -48
  194. package/src/core/components/index.ts +3 -2
  195. package/src/core/contexts/MediaDevicesContext.tsx +179 -136
  196. package/src/core/hooks/index.ts +2 -0
  197. package/src/core/hooks/useAudioPublisher.ts +9 -3
  198. package/src/core/hooks/useDevices.ts +161 -0
  199. package/src/core/hooks/useTrackElementVisibility.ts +44 -0
  200. package/src/core/hooks/useVideoPublisher.ts +36 -4
  201. package/src/hooks/index.ts +0 -1
  202. package/src/utilities/applyElementToRef.ts +12 -0
  203. package/src/utilities/chunk.ts +8 -0
  204. package/src/utilities/index.ts +3 -0
  205. package/src/utilities/isComponentType.ts +9 -0
  206. package/dist/src/components/CallControls/ToggleCameraButton.d.ts +0 -10
  207. package/dist/src/components/CallControls/ToggleCameraButton.js.map +0 -1
  208. package/dist/src/components/CallControls/ToggleParticipantListButton.d.ts +0 -6
  209. package/dist/src/components/CallControls/ToggleParticipantListButton.js +0 -7
  210. package/dist/src/components/CallControls/ToggleParticipantListButton.js.map +0 -1
  211. package/dist/src/components/Moderation/Restricted.d.ts +0 -19
  212. package/dist/src/components/Moderation/Restricted.js +0 -13
  213. package/dist/src/components/Moderation/Restricted.js.map +0 -1
  214. package/dist/src/components/Moderation/index.d.ts +0 -1
  215. package/dist/src/components/Moderation/index.js +0 -2
  216. package/dist/src/components/Moderation/index.js.map +0 -1
  217. package/dist/src/components/StreamCall/CallStats.d.ts +0 -2
  218. package/dist/src/components/StreamCall/CallStats.js.map +0 -1
  219. package/dist/src/components/StreamCall/CallStatsLatencyChart.js.map +0 -1
  220. package/dist/src/components/StreamMeeting/StreamMeeting.d.ts +0 -34
  221. package/dist/src/components/StreamMeeting/StreamMeeting.js +0 -26
  222. package/dist/src/components/StreamMeeting/StreamMeeting.js.map +0 -1
  223. package/dist/src/components/StreamMeeting/index.d.ts +0 -1
  224. package/dist/src/components/StreamMeeting/index.js +0 -2
  225. package/dist/src/components/StreamMeeting/index.js.map +0 -1
  226. package/dist/src/core/components/ParticipantBox/ParticipantBox.d.ts +0 -48
  227. package/dist/src/core/components/ParticipantBox/ParticipantBox.js +0 -58
  228. package/dist/src/core/components/ParticipantBox/ParticipantBox.js.map +0 -1
  229. package/dist/src/core/components/ParticipantBox/index.d.ts +0 -1
  230. package/dist/src/core/components/ParticipantBox/index.js +0 -2
  231. package/dist/src/core/components/ParticipantBox/index.js.map +0 -1
  232. package/dist/src/core/components/Video/VideoPlaceholder.d.ts +0 -6
  233. package/dist/src/core/components/Video/VideoPlaceholder.js +0 -12
  234. package/dist/src/core/components/Video/VideoPlaceholder.js.map +0 -1
  235. package/dist/src/hooks/useRtcStats.d.ts +0 -11
  236. package/dist/src/hooks/useRtcStats.js +0 -39
  237. package/dist/src/hooks/useRtcStats.js.map +0 -1
  238. package/src/components/CallControls/ToggleParticipantListButton.tsx +0 -17
  239. package/src/components/Moderation/Restricted.tsx +0 -38
  240. package/src/components/Moderation/index.ts +0 -1
  241. package/src/components/StreamMeeting/StreamMeeting.tsx +0 -80
  242. package/src/components/StreamMeeting/index.ts +0 -1
  243. package/src/core/components/ParticipantBox/ParticipantBox.tsx +0 -248
  244. package/src/core/components/ParticipantBox/index.ts +0 -1
  245. package/src/core/components/Video/VideoPlaceholder.tsx +0 -40
  246. package/src/hooks/useRtcStats.ts +0 -36
  247. /package/dist/src/components/{StreamCall → CallStats}/CallStatsLatencyChart.d.ts +0 -0
  248. /package/dist/src/components/{StreamCall → CallStats}/CallStatsLatencyChart.js +0 -0
  249. /package/src/components/{StreamCall → CallStats}/CallStatsLatencyChart.tsx +0 -0
@@ -0,0 +1,157 @@
1
+ import { PropsWithChildren, useEffect, useState } from 'react';
2
+ import { Call, CallingState, JoinCallData } from '@stream-io/video-client';
3
+ import {
4
+ StreamCallProvider,
5
+ useConnectedUser,
6
+ useStreamVideoClient,
7
+ } from '@stream-io/video-react-bindings';
8
+ import {
9
+ MediaDevicesProvider,
10
+ MediaDevicesProviderProps,
11
+ } from '../../contexts';
12
+
13
+ type InitWithCallCID = {
14
+ /**
15
+ * The call type.
16
+ */
17
+ callType: string;
18
+ /**
19
+ * The call id.
20
+ */
21
+ callId: string;
22
+ /**
23
+ * The call instance to use.
24
+ */
25
+ call?: never;
26
+ };
27
+
28
+ type InitWithCallInstance = {
29
+ /**
30
+ * The call instance to use.
31
+ */
32
+ call: Call | undefined;
33
+ /**
34
+ * The call type.
35
+ */
36
+ callType?: never;
37
+ /**
38
+ * The call id.
39
+ */
40
+ callId?: never;
41
+ };
42
+
43
+ type InitStreamCall = InitWithCallCID | InitWithCallInstance;
44
+
45
+ export type StreamCallProps = InitStreamCall & {
46
+ /**
47
+ * If true, the call will be joined automatically.
48
+ * Set it to true if you want to join the call immediately.
49
+ * Useful for scenarios where you want to skip prompting the user to join the call.
50
+ *
51
+ * @default false.
52
+ */
53
+ autoJoin?: boolean;
54
+
55
+ /**
56
+ * If true, the call data will be loaded automatically from the server.
57
+ *
58
+ * This property is useful for the scenarios where you declaratively create
59
+ * the call instance by using the `callId` and `callType` props,
60
+ * and you have a UI that depends on the call metadata.
61
+ *
62
+ * @example
63
+ * ```jsx
64
+ * <StreamCall callId="call-id" callType="call-type" autoLoad>
65
+ * <CallMetadata /> // has access to `call.metadata` although not joined yet
66
+ * <CallUI />
67
+ * <CallControls />
68
+ * </StreamCall>
69
+ * ```
70
+ *
71
+ * This property is ignored if you pass the `call` prop or enable `autoJoin`.
72
+ *
73
+ * @default true.
74
+ */
75
+ autoLoad?: boolean;
76
+
77
+ /**
78
+ * An optional data to pass when joining the call.
79
+ */
80
+ data?: JoinCallData;
81
+
82
+ /**
83
+ * An optional props to pass to the `MediaDevicesProvider`.
84
+ */
85
+ mediaDevicesProviderProps?: MediaDevicesProviderProps;
86
+ };
87
+
88
+ export const StreamCall = ({
89
+ children,
90
+ callId,
91
+ callType,
92
+ call,
93
+ autoJoin = false,
94
+ autoLoad = true,
95
+ data,
96
+ mediaDevicesProviderProps,
97
+ }: PropsWithChildren<StreamCallProps>) => {
98
+ const client = useStreamVideoClient();
99
+ const [activeCall, setActiveCall] = useState<Call | undefined>(() => {
100
+ if (call) return call;
101
+ if (!client || !callId || !callType) return;
102
+ return client.call(callType, callId);
103
+ });
104
+
105
+ useEffect(() => {
106
+ if (!client) return;
107
+
108
+ if (callId && callType && !activeCall) {
109
+ const newCall = client.call(callType, callId);
110
+ setActiveCall(newCall);
111
+ }
112
+ }, [activeCall, callId, callType, client]);
113
+
114
+ const connectedUser = useConnectedUser();
115
+ useEffect(() => {
116
+ // run the effect only when the user is connected and the call
117
+ // is created declaratively by using the `callId` and `callType` props.
118
+ if (!connectedUser) return;
119
+ if (activeCall && callType && callId && autoLoad && !autoJoin) {
120
+ activeCall
121
+ .getOrCreate({
122
+ ring: data?.ring,
123
+ data: data?.data,
124
+ members_limit: data?.members_limit,
125
+ })
126
+ .catch((err) => {
127
+ console.error(`Failed to get or create call`, err);
128
+ });
129
+ }
130
+ }, [
131
+ activeCall,
132
+ autoJoin,
133
+ autoLoad,
134
+ callId,
135
+ callType,
136
+ connectedUser,
137
+ data?.data,
138
+ data?.members_limit,
139
+ data?.ring,
140
+ ]);
141
+
142
+ useEffect(() => {
143
+ if (autoJoin && activeCall?.state.callingState === CallingState.IDLE) {
144
+ activeCall.join(data).catch((err) => {
145
+ console.error(`Failed to join call`, err);
146
+ });
147
+ }
148
+ }, [activeCall, autoJoin, data]);
149
+
150
+ return (
151
+ <StreamCallProvider call={activeCall}>
152
+ <MediaDevicesProvider {...mediaDevicesProviderProps}>
153
+ {children}
154
+ </MediaDevicesProvider>
155
+ </StreamCallProvider>
156
+ );
157
+ };
@@ -0,0 +1 @@
1
+ export * from './StreamCall';
@@ -1,18 +1,9 @@
1
- import {
2
- DetailedHTMLProps,
3
- ForwardedRef,
4
- forwardRef,
5
- useEffect,
6
- useState,
7
- VideoHTMLAttributes,
8
- } from 'react';
9
- import clsx from 'clsx';
1
+ import { ComponentPropsWithRef, forwardRef, useEffect, useState } from 'react';
10
2
  import { Browsers } from '@stream-io/video-client';
11
3
 
12
- export type VideoProps = DetailedHTMLProps<
13
- VideoHTMLAttributes<HTMLVideoElement>,
14
- HTMLVideoElement
15
- > & {
4
+ import { applyElementToRef } from '../../../utilities';
5
+
6
+ export type BaseVideoProps = ComponentPropsWithRef<'video'> & {
16
7
  stream?: MediaStream;
17
8
  };
18
9
 
@@ -20,19 +11,11 @@ export type VideoProps = DetailedHTMLProps<
20
11
  * @description Extends video element with `stream` property
21
12
  * (`srcObject`) to reactively handle stream changes
22
13
  */
23
- export const BaseVideo = forwardRef<HTMLVideoElement, VideoProps>(
14
+ export const BaseVideo = forwardRef<HTMLVideoElement, BaseVideoProps>(
24
15
  ({ stream, ...rest }, ref) => {
25
16
  const [videoElement, setVideoElement] = useState<HTMLVideoElement | null>(
26
17
  null,
27
18
  );
28
- const setRef: ForwardedRef<HTMLVideoElement> = (instance) => {
29
- setVideoElement(instance);
30
- if (typeof ref === 'function') {
31
- (ref as (instance: HTMLVideoElement | null) => void)(instance);
32
- } else if (ref) {
33
- ref.current = instance;
34
- }
35
- };
36
19
 
37
20
  useEffect(() => {
38
21
  if (!videoElement || !stream) return;
@@ -60,8 +43,10 @@ export const BaseVideo = forwardRef<HTMLVideoElement, VideoProps>(
60
43
  autoPlay
61
44
  playsInline
62
45
  {...rest}
63
- className={clsx('str-video__base-video', rest.className)}
64
- ref={setRef}
46
+ ref={(element) => {
47
+ applyElementToRef(ref, element);
48
+ setVideoElement(element);
49
+ }}
65
50
  />
66
51
  );
67
52
  },
@@ -0,0 +1,36 @@
1
+ import { ComponentPropsWithRef, forwardRef, useState } from 'react';
2
+ import type { StreamVideoParticipant } from '@stream-io/video-client';
3
+
4
+ export type VideoPlaceholderProps = {
5
+ participant: StreamVideoParticipant;
6
+ } & ComponentPropsWithRef<'div'>;
7
+
8
+ export const DefaultVideoPlaceholder = forwardRef<
9
+ HTMLDivElement,
10
+ VideoPlaceholderProps
11
+ >(({ participant, style }, ref) => {
12
+ const [error, setError] = useState(false);
13
+
14
+ const name = participant?.name || participant?.userId;
15
+
16
+ return (
17
+ <div className="str-video__video-placeholder" style={style} ref={ref}>
18
+ {(!participant.image || error) &&
19
+ (name ? (
20
+ <div className="str-video__video-placeholder__initials-fallback">
21
+ <div>{name[0]}</div>
22
+ </div>
23
+ ) : (
24
+ <div>Video is disabled</div>
25
+ ))}
26
+ {participant.image && !error && (
27
+ <img
28
+ onError={() => setError(true)}
29
+ alt="video-placeholder"
30
+ className="str-video__video-placeholder__avatar"
31
+ src={participant.image}
32
+ />
33
+ )}
34
+ </div>
35
+ );
36
+ });
@@ -1,45 +1,63 @@
1
1
  import {
2
- DetailedHTMLProps,
2
+ ComponentPropsWithoutRef,
3
+ ComponentType,
3
4
  useCallback,
4
5
  useEffect,
5
6
  useRef,
6
7
  useState,
7
- VideoHTMLAttributes,
8
8
  } from 'react';
9
9
  import {
10
- Call,
11
10
  DebounceType,
12
11
  SfuModels,
13
12
  StreamVideoParticipant,
14
13
  VisibilityState,
15
14
  } from '@stream-io/video-client';
16
15
  import clsx from 'clsx';
17
- import { VideoPlaceholder } from './VideoPlaceholder';
16
+ import {
17
+ DefaultVideoPlaceholder,
18
+ VideoPlaceholderProps,
19
+ } from './DefaultVideoPlaceholder';
18
20
  import { BaseVideo } from './BaseVideo';
21
+ import { useCall } from '@stream-io/video-react-bindings';
22
+
23
+ export type VideoProps = ComponentPropsWithoutRef<'video'> & {
24
+ kind: 'video' | 'screen';
25
+ participant: StreamVideoParticipant;
26
+ VideoPlaceholder?: ComponentType<VideoPlaceholderProps>;
27
+ refs?: {
28
+ setVideoElement?: (element: HTMLVideoElement | null) => void;
29
+ setVideoPlaceholderElement?: (element: HTMLDivElement | null) => void;
30
+ };
31
+ };
19
32
 
20
- export const Video = (
21
- props: DetailedHTMLProps<
22
- VideoHTMLAttributes<HTMLVideoElement>,
23
- HTMLVideoElement
24
- > & {
25
- call: Call;
26
- kind: 'video' | 'screen';
27
- participant: StreamVideoParticipant;
28
- setVideoElementRef?: (element: HTMLElement | null) => void;
29
- },
30
- ) => {
31
- const { call, kind, participant, className, setVideoElementRef, ...rest } =
32
- props;
33
- const { sessionId, videoStream, screenShareStream, publishedTracks } =
34
- participant;
33
+ export const Video = ({
34
+ kind,
35
+ participant,
36
+ className,
37
+ VideoPlaceholder = DefaultVideoPlaceholder,
38
+ refs,
39
+ ...rest
40
+ }: VideoProps) => {
41
+ const {
42
+ sessionId,
43
+ videoStream,
44
+ screenShareStream,
45
+ publishedTracks,
46
+ viewportVisibilityState,
47
+ isLoggedInUser,
48
+ userId,
49
+ } = participant;
50
+
51
+ const call = useCall();
35
52
 
36
53
  const [videoElement, setVideoElement] = useState<HTMLVideoElement | null>(
37
54
  null,
38
55
  );
56
+
39
57
  // const [videoTrackMuted, setVideoTrackMuted] = useState(false);
40
58
  const [videoPlaying, setVideoPlaying] = useState(false);
41
59
  const viewportVisibilityRef = useRef<VisibilityState | undefined>(
42
- participant.viewportVisibilityState,
60
+ viewportVisibilityState,
43
61
  );
44
62
 
45
63
  const stream = kind === 'video' ? videoStream : screenShareStream;
@@ -75,7 +93,7 @@ export const Video = (
75
93
 
76
94
  const displayPlaceholder =
77
95
  !isPublishingTrack ||
78
- (participant.viewportVisibilityState === VisibilityState.INVISIBLE &&
96
+ (viewportVisibilityState === VisibilityState.INVISIBLE &&
79
97
  !screenShareStream) ||
80
98
  !videoPlaying;
81
99
 
@@ -85,6 +103,8 @@ export const Video = (
85
103
  dimension?: SfuModels.VideoDimension,
86
104
  type: DebounceType = DebounceType.SLOW,
87
105
  ) => {
106
+ if (!call) return;
107
+
88
108
  call.updateSubscriptionsPartial(
89
109
  kind,
90
110
  {
@@ -98,17 +118,14 @@ export const Video = (
98
118
  [call, kind, sessionId],
99
119
  );
100
120
 
101
- // handle generic subscription updates
102
-
103
121
  // handle visibility subscription updates
104
122
  useEffect(() => {
105
- viewportVisibilityRef.current = participant.viewportVisibilityState;
123
+ viewportVisibilityRef.current = viewportVisibilityState;
106
124
 
107
- if (!videoElement || !isPublishingTrack || participant.isLoggedInUser)
108
- return;
125
+ if (!videoElement || !isPublishingTrack || isLoggedInUser) return;
109
126
 
110
127
  const isInvisibleVVS =
111
- participant.viewportVisibilityState === VisibilityState.INVISIBLE;
128
+ viewportVisibilityState === VisibilityState.INVISIBLE;
112
129
 
113
130
  updateSubscription(
114
131
  isInvisibleVVS
@@ -121,16 +138,15 @@ export const Video = (
121
138
  );
122
139
  }, [
123
140
  updateSubscription,
124
- participant.viewportVisibilityState,
141
+ viewportVisibilityState,
125
142
  videoElement,
126
143
  isPublishingTrack,
127
- participant.isLoggedInUser,
144
+ isLoggedInUser,
128
145
  ]);
129
146
 
130
147
  // handle resize subscription updates
131
148
  useEffect(() => {
132
- if (!videoElement || !isPublishingTrack || participant.isLoggedInUser)
133
- return;
149
+ if (!videoElement || !isPublishingTrack || isLoggedInUser) return;
134
150
 
135
151
  const resizeObserver = new ResizeObserver(() => {
136
152
  const currentDimensions = `${videoElement.clientWidth},${videoElement.clientHeight}`;
@@ -163,14 +179,14 @@ export const Video = (
163
179
  }, [
164
180
  updateSubscription,
165
181
  videoElement,
166
- participant.viewportVisibilityState,
182
+ viewportVisibilityState,
167
183
  isPublishingTrack,
168
- participant.isLoggedInUser,
184
+ isLoggedInUser,
169
185
  ]);
170
186
 
187
+ // handle generic subscription updates
171
188
  useEffect(() => {
172
- if (!isPublishingTrack || !videoElement || participant.isLoggedInUser)
173
- return;
189
+ if (!isPublishingTrack || !videoElement || isLoggedInUser) return;
174
190
 
175
191
  updateSubscription(
176
192
  {
@@ -183,12 +199,7 @@ export const Video = (
183
199
  return () => {
184
200
  updateSubscription(undefined, DebounceType.FAST);
185
201
  };
186
- }, [
187
- updateSubscription,
188
- videoElement,
189
- isPublishingTrack,
190
- participant.isLoggedInUser,
191
- ]);
202
+ }, [updateSubscription, videoElement, isPublishingTrack, isLoggedInUser]);
192
203
 
193
204
  const [isWideMode, setIsWideMode] = useState(true);
194
205
  useEffect(() => {
@@ -210,27 +221,30 @@ export const Video = (
210
221
  };
211
222
  }, [stream, videoElement]);
212
223
 
224
+ if (!call) return null;
225
+
213
226
  return (
214
227
  <>
215
228
  <BaseVideo
216
229
  {...rest}
217
230
  stream={stream}
218
- className={clsx(className, {
219
- 'str-video__video--wide': isWideMode,
231
+ className={clsx(className, 'str-video__video', {
220
232
  'str-video__video--tall': !isWideMode,
233
+ 'str-video__video--mirror': isLoggedInUser && kind === 'video',
234
+ 'str-video__video--screen-share': kind === 'screen',
221
235
  })}
222
- data-user-id={participant.userId}
236
+ data-user-id={userId}
223
237
  data-session-id={sessionId}
224
- ref={(ref) => {
225
- setVideoElement(ref);
226
- setVideoElementRef?.(ref);
238
+ ref={(element) => {
239
+ setVideoElement(element);
240
+ refs?.setVideoElement?.(element);
227
241
  }}
228
242
  />
229
243
  {displayPlaceholder && (
230
244
  <VideoPlaceholder
231
245
  style={{ position: 'absolute' }}
232
246
  participant={participant}
233
- ref={setVideoElementRef}
247
+ ref={refs?.setVideoPlaceholderElement}
234
248
  />
235
249
  )}
236
250
  </>
@@ -1,7 +1,8 @@
1
1
  export * from './Audio';
2
- export * from './ParticipantBox';
2
+ export * from './ParticipantView';
3
+ export * from './StreamCall';
3
4
 
4
5
  export { Video } from './Video';
5
- export type { VideoProps } from './Video';
6
+ export type { BaseVideoProps, VideoProps } from './Video';
6
7
 
7
8
  export * from './CallLayout';