@selfcommunity/react-ui 0.8.0-live.58 → 0.8.0-live.60

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 (66) hide show
  1. package/lib/cjs/components/CreateLiveStreamDialog/CreateLiveStreamDialog.js +8 -7
  2. package/lib/cjs/components/EventForm/EventAddress.js +12 -8
  3. package/lib/cjs/components/EventForm/EventForm.d.ts +6 -1
  4. package/lib/cjs/components/EventForm/EventForm.js +27 -9
  5. package/lib/cjs/components/EventForm/types.d.ts +2 -1
  6. package/lib/cjs/components/LiveStreamForm/LiveStreamForm.js +1 -3
  7. package/lib/cjs/components/LiveStreamForm/LiveStreamFormSettings.d.ts +2 -1
  8. package/lib/cjs/components/LiveStreamForm/LiveStreamFormSettings.js +1 -1
  9. package/lib/cjs/components/LiveStreamForm/constants.d.ts +4 -1
  10. package/lib/cjs/components/LiveStreamForm/constants.js +7 -4
  11. package/lib/cjs/components/LiveStreamRoom/LiveStreamRoom.js +12 -7
  12. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamProvider.d.ts +17 -0
  13. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamProvider.js +13 -0
  14. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.d.ts +0 -6
  15. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.js +11 -3
  16. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.d.ts +6 -0
  17. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +8 -0
  18. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.d.ts +28 -0
  19. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +65 -0
  20. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.d.ts +26 -0
  21. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.js +204 -0
  22. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.d.ts +15 -0
  23. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +38 -0
  24. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.d.ts +55 -0
  25. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +249 -0
  26. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.d.ts +23 -0
  27. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.js +31 -0
  28. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +4 -3
  29. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +5 -4
  30. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/constants.d.ts +1 -0
  31. package/lib/cjs/components/LiveStreamRoom/LiveStreamVideoConference/constants.js +2 -1
  32. package/lib/cjs/components/NavigationMenuIconButton/NavigationMenuDrawer.js +1 -1
  33. package/lib/esm/components/CreateLiveStreamDialog/CreateLiveStreamDialog.js +2 -1
  34. package/lib/esm/components/EventForm/EventAddress.js +13 -9
  35. package/lib/esm/components/EventForm/EventForm.d.ts +6 -1
  36. package/lib/esm/components/EventForm/EventForm.js +27 -9
  37. package/lib/esm/components/EventForm/types.d.ts +2 -1
  38. package/lib/esm/components/LiveStreamForm/LiveStreamForm.js +2 -4
  39. package/lib/esm/components/LiveStreamForm/LiveStreamFormSettings.d.ts +2 -1
  40. package/lib/esm/components/LiveStreamForm/LiveStreamFormSettings.js +1 -1
  41. package/lib/esm/components/LiveStreamForm/constants.d.ts +4 -1
  42. package/lib/esm/components/LiveStreamForm/constants.js +7 -4
  43. package/lib/esm/components/LiveStreamRoom/LiveStreamRoom.js +13 -8
  44. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamProvider.d.ts +17 -0
  45. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamProvider.js +9 -0
  46. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.d.ts +0 -6
  47. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/LiveStreamVideoConference.js +11 -3
  48. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.d.ts +6 -0
  49. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantPlaceholder.js +6 -0
  50. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.d.ts +28 -0
  51. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTile.js +60 -0
  52. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.d.ts +26 -0
  53. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileActions.js +201 -0
  54. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.d.ts +15 -0
  55. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/ParticipantTileAvatar.js +35 -0
  56. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.d.ts +55 -0
  57. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/PreJoin.js +243 -0
  58. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.d.ts +23 -0
  59. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/TrackToggle.js +27 -0
  60. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.d.ts +4 -3
  61. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/VideoConference.js +6 -5
  62. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/constants.d.ts +1 -0
  63. package/lib/esm/components/LiveStreamRoom/LiveStreamVideoConference/constants.js +1 -0
  64. package/lib/esm/components/NavigationMenuIconButton/NavigationMenuDrawer.js +1 -1
  65. package/lib/umd/react-ui.js +1 -1
  66. package/package.json +7 -7
@@ -0,0 +1,243 @@
1
+ import { __awaiter, __rest } from "tslib";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { createLocalAudioTrack, createLocalTracks, createLocalVideoTrack, facingModeFromLocalTrack, Track, VideoPresets, Mutex } from 'livekit-client';
4
+ import * as React from 'react';
5
+ import { log } from '@livekit/components-core';
6
+ import { defaultUserChoices } from '@livekit/components-core';
7
+ import { MediaDeviceMenu, useMediaDevices, usePersistentUserChoices } from '@livekit/components-react';
8
+ import { useSCUser } from '@selfcommunity/react-core';
9
+ import ParticipantTileAvatar from './ParticipantTileAvatar';
10
+ import { useMemo } from 'react';
11
+ import { TrackToggle } from './TrackToggle';
12
+ import { useLiveStream } from './LiveStreamProvider';
13
+ /** @alpha */
14
+ export function usePreviewTracks(options, onError) {
15
+ const [tracks, setTracks] = React.useState();
16
+ const trackLock = React.useMemo(() => new Mutex(), []);
17
+ React.useEffect(() => {
18
+ let needsCleanup = false;
19
+ let localTracks = [];
20
+ trackLock.lock().then((unlock) => __awaiter(this, void 0, void 0, function* () {
21
+ try {
22
+ if (options.audio || options.video) {
23
+ localTracks = yield createLocalTracks(options);
24
+ if (needsCleanup) {
25
+ localTracks.forEach((tr) => tr.stop());
26
+ }
27
+ else {
28
+ setTracks(localTracks);
29
+ }
30
+ }
31
+ }
32
+ catch (e) {
33
+ if (onError && e instanceof Error) {
34
+ onError(e);
35
+ }
36
+ else {
37
+ log.error(e);
38
+ }
39
+ }
40
+ finally {
41
+ unlock();
42
+ }
43
+ }));
44
+ return () => {
45
+ needsCleanup = true;
46
+ localTracks.forEach((track) => {
47
+ track.stop();
48
+ });
49
+ };
50
+ }, [JSON.stringify(options), onError, trackLock]);
51
+ return tracks;
52
+ }
53
+ /** @public */
54
+ export function usePreviewDevice(enabled, deviceId, kind) {
55
+ const [deviceError, setDeviceError] = React.useState(null);
56
+ const [isCreatingTrack, setIsCreatingTrack] = React.useState(false);
57
+ const devices = useMediaDevices({ kind });
58
+ const [selectedDevice, setSelectedDevice] = React.useState(undefined);
59
+ const [localTrack, setLocalTrack] = React.useState();
60
+ const [localDeviceId, setLocalDeviceId] = React.useState(deviceId);
61
+ React.useEffect(() => {
62
+ setLocalDeviceId(deviceId);
63
+ }, [deviceId]);
64
+ const createTrack = (deviceId, kind) => __awaiter(this, void 0, void 0, function* () {
65
+ try {
66
+ const track = kind === 'videoinput'
67
+ ? yield createLocalVideoTrack({
68
+ deviceId: deviceId,
69
+ resolution: VideoPresets.h720.resolution
70
+ })
71
+ : yield createLocalAudioTrack({ deviceId });
72
+ const newDeviceId = yield track.getDeviceId();
73
+ if (newDeviceId && deviceId !== newDeviceId) {
74
+ prevDeviceId.current = newDeviceId;
75
+ setLocalDeviceId(newDeviceId);
76
+ }
77
+ setLocalTrack(track);
78
+ }
79
+ catch (e) {
80
+ if (e instanceof Error) {
81
+ setDeviceError(e);
82
+ }
83
+ }
84
+ });
85
+ const switchDevice = (track, id) => __awaiter(this, void 0, void 0, function* () {
86
+ yield track.setDeviceId(id);
87
+ prevDeviceId.current = id;
88
+ });
89
+ const prevDeviceId = React.useRef(localDeviceId);
90
+ React.useEffect(() => {
91
+ if (enabled && !localTrack && !deviceError && !isCreatingTrack) {
92
+ log.debug('creating track', kind);
93
+ setIsCreatingTrack(true);
94
+ createTrack(localDeviceId, kind).finally(() => {
95
+ setIsCreatingTrack(false);
96
+ });
97
+ }
98
+ }, [enabled, localTrack, deviceError, isCreatingTrack]);
99
+ // switch camera device
100
+ React.useEffect(() => {
101
+ if (!localTrack) {
102
+ return;
103
+ }
104
+ if (!enabled) {
105
+ log.debug(`muting ${kind} track`);
106
+ localTrack.mute().then(() => log.debug(localTrack.mediaStreamTrack));
107
+ }
108
+ else if ((selectedDevice === null || selectedDevice === void 0 ? void 0 : selectedDevice.deviceId) && prevDeviceId.current !== (selectedDevice === null || selectedDevice === void 0 ? void 0 : selectedDevice.deviceId)) {
109
+ log.debug(`switching ${kind} device from`, prevDeviceId.current, selectedDevice.deviceId);
110
+ switchDevice(localTrack, selectedDevice.deviceId);
111
+ }
112
+ else {
113
+ log.debug(`unmuting local ${kind} track`);
114
+ localTrack.unmute();
115
+ }
116
+ }, [localTrack, selectedDevice, enabled, kind]);
117
+ React.useEffect(() => {
118
+ return () => {
119
+ if (localTrack) {
120
+ log.debug(`stopping local ${kind} track`);
121
+ localTrack.stop();
122
+ localTrack.mute();
123
+ }
124
+ };
125
+ }, []);
126
+ React.useEffect(() => {
127
+ setSelectedDevice(devices === null || devices === void 0 ? void 0 : devices.find((dev) => dev.deviceId === localDeviceId));
128
+ }, [localDeviceId, devices]);
129
+ return {
130
+ selectedDevice,
131
+ localTrack,
132
+ deviceError
133
+ };
134
+ }
135
+ /**
136
+ * The `PreJoin` prefab component is normally presented to the user before he enters a room.
137
+ * This component allows the user to check and select the preferred media device (camera und microphone).
138
+ * 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.
139
+ *
140
+ * @remarks
141
+ * This component is independent of the `LiveKitRoom` component and should not be nested within it.
142
+ * Because it only accesses the local media tracks this component is self-contained and works without connection to the LiveKit server.
143
+ *
144
+ * @example
145
+ * ```tsx
146
+ * <PreJoin />
147
+ * ```
148
+ * @public
149
+ */
150
+ export function PreJoin(_a) {
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
+ const { liveStream } = useLiveStream();
153
+ const [userChoices, setUserChoices] = React.useState(defaultUserChoices);
154
+ // TODO: Remove and pipe `defaults` object directly into `usePersistentUserChoices` once we fully switch from type `LocalUserChoices` to `UserChoices`.
155
+ 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 }));
156
+ const { userChoices: initialUserChoices, saveAudioInputDeviceId, saveAudioInputEnabled, saveVideoInputDeviceId, saveVideoInputEnabled, saveUsername } = usePersistentUserChoices({
157
+ defaults: partialDefaults,
158
+ preventSave: !persistUserChoices,
159
+ preventLoad: !persistUserChoices
160
+ });
161
+ // Initialize device settings
162
+ const [audioEnabled, setAudioEnabled] = React.useState(initialUserChoices.audioEnabled);
163
+ const [videoEnabled, setVideoEnabled] = React.useState(initialUserChoices.videoEnabled);
164
+ const [audioDeviceId, setAudioDeviceId] = React.useState(initialUserChoices.audioDeviceId);
165
+ const [videoDeviceId, setVideoDeviceId] = React.useState(initialUserChoices.videoDeviceId);
166
+ const [username, setUsername] = React.useState(initialUserChoices.username);
167
+ // Save user choices to persistent storage.
168
+ React.useEffect(() => {
169
+ saveAudioInputEnabled(audioEnabled);
170
+ }, [audioEnabled, saveAudioInputEnabled]);
171
+ React.useEffect(() => {
172
+ saveVideoInputEnabled(videoEnabled);
173
+ }, [videoEnabled, saveVideoInputEnabled]);
174
+ React.useEffect(() => {
175
+ saveAudioInputDeviceId(audioDeviceId);
176
+ }, [audioDeviceId, saveAudioInputDeviceId]);
177
+ React.useEffect(() => {
178
+ saveVideoInputDeviceId(videoDeviceId);
179
+ }, [videoDeviceId, saveVideoInputDeviceId]);
180
+ React.useEffect(() => {
181
+ saveUsername(username);
182
+ }, [username, saveUsername]);
183
+ const tracks = usePreviewTracks({
184
+ audio: audioEnabled ? { deviceId: initialUserChoices.audioDeviceId } : false,
185
+ video: videoEnabled ? { deviceId: initialUserChoices.videoDeviceId } : false
186
+ }, onError);
187
+ const scUserContext = useSCUser();
188
+ const videoEl = React.useRef(null);
189
+ const videoTrack = React.useMemo(() => tracks === null || tracks === void 0 ? void 0 : tracks.filter((track) => track.kind === Track.Kind.Video)[0], [tracks]);
190
+ const facingMode = React.useMemo(() => {
191
+ if (videoTrack) {
192
+ const { facingMode } = facingModeFromLocalTrack(videoTrack);
193
+ return facingMode;
194
+ }
195
+ else {
196
+ return 'undefined';
197
+ }
198
+ }, [videoTrack]);
199
+ const audioTrack = React.useMemo(() => tracks === null || tracks === void 0 ? void 0 : tracks.filter((track) => track.kind === Track.Kind.Audio)[0], [tracks]);
200
+ React.useEffect(() => {
201
+ if (videoEl.current && videoTrack) {
202
+ videoTrack.unmute();
203
+ videoTrack.attach(videoEl.current);
204
+ }
205
+ return () => {
206
+ videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.detach();
207
+ };
208
+ }, [videoTrack]);
209
+ const [isValid, setIsValid] = React.useState();
210
+ const handleValidation = React.useCallback((values) => {
211
+ if (typeof onValidate === 'function') {
212
+ return onValidate(values);
213
+ }
214
+ else {
215
+ return values.username !== '';
216
+ }
217
+ }, [onValidate]);
218
+ React.useEffect(() => {
219
+ const newUserChoices = {
220
+ username,
221
+ videoEnabled,
222
+ videoDeviceId,
223
+ audioEnabled,
224
+ audioDeviceId
225
+ };
226
+ setUserChoices(newUserChoices);
227
+ setIsValid(handleValidation(newUserChoices));
228
+ }, [username, videoEnabled, handleValidation, audioEnabled, audioDeviceId, videoDeviceId]);
229
+ function handleSubmit(event) {
230
+ event.preventDefault();
231
+ if (handleValidation(userChoices)) {
232
+ if (typeof onSubmit === 'function') {
233
+ onSubmit(userChoices);
234
+ }
235
+ }
236
+ else {
237
+ log.warn('Validation failed with: ', userChoices);
238
+ }
239
+ }
240
+ 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
+ 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}`] })] }))] }))] })));
243
+ }
@@ -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,27 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { Track } from 'livekit-client';
5
+ import { useTrackToggle, CameraIcon, CameraDisabledIcon, MicDisabledIcon, MicIcon, ScreenShareIcon, ScreenShareStopIcon } from '@livekit/components-react';
6
+ export function getSourceIcon(source, enabled) {
7
+ switch (source) {
8
+ case Track.Source.Microphone:
9
+ return enabled ? _jsx(MicIcon, {}) : _jsx(MicDisabledIcon, {});
10
+ case Track.Source.Camera:
11
+ return enabled ? _jsx(CameraIcon, {}) : _jsx(CameraDisabledIcon, {});
12
+ case Track.Source.ScreenShare:
13
+ return enabled ? _jsx(ScreenShareStopIcon, {}) : _jsx(ScreenShareIcon, {});
14
+ default:
15
+ return undefined;
16
+ }
17
+ }
18
+ /**
19
+ * With the `TrackToggle` component it is possible to mute and unmute your camera and microphone.
20
+ * The component uses an html button element under the hood so you can treat it like a button.
21
+ */
22
+ export const TrackToggle =
23
+ /* @__PURE__ */ React.forwardRef(function TrackToggle(_a, ref) {
24
+ var { showIcon, disabled } = _a, props = __rest(_a, ["showIcon", "disabled"]);
25
+ const { buttonProps, enabled } = useTrackToggle(props);
26
+ return (_jsxs("button", Object.assign({ ref: ref }, buttonProps, { disabled: disabled }, { children: [(showIcon !== null && showIcon !== void 0 ? showIcon : true) && getSourceIcon(props.source, enabled && !disabled), props.children] })));
27
+ });
@@ -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?: string;
14
+ speakerFocused?: SCUserType;
14
15
  disableChat?: boolean;
15
16
  disableMicrophone?: boolean;
16
17
  disableCamera?: boolean;
17
- disableScreenShare?: boolean;
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, disableScreenShare, hideParticipantList, showSettings, ...props }: VideoConferenceProps): JSX.Element;
40
+ export declare function VideoConference({ chatMessageFormatter, chatMessageDecoder, chatMessageEncoder, SettingsComponent, speakerFocused, disableChat, disableMicrophone, disableCamera, disableShareScreen, hideParticipantList, showSettings, ...props }: VideoConferenceProps): JSX.Element;
@@ -3,7 +3,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { isEqualTrackRef, isTrackReference, isWeb, log } from '@livekit/components-core';
5
5
  import { RoomEvent, Track } from 'livekit-client';
6
- import { CarouselLayout, Chat, ConnectionStateToast, ControlBar, FocusLayout, FocusLayoutContainer, GridLayout, LayoutContextProvider, ParticipantTile, RoomAudioRenderer, useCreateLayoutContext, useLocalParticipant, useParticipants, usePinnedTracks, useTracks } from '@livekit/components-react';
6
+ import { CarouselLayout, Chat, ConnectionStateToast, ControlBar, FocusLayout, FocusLayoutContainer, GridLayout, LayoutContextProvider, RoomAudioRenderer, useCreateLayoutContext, useLocalParticipant, useParticipants, usePinnedTracks, useTracks } from '@livekit/components-react';
7
+ import { ParticipantTile } from './ParticipantTile';
7
8
  /**
8
9
  * The `VideoConference` ready-made component is your drop-in solution for a classic video conferencing application.
9
10
  * It provides functionality such as focusing on one participant, grid view with pagination to handle large numbers
@@ -24,7 +25,7 @@ import { CarouselLayout, Chat, ConnectionStateToast, ControlBar, FocusLayout, Fo
24
25
  */
25
26
  export function VideoConference(_a) {
26
27
  var _b, _c;
27
- var { chatMessageFormatter, chatMessageDecoder, chatMessageEncoder, SettingsComponent, speakerFocused, disableChat = false, disableMicrophone = false, disableCamera = false, disableScreenShare = false, hideParticipantList = false, showSettings } = _a, props = __rest(_a, ["chatMessageFormatter", "chatMessageDecoder", "chatMessageEncoder", "SettingsComponent", "speakerFocused", "disableChat", "disableMicrophone", "disableCamera", "disableScreenShare", "hideParticipantList", "showSettings"]);
28
+ var { chatMessageFormatter, chatMessageDecoder, chatMessageEncoder, SettingsComponent, speakerFocused, disableChat = false, disableMicrophone = false, disableCamera = false, disableShareScreen = false, hideParticipantList = false, showSettings } = _a, props = __rest(_a, ["chatMessageFormatter", "chatMessageDecoder", "chatMessageEncoder", "SettingsComponent", "speakerFocused", "disableChat", "disableMicrophone", "disableCamera", "disableShareScreen", "hideParticipantList", "showSettings"]);
28
29
  const [widgetState, setWidgetState] = React.useState({
29
30
  showChat: false,
30
31
  unreadMessages: 0,
@@ -77,7 +78,7 @@ export function VideoConference(_a) {
77
78
  }
78
79
  else if (speakerFocused) {
79
80
  const speaker = participants.find((pt) => {
80
- return pt.name === speakerFocused;
81
+ return pt.name === speakerFocused.username;
81
82
  });
82
83
  if (speaker) {
83
84
  const updatedFocusTrack = tracks.find((tr) => {
@@ -96,12 +97,12 @@ export function VideoConference(_a) {
96
97
  participants,
97
98
  speakerFocused
98
99
  ]);
99
- 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: [!hideParticipantList && (_jsx(CarouselLayout, Object.assign({ tracks: carouselTracks }, { children: _jsx(ParticipantTile, {}) }))), focusTrack && _jsx(FocusLayout, { trackRef: focusTrack })] }) }))), _jsx(ControlBar, { controls: Object.assign(Object.assign({}, (localParticipant.name !== speakerFocused
100
+ 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: [!hideParticipantList && (_jsx(CarouselLayout, Object.assign({ tracks: carouselTracks }, { children: _jsx(ParticipantTile, {}) }))), focusTrack && _jsx(FocusLayout, { trackRef: focusTrack })] }) }))), _jsx(ControlBar, { controls: Object.assign(Object.assign({}, (localParticipant.name !== speakerFocused.username
100
101
  ? {
101
102
  chat: !disableChat,
102
103
  microphone: !disableMicrophone,
103
104
  camera: !disableCamera,
104
- screenShare: !disableScreenShare
105
+ screenShare: !disableShareScreen
105
106
  }
106
107
  : {})), { settings: !!SettingsComponent }) })] })), !disableChat && (_jsx(Chat, { style: { display: widgetState.showChat ? 'grid' : 'none' }, messageFormatter: chatMessageFormatter, messageEncoder: chatMessageEncoder, messageDecoder: chatMessageDecoder })), SettingsComponent && (_jsx("div", Object.assign({ className: "lk-settings-menu-modal", style: { display: widgetState.showSettings ? 'block' : 'none' } }, { children: _jsx(SettingsComponent, {}) })))] }))), _jsx(RoomAudioRenderer, {}), _jsx(ConnectionStateToast, {})] })));
107
108
  }
@@ -1 +1,2 @@
1
1
  export declare const PREFIX = "SCLiveStreamVideoConference";
2
+ export declare const BAN_ROOM_USER = "_ban_room_user";
@@ -1 +1,2 @@
1
1
  export const PREFIX = 'SCLiveStreamVideoConference';
2
+ export const BAN_ROOM_USER = '_ban_room_user';
@@ -37,5 +37,5 @@ export default function NavigationMenuDrawer(inProps) {
37
37
  const { className = null, showDrawerHeader = true, drawerHeaderContent = _jsx(DefaultHeaderContent, {}), drawerContent = _jsx(DefaultDrawerContent, {}), showDrawerFooterContent = true, drawerFooterContent = null, ScrollContainerProps = {}, CreateLiveStreamButtonComponentProps = {}, open, onClose } = props, rest = __rest(props, ["className", "showDrawerHeader", "drawerHeaderContent", "drawerContent", "showDrawerFooterContent", "drawerFooterContent", "ScrollContainerProps", "CreateLiveStreamButtonComponentProps", "open", "onClose"]);
38
38
  const scUserContext = useSCUser();
39
39
  const canCreateLiveStream = useMemo(() => { var _a, _b; return (_b = (_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.create_livestream; }, [(_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.permission]);
40
- return (_jsxs(Root, Object.assign({ anchor: "left", className: classNames(classes.root, className), open: open, onClose: onClose }, rest, { children: [showDrawerHeader && (_jsxs(_Fragment, { children: [_jsxs(Box, Object.assign({ className: classes.drawerHeader }, { children: [drawerHeaderContent, _jsx(IconButton, Object.assign({ className: classes.drawerHeaderAction, onClick: onClose }, { children: _jsx(Icon, { children: "close" }) }))] })), _jsx(Divider, {})] })), _jsx(ScrollContainer, Object.assign({}, ScrollContainerProps, { children: _jsx(List, Object.assign({ className: classes.drawerContent, onClick: onClose }, { children: drawerContent })) })), showDrawerFooterContent && (_jsxs(_Fragment, { children: [Boolean(drawerContent || canCreateLiveStream) && _jsx(Divider, {}), _jsx(Box, Object.assign({ className: classes.drawerFooter }, { children: drawerFooterContent ? (drawerFooterContent) : (_jsx(Box, Object.assign({ className: classes.drawerFooterLiveStream }, { children: _jsx(CreateLiveStreamButton, Object.assign({ color: "primary", className: classes.drawerFooterLiveStreamButton, fullWidth: true }, CreateLiveStreamButtonComponentProps)) }))) }))] }))] })));
40
+ return (_jsxs(Root, Object.assign({ anchor: "left", className: classNames(classes.root, className), open: open, onClose: onClose }, rest, { children: [showDrawerHeader && (_jsxs(_Fragment, { children: [_jsxs(Box, Object.assign({ className: classes.drawerHeader }, { children: [drawerHeaderContent, _jsx(IconButton, Object.assign({ className: classes.drawerHeaderAction, onClick: onClose }, { children: _jsx(Icon, { children: "close" }) }))] })), _jsx(Divider, {})] })), _jsx(ScrollContainer, Object.assign({}, ScrollContainerProps, { children: _jsx(List, Object.assign({ className: classes.drawerContent, onClick: onClose }, { children: drawerContent })) })), showDrawerFooterContent && (_jsx(_Fragment, { children: _jsx(Box, Object.assign({ className: classes.drawerFooter }, { children: drawerFooterContent ? (drawerFooterContent) : (_jsxs(_Fragment, { children: [canCreateLiveStream && _jsx(Divider, {}), _jsx(Box, Object.assign({ className: classes.drawerFooterLiveStream }, { children: _jsx(CreateLiveStreamButton, Object.assign({ color: "primary", className: classes.drawerFooterLiveStreamButton, fullWidth: true }, CreateLiveStreamButtonComponentProps)) }))] })) })) }))] })));
41
41
  }