@selfcommunity/react-ui 0.8.0-live.71 → 0.8.0-live.73

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 (22) hide show
  1. package/lib/cjs/components/CreateLiveStreamDialog/LiveStreamSelector/LiveStreamSelector.js +1 -1
  2. package/lib/cjs/components/LiveStreamRoom/LiveStreamRoom.js +9 -3
  3. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/DisconnectButton.js +7 -2
  4. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/FocusLayout.d.ts +1 -0
  5. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/FocusLayout.js +6 -1
  6. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.js +6 -2
  7. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +1 -1
  8. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +8 -6
  9. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +1 -1
  10. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/useLiveStreamCheck.js +5 -4
  11. package/lib/esm/components/CreateLiveStreamDialog/LiveStreamSelector/LiveStreamSelector.js +1 -1
  12. package/lib/esm/components/LiveStreamRoom/LiveStreamRoom.js +10 -4
  13. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/DisconnectButton.js +7 -2
  14. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/FocusLayout.d.ts +1 -0
  15. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/FocusLayout.js +4 -0
  16. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.js +6 -2
  17. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +1 -1
  18. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +9 -7
  19. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +2 -2
  20. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/useLiveStreamCheck.js +5 -4
  21. package/lib/umd/react-ui.js +1 -1
  22. package/package.json +7 -7
@@ -183,6 +183,6 @@ function LiveStreamSelector(inProps) {
183
183
  }, theme: undefined }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h6", component: "h2", sx: { fontWeight: 500 } }, { children: option.title })), (0, jsx_runtime_1.jsx)(material_1.Radio, { checked: selectedOption === option.type })] }), (0, jsx_runtime_1.jsx)("img", { src: option.image, alt: "logo" }), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ component: "ul" }, { children: option.features.map((feature, featureIndex) => {
184
184
  const _Icon = option.icons[featureIndex];
185
185
  return ((0, jsx_runtime_1.jsxs)(FeatureItem, Object.assign({ component: "li" }, { children: [_Icon, (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2", color: "text.secondary", sx: { flex: 1 } }, { children: feature }))] }), featureIndex));
186
- }) }))] }), index))) })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ disabled: !selectedOption || !timeRemaining, variant: "contained", onClick: handleNext, color: "secondary" }, { children: "Next" })) }))] })));
186
+ }) }))] }), index))) })), (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.actions }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ disabled: !selectedOption || !timeRemaining, variant: "contained", onClick: handleNext, color: "secondary" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamForm.selector.next", defaultMessage: "ui.liveStreamForm.selector.next" }) })) }))] })));
187
187
  }
188
188
  exports.default = LiveStreamSelector;
@@ -134,9 +134,15 @@ function LiveStreamRoom(inProps) {
134
134
  if (error.response.data.errors[0].code) {
135
135
  const _error = `ui.liveStreamRoom.connect.error.${(0, utils_1.camelCase)(error.response.data.errors[0].code)}`;
136
136
  _msg = intl.formatMessage({ id: _error, defaultMessage: _error });
137
+ if (error.response.data.errors[0].code !== types_1.SCLiveStreamConnectionDetailsErrorType.WAITING_HOST_TO_START_LIVE_STREAM) {
138
+ setError(_msg);
139
+ }
140
+ enqueueSnackbar(_msg, { variant: 'error', autoHideDuration: 5000 });
141
+ }
142
+ else {
143
+ enqueueSnackbar(_msg, { variant: 'error' });
144
+ setError(_msg);
137
145
  }
138
- setError(_msg);
139
- enqueueSnackbar(_msg, { variant: 'error' });
140
146
  }
141
147
  setLoading(false);
142
148
  });
@@ -169,7 +175,7 @@ function LiveStreamRoom(inProps) {
169
175
  /**
170
176
  * Renders root object
171
177
  */
172
- return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className) }, rest, { children: scLiveStream.closed_at_by_host ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsxs)(DialogContent_1.default, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.conference.closed", defaultMessage: "ui.liveStreamRoom.conference.closed" }) })), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) }))] })) }))) : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.content, "data-lk-theme": "default" }, { children: connectionDetails === undefined || preJoinChoices === undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [startPrejoinContent && (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.startPrejoinContent }, { children: startPrejoinContent })), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title) && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div', variant: "h5", className: classes.title }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title }))), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description) && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div', variant: "body1", className: classes.description }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description }))), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: (0, classnames_1.default)(classes.preJoin, { [classes.preJoinLoading]: loading || error }) }, { children: [(0, jsx_runtime_1.jsx)(LiveStreamProvider_1.LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: (0, jsx_runtime_1.jsx)(PreJoin_1.PreJoin, { defaults: preJoinDefaults, onSubmit: handlePreJoinSubmit, onError: handlePreJoinError }) })), loading && ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.prejoinLoader }, { children: [(0, jsx_runtime_1.jsx)(material_1.CircularProgress, {}), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div', variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.connecting", defaultMessage: "ui.liveStreamRoom.connecting" }) }))] })))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endPrejoinContent }, { children: [Boolean(scUserContext.user &&
178
+ return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className) }, rest, { children: scLiveStream.closed_at_by_host ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsxs)(DialogContent_1.default, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.conference.closed", defaultMessage: "ui.liveStreamRoom.conference.closed" }) })), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) }))] })) }))) : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.content, "data-lk-theme": "default" }, { children: connectionDetails === undefined || preJoinChoices === undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [startPrejoinContent && (0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.startPrejoinContent }, { children: startPrejoinContent })), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title) && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div', variant: "h5", className: classes.title }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title }))), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description) && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div', variant: "body1", className: classes.description }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description }))), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: (0, classnames_1.default)(classes.preJoin, { [classes.preJoinLoading]: loading || error }) }, { children: [(0, jsx_runtime_1.jsx)(LiveStreamProvider_1.LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: (0, jsx_runtime_1.jsx)(PreJoin_1.PreJoin, { defaults: preJoinDefaults, onSubmit: handlePreJoinSubmit, onError: handlePreJoinError, joinLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.joinRoom', defaultMessage: 'ui.liveStreamRoom.preJoin.joinRoom' }), micLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.microphone', defaultMessage: 'ui.liveStreamRoom.preJoin.microphone' }), camLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.camera', defaultMessage: 'ui.liveStreamRoom.preJoin.camera' }), userLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.username', defaultMessage: 'ui.liveStreamRoom.preJoin.username' }) }) })), loading && ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.prejoinLoader }, { children: [(0, jsx_runtime_1.jsx)(material_1.CircularProgress, {}), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: 'div', variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.connecting", defaultMessage: "ui.liveStreamRoom.connecting" }) }))] })))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endPrejoinContent }, { children: [Boolean(scUserContext.user &&
173
179
  scUserContext.user.id !== scLiveStream.host.id &&
174
180
  scLiveStream &&
175
181
  (((_a = scLiveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants) || (scLiveStream && ((_b = scLiveStream.settings) === null || _b === void 0 ? void 0 : _b.disableVideo)))) && ((0, jsx_runtime_1.jsxs)(material_1.Stack, Object.assign({ sx: { width: '60%' }, spacing: 1 }, { children: [scLiveStream && ((_c = scLiveStream.settings) === null || _c === void 0 ? void 0 : _c.muteParticipants) && ((0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ variant: "filled", severity: "info", component: 'div' }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.hostDisableMicrophone", defaultMessage: "ui.liveStreamRoom.hostDisableMicrophone" }) }))), scLiveStream && ((_d = scLiveStream.settings) === null || _d === void 0 ? void 0 : _d.disableVideo) && ((0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ variant: "filled", severity: "info" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.hostDisableVideo", defaultMessage: "ui.liveStreamRoom.hostDisableVideo" }) })))] }))), endPrejoinContent] }))] })) : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.conference }, { children: (0, jsx_runtime_1.jsx)(LiveStreamProvider_1.LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: (0, jsx_runtime_1.jsx)(LiveStreamVideoConference_1.default, Object.assign({ connectionDetails: connectionDetails, userChoices: preJoinChoices }, LiveStreamVideoConferenceComponentProps)) })) }))) }))) })));
@@ -31,8 +31,13 @@ exports.DisconnectButton =
31
31
  * Intercept fist leave action
32
32
  */
33
33
  const handleOnLeave = (0, react_1.useCallback)(() => {
34
- setOpenConfirmDialog(true);
35
- }, [setOpenConfirmDialog]);
34
+ if (liveStream && scUserContext.user.id === liveStream.host.id) {
35
+ setOpenConfirmDialog(true);
36
+ }
37
+ else {
38
+ onClick === null || onClick === void 0 ? void 0 : onClick();
39
+ }
40
+ }, [setOpenConfirmDialog, liveStream, scUserContext.user]);
36
41
  /**
37
42
  * Control close live
38
43
  */
@@ -9,6 +9,7 @@ export type FocusLayoutContainerProps = React.HTMLAttributes<HTMLDivElement>;
9
9
  * For example, with the `FocusLayout` component.
10
10
  */
11
11
  export declare function FocusLayoutContainer(props: FocusLayoutContainerProps): JSX.Element;
12
+ export declare function FocusLayoutContainerNoParticipants(props: FocusLayoutContainerProps): JSX.Element;
12
13
  export interface FocusLayoutProps extends React.HTMLAttributes<HTMLElement> {
13
14
  /** The track to display in the focus layout. */
14
15
  trackRef?: TrackReferenceOrPlaceholder;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FocusLayout = exports.FocusLayoutContainer = void 0;
3
+ exports.FocusLayout = exports.FocusLayoutContainerNoParticipants = exports.FocusLayoutContainer = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const ParticipantTile_1 = require("./ParticipantTile");
@@ -16,6 +16,11 @@ function FocusLayoutContainer(props) {
16
16
  return (0, jsx_runtime_1.jsx)("div", Object.assign({}, elementProps, { children: props.children }));
17
17
  }
18
18
  exports.FocusLayoutContainer = FocusLayoutContainer;
19
+ function FocusLayoutContainerNoParticipants(props) {
20
+ const elementProps = (0, utils_1.mergeProps)(props, { className: 'lk-focus-layout' });
21
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({}, elementProps, { style: { gridTemplateColumns: 'none' } }, { children: props.children })));
22
+ }
23
+ exports.FocusLayoutContainerNoParticipants = FocusLayoutContainerNoParticipants;
19
24
  /**
20
25
  * The `FocusLayout` component is just a light wrapper around the `ParticipantTile` to display a single participant.
21
26
  */
@@ -18,6 +18,7 @@ const VideoConference_1 = require("./VideoConference");
18
18
  const LiveStreamProvider_1 = require("./LiveStreamProvider");
19
19
  const DialogContent_1 = tslib_1.__importDefault(require("@mui/material/DialogContent"));
20
20
  const BaseDialog_1 = tslib_1.__importDefault(require("../../../shared/BaseDialog"));
21
+ const notistack_1 = require("notistack");
21
22
  const classes = {
22
23
  root: `${constants_1.PREFIX}-root`,
23
24
  logo: `${constants_1.PREFIX}-logo`,
@@ -86,7 +87,7 @@ function LiveStreamVideoConference(inProps) {
86
87
  const canUseChat = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableChat); }, [scUserContext, liveStream]);
87
88
  const canUseShareScreen = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableShareScreen))); }, [scUserContext, liveStream]);
88
89
  const speakerFocused = (0, react_1.useMemo)(() => (scUserContext.user && liveStream && liveStream.settings.view === types_1.SCLiveStreamViewType.SPEAKER ? liveStream.host : null), [scUserContext, liveStream]);
89
- const hideParticipantsList = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && liveStream.host.id !== scUserContext.user.id && liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.hideParticipantList); }, [scUserContext, liveStream]);
90
+ const hideParticipantsList = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && ((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.hideParticipantsList) && liveStream.host.id !== scUserContext.user.id; }, [scUserContext, liveStream]);
90
91
  // CONNECT OPTIONS
91
92
  const connectOptions = (0, react_1.useMemo)(() => {
92
93
  return {
@@ -119,6 +120,9 @@ function LiveStreamVideoConference(inProps) {
119
120
  setError(`Encountered an unexpected encryption error, check the console logs for details: ${error.message}`);
120
121
  setLiveActive(false);
121
122
  }, []);
123
+ const handleBackHome = (0, react_1.useCallback)(() => {
124
+ (0, notistack_1.closeSnackbar)();
125
+ }, [notistack_1.closeSnackbar]);
122
126
  /**
123
127
  * User must be authenticated
124
128
  */
@@ -128,6 +132,6 @@ function LiveStreamVideoConference(inProps) {
128
132
  /**
129
133
  * Renders root object
130
134
  */
131
- return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: liveActive && !error ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(components_react_1.LiveKitRoom, Object.assign({ connect: Boolean(liveActive), token: connectionDetails['participantToken'], serverUrl: connectionDetails['serverUrl'], connectOptions: connectOptions, video: userChoices.videoEnabled, audio: userChoices.audioEnabled, onDisconnected: handleOnLeave, onEncryptionError: handleEncryptionError, onError: handleError }, LiveKitRoomComponentProps, { children: (0, jsx_runtime_1.jsxs)(components_react_1.LayoutContextProvider, { children: [(0, jsx_runtime_1.jsx)(VideoConference_1.VideoConference, Object.assign({ chatMessageFormatter: components_react_1.formatChatMessageLinks }, (speakerFocused && { speakerFocused: liveStream.host }), VideoConferenceComponentProps, { disableMicrophone: !canUseAudio, disableCamera: !canUseVideo, disableChat: !canUseChat, disableShareScreen: !canUseShareScreen, hideParticipantsList: hideParticipantsList })), (0, jsx_runtime_1.jsx)(components_react_1.ConnectionState, {})] }) })) })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: error ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(DialogContent_1.default, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: (0, jsx_runtime_1.jsx)("img", { src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, error, (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : liveActive === false ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(DialogContent_1.default, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: (0, jsx_runtime_1.jsx)("img", { src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.conference.end", defaultMessage: "ui.liveStreamRoom.conference.end" }) })), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, {})) })) })));
135
+ return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: liveActive && !error ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(components_react_1.LiveKitRoom, Object.assign({ connect: Boolean(liveActive), token: connectionDetails['participantToken'], serverUrl: connectionDetails['serverUrl'], connectOptions: connectOptions, video: userChoices.videoEnabled, audio: userChoices.audioEnabled, onDisconnected: handleOnLeave, onEncryptionError: handleEncryptionError, onError: handleError }, LiveKitRoomComponentProps, { children: (0, jsx_runtime_1.jsxs)(components_react_1.LayoutContextProvider, { children: [(0, jsx_runtime_1.jsx)(VideoConference_1.VideoConference, Object.assign({ chatMessageFormatter: components_react_1.formatChatMessageLinks }, (speakerFocused && { speakerFocused: liveStream.host }), VideoConferenceComponentProps, { disableMicrophone: !canUseAudio, disableCamera: !canUseVideo, disableChat: !canUseChat, disableShareScreen: !canUseShareScreen, hideParticipantsList: hideParticipantsList })), (0, jsx_runtime_1.jsx)(components_react_1.ConnectionState, {})] }) })) })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: error ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(DialogContent_1.default, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: (0, jsx_runtime_1.jsx)("img", { src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, error, (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : liveActive === false ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: (0, jsx_runtime_1.jsx)(DialogContent_1.default, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.endConferenceWrap }, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Link, Object.assign({ to: scRoutingContext.url(react_core_1.SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: (0, jsx_runtime_1.jsx)("img", { src: preferences[react_core_1.SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "h5" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.conference.end", defaultMessage: "ui.liveStreamRoom.conference.end" }) })), (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ variant: "contained", color: "secondary", component: react_core_1.Link, to: '/', onClick: handleBackHome, className: classes.btnBackHome }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, {})) })) })));
132
136
  }
133
137
  exports.default = LiveStreamVideoConference;
@@ -60,7 +60,7 @@ exports.ParticipantTile =
60
60
  return ((0, jsx_runtime_1.jsx)("div", Object.assign({ ref: ref, style: { position: 'relative' } }, elementProps, { children: (0, jsx_runtime_1.jsx)(TrackRefContextIfNeeded, Object.assign({ trackRef: trackReference }, { children: (0, jsx_runtime_1.jsxs)(ParticipantContextIfNeeded, Object.assign({ participant: trackReference.participant }, { children: [children !== null && children !== void 0 ? children : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, components_core_1.isTrackReference)(trackReference) &&
61
61
  (((_c = trackReference.publication) === null || _c === void 0 ? void 0 : _c.kind) === 'video' ||
62
62
  trackReference.source === livekit_client_1.Track.Source.Camera ||
63
- trackReference.source === livekit_client_1.Track.Source.ScreenShare) ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(components_react_1.VideoTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe, manageSubscription: autoManageSubscription }) })) : ((0, components_core_1.isTrackReference)(trackReference) && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(components_react_1.AudioTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe }) }))), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-participant-placeholder" }, { children: (0, jsx_runtime_1.jsx)(ParticipantTileAvatar_1.default, Object.assign({}, ((liveStream === null || liveStream === void 0 ? void 0 : liveStream.host.id) !== scUserContext.user.id ? { participant: trackReference.participant } : { user: scUserContext.user }))) })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-participant-metadata" }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-participant-metadata-item" }, { children: trackReference.source === livekit_client_1.Track.Source.Camera ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isEncrypted && (0, jsx_runtime_1.jsx)(components_react_1.LockLockedIcon, { style: { marginRight: '0.25rem' } }), (0, jsx_runtime_1.jsx)(components_react_1.TrackMutedIndicator, { trackRef: {
63
+ trackReference.source === livekit_client_1.Track.Source.ScreenShare) ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(components_react_1.VideoTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe, manageSubscription: autoManageSubscription }) })) : ((0, components_core_1.isTrackReference)(trackReference) && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(components_react_1.AudioTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe }) }))), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-participant-placeholder" }, { children: (0, jsx_runtime_1.jsx)(ParticipantTileAvatar_1.default, { participant: trackReference.participant }) })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-participant-metadata" }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-participant-metadata-item" }, { children: trackReference.source === livekit_client_1.Track.Source.Camera ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isEncrypted && (0, jsx_runtime_1.jsx)(components_react_1.LockLockedIcon, { style: { marginRight: '0.25rem' } }), (0, jsx_runtime_1.jsx)(components_react_1.TrackMutedIndicator, { trackRef: {
64
64
  participant: trackReference.participant,
65
65
  source: livekit_client_1.Track.Source.Microphone
66
66
  }, show: 'muted' }), (0, jsx_runtime_1.jsx)(components_react_1.ParticipantName, { children: !disableTileActions && (0, jsx_runtime_1.jsx)(ParticipantTileActions_1.default, {}) })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(components_react_1.ScreenShareIcon, { style: { marginRight: '0.25rem' } }), (0, jsx_runtime_1.jsx)(components_react_1.ParticipantName, { children: "'s screen" })] })) })), (0, jsx_runtime_1.jsx)(components_react_1.ConnectionQualityIndicator, { className: "lk-participant-metadata-item" })] }))] })), (0, jsx_runtime_1.jsx)(components_react_1.FocusToggle, { trackRef: trackReference })] })) })) })));
@@ -155,6 +155,7 @@ exports.usePreviewDevice = usePreviewDevice;
155
155
  function PreJoin(_a) {
156
156
  var { defaults = {}, onValidate, onSubmit, onError, debug, joinLabel = 'Join Room', micLabel = 'Microphone', camLabel = 'Camera', userLabel = 'Username', persistUserChoices = true } = _a, htmlProps = tslib_1.__rest(_a, ["defaults", "onValidate", "onSubmit", "onError", "debug", "joinLabel", "micLabel", "camLabel", "userLabel", "persistUserChoices"]);
157
157
  const { liveStream } = (0, LiveStreamProvider_1.useLiveStream)();
158
+ const scUserContext = (0, react_core_1.useSCUser)();
158
159
  const [userChoices, setUserChoices] = React.useState(components_core_2.defaultUserChoices);
159
160
  // TODO: Remove and pipe `defaults` object directly into `usePersistentUserChoices` once we fully switch from type `LocalUserChoices` to `UserChoices`.
160
161
  const partialDefaults = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (defaults.audioDeviceId !== undefined && { audioDeviceId: defaults.audioDeviceId })), (defaults.videoDeviceId !== undefined && { videoDeviceId: defaults.videoDeviceId })), (defaults.audioEnabled !== undefined && { audioEnabled: defaults.audioEnabled })), (defaults.videoEnabled !== undefined && { videoEnabled: defaults.videoEnabled })), (defaults.username !== undefined && { username: defaults.username }));
@@ -183,13 +184,14 @@ function PreJoin(_a) {
183
184
  saveVideoInputDeviceId(videoDeviceId);
184
185
  }, [videoDeviceId, saveVideoInputDeviceId]);
185
186
  React.useEffect(() => {
186
- saveUsername(username);
187
- }, [username, saveUsername]);
187
+ if (scUserContext.user) {
188
+ saveUsername(scUserContext.user.username);
189
+ }
190
+ }, [username, saveUsername, scUserContext.user]);
188
191
  const tracks = usePreviewTracks({
189
192
  audio: audioEnabled ? { deviceId: initialUserChoices.audioDeviceId } : false,
190
193
  video: videoEnabled ? { deviceId: initialUserChoices.videoDeviceId } : false
191
194
  }, onError);
192
- const scUserContext = (0, react_core_1.useSCUser)();
193
195
  const videoEl = React.useRef(null);
194
196
  const videoTrack = React.useMemo(() => tracks === null || tracks === void 0 ? void 0 : tracks.filter((track) => track.kind === livekit_client_1.Track.Kind.Video)[0], [tracks]);
195
197
  const facingMode = React.useMemo(() => {
@@ -220,7 +222,7 @@ function PreJoin(_a) {
220
222
  return values.username !== '';
221
223
  }
222
224
  }, [onValidate]);
223
- React.useEffect(() => {
225
+ (0, react_1.useEffect)(() => {
224
226
  const newUserChoices = {
225
227
  username,
226
228
  videoEnabled,
@@ -230,7 +232,7 @@ function PreJoin(_a) {
230
232
  };
231
233
  setUserChoices(newUserChoices);
232
234
  setIsValid(handleValidation(newUserChoices));
233
- }, [username, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
235
+ }, [username, scUserContext.user, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
234
236
  function handleSubmit(event) {
235
237
  event.preventDefault();
236
238
  if (handleValidation(userChoices)) {
@@ -244,6 +246,6 @@ function PreJoin(_a) {
244
246
  }
245
247
  const canUseAudio = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants))); }, [scUserContext, liveStream]);
246
248
  const canUseVideo = (0, react_1.useMemo)(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableVideo))); }, [scUserContext, liveStream]);
247
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-prejoin" }, htmlProps, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-video-container" }, { children: [videoTrack && (0, jsx_runtime_1.jsx)("video", { ref: videoEl, width: "1280", height: "720", "data-lk-facing-mode": facingMode }), (!videoTrack || !videoEnabled) && ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-camera-off-note" }, { children: (0, jsx_runtime_1.jsx)(ParticipantTileAvatar_1.default, { user: scUserContext.user }) })))] })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-button-group-container" }, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-button-group audio" }, { children: [(0, jsx_runtime_1.jsx)(TrackToggle_1.TrackToggle, Object.assign({ disabled: !canUseAudio, initialState: audioEnabled, source: livekit_client_1.Track.Source.Microphone, onChange: (enabled) => setAudioEnabled(enabled) }, { children: micLabel })), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-button-group-menu" }, { children: (0, jsx_runtime_1.jsx)(components_react_1.MediaDeviceMenu, { initialSelection: audioDeviceId, kind: "audioinput", disabled: !audioTrack || !canUseAudio, tracks: { audioinput: audioTrack }, onActiveDeviceChange: (_, id) => setAudioDeviceId(id) }) }))] })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-button-group video" }, { children: [(0, jsx_runtime_1.jsx)(TrackToggle_1.TrackToggle, Object.assign({ disabled: !canUseVideo, initialState: videoEnabled, source: livekit_client_1.Track.Source.Camera, onChange: (enabled) => setVideoEnabled(enabled) }, { children: camLabel })), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-button-group-menu" }, { children: (0, jsx_runtime_1.jsx)(components_react_1.MediaDeviceMenu, { initialSelection: videoDeviceId, kind: "videoinput", disabled: !videoTrack || !canUseVideo, tracks: { videoinput: videoTrack }, onActiveDeviceChange: (_, id) => setVideoDeviceId(id) }) }))] }))] })), (0, jsx_runtime_1.jsxs)("form", Object.assign({ className: "lk-username-container" }, { children: [(0, jsx_runtime_1.jsx)("input", { className: "lk-form-control", id: "username", name: "username", type: "text", defaultValue: username, placeholder: userLabel, onChange: (inputEl) => setUsername(inputEl.target.value), autoComplete: "off" }), (0, jsx_runtime_1.jsx)("button", Object.assign({ className: "lk-button lk-join-button", type: "submit", onClick: handleSubmit, disabled: !isValid }, { children: joinLabel }))] })), debug && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("strong", { children: "User Choices:" }), (0, jsx_runtime_1.jsxs)("ul", Object.assign({ className: "lk-list", style: { overflow: 'hidden', maxWidth: '15rem' } }, { children: [(0, jsx_runtime_1.jsxs)("li", { children: ["Username: ", `${userChoices.username}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Video Enabled: ", `${userChoices.videoEnabled}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Audio Enabled: ", `${userChoices.audioEnabled}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Video Device: ", `${userChoices.videoDeviceId}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Audio Device: ", `${userChoices.audioDeviceId}`] })] }))] }))] })));
249
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-prejoin" }, htmlProps, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-video-container" }, { children: [videoTrack && (0, jsx_runtime_1.jsx)("video", { ref: videoEl, width: "1280", height: "720", "data-lk-facing-mode": facingMode }), (!videoTrack || !videoEnabled) && ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-camera-off-note" }, { children: (0, jsx_runtime_1.jsx)(ParticipantTileAvatar_1.default, { user: scUserContext.user }) })))] })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-button-group-container" }, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-button-group audio" }, { children: [(0, jsx_runtime_1.jsx)(TrackToggle_1.TrackToggle, Object.assign({ disabled: !canUseAudio, initialState: audioEnabled, source: livekit_client_1.Track.Source.Microphone, onChange: (enabled) => setAudioEnabled(enabled) }, { children: micLabel })), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-button-group-menu" }, { children: (0, jsx_runtime_1.jsx)(components_react_1.MediaDeviceMenu, { initialSelection: audioDeviceId, kind: "audioinput", disabled: !audioTrack || !canUseAudio, tracks: { audioinput: audioTrack }, onActiveDeviceChange: (_, id) => setAudioDeviceId(id) }) }))] })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-button-group video" }, { children: [(0, jsx_runtime_1.jsx)(TrackToggle_1.TrackToggle, Object.assign({ disabled: !canUseVideo, initialState: videoEnabled, source: livekit_client_1.Track.Source.Camera, onChange: (enabled) => setVideoEnabled(enabled) }, { children: camLabel })), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-button-group-menu" }, { children: (0, jsx_runtime_1.jsx)(components_react_1.MediaDeviceMenu, { initialSelection: videoDeviceId, kind: "videoinput", disabled: !videoTrack || !canUseVideo, tracks: { videoinput: videoTrack }, onActiveDeviceChange: (_, id) => setVideoDeviceId(id) }) }))] }))] })), (0, jsx_runtime_1.jsx)("form", Object.assign({ className: "lk-username-container" }, { children: (0, jsx_runtime_1.jsx)("button", Object.assign({ className: "lk-button lk-join-button", type: "submit", onClick: handleSubmit, disabled: !isValid }, { children: joinLabel })) })), debug && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("strong", { children: "User Choices:" }), (0, jsx_runtime_1.jsxs)("ul", Object.assign({ className: "lk-list", style: { overflow: 'hidden', maxWidth: '15rem' } }, { children: [(0, jsx_runtime_1.jsxs)("li", { children: ["Username: ", `${userChoices.username}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Video Enabled: ", `${userChoices.videoEnabled}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Audio Enabled: ", `${userChoices.audioEnabled}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Video Device: ", `${userChoices.videoDeviceId}`] }), (0, jsx_runtime_1.jsxs)("li", { children: ["Audio Device: ", `${userChoices.audioDeviceId}`] })] }))] }))] })));
248
250
  }
249
251
  exports.PreJoin = PreJoin;
@@ -93,7 +93,7 @@ function VideoConference(_a) {
93
93
  participants,
94
94
  speakerFocused
95
95
  ]);
96
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-video-conference" }, props, { children: [(0, components_core_1.isWeb)() && ((0, jsx_runtime_1.jsxs)(components_react_1.LayoutContextProvider, Object.assign({ value: layoutContext, onPinChange: handleFocusStateChange, onWidgetChange: widgetUpdate }, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-video-conference-inner" }, { children: [!focusTrack ? ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-grid-layout-wrapper" }, { children: (0, jsx_runtime_1.jsx)(components_react_1.GridLayout, Object.assign({ tracks: tracks }, { children: (0, jsx_runtime_1.jsx)(ParticipantTile_1.ParticipantTile, {}) })) }))) : ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-focus-layout-wrapper" }, { children: (0, jsx_runtime_1.jsxs)(FocusLayout_1.FocusLayoutContainer, { children: [!hideParticipantsList && ((0, jsx_runtime_1.jsx)(components_react_1.CarouselLayout, Object.assign({ tracks: carouselTracks }, { children: (0, jsx_runtime_1.jsx)(ParticipantTile_1.ParticipantTile, {}) }))), focusTrack && (0, jsx_runtime_1.jsx)(FocusLayout_1.FocusLayout, { trackRef: focusTrack })] }) }))), (0, jsx_runtime_1.jsx)(ControlBar_1.ControlBar, { controls: Object.assign({
96
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-video-conference" }, props, { children: [(0, components_core_1.isWeb)() && ((0, jsx_runtime_1.jsxs)(components_react_1.LayoutContextProvider, Object.assign({ value: layoutContext, onPinChange: handleFocusStateChange, onWidgetChange: widgetUpdate }, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: "lk-video-conference-inner" }, { children: [!focusTrack ? ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-grid-layout-wrapper" }, { children: (0, jsx_runtime_1.jsx)(components_react_1.GridLayout, Object.assign({ tracks: tracks }, { children: (0, jsx_runtime_1.jsx)(ParticipantTile_1.ParticipantTile, {}) })) }))) : ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: "lk-focus-layout-wrapper" }, { children: hideParticipantsList ? ((0, jsx_runtime_1.jsx)(FocusLayout_1.FocusLayoutContainerNoParticipants, { children: focusTrack && (0, jsx_runtime_1.jsx)(FocusLayout_1.FocusLayout, { trackRef: focusTrack }) })) : ((0, jsx_runtime_1.jsxs)(FocusLayout_1.FocusLayoutContainer, { children: [(0, jsx_runtime_1.jsx)(components_react_1.CarouselLayout, Object.assign({ tracks: carouselTracks }, { children: (0, jsx_runtime_1.jsx)(ParticipantTile_1.ParticipantTile, {}) })), focusTrack && (0, jsx_runtime_1.jsx)(FocusLayout_1.FocusLayout, { trackRef: focusTrack })] })) }))), (0, jsx_runtime_1.jsx)(ControlBar_1.ControlBar, { controls: Object.assign({
97
97
  chat: !disableChat,
98
98
  microphone: !disableMicrophone,
99
99
  camera: !disableCamera,
@@ -60,12 +60,13 @@ function useLivestreamCheck(warningThreshold = constants_1.WARNING_THRESHOLD_EXP
60
60
  console.log(participants.length);
61
61
  console.log('isExpiringSoon: ', isExpiringSoon);
62
62
  console.log('isExpired: ', isExpired);
63
- console.log('Checking participants...');
63
+ console.log('Checking participants...', participants.length);
64
+ console.log(participants);
64
65
  }
65
66
  if (participants.length <= 1) {
66
67
  isExpiringSoon ? setIsExpired(true) : setIsExpiringSoon(true);
67
68
  if (!isExpiringSoon && !isExpired && showWarnings) {
68
- enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.youAreAloneInTheRoom', defaultMessage: 'ui.liveStreamRoom.check.youAreAloneInTheRoom' }), { variant: 'warning', autoHideDuration: 20000 });
69
+ enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.youAreAloneInTheRoom', defaultMessage: 'ui.liveStreamRoom.check.youAreAloneInTheRoom' }), { variant: 'warning', autoHideDuration: 7000 });
69
70
  }
70
71
  else if (isExpired && performDisconnect) {
71
72
  // Leave the room
@@ -83,7 +84,7 @@ function useLivestreamCheck(warningThreshold = constants_1.WARNING_THRESHOLD_EXP
83
84
  if (!isExpiringSoon && !isExpired && liveStream.host.id !== scUserContext.user.id && showWarnings) {
84
85
  enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.hostMissing', defaultMessage: 'ui.liveStreamRoom.check.hostMissing' }), {
85
86
  variant: 'warning',
86
- autoHideDuration: 20000
87
+ autoHideDuration: 7000
87
88
  });
88
89
  }
89
90
  else if (isExpired && performDisconnect) {
@@ -94,7 +95,7 @@ function useLivestreamCheck(warningThreshold = constants_1.WARNING_THRESHOLD_EXP
94
95
  }
95
96
  __DEBUG && console.log('Checking live status resources...');
96
97
  fetchLivestreamStatus();
97
- }, [isExpired, isExpiringSoon, buttonProps]);
98
+ }, [isExpired, isExpiringSoon, buttonProps, participants]);
98
99
  (0, react_1.useEffect)(() => {
99
100
  intervalRef.current = setInterval(check, constants_1.LIVE_CHECKING_INTERVAL * 1000);
100
101
  return () => intervalRef.current && clearInterval(intervalRef.current);
@@ -179,5 +179,5 @@ export default function LiveStreamSelector(inProps) {
179
179
  }, theme: undefined }, { children: [_jsxs(Box, { children: [_jsx(Typography, Object.assign({ variant: "h6", component: "h2", sx: { fontWeight: 500 } }, { children: option.title })), _jsx(Radio, { checked: selectedOption === option.type })] }), _jsx("img", { src: option.image, alt: "logo" }), _jsx(Box, Object.assign({ component: "ul" }, { children: option.features.map((feature, featureIndex) => {
180
180
  const _Icon = option.icons[featureIndex];
181
181
  return (_jsxs(FeatureItem, Object.assign({ component: "li" }, { children: [_Icon, _jsx(Typography, Object.assign({ variant: "body2", color: "text.secondary", sx: { flex: 1 } }, { children: feature }))] }), featureIndex));
182
- }) }))] }), index))) })), _jsx(Box, Object.assign({ className: classes.actions }, { children: _jsx(Button, Object.assign({ disabled: !selectedOption || !timeRemaining, variant: "contained", onClick: handleNext, color: "secondary" }, { children: "Next" })) }))] })));
182
+ }) }))] }), index))) })), _jsx(Box, Object.assign({ className: classes.actions }, { children: _jsx(Button, Object.assign({ disabled: !selectedOption || !timeRemaining, variant: "contained", onClick: handleNext, color: "secondary" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamForm.selector.next", defaultMessage: "ui.liveStreamForm.selector.next" }) })) }))] })));
183
183
  }
@@ -4,7 +4,7 @@ import { Alert, Box, Button, CircularProgress, Stack, Typography } from '@mui/ma
4
4
  import { styled } from '@mui/material/styles';
5
5
  import { useThemeProps } from '@mui/system';
6
6
  import { Link, SCPreferences, useSCFetchLiveStream, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
7
- import { SCFeatureName } from '@selfcommunity/types';
7
+ import { SCFeatureName, SCLiveStreamConnectionDetailsErrorType } from '@selfcommunity/types';
8
8
  import classNames from 'classnames';
9
9
  import { FormattedMessage, useIntl } from 'react-intl';
10
10
  import { PREFIX } from './constants';
@@ -132,9 +132,15 @@ export default function LiveStreamRoom(inProps) {
132
132
  if (error.response.data.errors[0].code) {
133
133
  const _error = `ui.liveStreamRoom.connect.error.${camelCase(error.response.data.errors[0].code)}`;
134
134
  _msg = intl.formatMessage({ id: _error, defaultMessage: _error });
135
+ if (error.response.data.errors[0].code !== SCLiveStreamConnectionDetailsErrorType.WAITING_HOST_TO_START_LIVE_STREAM) {
136
+ setError(_msg);
137
+ }
138
+ enqueueSnackbar(_msg, { variant: 'error', autoHideDuration: 5000 });
139
+ }
140
+ else {
141
+ enqueueSnackbar(_msg, { variant: 'error' });
142
+ setError(_msg);
135
143
  }
136
- setError(_msg);
137
- enqueueSnackbar(_msg, { variant: 'error' });
138
144
  }
139
145
  setLoading(false);
140
146
  });
@@ -167,7 +173,7 @@ export default function LiveStreamRoom(inProps) {
167
173
  /**
168
174
  * Renders root object
169
175
  */
170
- return (_jsx(Root, Object.assign({ id: id, className: classNames(classes.root, className) }, rest, { children: scLiveStream.closed_at_by_host ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsxs(DialogContent, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.conference.closed", defaultMessage: "ui.liveStreamRoom.conference.closed" }) })), _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) }))] })) }))) : (_jsx(Box, Object.assign({ className: classes.content, "data-lk-theme": "default" }, { children: connectionDetails === undefined || preJoinChoices === undefined ? (_jsxs(_Fragment, { children: [startPrejoinContent && _jsx(Box, Object.assign({ className: classes.startPrejoinContent }, { children: startPrejoinContent })), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title) && (_jsx(Typography, Object.assign({ component: 'div', variant: "h5", className: classes.title }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title }))), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description) && (_jsx(Typography, Object.assign({ component: 'div', variant: "body1", className: classes.description }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description }))), _jsxs(Box, Object.assign({ className: classNames(classes.preJoin, { [classes.preJoinLoading]: loading || error }) }, { children: [_jsx(LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: _jsx(PreJoin, { defaults: preJoinDefaults, onSubmit: handlePreJoinSubmit, onError: handlePreJoinError }) })), loading && (_jsxs(Box, Object.assign({ className: classes.prejoinLoader }, { children: [_jsx(CircularProgress, {}), _jsx(Typography, Object.assign({ component: 'div', variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.connecting", defaultMessage: "ui.liveStreamRoom.connecting" }) }))] })))] })), _jsxs(Box, Object.assign({ className: classes.endPrejoinContent }, { children: [Boolean(scUserContext.user &&
176
+ return (_jsx(Root, Object.assign({ id: id, className: classNames(classes.root, className) }, rest, { children: scLiveStream.closed_at_by_host ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsxs(DialogContent, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.conference.closed", defaultMessage: "ui.liveStreamRoom.conference.closed" }) })), _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) }))] })) }))) : (_jsx(Box, Object.assign({ className: classes.content, "data-lk-theme": "default" }, { children: connectionDetails === undefined || preJoinChoices === undefined ? (_jsxs(_Fragment, { children: [startPrejoinContent && _jsx(Box, Object.assign({ className: classes.startPrejoinContent }, { children: startPrejoinContent })), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title) && (_jsx(Typography, Object.assign({ component: 'div', variant: "h5", className: classes.title }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title }))), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description) && (_jsx(Typography, Object.assign({ component: 'div', variant: "body1", className: classes.description }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description }))), _jsxs(Box, Object.assign({ className: classNames(classes.preJoin, { [classes.preJoinLoading]: loading || error }) }, { children: [_jsx(LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: _jsx(PreJoin, { defaults: preJoinDefaults, onSubmit: handlePreJoinSubmit, onError: handlePreJoinError, joinLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.joinRoom', defaultMessage: 'ui.liveStreamRoom.preJoin.joinRoom' }), micLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.microphone', defaultMessage: 'ui.liveStreamRoom.preJoin.microphone' }), camLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.camera', defaultMessage: 'ui.liveStreamRoom.preJoin.camera' }), userLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.username', defaultMessage: 'ui.liveStreamRoom.preJoin.username' }) }) })), loading && (_jsxs(Box, Object.assign({ className: classes.prejoinLoader }, { children: [_jsx(CircularProgress, {}), _jsx(Typography, Object.assign({ component: 'div', variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.connecting", defaultMessage: "ui.liveStreamRoom.connecting" }) }))] })))] })), _jsxs(Box, Object.assign({ className: classes.endPrejoinContent }, { children: [Boolean(scUserContext.user &&
171
177
  scUserContext.user.id !== scLiveStream.host.id &&
172
178
  scLiveStream &&
173
179
  (((_a = scLiveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants) || (scLiveStream && ((_b = scLiveStream.settings) === null || _b === void 0 ? void 0 : _b.disableVideo)))) && (_jsxs(Stack, Object.assign({ sx: { width: '60%' }, spacing: 1 }, { children: [scLiveStream && ((_c = scLiveStream.settings) === null || _c === void 0 ? void 0 : _c.muteParticipants) && (_jsx(Alert, Object.assign({ variant: "filled", severity: "info", component: 'div' }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.hostDisableMicrophone", defaultMessage: "ui.liveStreamRoom.hostDisableMicrophone" }) }))), scLiveStream && ((_d = scLiveStream.settings) === null || _d === void 0 ? void 0 : _d.disableVideo) && (_jsx(Alert, Object.assign({ variant: "filled", severity: "info" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.hostDisableVideo", defaultMessage: "ui.liveStreamRoom.hostDisableVideo" }) })))] }))), endPrejoinContent] }))] })) : (_jsx(Box, Object.assign({ className: classes.conference }, { children: _jsx(LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: _jsx(LiveStreamVideoConference, Object.assign({ connectionDetails: connectionDetails, userChoices: preJoinChoices }, LiveStreamVideoConferenceComponentProps)) })) }))) }))) })));
@@ -28,8 +28,13 @@ export const DisconnectButton =
28
28
  * Intercept fist leave action
29
29
  */
30
30
  const handleOnLeave = useCallback(() => {
31
- setOpenConfirmDialog(true);
32
- }, [setOpenConfirmDialog]);
31
+ if (liveStream && scUserContext.user.id === liveStream.host.id) {
32
+ setOpenConfirmDialog(true);
33
+ }
34
+ else {
35
+ onClick === null || onClick === void 0 ? void 0 : onClick();
36
+ }
37
+ }, [setOpenConfirmDialog, liveStream, scUserContext.user]);
33
38
  /**
34
39
  * Control close live
35
40
  */
@@ -9,6 +9,7 @@ export type FocusLayoutContainerProps = React.HTMLAttributes<HTMLDivElement>;
9
9
  * For example, with the `FocusLayout` component.
10
10
  */
11
11
  export declare function FocusLayoutContainer(props: FocusLayoutContainerProps): JSX.Element;
12
+ export declare function FocusLayoutContainerNoParticipants(props: FocusLayoutContainerProps): JSX.Element;
12
13
  export interface FocusLayoutProps extends React.HTMLAttributes<HTMLElement> {
13
14
  /** The track to display in the focus layout. */
14
15
  trackRef?: TrackReferenceOrPlaceholder;
@@ -12,6 +12,10 @@ export function FocusLayoutContainer(props) {
12
12
  const elementProps = mergeProps(props, { className: 'lk-focus-layout' });
13
13
  return _jsx("div", Object.assign({}, elementProps, { children: props.children }));
14
14
  }
15
+ export function FocusLayoutContainerNoParticipants(props) {
16
+ const elementProps = mergeProps(props, { className: 'lk-focus-layout' });
17
+ return (_jsx("div", Object.assign({}, elementProps, { style: { gridTemplateColumns: 'none' } }, { children: props.children })));
18
+ }
15
19
  /**
16
20
  * The `FocusLayout` component is just a light wrapper around the `ParticipantTile` to display a single participant.
17
21
  */
@@ -16,6 +16,7 @@ import { VideoConference } from './VideoConference';
16
16
  import { useLiveStream } from './LiveStreamProvider';
17
17
  import DialogContent from '@mui/material/DialogContent';
18
18
  import BaseDialog from '../../../shared/BaseDialog';
19
+ import { closeSnackbar } from 'notistack';
19
20
  const classes = {
20
21
  root: `${PREFIX}-root`,
21
22
  logo: `${PREFIX}-logo`,
@@ -84,7 +85,7 @@ export default function LiveStreamVideoConference(inProps) {
84
85
  const canUseChat = useMemo(() => { var _a; return scUserContext.user && liveStream && liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableChat); }, [scUserContext, liveStream]);
85
86
  const canUseShareScreen = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableShareScreen))); }, [scUserContext, liveStream]);
86
87
  const speakerFocused = useMemo(() => (scUserContext.user && liveStream && liveStream.settings.view === SCLiveStreamViewType.SPEAKER ? liveStream.host : null), [scUserContext, liveStream]);
87
- const hideParticipantsList = useMemo(() => { var _a; return scUserContext.user && liveStream && liveStream.host.id !== scUserContext.user.id && liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.hideParticipantList); }, [scUserContext, liveStream]);
88
+ const hideParticipantsList = useMemo(() => { var _a; return scUserContext.user && liveStream && ((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.hideParticipantsList) && liveStream.host.id !== scUserContext.user.id; }, [scUserContext, liveStream]);
88
89
  // CONNECT OPTIONS
89
90
  const connectOptions = useMemo(() => {
90
91
  return {
@@ -117,6 +118,9 @@ export default function LiveStreamVideoConference(inProps) {
117
118
  setError(`Encountered an unexpected encryption error, check the console logs for details: ${error.message}`);
118
119
  setLiveActive(false);
119
120
  }, []);
121
+ const handleBackHome = useCallback(() => {
122
+ closeSnackbar();
123
+ }, [closeSnackbar]);
120
124
  /**
121
125
  * User must be authenticated
122
126
  */
@@ -126,5 +130,5 @@ export default function LiveStreamVideoConference(inProps) {
126
130
  /**
127
131
  * Renders root object
128
132
  */
129
- return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: liveActive && !error ? (_jsx(_Fragment, { children: _jsx(LiveKitRoom, Object.assign({ connect: Boolean(liveActive), token: connectionDetails['participantToken'], serverUrl: connectionDetails['serverUrl'], connectOptions: connectOptions, video: userChoices.videoEnabled, audio: userChoices.audioEnabled, onDisconnected: handleOnLeave, onEncryptionError: handleEncryptionError, onError: handleError }, LiveKitRoomComponentProps, { children: _jsxs(LayoutContextProvider, { children: [_jsx(VideoConference, Object.assign({ chatMessageFormatter: formatChatMessageLinks }, (speakerFocused && { speakerFocused: liveStream.host }), VideoConferenceComponentProps, { disableMicrophone: !canUseAudio, disableCamera: !canUseVideo, disableChat: !canUseChat, disableShareScreen: !canUseShareScreen, hideParticipantsList: hideParticipantsList })), _jsx(ConnectionState, {})] }) })) })) : (_jsx(_Fragment, { children: error ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, error, _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : liveActive === false ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.conference.end", defaultMessage: "ui.liveStreamRoom.conference.end" }) })), _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : (_jsx(CircularProgress, {})) })) })));
133
+ return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: liveActive && !error ? (_jsx(_Fragment, { children: _jsx(LiveKitRoom, Object.assign({ connect: Boolean(liveActive), token: connectionDetails['participantToken'], serverUrl: connectionDetails['serverUrl'], connectOptions: connectOptions, video: userChoices.videoEnabled, audio: userChoices.audioEnabled, onDisconnected: handleOnLeave, onEncryptionError: handleEncryptionError, onError: handleError }, LiveKitRoomComponentProps, { children: _jsxs(LayoutContextProvider, { children: [_jsx(VideoConference, Object.assign({ chatMessageFormatter: formatChatMessageLinks }, (speakerFocused && { speakerFocused: liveStream.host }), VideoConferenceComponentProps, { disableMicrophone: !canUseAudio, disableCamera: !canUseVideo, disableChat: !canUseChat, disableShareScreen: !canUseShareScreen, hideParticipantsList: hideParticipantsList })), _jsx(ConnectionState, {})] }) })) })) : (_jsx(_Fragment, { children: error ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, error, _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : liveActive === false ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.conference.end", defaultMessage: "ui.liveStreamRoom.conference.end" }) })), _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', onClick: handleBackHome, className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : (_jsx(CircularProgress, {})) })) })));
130
134
  }
@@ -55,7 +55,7 @@ export const ParticipantTile =
55
55
  return (_jsx("div", Object.assign({ ref: ref, style: { position: 'relative' } }, elementProps, { children: _jsx(TrackRefContextIfNeeded, Object.assign({ trackRef: trackReference }, { children: _jsxs(ParticipantContextIfNeeded, Object.assign({ participant: trackReference.participant }, { children: [children !== null && children !== void 0 ? children : (_jsxs(_Fragment, { children: [isTrackReference(trackReference) &&
56
56
  (((_c = trackReference.publication) === null || _c === void 0 ? void 0 : _c.kind) === 'video' ||
57
57
  trackReference.source === Track.Source.Camera ||
58
- trackReference.source === Track.Source.ScreenShare) ? (_jsx(_Fragment, { children: _jsx(VideoTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe, manageSubscription: autoManageSubscription }) })) : (isTrackReference(trackReference) && (_jsx(_Fragment, { children: _jsx(AudioTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe }) }))), _jsx("div", Object.assign({ className: "lk-participant-placeholder" }, { children: _jsx(ParticipantTileAvatar, Object.assign({}, ((liveStream === null || liveStream === void 0 ? void 0 : liveStream.host.id) !== scUserContext.user.id ? { participant: trackReference.participant } : { user: scUserContext.user }))) })), _jsxs("div", Object.assign({ className: "lk-participant-metadata" }, { children: [_jsx("div", Object.assign({ className: "lk-participant-metadata-item" }, { children: trackReference.source === Track.Source.Camera ? (_jsxs(_Fragment, { children: [isEncrypted && _jsx(LockLockedIcon, { style: { marginRight: '0.25rem' } }), _jsx(TrackMutedIndicator, { trackRef: {
58
+ trackReference.source === Track.Source.ScreenShare) ? (_jsx(_Fragment, { children: _jsx(VideoTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe, manageSubscription: autoManageSubscription }) })) : (isTrackReference(trackReference) && (_jsx(_Fragment, { children: _jsx(AudioTrack, { trackRef: trackReference, onSubscriptionStatusChanged: handleSubscribe }) }))), _jsx("div", Object.assign({ className: "lk-participant-placeholder" }, { children: _jsx(ParticipantTileAvatar, { participant: trackReference.participant }) })), _jsxs("div", Object.assign({ className: "lk-participant-metadata" }, { children: [_jsx("div", Object.assign({ className: "lk-participant-metadata-item" }, { children: trackReference.source === Track.Source.Camera ? (_jsxs(_Fragment, { children: [isEncrypted && _jsx(LockLockedIcon, { style: { marginRight: '0.25rem' } }), _jsx(TrackMutedIndicator, { trackRef: {
59
59
  participant: trackReference.participant,
60
60
  source: Track.Source.Microphone
61
61
  }, show: 'muted' }), _jsx(ParticipantName, { children: !disableTileActions && _jsx(ParticipantTileActions, {}) })] })) : (_jsxs(_Fragment, { children: [_jsx(ScreenShareIcon, { style: { marginRight: '0.25rem' } }), _jsx(ParticipantName, { children: "'s screen" })] })) })), _jsx(ConnectionQualityIndicator, { className: "lk-participant-metadata-item" })] }))] })), _jsx(FocusToggle, { trackRef: trackReference })] })) })) })));
@@ -7,7 +7,7 @@ import { defaultUserChoices } from '@livekit/components-core';
7
7
  import { MediaDeviceMenu, useMediaDevices, usePersistentUserChoices } from '@livekit/components-react';
8
8
  import { useSCUser } from '@selfcommunity/react-core';
9
9
  import ParticipantTileAvatar from './ParticipantTileAvatar';
10
- import { useMemo } from 'react';
10
+ import { useEffect, useMemo } from 'react';
11
11
  import { TrackToggle } from './TrackToggle';
12
12
  import { useLiveStream } from './LiveStreamProvider';
13
13
  /** @alpha */
@@ -150,6 +150,7 @@ export function usePreviewDevice(enabled, deviceId, kind) {
150
150
  export function PreJoin(_a) {
151
151
  var { defaults = {}, onValidate, onSubmit, onError, debug, joinLabel = 'Join Room', micLabel = 'Microphone', camLabel = 'Camera', userLabel = 'Username', persistUserChoices = true } = _a, htmlProps = __rest(_a, ["defaults", "onValidate", "onSubmit", "onError", "debug", "joinLabel", "micLabel", "camLabel", "userLabel", "persistUserChoices"]);
152
152
  const { liveStream } = useLiveStream();
153
+ const scUserContext = useSCUser();
153
154
  const [userChoices, setUserChoices] = React.useState(defaultUserChoices);
154
155
  // TODO: Remove and pipe `defaults` object directly into `usePersistentUserChoices` once we fully switch from type `LocalUserChoices` to `UserChoices`.
155
156
  const partialDefaults = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (defaults.audioDeviceId !== undefined && { audioDeviceId: defaults.audioDeviceId })), (defaults.videoDeviceId !== undefined && { videoDeviceId: defaults.videoDeviceId })), (defaults.audioEnabled !== undefined && { audioEnabled: defaults.audioEnabled })), (defaults.videoEnabled !== undefined && { videoEnabled: defaults.videoEnabled })), (defaults.username !== undefined && { username: defaults.username }));
@@ -178,13 +179,14 @@ export function PreJoin(_a) {
178
179
  saveVideoInputDeviceId(videoDeviceId);
179
180
  }, [videoDeviceId, saveVideoInputDeviceId]);
180
181
  React.useEffect(() => {
181
- saveUsername(username);
182
- }, [username, saveUsername]);
182
+ if (scUserContext.user) {
183
+ saveUsername(scUserContext.user.username);
184
+ }
185
+ }, [username, saveUsername, scUserContext.user]);
183
186
  const tracks = usePreviewTracks({
184
187
  audio: audioEnabled ? { deviceId: initialUserChoices.audioDeviceId } : false,
185
188
  video: videoEnabled ? { deviceId: initialUserChoices.videoDeviceId } : false
186
189
  }, onError);
187
- const scUserContext = useSCUser();
188
190
  const videoEl = React.useRef(null);
189
191
  const videoTrack = React.useMemo(() => tracks === null || tracks === void 0 ? void 0 : tracks.filter((track) => track.kind === Track.Kind.Video)[0], [tracks]);
190
192
  const facingMode = React.useMemo(() => {
@@ -215,7 +217,7 @@ export function PreJoin(_a) {
215
217
  return values.username !== '';
216
218
  }
217
219
  }, [onValidate]);
218
- React.useEffect(() => {
220
+ useEffect(() => {
219
221
  const newUserChoices = {
220
222
  username,
221
223
  videoEnabled,
@@ -225,7 +227,7 @@ export function PreJoin(_a) {
225
227
  };
226
228
  setUserChoices(newUserChoices);
227
229
  setIsValid(handleValidation(newUserChoices));
228
- }, [username, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
230
+ }, [username, scUserContext.user, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
229
231
  function handleSubmit(event) {
230
232
  event.preventDefault();
231
233
  if (handleValidation(userChoices)) {
@@ -239,5 +241,5 @@ export function PreJoin(_a) {
239
241
  }
240
242
  const canUseAudio = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants))); }, [scUserContext, liveStream]);
241
243
  const canUseVideo = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableVideo))); }, [scUserContext, liveStream]);
242
- return (_jsxs("div", Object.assign({ className: "lk-prejoin" }, htmlProps, { children: [_jsxs("div", Object.assign({ className: "lk-video-container" }, { children: [videoTrack && _jsx("video", { ref: videoEl, width: "1280", height: "720", "data-lk-facing-mode": facingMode }), (!videoTrack || !videoEnabled) && (_jsx("div", Object.assign({ className: "lk-camera-off-note" }, { children: _jsx(ParticipantTileAvatar, { user: scUserContext.user }) })))] })), _jsxs("div", Object.assign({ className: "lk-button-group-container" }, { children: [_jsxs("div", Object.assign({ className: "lk-button-group audio" }, { children: [_jsx(TrackToggle, Object.assign({ disabled: !canUseAudio, initialState: audioEnabled, source: Track.Source.Microphone, onChange: (enabled) => setAudioEnabled(enabled) }, { children: micLabel })), _jsx("div", Object.assign({ className: "lk-button-group-menu" }, { children: _jsx(MediaDeviceMenu, { initialSelection: audioDeviceId, kind: "audioinput", disabled: !audioTrack || !canUseAudio, tracks: { audioinput: audioTrack }, onActiveDeviceChange: (_, id) => setAudioDeviceId(id) }) }))] })), _jsxs("div", Object.assign({ className: "lk-button-group video" }, { children: [_jsx(TrackToggle, Object.assign({ disabled: !canUseVideo, initialState: videoEnabled, source: Track.Source.Camera, onChange: (enabled) => setVideoEnabled(enabled) }, { children: camLabel })), _jsx("div", Object.assign({ className: "lk-button-group-menu" }, { children: _jsx(MediaDeviceMenu, { initialSelection: videoDeviceId, kind: "videoinput", disabled: !videoTrack || !canUseVideo, tracks: { videoinput: videoTrack }, onActiveDeviceChange: (_, id) => setVideoDeviceId(id) }) }))] }))] })), _jsxs("form", Object.assign({ className: "lk-username-container" }, { children: [_jsx("input", { className: "lk-form-control", id: "username", name: "username", type: "text", defaultValue: username, placeholder: userLabel, onChange: (inputEl) => setUsername(inputEl.target.value), autoComplete: "off" }), _jsx("button", Object.assign({ className: "lk-button lk-join-button", type: "submit", onClick: handleSubmit, disabled: !isValid }, { children: joinLabel }))] })), debug && (_jsxs(_Fragment, { children: [_jsx("strong", { children: "User Choices:" }), _jsxs("ul", Object.assign({ className: "lk-list", style: { overflow: 'hidden', maxWidth: '15rem' } }, { children: [_jsxs("li", { children: ["Username: ", `${userChoices.username}`] }), _jsxs("li", { children: ["Video Enabled: ", `${userChoices.videoEnabled}`] }), _jsxs("li", { children: ["Audio Enabled: ", `${userChoices.audioEnabled}`] }), _jsxs("li", { children: ["Video Device: ", `${userChoices.videoDeviceId}`] }), _jsxs("li", { children: ["Audio Device: ", `${userChoices.audioDeviceId}`] })] }))] }))] })));
244
+ return (_jsxs("div", Object.assign({ className: "lk-prejoin" }, htmlProps, { children: [_jsxs("div", Object.assign({ className: "lk-video-container" }, { children: [videoTrack && _jsx("video", { ref: videoEl, width: "1280", height: "720", "data-lk-facing-mode": facingMode }), (!videoTrack || !videoEnabled) && (_jsx("div", Object.assign({ className: "lk-camera-off-note" }, { children: _jsx(ParticipantTileAvatar, { user: scUserContext.user }) })))] })), _jsxs("div", Object.assign({ className: "lk-button-group-container" }, { children: [_jsxs("div", Object.assign({ className: "lk-button-group audio" }, { children: [_jsx(TrackToggle, Object.assign({ disabled: !canUseAudio, initialState: audioEnabled, source: Track.Source.Microphone, onChange: (enabled) => setAudioEnabled(enabled) }, { children: micLabel })), _jsx("div", Object.assign({ className: "lk-button-group-menu" }, { children: _jsx(MediaDeviceMenu, { initialSelection: audioDeviceId, kind: "audioinput", disabled: !audioTrack || !canUseAudio, tracks: { audioinput: audioTrack }, onActiveDeviceChange: (_, id) => setAudioDeviceId(id) }) }))] })), _jsxs("div", Object.assign({ className: "lk-button-group video" }, { children: [_jsx(TrackToggle, Object.assign({ disabled: !canUseVideo, initialState: videoEnabled, source: Track.Source.Camera, onChange: (enabled) => setVideoEnabled(enabled) }, { children: camLabel })), _jsx("div", Object.assign({ className: "lk-button-group-menu" }, { children: _jsx(MediaDeviceMenu, { initialSelection: videoDeviceId, kind: "videoinput", disabled: !videoTrack || !canUseVideo, tracks: { videoinput: videoTrack }, onActiveDeviceChange: (_, id) => setVideoDeviceId(id) }) }))] }))] })), _jsx("form", Object.assign({ className: "lk-username-container" }, { children: _jsx("button", Object.assign({ className: "lk-button lk-join-button", type: "submit", onClick: handleSubmit, disabled: !isValid }, { children: joinLabel })) })), debug && (_jsxs(_Fragment, { children: [_jsx("strong", { children: "User Choices:" }), _jsxs("ul", Object.assign({ className: "lk-list", style: { overflow: 'hidden', maxWidth: '15rem' } }, { children: [_jsxs("li", { children: ["Username: ", `${userChoices.username}`] }), _jsxs("li", { children: ["Video Enabled: ", `${userChoices.videoEnabled}`] }), _jsxs("li", { children: ["Audio Enabled: ", `${userChoices.audioEnabled}`] }), _jsxs("li", { children: ["Video Device: ", `${userChoices.videoDeviceId}`] }), _jsxs("li", { children: ["Audio Device: ", `${userChoices.audioDeviceId}`] })] }))] }))] })));
243
245
  }
@@ -8,7 +8,7 @@ import { ParticipantTile } from './ParticipantTile';
8
8
  import { ControlBar } from './ControlBar';
9
9
  import { useEffect } from 'react';
10
10
  import { useLivestreamCheck } from './useLiveStreamCheck';
11
- import { FocusLayout, FocusLayoutContainer } from './FocusLayout';
11
+ import { FocusLayout, FocusLayoutContainer, FocusLayoutContainerNoParticipants } from './FocusLayout';
12
12
  /**
13
13
  * The `VideoConference` ready-made component is your drop-in solution for a classic video conferencing application.
14
14
  * It provides functionality such as focusing on one participant, grid view with pagination to handle large numbers
@@ -90,7 +90,7 @@ export function VideoConference(_a) {
90
90
  participants,
91
91
  speakerFocused
92
92
  ]);
93
- return (_jsxs("div", Object.assign({ className: "lk-video-conference" }, props, { children: [isWeb() && (_jsxs(LayoutContextProvider, Object.assign({ value: layoutContext, onPinChange: handleFocusStateChange, onWidgetChange: widgetUpdate }, { children: [_jsxs("div", Object.assign({ className: "lk-video-conference-inner" }, { children: [!focusTrack ? (_jsx("div", Object.assign({ className: "lk-grid-layout-wrapper" }, { children: _jsx(GridLayout, Object.assign({ tracks: tracks }, { children: _jsx(ParticipantTile, {}) })) }))) : (_jsx("div", Object.assign({ className: "lk-focus-layout-wrapper" }, { children: _jsxs(FocusLayoutContainer, { children: [!hideParticipantsList && (_jsx(CarouselLayout, Object.assign({ tracks: carouselTracks }, { children: _jsx(ParticipantTile, {}) }))), focusTrack && _jsx(FocusLayout, { trackRef: focusTrack })] }) }))), _jsx(ControlBar, { controls: Object.assign({
93
+ return (_jsxs("div", Object.assign({ className: "lk-video-conference" }, props, { children: [isWeb() && (_jsxs(LayoutContextProvider, Object.assign({ value: layoutContext, onPinChange: handleFocusStateChange, onWidgetChange: widgetUpdate }, { children: [_jsxs("div", Object.assign({ className: "lk-video-conference-inner" }, { children: [!focusTrack ? (_jsx("div", Object.assign({ className: "lk-grid-layout-wrapper" }, { children: _jsx(GridLayout, Object.assign({ tracks: tracks }, { children: _jsx(ParticipantTile, {}) })) }))) : (_jsx("div", Object.assign({ className: "lk-focus-layout-wrapper" }, { children: hideParticipantsList ? (_jsx(FocusLayoutContainerNoParticipants, { children: focusTrack && _jsx(FocusLayout, { trackRef: focusTrack }) })) : (_jsxs(FocusLayoutContainer, { children: [_jsx(CarouselLayout, Object.assign({ tracks: carouselTracks }, { children: _jsx(ParticipantTile, {}) })), focusTrack && _jsx(FocusLayout, { trackRef: focusTrack })] })) }))), _jsx(ControlBar, { controls: Object.assign({
94
94
  chat: !disableChat,
95
95
  microphone: !disableMicrophone,
96
96
  camera: !disableCamera,
@@ -57,12 +57,13 @@ export function useLivestreamCheck(warningThreshold = WARNING_THRESHOLD_EXPIRING
57
57
  console.log(participants.length);
58
58
  console.log('isExpiringSoon: ', isExpiringSoon);
59
59
  console.log('isExpired: ', isExpired);
60
- console.log('Checking participants...');
60
+ console.log('Checking participants...', participants.length);
61
+ console.log(participants);
61
62
  }
62
63
  if (participants.length <= 1) {
63
64
  isExpiringSoon ? setIsExpired(true) : setIsExpiringSoon(true);
64
65
  if (!isExpiringSoon && !isExpired && showWarnings) {
65
- enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.youAreAloneInTheRoom', defaultMessage: 'ui.liveStreamRoom.check.youAreAloneInTheRoom' }), { variant: 'warning', autoHideDuration: 20000 });
66
+ enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.youAreAloneInTheRoom', defaultMessage: 'ui.liveStreamRoom.check.youAreAloneInTheRoom' }), { variant: 'warning', autoHideDuration: 7000 });
66
67
  }
67
68
  else if (isExpired && performDisconnect) {
68
69
  // Leave the room
@@ -80,7 +81,7 @@ export function useLivestreamCheck(warningThreshold = WARNING_THRESHOLD_EXPIRING
80
81
  if (!isExpiringSoon && !isExpired && liveStream.host.id !== scUserContext.user.id && showWarnings) {
81
82
  enqueueSnackbar(intl.formatMessage({ id: 'ui.liveStreamRoom.check.hostMissing', defaultMessage: 'ui.liveStreamRoom.check.hostMissing' }), {
82
83
  variant: 'warning',
83
- autoHideDuration: 20000
84
+ autoHideDuration: 7000
84
85
  });
85
86
  }
86
87
  else if (isExpired && performDisconnect) {
@@ -91,7 +92,7 @@ export function useLivestreamCheck(warningThreshold = WARNING_THRESHOLD_EXPIRING
91
92
  }
92
93
  __DEBUG && console.log('Checking live status resources...');
93
94
  fetchLivestreamStatus();
94
- }, [isExpired, isExpiringSoon, buttonProps]);
95
+ }, [isExpired, isExpiringSoon, buttonProps, participants]);
95
96
  useEffect(() => {
96
97
  intervalRef.current = setInterval(check, LIVE_CHECKING_INTERVAL * 1000);
97
98
  return () => intervalRef.current && clearInterval(intervalRef.current);