@skooldev/skool-stream-layout 1.0.12 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -82,10 +82,30 @@ const ParticipantsViewCountContext = (0,external_react_namespaceObject.createCon
82
82
  increment: () => { },
83
83
  decrement: () => { },
84
84
  });
85
+ const RecordingSceneReadyContext = (0,external_react_namespaceObject.createContext)(undefined);
85
86
  const CustomParticipantViewUI = () => {
86
87
  const { increment, decrement } = (0,external_react_namespaceObject.useContext)(ParticipantsViewCountContext);
87
- const context = (0,video_react_sdk_namespaceObject.useParticipantViewContext)();
88
- const { participant } = context;
88
+ const notifyReady = (0,external_react_namespaceObject.useContext)(RecordingSceneReadyContext);
89
+ const { participant, videoElement, videoPlaceholderElement } = (0,video_react_sdk_namespaceObject.useParticipantViewContext)();
90
+ (0,external_react_namespaceObject.useEffect)(() => {
91
+ // no-op for non-recording use-cases
92
+ if (!notifyReady)
93
+ return;
94
+ const isPublishingVideoTrack = participant === null || participant === void 0 ? void 0 : participant.publishedTracks.includes(video_react_sdk_namespaceObject.SfuModels.TrackType.VIDEO);
95
+ // video element for participants with video
96
+ if (isPublishingVideoTrack && videoElement) {
97
+ const isAlreadyPlaying = videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended;
98
+ if (isAlreadyPlaying)
99
+ notifyReady(true);
100
+ const onPlay = () => notifyReady(true);
101
+ videoElement.addEventListener("play", onPlay, { once: true });
102
+ return () => videoElement.removeEventListener("play", onPlay);
103
+ }
104
+ // placeholder div for audio-only participants
105
+ if (!isPublishingVideoTrack && videoPlaceholderElement) {
106
+ notifyReady(true);
107
+ }
108
+ }, [notifyReady, participant === null || participant === void 0 ? void 0 : participant.publishedTracks, videoElement, videoPlaceholderElement]);
89
109
  (0,external_react_namespaceObject.useLayoutEffect)(() => {
90
110
  increment();
91
111
  return () => {
@@ -96,7 +116,7 @@ const CustomParticipantViewUI = () => {
96
116
  return ((0,jsx_runtime_namespaceObject.jsxs)("div", { className: "participant-label", children: [(0,jsx_runtime_namespaceObject.jsx)("span", { children: participant.name }), !(0,video_react_sdk_namespaceObject.hasAudio)(participant) && (0,jsx_runtime_namespaceObject.jsx)("span", { className: "mute-icon" }), (0,video_react_sdk_namespaceObject.isPinned)(participant) && (0,jsx_runtime_namespaceObject.jsx)("span", { className: "pin-icon" }), hasPausedVideo && (0,jsx_runtime_namespaceObject.jsx)(video_react_sdk_namespaceObject.Icon, { icon: "low-bandwidth" })] }));
97
117
  };
98
118
  const SkoolStreamLayoutComponent = (props) => {
99
- const { excludeLocalParticipant = false } = props;
119
+ const { excludeLocalParticipant = false, notifyReady } = props;
100
120
  const call = (0,video_react_sdk_namespaceObject.useCall)();
101
121
  const { useParticipants, useHasOngoingScreenShare } = (0,video_react_sdk_namespaceObject.useCallStateHooks)();
102
122
  const participants = useParticipants();
@@ -130,7 +150,7 @@ const SkoolStreamLayoutComponent = (props) => {
130
150
  hasPinnedParticipant,
131
151
  isWebinar,
132
152
  ]);
133
- return ((0,jsx_runtime_namespaceObject.jsx)(ParticipantsViewCountContext.Provider, { value: value, children: (0,jsx_runtime_namespaceObject.jsx)("div", { "data-participants": numParticipantsInView, className: "skool-stream-layout", children: mainLayout }) }));
153
+ return ((0,jsx_runtime_namespaceObject.jsx)(RecordingSceneReadyContext.Provider, { value: notifyReady, children: (0,jsx_runtime_namespaceObject.jsx)(ParticipantsViewCountContext.Provider, { value: value, children: (0,jsx_runtime_namespaceObject.jsx)("div", { "data-participants": numParticipantsInView, className: "skool-stream-layout", children: mainLayout }) }) }));
134
154
  };
135
155
  const SkoolStreamLayout = (0,external_react_namespaceObject.memo)(SkoolStreamLayoutComponent);
136
156
 
package/dist/index.d.ts CHANGED
@@ -2,4 +2,5 @@ import React from "react";
2
2
  import "./styles.scss";
3
3
  export declare const SkoolStreamLayout: React.MemoExoticComponent<(props: {
4
4
  excludeLocalParticipant?: boolean;
5
+ notifyReady?: (ready: boolean) => void;
5
6
  }) => import("react/jsx-runtime").JSX.Element>;
package/dist/index.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__, jsxs as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsxs__ } from "react/jsx-runtime";
2
- import { createContext as __WEBPACK_EXTERNAL_MODULE_react_createContext__, memo as __WEBPACK_EXTERNAL_MODULE_react_memo__, useContext as __WEBPACK_EXTERNAL_MODULE_react_useContext__, useLayoutEffect as __WEBPACK_EXTERNAL_MODULE_react_useLayoutEffect__, useMemo as __WEBPACK_EXTERNAL_MODULE_react_useMemo__, useState as __WEBPACK_EXTERNAL_MODULE_react_useState__ } from "react";
2
+ import { createContext as __WEBPACK_EXTERNAL_MODULE_react_createContext__, memo as __WEBPACK_EXTERNAL_MODULE_react_memo__, useContext as __WEBPACK_EXTERNAL_MODULE_react_useContext__, useEffect as __WEBPACK_EXTERNAL_MODULE_react_useEffect__, useLayoutEffect as __WEBPACK_EXTERNAL_MODULE_react_useLayoutEffect__, useMemo as __WEBPACK_EXTERNAL_MODULE_react_useMemo__, useState as __WEBPACK_EXTERNAL_MODULE_react_useState__ } from "react";
3
3
  import { Icon as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_Icon__, PaginatedGridLayout as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_PaginatedGridLayout__, ParticipantView as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_ParticipantView__, SfuModels as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_SfuModels__, SpeakerLayout as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_SpeakerLayout__, hasAudio as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_hasAudio__, isPinned as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_isPinned__, useCall as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_useCall__, useCallStateHooks as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_useCallStateHooks__, useParticipantViewContext as __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_useParticipantViewContext__ } from "@stream-io/video-react-sdk";
4
4
  /******/ // The require scope
5
5
  /******/ var __webpack_require__ = {};
@@ -65,10 +65,30 @@ const ParticipantsViewCountContext = __WEBPACK_EXTERNAL_MODULE_react_createConte
65
65
  increment: () => { },
66
66
  decrement: () => { },
67
67
  });
68
+ const RecordingSceneReadyContext = __WEBPACK_EXTERNAL_MODULE_react_createContext__(undefined);
68
69
  const CustomParticipantViewUI = () => {
69
70
  const { increment, decrement } = __WEBPACK_EXTERNAL_MODULE_react_useContext__(ParticipantsViewCountContext);
70
- const context = __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_useParticipantViewContext__();
71
- const { participant } = context;
71
+ const notifyReady = __WEBPACK_EXTERNAL_MODULE_react_useContext__(RecordingSceneReadyContext);
72
+ const { participant, videoElement, videoPlaceholderElement } = __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_useParticipantViewContext__();
73
+ __WEBPACK_EXTERNAL_MODULE_react_useEffect__(() => {
74
+ // no-op for non-recording use-cases
75
+ if (!notifyReady)
76
+ return;
77
+ const isPublishingVideoTrack = participant === null || participant === void 0 ? void 0 : participant.publishedTracks.includes(__WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_SfuModels__.TrackType.VIDEO);
78
+ // video element for participants with video
79
+ if (isPublishingVideoTrack && videoElement) {
80
+ const isAlreadyPlaying = videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended;
81
+ if (isAlreadyPlaying)
82
+ notifyReady(true);
83
+ const onPlay = () => notifyReady(true);
84
+ videoElement.addEventListener("play", onPlay, { once: true });
85
+ return () => videoElement.removeEventListener("play", onPlay);
86
+ }
87
+ // placeholder div for audio-only participants
88
+ if (!isPublishingVideoTrack && videoPlaceholderElement) {
89
+ notifyReady(true);
90
+ }
91
+ }, [notifyReady, participant === null || participant === void 0 ? void 0 : participant.publishedTracks, videoElement, videoPlaceholderElement]);
72
92
  __WEBPACK_EXTERNAL_MODULE_react_useLayoutEffect__(() => {
73
93
  increment();
74
94
  return () => {
@@ -79,7 +99,7 @@ const CustomParticipantViewUI = () => {
79
99
  return (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsxs__("div", { className: "participant-label", children: [__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__("span", { children: participant.name }), !__WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_hasAudio__(participant) && __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__("span", { className: "mute-icon" }), __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_isPinned__(participant) && __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__("span", { className: "pin-icon" }), hasPausedVideo && __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__(__WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_Icon__, { icon: "low-bandwidth" })] }));
80
100
  };
81
101
  const SkoolStreamLayoutComponent = (props) => {
82
- const { excludeLocalParticipant = false } = props;
102
+ const { excludeLocalParticipant = false, notifyReady } = props;
83
103
  const call = __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_useCall__();
84
104
  const { useParticipants, useHasOngoingScreenShare } = __WEBPACK_EXTERNAL_MODULE__stream_io_video_react_sdk_4ccb1546_useCallStateHooks__();
85
105
  const participants = useParticipants();
@@ -113,7 +133,7 @@ const SkoolStreamLayoutComponent = (props) => {
113
133
  hasPinnedParticipant,
114
134
  isWebinar,
115
135
  ]);
116
- return (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__(ParticipantsViewCountContext.Provider, { value: value, children: __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__("div", { "data-participants": numParticipantsInView, className: "skool-stream-layout", children: mainLayout }) }));
136
+ return (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__(RecordingSceneReadyContext.Provider, { value: notifyReady, children: __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__(ParticipantsViewCountContext.Provider, { value: value, children: __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8_jsx__("div", { "data-participants": numParticipantsInView, className: "skool-stream-layout", children: mainLayout }) }) }));
117
137
  };
118
138
  const SkoolStreamLayout = __WEBPACK_EXTERNAL_MODULE_react_memo__(SkoolStreamLayoutComponent);
119
139
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skooldev/skool-stream-layout",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "Skool Stream Layout",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",