@selfcommunity/react-ui 0.8.0-live.58 → 0.8.0-live.59
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/lib/cjs/components/CreateLiveStreamDialog/CreateLiveStreamDialog.js +8 -7
- package/lib/cjs/components/EventForm/EventAddress.js +7 -6
- package/lib/cjs/components/EventForm/EventForm.d.ts +6 -1
- package/lib/cjs/components/EventForm/EventForm.js +27 -9
- package/lib/cjs/components/EventForm/types.d.ts +2 -1
- package/lib/cjs/components/LiveStreamForm/LiveStreamFormSettings.d.ts +2 -1
- package/lib/cjs/components/LiveStreamForm/LiveStreamFormSettings.js +1 -1
- package/lib/cjs/components/LiveStreamForm/constants.d.ts +3 -0
- package/lib/cjs/components/LiveStreamForm/constants.js +6 -3
- package/lib/cjs/components/LiveStreamRoom/LiveStreamRoom.js +12 -6
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.js +5 -1
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.d.ts +6 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +8 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.d.ts +27 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +65 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.d.ts +26 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.js +194 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.d.ts +15 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +38 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.d.ts +61 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +247 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.d.ts +23 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.js +31 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +4 -3
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +5 -4
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/constants.d.ts +1 -0
- package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/constants.js +2 -1
- package/lib/esm/components/CreateLiveStreamDialog/CreateLiveStreamDialog.js +2 -1
- package/lib/esm/components/EventForm/EventAddress.js +7 -6
- package/lib/esm/components/EventForm/EventForm.d.ts +6 -1
- package/lib/esm/components/EventForm/EventForm.js +27 -9
- package/lib/esm/components/EventForm/types.d.ts +2 -1
- package/lib/esm/components/LiveStreamForm/LiveStreamFormSettings.d.ts +2 -1
- package/lib/esm/components/LiveStreamForm/LiveStreamFormSettings.js +1 -1
- package/lib/esm/components/LiveStreamForm/constants.d.ts +3 -0
- package/lib/esm/components/LiveStreamForm/constants.js +6 -3
- package/lib/esm/components/LiveStreamRoom/LiveStreamRoom.js +13 -7
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.js +5 -1
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.d.ts +6 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +6 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.d.ts +27 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +60 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.d.ts +26 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.js +191 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.d.ts +15 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +35 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.d.ts +61 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +241 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.d.ts +23 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.js +27 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +4 -3
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +6 -5
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/constants.d.ts +1 -0
- package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/constants.js +1 -0
- package/lib/umd/react-ui.js +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const styles_1 = require("@mui/material/styles");
|
|
7
|
+
const react_intl_1 = require("react-intl");
|
|
8
|
+
const Popper_1 = tslib_1.__importDefault(require("@mui/material/Popper"));
|
|
9
|
+
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
|
|
10
|
+
const notistack_1 = require("notistack");
|
|
11
|
+
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|
12
|
+
const material_1 = require("@mui/material");
|
|
13
|
+
const api_services_1 = require("@selfcommunity/api-services");
|
|
14
|
+
const react_core_1 = require("@selfcommunity/react-core");
|
|
15
|
+
const constants_1 = require("./constants");
|
|
16
|
+
const ConfirmDialog_1 = tslib_1.__importDefault(require("../../../shared/ConfirmDialog/ConfirmDialog"));
|
|
17
|
+
const components_react_1 = require("@livekit/components-react");
|
|
18
|
+
const PREFIX = 'SCParticipantTileActionsMenu';
|
|
19
|
+
const classes = {
|
|
20
|
+
root: `${PREFIX}-root`,
|
|
21
|
+
button: `${PREFIX}-button`,
|
|
22
|
+
popperRoot: `${PREFIX}-popper-root`,
|
|
23
|
+
paper: `${PREFIX}-paper`,
|
|
24
|
+
item: `${PREFIX}-item`,
|
|
25
|
+
itemText: `${PREFIX}-item-text`,
|
|
26
|
+
subItem: `${PREFIX}-sub-item`,
|
|
27
|
+
subItemText: `${PREFIX}-sub-item-text`,
|
|
28
|
+
footerSubItems: `${PREFIX}-footer-sub-items`,
|
|
29
|
+
selectedIcon: `${PREFIX}-selected-icon`,
|
|
30
|
+
sectionBadge: `${PREFIX}-section-badge`,
|
|
31
|
+
sectionWithSelectionIcon: `${PREFIX}-section-with-selection-icon`,
|
|
32
|
+
visibilityIcons: `${PREFIX}-visibility-icons`
|
|
33
|
+
};
|
|
34
|
+
const PopperRoot = (0, styles_1.styled)(Popper_1.default, {
|
|
35
|
+
name: PREFIX,
|
|
36
|
+
slot: 'Root',
|
|
37
|
+
overridesResolver: (props, styles) => styles.popperRoot
|
|
38
|
+
})(() => ({
|
|
39
|
+
'& .SCParticipantTileActionsMenu-paper': {
|
|
40
|
+
borderRadius: 5
|
|
41
|
+
}
|
|
42
|
+
}));
|
|
43
|
+
const Root = (0, styles_1.styled)(material_1.Box, {
|
|
44
|
+
name: PREFIX,
|
|
45
|
+
slot: 'Root',
|
|
46
|
+
overridesResolver: (props, styles) => styles.root
|
|
47
|
+
})(({ theme }) => ({
|
|
48
|
+
display: 'inline-block',
|
|
49
|
+
'& button': {
|
|
50
|
+
color: theme.palette.common.white
|
|
51
|
+
}
|
|
52
|
+
}));
|
|
53
|
+
function ContributionActionsMenu(props) {
|
|
54
|
+
// PROPS
|
|
55
|
+
const { className, participant, onBanParticipant, PopperProps = {} } = props, rest = tslib_1.__rest(props, ["className", "participant", "onBanParticipant", "PopperProps"]);
|
|
56
|
+
// INTL
|
|
57
|
+
const intl = (0, react_intl_1.useIntl)();
|
|
58
|
+
// CONTEXT
|
|
59
|
+
const theme = (0, material_1.useTheme)();
|
|
60
|
+
const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md'));
|
|
61
|
+
const scContext = (0, react_1.useContext)(react_core_1.SCContext);
|
|
62
|
+
const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
|
|
63
|
+
const scUserId = scUserContext.user ? scUserContext.user.id : null;
|
|
64
|
+
const scRoutingContext = (0, react_core_1.useSCRouting)();
|
|
65
|
+
const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
|
|
66
|
+
const p = (0, components_react_1.useEnsureParticipant)(participant);
|
|
67
|
+
// GENERAL POPPER STATE
|
|
68
|
+
const [open, setOpen] = (0, react_1.useState)(false);
|
|
69
|
+
const [isLoading, setIsLoading] = (0, react_1.useState)(false);
|
|
70
|
+
// CONFIRM ACTION DIALOG STATE
|
|
71
|
+
const [openConfirmDialog, setOpenConfirmDialog] = (0, react_1.useState)(false);
|
|
72
|
+
const [currentAction, setCurrentAction] = (0, react_1.useState)(null);
|
|
73
|
+
const [currentActionLoading, setCurrentActionLoading] = (0, react_1.useState)(null);
|
|
74
|
+
// CONST
|
|
75
|
+
let popperRef = (0, react_1.useRef)(null);
|
|
76
|
+
/**
|
|
77
|
+
* Handles open popup
|
|
78
|
+
*/
|
|
79
|
+
function handleOpen() {
|
|
80
|
+
if (scUserContext.user) {
|
|
81
|
+
setOpen(true);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
scContext.settings.handleAnonymousAction();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Closes popup
|
|
89
|
+
*/
|
|
90
|
+
function handleClose() {
|
|
91
|
+
if (popperRef.current && popperRef.current.contains(event.target)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
setOpen(false);
|
|
95
|
+
if (rest.onClose) {
|
|
96
|
+
rest.onClose();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Perform delete contribution
|
|
101
|
+
*/
|
|
102
|
+
const performBanParticipant = (0, react_1.useMemo)(() => () => {
|
|
103
|
+
return api_services_1.http
|
|
104
|
+
.request({
|
|
105
|
+
url: api_services_1.Endpoints.DeleteComment.url({ id: p.identity }),
|
|
106
|
+
method: api_services_1.Endpoints.DeleteComment.method
|
|
107
|
+
})
|
|
108
|
+
.then((res) => {
|
|
109
|
+
if (res.status >= 300) {
|
|
110
|
+
return Promise.reject(res);
|
|
111
|
+
}
|
|
112
|
+
return Promise.resolve(res.data);
|
|
113
|
+
});
|
|
114
|
+
}, [p]);
|
|
115
|
+
/**
|
|
116
|
+
* handle action
|
|
117
|
+
*/
|
|
118
|
+
function handleAction(action) {
|
|
119
|
+
if (action === constants_1.BAN_ROOM_USER) {
|
|
120
|
+
setCurrentAction(constants_1.BAN_ROOM_USER);
|
|
121
|
+
setOpenConfirmDialog(true);
|
|
122
|
+
handleClose();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Perform additional operations at the end of single action
|
|
127
|
+
*/
|
|
128
|
+
function performPostConfirmAction(success) {
|
|
129
|
+
if (success) {
|
|
130
|
+
setCurrentActionLoading(null);
|
|
131
|
+
setCurrentAction(null);
|
|
132
|
+
setOpenConfirmDialog(false);
|
|
133
|
+
enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.actionSuccess", defaultMessage: "ui.contributionActionMenu.actionSuccess" }), {
|
|
134
|
+
variant: 'success',
|
|
135
|
+
autoHideDuration: 3000
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
setCurrentActionLoading(null);
|
|
140
|
+
enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.contributionActionMenu.actionError", defaultMessage: "ui.contributionActionMenu.actionError" }), {
|
|
141
|
+
variant: 'error',
|
|
142
|
+
autoHideDuration: 3000
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Delete a contribution
|
|
148
|
+
*/
|
|
149
|
+
function handleConfirmedAction() {
|
|
150
|
+
if (p && !isLoading && !currentActionLoading) {
|
|
151
|
+
if (currentAction === constants_1.BAN_ROOM_USER) {
|
|
152
|
+
setCurrentActionLoading(constants_1.BAN_ROOM_USER);
|
|
153
|
+
/* performBanParticipant()
|
|
154
|
+
.then(() => {
|
|
155
|
+
onBanParticipant && onBanParticipant(p);
|
|
156
|
+
performPostConfirmAction(true);
|
|
157
|
+
})
|
|
158
|
+
.catch((error) => {
|
|
159
|
+
Logger.error(SCOPE_SC_UI, error);
|
|
160
|
+
performPostConfirmAction(false);
|
|
161
|
+
}); */
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Can authenticated ban a user in a room
|
|
167
|
+
*/
|
|
168
|
+
function canBanUser() {
|
|
169
|
+
return scUserContext.user && react_core_1.UserUtils.isStaff(scUserContext.user) && scUserContext.user.id.toString() !== p.identity;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Renders section general
|
|
173
|
+
*/
|
|
174
|
+
function renderGeneralSection() {
|
|
175
|
+
return ((0, jsx_runtime_1.jsx)(material_1.Box, { children: canBanUser() && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.subItem, disabled: currentActionLoading === constants_1.BAN_ROOM_USER }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "person" }) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.participantTileActions.banRoomUser", defaultMessage: "ui.liveStreamRoom.participantTileActions.banRoomUser" }), onClick: () => handleAction(constants_1.BAN_ROOM_USER), classes: { root: classes.itemText } })] }))) }));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Renders contribution menu content
|
|
179
|
+
*/
|
|
180
|
+
function renderContent() {
|
|
181
|
+
return ((0, jsx_runtime_1.jsx)(material_1.Box, { children: (0, jsx_runtime_1.jsx)(material_1.MenuList, { children: renderGeneralSection() }) }));
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Renders component
|
|
185
|
+
*/
|
|
186
|
+
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ ref: (ref) => {
|
|
187
|
+
popperRef.current = ref;
|
|
188
|
+
}, "aria-haspopup": "true", onClick: handleOpen, className: classes.button, size: "small" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "expand_more" }) })), isMobile ? ((0, jsx_runtime_1.jsx)(material_1.SwipeableDrawer, Object.assign({ open: open, onClose: handleClose, onOpen: handleOpen, anchor: "bottom", disableSwipeToOpen: true }, { children: renderContent() }))) : ((0, jsx_runtime_1.jsx)(PopperRoot, Object.assign({ open: open, anchorEl: popperRef.current, role: undefined, transition: true, className: classes.popperRoot }, PopperProps, { placement: "right" }, { children: ({ TransitionProps, placement }) => ((0, jsx_runtime_1.jsx)(material_1.Grow, Object.assign({}, TransitionProps, { style: { transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom' } }, { children: (0, jsx_runtime_1.jsx)(material_1.Paper, Object.assign({ variant: 'outlined', className: classes.paper }, { children: (0, jsx_runtime_1.jsx)(material_1.ClickAwayListener, Object.assign({ onClickAway: handleClose }, { children: renderContent() })) })) }))) }))), openConfirmDialog && ((0, jsx_runtime_1.jsx)(ConfirmDialog_1.default, Object.assign({ open: openConfirmDialog }, (currentAction === constants_1.BAN_ROOM_USER
|
|
189
|
+
? {
|
|
190
|
+
content: ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.liveStreamRoom.participantTileActions.banRoomUser", defaultMessage: "ui.liveStreamRoom.participantTileActions.banRoomUser" }))
|
|
191
|
+
}
|
|
192
|
+
: {}), { onConfirm: handleConfirmedAction, isUpdating: Boolean(currentActionLoading), onClose: () => setOpenConfirmDialog(false) })))] })));
|
|
193
|
+
}
|
|
194
|
+
exports.default = ContributionActionsMenu;
|
package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SCUserType } from '@selfcommunity/types';
|
|
2
|
+
export interface ParticipantTileProps {
|
|
3
|
+
className?: string;
|
|
4
|
+
/**
|
|
5
|
+
* User Object
|
|
6
|
+
* @default null
|
|
7
|
+
*/
|
|
8
|
+
user?: SCUserType;
|
|
9
|
+
/**
|
|
10
|
+
* User Object
|
|
11
|
+
* @default null
|
|
12
|
+
*/
|
|
13
|
+
participant?: any;
|
|
14
|
+
}
|
|
15
|
+
export default function UserAvatar(inProps: ParticipantTileProps): JSX.Element;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const styles_1 = require("@mui/material/styles");
|
|
6
|
+
const system_1 = require("@mui/system");
|
|
7
|
+
const material_1 = require("@mui/material");
|
|
8
|
+
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|
9
|
+
const ParticipantPlaceholder_1 = tslib_1.__importDefault(require("./ParticipantPlaceholder"));
|
|
10
|
+
const react_core_1 = require("@selfcommunity/react-core");
|
|
11
|
+
const PREFIX = 'SCParticipantTileAvatar';
|
|
12
|
+
const classes = {
|
|
13
|
+
root: `${PREFIX}-root`
|
|
14
|
+
};
|
|
15
|
+
const Root = (0, styles_1.styled)(material_1.Box, {
|
|
16
|
+
name: PREFIX,
|
|
17
|
+
slot: 'Root',
|
|
18
|
+
overridesResolver: (props, styles) => styles.root
|
|
19
|
+
})(({ theme }) => ({
|
|
20
|
+
height: 'auto !important',
|
|
21
|
+
'& img': {
|
|
22
|
+
borderRadius: '50%',
|
|
23
|
+
width: 100,
|
|
24
|
+
height: 100
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
27
|
+
function UserAvatar(inProps) {
|
|
28
|
+
// PROPS
|
|
29
|
+
const props = (0, system_1.useThemeProps)({
|
|
30
|
+
props: inProps,
|
|
31
|
+
name: PREFIX
|
|
32
|
+
});
|
|
33
|
+
const { className, user, participant } = props, rest = tslib_1.__rest(props, ["className", "user", "participant"]);
|
|
34
|
+
// CONTEXT
|
|
35
|
+
const scContext = (0, react_core_1.useSCContext)();
|
|
36
|
+
return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(className, classes.root) }, rest, { children: user ? ((0, jsx_runtime_1.jsx)("img", { src: `${user.avatar}` })) : participant ? ((0, jsx_runtime_1.jsx)("img", { src: `${scContext.settings.portal}/api/v2/avatar/${participant.identity}` })) : ((0, jsx_runtime_1.jsx)(ParticipantPlaceholder_1.default, {})) })));
|
|
37
|
+
}
|
|
38
|
+
exports.default = UserAvatar;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { CreateLocalTracksOptions, LocalAudioTrack, LocalTrack, LocalVideoTrack } from 'livekit-client';
|
|
2
|
+
import { Track } from 'livekit-client';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import type { LocalUserChoices } from '@livekit/components-core';
|
|
5
|
+
import { SCLiveStreamType } from '@selfcommunity/types';
|
|
6
|
+
/**
|
|
7
|
+
* Props for the PreJoin component.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export interface PreJoinProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSubmit' | 'onError'> {
|
|
11
|
+
/** This function is called with the `LocalUserChoices` if validation is passed. */
|
|
12
|
+
onSubmit?: (values: LocalUserChoices) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Provide your custom validation function. Only if validation is successful the user choices are past to the onSubmit callback.
|
|
15
|
+
*/
|
|
16
|
+
onValidate?: (values: LocalUserChoices) => boolean;
|
|
17
|
+
onError?: (error: Error) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Livestream Object
|
|
20
|
+
* @default null
|
|
21
|
+
*/
|
|
22
|
+
liveStream?: SCLiveStreamType;
|
|
23
|
+
/** Prefill the input form with initial values. */
|
|
24
|
+
defaults?: Partial<LocalUserChoices>;
|
|
25
|
+
/** Display a debug window for your convenience. */
|
|
26
|
+
debug?: boolean;
|
|
27
|
+
joinLabel?: string;
|
|
28
|
+
micLabel?: string;
|
|
29
|
+
camLabel?: string;
|
|
30
|
+
userLabel?: string;
|
|
31
|
+
/**
|
|
32
|
+
* If true, user choices are persisted across sessions.
|
|
33
|
+
* @defaultValue true
|
|
34
|
+
* @alpha
|
|
35
|
+
*/
|
|
36
|
+
persistUserChoices?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** @alpha */
|
|
39
|
+
export declare function usePreviewTracks(options: CreateLocalTracksOptions, onError?: (err: Error) => void): LocalTrack<Track.Kind>[];
|
|
40
|
+
/** @public */
|
|
41
|
+
export declare function usePreviewDevice<T extends LocalVideoTrack | LocalAudioTrack>(enabled: boolean, deviceId: string, kind: 'videoinput' | 'audioinput'): {
|
|
42
|
+
selectedDevice: MediaDeviceInfo;
|
|
43
|
+
localTrack: T;
|
|
44
|
+
deviceError: Error;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The `PreJoin` prefab component is normally presented to the user before he enters a room.
|
|
48
|
+
* This component allows the user to check and select the preferred media device (camera und microphone).
|
|
49
|
+
* On submit the user decisions are returned, which can then be passed on to the `LiveKitRoom` so that the user enters the room with the correct media devices.
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* This component is independent of the `LiveKitRoom` component and should not be nested within it.
|
|
53
|
+
* Because it only accesses the local media tracks this component is self-contained and works without connection to the LiveKit server.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```tsx
|
|
57
|
+
* <PreJoin />
|
|
58
|
+
* ```
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export declare function PreJoin({ liveStream, defaults, onValidate, onSubmit, onError, debug, joinLabel, micLabel, camLabel, userLabel, persistUserChoices, ...htmlProps }: PreJoinProps): JSX.Element;
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PreJoin = exports.usePreviewDevice = exports.usePreviewTracks = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const livekit_client_1 = require("livekit-client");
|
|
7
|
+
const React = tslib_1.__importStar(require("react"));
|
|
8
|
+
const components_core_1 = require("@livekit/components-core");
|
|
9
|
+
const components_core_2 = require("@livekit/components-core");
|
|
10
|
+
const components_react_1 = require("@livekit/components-react");
|
|
11
|
+
const react_core_1 = require("@selfcommunity/react-core");
|
|
12
|
+
const ParticipantTileAvatar_1 = tslib_1.__importDefault(require("./ParticipantTileAvatar"));
|
|
13
|
+
const react_1 = require("react");
|
|
14
|
+
const TrackToggle_1 = require("./TrackToggle");
|
|
15
|
+
/** @alpha */
|
|
16
|
+
function usePreviewTracks(options, onError) {
|
|
17
|
+
const [tracks, setTracks] = React.useState();
|
|
18
|
+
const trackLock = React.useMemo(() => new livekit_client_1.Mutex(), []);
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
let needsCleanup = false;
|
|
21
|
+
let localTracks = [];
|
|
22
|
+
trackLock.lock().then((unlock) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
try {
|
|
24
|
+
if (options.audio || options.video) {
|
|
25
|
+
localTracks = yield (0, livekit_client_1.createLocalTracks)(options);
|
|
26
|
+
if (needsCleanup) {
|
|
27
|
+
localTracks.forEach((tr) => tr.stop());
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
setTracks(localTracks);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
if (onError && e instanceof Error) {
|
|
36
|
+
onError(e);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
components_core_1.log.error(e);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
unlock();
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
return () => {
|
|
47
|
+
needsCleanup = true;
|
|
48
|
+
localTracks.forEach((track) => {
|
|
49
|
+
track.stop();
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
}, [JSON.stringify(options), onError, trackLock]);
|
|
53
|
+
return tracks;
|
|
54
|
+
}
|
|
55
|
+
exports.usePreviewTracks = usePreviewTracks;
|
|
56
|
+
/** @public */
|
|
57
|
+
function usePreviewDevice(enabled, deviceId, kind) {
|
|
58
|
+
const [deviceError, setDeviceError] = React.useState(null);
|
|
59
|
+
const [isCreatingTrack, setIsCreatingTrack] = React.useState(false);
|
|
60
|
+
const devices = (0, components_react_1.useMediaDevices)({ kind });
|
|
61
|
+
const [selectedDevice, setSelectedDevice] = React.useState(undefined);
|
|
62
|
+
const [localTrack, setLocalTrack] = React.useState();
|
|
63
|
+
const [localDeviceId, setLocalDeviceId] = React.useState(deviceId);
|
|
64
|
+
React.useEffect(() => {
|
|
65
|
+
setLocalDeviceId(deviceId);
|
|
66
|
+
}, [deviceId]);
|
|
67
|
+
const createTrack = (deviceId, kind) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
try {
|
|
69
|
+
const track = kind === 'videoinput'
|
|
70
|
+
? yield (0, livekit_client_1.createLocalVideoTrack)({
|
|
71
|
+
deviceId: deviceId,
|
|
72
|
+
resolution: livekit_client_1.VideoPresets.h720.resolution
|
|
73
|
+
})
|
|
74
|
+
: yield (0, livekit_client_1.createLocalAudioTrack)({ deviceId });
|
|
75
|
+
const newDeviceId = yield track.getDeviceId();
|
|
76
|
+
if (newDeviceId && deviceId !== newDeviceId) {
|
|
77
|
+
prevDeviceId.current = newDeviceId;
|
|
78
|
+
setLocalDeviceId(newDeviceId);
|
|
79
|
+
}
|
|
80
|
+
setLocalTrack(track);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
if (e instanceof Error) {
|
|
84
|
+
setDeviceError(e);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
const switchDevice = (track, id) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
yield track.setDeviceId(id);
|
|
90
|
+
prevDeviceId.current = id;
|
|
91
|
+
});
|
|
92
|
+
const prevDeviceId = React.useRef(localDeviceId);
|
|
93
|
+
React.useEffect(() => {
|
|
94
|
+
if (enabled && !localTrack && !deviceError && !isCreatingTrack) {
|
|
95
|
+
components_core_1.log.debug('creating track', kind);
|
|
96
|
+
setIsCreatingTrack(true);
|
|
97
|
+
createTrack(localDeviceId, kind).finally(() => {
|
|
98
|
+
setIsCreatingTrack(false);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}, [enabled, localTrack, deviceError, isCreatingTrack]);
|
|
102
|
+
// switch camera device
|
|
103
|
+
React.useEffect(() => {
|
|
104
|
+
if (!localTrack) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (!enabled) {
|
|
108
|
+
components_core_1.log.debug(`muting ${kind} track`);
|
|
109
|
+
localTrack.mute().then(() => components_core_1.log.debug(localTrack.mediaStreamTrack));
|
|
110
|
+
}
|
|
111
|
+
else if ((selectedDevice === null || selectedDevice === void 0 ? void 0 : selectedDevice.deviceId) && prevDeviceId.current !== (selectedDevice === null || selectedDevice === void 0 ? void 0 : selectedDevice.deviceId)) {
|
|
112
|
+
components_core_1.log.debug(`switching ${kind} device from`, prevDeviceId.current, selectedDevice.deviceId);
|
|
113
|
+
switchDevice(localTrack, selectedDevice.deviceId);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
components_core_1.log.debug(`unmuting local ${kind} track`);
|
|
117
|
+
localTrack.unmute();
|
|
118
|
+
}
|
|
119
|
+
}, [localTrack, selectedDevice, enabled, kind]);
|
|
120
|
+
React.useEffect(() => {
|
|
121
|
+
return () => {
|
|
122
|
+
if (localTrack) {
|
|
123
|
+
components_core_1.log.debug(`stopping local ${kind} track`);
|
|
124
|
+
localTrack.stop();
|
|
125
|
+
localTrack.mute();
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}, []);
|
|
129
|
+
React.useEffect(() => {
|
|
130
|
+
setSelectedDevice(devices === null || devices === void 0 ? void 0 : devices.find((dev) => dev.deviceId === localDeviceId));
|
|
131
|
+
}, [localDeviceId, devices]);
|
|
132
|
+
return {
|
|
133
|
+
selectedDevice,
|
|
134
|
+
localTrack,
|
|
135
|
+
deviceError
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
exports.usePreviewDevice = usePreviewDevice;
|
|
139
|
+
/**
|
|
140
|
+
* The `PreJoin` prefab component is normally presented to the user before he enters a room.
|
|
141
|
+
* This component allows the user to check and select the preferred media device (camera und microphone).
|
|
142
|
+
* On submit the user decisions are returned, which can then be passed on to the `LiveKitRoom` so that the user enters the room with the correct media devices.
|
|
143
|
+
*
|
|
144
|
+
* @remarks
|
|
145
|
+
* This component is independent of the `LiveKitRoom` component and should not be nested within it.
|
|
146
|
+
* Because it only accesses the local media tracks this component is self-contained and works without connection to the LiveKit server.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```tsx
|
|
150
|
+
* <PreJoin />
|
|
151
|
+
* ```
|
|
152
|
+
* @public
|
|
153
|
+
*/
|
|
154
|
+
function PreJoin(_a) {
|
|
155
|
+
var { liveStream, defaults = {}, onValidate, onSubmit, onError, debug, joinLabel = 'Join Room', micLabel = 'Microphone', camLabel = 'Camera', userLabel = 'Username', persistUserChoices = true } = _a, htmlProps = tslib_1.__rest(_a, ["liveStream", "defaults", "onValidate", "onSubmit", "onError", "debug", "joinLabel", "micLabel", "camLabel", "userLabel", "persistUserChoices"]);
|
|
156
|
+
const [userChoices, setUserChoices] = React.useState(components_core_2.defaultUserChoices);
|
|
157
|
+
// TODO: Remove and pipe `defaults` object directly into `usePersistentUserChoices` once we fully switch from type `LocalUserChoices` to `UserChoices`.
|
|
158
|
+
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 }));
|
|
159
|
+
const { userChoices: initialUserChoices, saveAudioInputDeviceId, saveAudioInputEnabled, saveVideoInputDeviceId, saveVideoInputEnabled, saveUsername } = (0, components_react_1.usePersistentUserChoices)({
|
|
160
|
+
defaults: partialDefaults,
|
|
161
|
+
preventSave: !persistUserChoices,
|
|
162
|
+
preventLoad: !persistUserChoices
|
|
163
|
+
});
|
|
164
|
+
// Initialize device settings
|
|
165
|
+
const [audioEnabled, setAudioEnabled] = React.useState(initialUserChoices.audioEnabled);
|
|
166
|
+
const [videoEnabled, setVideoEnabled] = React.useState(initialUserChoices.videoEnabled);
|
|
167
|
+
const [audioDeviceId, setAudioDeviceId] = React.useState(initialUserChoices.audioDeviceId);
|
|
168
|
+
const [videoDeviceId, setVideoDeviceId] = React.useState(initialUserChoices.videoDeviceId);
|
|
169
|
+
const [username, setUsername] = React.useState(initialUserChoices.username);
|
|
170
|
+
// Save user choices to persistent storage.
|
|
171
|
+
React.useEffect(() => {
|
|
172
|
+
saveAudioInputEnabled(audioEnabled);
|
|
173
|
+
}, [audioEnabled, saveAudioInputEnabled]);
|
|
174
|
+
React.useEffect(() => {
|
|
175
|
+
saveVideoInputEnabled(videoEnabled);
|
|
176
|
+
}, [videoEnabled, saveVideoInputEnabled]);
|
|
177
|
+
React.useEffect(() => {
|
|
178
|
+
saveAudioInputDeviceId(audioDeviceId);
|
|
179
|
+
}, [audioDeviceId, saveAudioInputDeviceId]);
|
|
180
|
+
React.useEffect(() => {
|
|
181
|
+
saveVideoInputDeviceId(videoDeviceId);
|
|
182
|
+
}, [videoDeviceId, saveVideoInputDeviceId]);
|
|
183
|
+
React.useEffect(() => {
|
|
184
|
+
saveUsername(username);
|
|
185
|
+
}, [username, saveUsername]);
|
|
186
|
+
const tracks = usePreviewTracks({
|
|
187
|
+
audio: audioEnabled ? { deviceId: initialUserChoices.audioDeviceId } : false,
|
|
188
|
+
video: videoEnabled ? { deviceId: initialUserChoices.videoDeviceId } : false
|
|
189
|
+
}, onError);
|
|
190
|
+
const scUserContext = (0, react_core_1.useSCUser)();
|
|
191
|
+
const videoEl = React.useRef(null);
|
|
192
|
+
const videoTrack = React.useMemo(() => tracks === null || tracks === void 0 ? void 0 : tracks.filter((track) => track.kind === livekit_client_1.Track.Kind.Video)[0], [tracks]);
|
|
193
|
+
const facingMode = React.useMemo(() => {
|
|
194
|
+
if (videoTrack) {
|
|
195
|
+
const { facingMode } = (0, livekit_client_1.facingModeFromLocalTrack)(videoTrack);
|
|
196
|
+
return facingMode;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
return 'undefined';
|
|
200
|
+
}
|
|
201
|
+
}, [videoTrack]);
|
|
202
|
+
const audioTrack = React.useMemo(() => tracks === null || tracks === void 0 ? void 0 : tracks.filter((track) => track.kind === livekit_client_1.Track.Kind.Audio)[0], [tracks]);
|
|
203
|
+
React.useEffect(() => {
|
|
204
|
+
if (videoEl.current && videoTrack) {
|
|
205
|
+
videoTrack.unmute();
|
|
206
|
+
videoTrack.attach(videoEl.current);
|
|
207
|
+
}
|
|
208
|
+
return () => {
|
|
209
|
+
videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.detach();
|
|
210
|
+
};
|
|
211
|
+
}, [videoTrack]);
|
|
212
|
+
const [isValid, setIsValid] = React.useState();
|
|
213
|
+
const handleValidation = React.useCallback((values) => {
|
|
214
|
+
if (typeof onValidate === 'function') {
|
|
215
|
+
return onValidate(values);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
return values.username !== '';
|
|
219
|
+
}
|
|
220
|
+
}, [onValidate]);
|
|
221
|
+
React.useEffect(() => {
|
|
222
|
+
const newUserChoices = {
|
|
223
|
+
username,
|
|
224
|
+
videoEnabled,
|
|
225
|
+
videoDeviceId,
|
|
226
|
+
audioEnabled,
|
|
227
|
+
audioDeviceId
|
|
228
|
+
};
|
|
229
|
+
setUserChoices(newUserChoices);
|
|
230
|
+
setIsValid(handleValidation(newUserChoices));
|
|
231
|
+
}, [username, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
|
|
232
|
+
function handleSubmit(event) {
|
|
233
|
+
event.preventDefault();
|
|
234
|
+
if (handleValidation(userChoices)) {
|
|
235
|
+
if (typeof onSubmit === 'function') {
|
|
236
|
+
onSubmit(userChoices);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
components_core_1.log.warn('Validation failed with: ', userChoices);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
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.muteParticipant)); }, [scUserContext, liveStream]);
|
|
244
|
+
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]);
|
|
245
|
+
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}`] })] }))] }))] })));
|
|
246
|
+
}
|
|
247
|
+
exports.PreJoin = PreJoin;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CaptureOptionsBySource, ToggleSource } from '@livekit/components-core';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Track, TrackPublishOptions } from 'livekit-client';
|
|
4
|
+
export declare function getSourceIcon(source: Track.Source, enabled: boolean): JSX.Element;
|
|
5
|
+
export interface TrackToggleProps<T extends ToggleSource> extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> {
|
|
6
|
+
source: T;
|
|
7
|
+
showIcon?: boolean;
|
|
8
|
+
initialState?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Function that is called when the enabled state of the toggle changes.
|
|
12
|
+
* The second function argument `isUserInitiated` is `true` if the change was initiated by a user interaction, such as a click.
|
|
13
|
+
*/
|
|
14
|
+
onChange?: (enabled: boolean, isUserInitiated: boolean) => void;
|
|
15
|
+
captureOptions?: CaptureOptionsBySource<T>;
|
|
16
|
+
publishOptions?: TrackPublishOptions;
|
|
17
|
+
onDeviceError?: (error: Error) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* With the `TrackToggle` component it is possible to mute and unmute your camera and microphone.
|
|
21
|
+
* The component uses an html button element under the hood so you can treat it like a button.
|
|
22
|
+
*/
|
|
23
|
+
export declare const TrackToggle: <T extends ToggleSource>(props: TrackToggleProps<T> & React.RefAttributes<HTMLButtonElement>) => React.ReactNode;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TrackToggle = exports.getSourceIcon = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const React = tslib_1.__importStar(require("react"));
|
|
7
|
+
const livekit_client_1 = require("livekit-client");
|
|
8
|
+
const components_react_1 = require("@livekit/components-react");
|
|
9
|
+
function getSourceIcon(source, enabled) {
|
|
10
|
+
switch (source) {
|
|
11
|
+
case livekit_client_1.Track.Source.Microphone:
|
|
12
|
+
return enabled ? (0, jsx_runtime_1.jsx)(components_react_1.MicIcon, {}) : (0, jsx_runtime_1.jsx)(components_react_1.MicDisabledIcon, {});
|
|
13
|
+
case livekit_client_1.Track.Source.Camera:
|
|
14
|
+
return enabled ? (0, jsx_runtime_1.jsx)(components_react_1.CameraIcon, {}) : (0, jsx_runtime_1.jsx)(components_react_1.CameraDisabledIcon, {});
|
|
15
|
+
case livekit_client_1.Track.Source.ScreenShare:
|
|
16
|
+
return enabled ? (0, jsx_runtime_1.jsx)(components_react_1.ScreenShareStopIcon, {}) : (0, jsx_runtime_1.jsx)(components_react_1.ScreenShareIcon, {});
|
|
17
|
+
default:
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.getSourceIcon = getSourceIcon;
|
|
22
|
+
/**
|
|
23
|
+
* With the `TrackToggle` component it is possible to mute and unmute your camera and microphone.
|
|
24
|
+
* The component uses an html button element under the hood so you can treat it like a button.
|
|
25
|
+
*/
|
|
26
|
+
exports.TrackToggle =
|
|
27
|
+
/* @__PURE__ */ React.forwardRef(function TrackToggle(_a, ref) {
|
|
28
|
+
var { showIcon, disabled } = _a, props = tslib_1.__rest(_a, ["showIcon", "disabled"]);
|
|
29
|
+
const { buttonProps, enabled } = (0, components_react_1.useTrackToggle)(props);
|
|
30
|
+
return ((0, jsx_runtime_1.jsxs)("button", Object.assign({ ref: ref }, buttonProps, { disabled: disabled }, { children: [(showIcon !== null && showIcon !== void 0 ? showIcon : true) && getSourceIcon(props.source, enabled && !disabled), props.children] })));
|
|
31
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { MessageDecoder, MessageEncoder } from '@livekit/components-core';
|
|
3
3
|
import { MessageFormatter } from '@livekit/components-react';
|
|
4
|
+
import { SCUserType } from '@selfcommunity/types';
|
|
4
5
|
/**
|
|
5
6
|
* @public
|
|
6
7
|
*/
|
|
@@ -10,11 +11,11 @@ export interface VideoConferenceProps extends React.HTMLAttributes<HTMLDivElemen
|
|
|
10
11
|
chatMessageDecoder?: MessageDecoder;
|
|
11
12
|
/** @alpha */
|
|
12
13
|
SettingsComponent?: React.ComponentType;
|
|
13
|
-
speakerFocused?:
|
|
14
|
+
speakerFocused?: SCUserType;
|
|
14
15
|
disableChat?: boolean;
|
|
15
16
|
disableMicrophone?: boolean;
|
|
16
17
|
disableCamera?: boolean;
|
|
17
|
-
|
|
18
|
+
disableShareScreen?: boolean;
|
|
18
19
|
hideParticipantList?: boolean;
|
|
19
20
|
showSettings?: boolean;
|
|
20
21
|
}
|
|
@@ -36,4 +37,4 @@ export interface VideoConferenceProps extends React.HTMLAttributes<HTMLDivElemen
|
|
|
36
37
|
* ```
|
|
37
38
|
* @public
|
|
38
39
|
*/
|
|
39
|
-
export declare function VideoConference({ chatMessageFormatter, chatMessageDecoder, chatMessageEncoder, SettingsComponent, speakerFocused, disableChat, disableMicrophone, disableCamera,
|
|
40
|
+
export declare function VideoConference({ chatMessageFormatter, chatMessageDecoder, chatMessageEncoder, SettingsComponent, speakerFocused, disableChat, disableMicrophone, disableCamera, disableShareScreen, hideParticipantList, showSettings, ...props }: VideoConferenceProps): JSX.Element;
|