@100mslive/roomkit-react 0.1.4-alpha.1 → 0.1.5

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 (152) hide show
  1. package/dist/{HLSView-F2K5VSTS.js → HLSView-P57IRMAR.js} +7 -11
  2. package/dist/{HLSView-F2K5VSTS.js.map → HLSView-P57IRMAR.js.map} +1 -1
  3. package/dist/PinnedTrackView-4FYJEBTB.js +102 -0
  4. package/dist/PinnedTrackView-4FYJEBTB.js.map +7 -0
  5. package/dist/Popover/index.d.ts +1 -0
  6. package/dist/Prebuilt/App.d.ts +25 -0
  7. package/dist/Prebuilt/index.d.ts +1 -0
  8. package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +1 -1
  9. package/dist/Sheet/Sheet.d.ts +3093 -0
  10. package/dist/Sheet/index.d.ts +1 -0
  11. package/dist/Theme/ThemeProvider.d.ts +4 -286
  12. package/dist/Theme/stitches.config.d.ts +1 -1
  13. package/dist/{VirtualBackground-S3XEPZ2T.js → VirtualBackground-GGCQJ5JM.js} +31 -7
  14. package/dist/VirtualBackground-GGCQJ5JM.js.map +7 -0
  15. package/dist/chunk-IVTWKQI3.js +827 -0
  16. package/dist/chunk-IVTWKQI3.js.map +7 -0
  17. package/dist/{chunk-42SWPN2C.js → chunk-OSM4QEQG.js} +3020 -2189
  18. package/dist/chunk-OSM4QEQG.js.map +7 -0
  19. package/dist/chunk-P5X32KOD.js +67 -0
  20. package/dist/chunk-P5X32KOD.js.map +7 -0
  21. package/dist/chunk-RVCZPPTL.js +1100 -0
  22. package/dist/chunk-RVCZPPTL.js.map +7 -0
  23. package/dist/{chunk-ESUJK7AT.js → conference-P6I6ESVF.js} +3136 -653
  24. package/dist/conference-P6I6ESVF.js.map +7 -0
  25. package/dist/index.cjs.js +15733 -15498
  26. package/dist/index.cjs.js.map +4 -4
  27. package/dist/index.js +4 -8
  28. package/dist/meta.cjs.json +3355 -3017
  29. package/dist/meta.esbuild.json +3534 -3329
  30. package/dist/utils/animations.d.ts +16 -0
  31. package/package.json +8 -10
  32. package/src/Button/Button.tsx +4 -4
  33. package/src/Dropdown/Dropdown.tsx +2 -2
  34. package/src/IconButton/IconButton.tsx +4 -2
  35. package/src/Pagination/StyledPagination.tsx +1 -0
  36. package/src/Popover/index.tsx +2 -1
  37. package/src/Prebuilt/{App.jsx → App.tsx} +95 -48
  38. package/src/Prebuilt/Prebuilt.stories.tsx +22 -8
  39. package/src/Prebuilt/common/constants.js +1 -2
  40. package/src/Prebuilt/common/hooks.js +8 -0
  41. package/src/Prebuilt/common/utils.js +15 -0
  42. package/src/Prebuilt/components/AppData/AppData.jsx +1 -2
  43. package/src/Prebuilt/components/AppData/useUISettings.js +0 -5
  44. package/src/Prebuilt/components/AudioVideoToggle.jsx +69 -26
  45. package/src/Prebuilt/components/AuthToken.jsx +3 -2
  46. package/src/Prebuilt/components/Chat/ChatSelector.jsx +1 -1
  47. package/src/Prebuilt/components/Connection/TileConnection.jsx +0 -1
  48. package/src/Prebuilt/components/EmojiReaction.jsx +23 -73
  49. package/src/Prebuilt/components/EndSessionContent.jsx +57 -0
  50. package/src/Prebuilt/components/EqualProminence.jsx +180 -0
  51. package/src/Prebuilt/components/ErrorBoundary.jsx +4 -10
  52. package/src/Prebuilt/components/Footer/EmojiCard.jsx +34 -0
  53. package/src/Prebuilt/components/Footer/Footer.jsx +73 -0
  54. package/src/Prebuilt/components/{Header → Footer}/ParticipantList.jsx +5 -5
  55. package/src/Prebuilt/components/Header/ConferencingHeader.jsx +27 -7
  56. package/src/Prebuilt/components/Header/HeaderComponents.jsx +16 -14
  57. package/src/Prebuilt/components/Header/StreamActions.jsx +101 -36
  58. package/src/Prebuilt/components/Header/StreamingHeader.jsx +1 -1
  59. package/src/Prebuilt/components/Header/common.jsx +164 -0
  60. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +1 -2
  61. package/src/Prebuilt/components/LeaveCard.jsx +19 -0
  62. package/src/Prebuilt/components/LeaveRoom.jsx +35 -143
  63. package/src/Prebuilt/components/LeaveSessionContent.jsx +45 -0
  64. package/src/Prebuilt/components/MoreSettings/ActionTile.jsx +55 -0
  65. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +96 -0
  66. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +31 -54
  67. package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +48 -73
  68. package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +5 -221
  69. package/src/Prebuilt/components/MoreSettings/MuteAllContent.jsx +61 -0
  70. package/src/Prebuilt/components/MoreSettings/MuteAllModal.jsx +32 -49
  71. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopLeaveRoom.jsx +129 -0
  72. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.jsx +219 -0
  73. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebLeaveRoom.jsx +100 -0
  74. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.jsx +259 -0
  75. package/src/Prebuilt/components/Notifications/Notifications.jsx +0 -2
  76. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +0 -4
  77. package/src/Prebuilt/components/PIP/PIPComponent.jsx +30 -26
  78. package/src/Prebuilt/components/PIP/PIPManager.js +13 -0
  79. package/src/Prebuilt/components/PIP/index.jsx +2 -7
  80. package/src/Prebuilt/components/Pagination.jsx +4 -4
  81. package/src/Prebuilt/components/Preview/PreviewContainer.jsx +5 -13
  82. package/src/Prebuilt/components/Preview/PreviewForm.jsx +9 -5
  83. package/src/Prebuilt/components/Preview/PreviewJoin.jsx +20 -27
  84. package/src/Prebuilt/components/RaiseHand.jsx +27 -0
  85. package/src/Prebuilt/components/ScreenShare.jsx +1 -1
  86. package/src/Prebuilt/components/ScreenshareDisplay.jsx +2 -2
  87. package/src/Prebuilt/components/ScreenshareTile.jsx +2 -2
  88. package/src/Prebuilt/components/Settings/DeviceSettings.jsx +2 -1
  89. package/src/Prebuilt/components/Settings/LayoutSettings.jsx +1 -24
  90. package/src/Prebuilt/components/Settings/SettingsModal.jsx +152 -17
  91. package/src/Prebuilt/components/ShareMenuIcon.jsx +1 -0
  92. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +133 -0
  93. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +313 -0
  94. package/src/Prebuilt/components/VideoList.jsx +5 -33
  95. package/src/Prebuilt/components/VideoTile.jsx +30 -8
  96. package/src/Prebuilt/components/conference.jsx +14 -1
  97. package/src/Prebuilt/components/init/Init.jsx +0 -27
  98. package/src/Prebuilt/components/init/initUtils.js +0 -23
  99. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +2 -1
  100. package/src/Prebuilt/components/pdfAnnotator/pdfInfo.jsx +1 -1
  101. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +19 -8
  102. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -0
  103. package/src/Prebuilt/images/pdf-share.png +0 -0
  104. package/src/Prebuilt/images/screen-share.png +0 -0
  105. package/src/Prebuilt/index.ts +1 -0
  106. package/src/Prebuilt/layouts/EmbedView.jsx +0 -1
  107. package/src/Prebuilt/layouts/InsetView.jsx +65 -24
  108. package/src/Prebuilt/layouts/PDFView.jsx +0 -1
  109. package/src/Prebuilt/layouts/SidePane.jsx +8 -7
  110. package/src/Prebuilt/layouts/mainView.jsx +22 -31
  111. package/src/Prebuilt/layouts/screenShareView.jsx +0 -2
  112. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +25 -1
  113. package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
  114. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
  115. package/src/Sheet/Sheet.mdx +19 -0
  116. package/src/Sheet/Sheet.stories.tsx +103 -0
  117. package/src/Sheet/Sheet.tsx +118 -0
  118. package/src/Sheet/index.ts +1 -0
  119. package/src/Theme/ThemeProvider.tsx +10 -13
  120. package/src/Theme/base.config.ts +1 -1
  121. package/src/Theme/stitches.config.ts +1 -1
  122. package/src/TileMenu/StyledMenuTile.tsx +2 -2
  123. package/src/TileMenu/TileMenu.tsx +2 -0
  124. package/src/VideoTile/StyledVideoTile.tsx +5 -0
  125. package/src/utils/animations.ts +18 -0
  126. package/dist/ActiveSpeakerView-V6O4K3BV.js +0 -39
  127. package/dist/ActiveSpeakerView-V6O4K3BV.js.map +0 -7
  128. package/dist/PinnedTrackView-7YQG4QKC.js +0 -70
  129. package/dist/PinnedTrackView-7YQG4QKC.js.map +0 -7
  130. package/dist/VirtualBackground-S3XEPZ2T.js.map +0 -7
  131. package/dist/chunk-42SWPN2C.js.map +0 -7
  132. package/dist/chunk-4NEZLVVH.js +0 -811
  133. package/dist/chunk-4NEZLVVH.js.map +0 -7
  134. package/dist/chunk-4ZBEFSRC.js +0 -58
  135. package/dist/chunk-4ZBEFSRC.js.map +0 -7
  136. package/dist/chunk-ESUJK7AT.js.map +0 -7
  137. package/dist/chunk-R6PDR5WZ.js +0 -243
  138. package/dist/chunk-R6PDR5WZ.js.map +0 -7
  139. package/dist/conference-7QKOMJPP.js +0 -3697
  140. package/dist/conference-7QKOMJPP.js.map +0 -7
  141. package/dist/transcription-RJA4V6PC.js +0 -356
  142. package/dist/transcription-RJA4V6PC.js.map +0 -7
  143. package/src/Prebuilt/common/useSortedPeers.js +0 -28
  144. package/src/Prebuilt/components/BottomActionSheet/BottomActionSheet.jsx +0 -96
  145. package/src/Prebuilt/components/BottomActionSheet/BottomActionSheet.stories.tsx +0 -46
  146. package/src/Prebuilt/components/Footer/ConferencingFooter.jsx +0 -101
  147. package/src/Prebuilt/components/Footer/StreamingFooter.jsx +0 -71
  148. package/src/Prebuilt/components/Footer.jsx +0 -8
  149. package/src/Prebuilt/components/MoreSettings/ChangeSelfRole.jsx +0 -67
  150. package/src/Prebuilt/components/TileMenu.jsx +0 -268
  151. package/src/Prebuilt/index.d.ts +0 -20
  152. package/src/Prebuilt/index.js +0 -2
@@ -1,356 +0,0 @@
1
- import {
2
- Box,
3
- Text
4
- } from "./chunk-R6PDR5WZ.js";
5
- import {
6
- IconButton_default,
7
- SESSION_STORE_KEY,
8
- Tooltip,
9
- __async,
10
- __publicField,
11
- __spreadProps,
12
- __spreadValues,
13
- define_process_env_default,
14
- init_define_process_env
15
- } from "./chunk-4NEZLVVH.js";
16
-
17
- // src/Prebuilt/plugins/transcription/index.jsx
18
- init_define_process_env();
19
-
20
- // src/Prebuilt/plugins/transcription/TranscriptionButton.jsx
21
- init_define_process_env();
22
- import React, { useCallback, useEffect, useRef } from "react";
23
- import {
24
- selectIsAllowedToPublish,
25
- selectSessionStore,
26
- useHMSActions,
27
- useHMSStore,
28
- useHMSVanillaStore
29
- } from "@100mslive/react-sdk";
30
- import { ClosedCaptionIcon } from "@100mslive/react-icons";
31
-
32
- // src/Prebuilt/plugins/transcription/Transcriber.js
33
- init_define_process_env();
34
- import RecordRTC, { StereoAudioRecorder } from "recordrtc";
35
- import { selectIsLocalAudioEnabled, selectLocalPeerName } from "@100mslive/react-sdk";
36
- var Transcriber = class {
37
- constructor({ hmsStore, setTranscriptAndSpeakingPeer, setIsTranscriptionEnabled }) {
38
- /**
39
- * This method is used to get the local peer's stream and observe it for changes.
40
- * @returns {Promise<void>}
41
- */
42
- __publicField(this, "getAndObserveStream", () => __async(this, null, function* () {
43
- const localPeer = window.__hms.sdk.getLocalPeer();
44
- const mediaTrack = localPeer.audioTrack.nativeTrack;
45
- if (!mediaTrack || mediaTrack.id === this.trackIdBeingObserved) {
46
- return;
47
- }
48
- this.trackIdBeingObserved = mediaTrack.id;
49
- console.log("transcription - observing local peer track", mediaTrack.id);
50
- try {
51
- if (this.recordRTCInstance) {
52
- console.log("transcription - destroying earlier instance");
53
- this.recordRTCInstance.destroy();
54
- }
55
- this.recordRTCInstance = null;
56
- } catch (err) {
57
- console.error("transcription - in destroying earlier instance", err);
58
- }
59
- const stream = new MediaStream([mediaTrack]);
60
- yield this.observeStream(stream);
61
- }));
62
- this.hmsStore = hmsStore;
63
- this.enabled = false;
64
- this.audioSocket = null;
65
- this.setTranscriptAndSpeakingPeer = setTranscriptAndSpeakingPeer;
66
- this.setIsTranscriptionEnabled = setIsTranscriptionEnabled;
67
- this.sttTuningConfig = {
68
- timeSlice: 250,
69
- desiredSampRate: 8e3,
70
- numberOfAudioChannels: 1,
71
- bufferSize: 256
72
- };
73
- this.resetTextTimer = null;
74
- this.localPeerName = hmsStore.getState(selectLocalPeerName);
75
- this.observingLocalPeerTrack = false;
76
- this.trackIdBeingObserved = null;
77
- this.recordRTCInstance = null;
78
- this.unsubscribes = [];
79
- }
80
- toggleTranscriptionState() {
81
- return __async(this, null, function* () {
82
- yield this.enableTranscription(!this.enabled);
83
- });
84
- }
85
- enableTranscription(enable) {
86
- return __async(this, null, function* () {
87
- if (enable === this.enabled) {
88
- return;
89
- }
90
- console.log("transcription enabled", enable);
91
- if (enable) {
92
- this.enabled = true;
93
- yield this.setIsTranscriptionEnabled(true);
94
- yield this.listen();
95
- } else {
96
- this.enabled = false;
97
- yield this.setIsTranscriptionEnabled(false);
98
- this.cleanup();
99
- }
100
- });
101
- }
102
- setTranscriptAndPeerWithExpiry(transcript, peerName) {
103
- if (!transcript) {
104
- return;
105
- }
106
- this.setTranscriptAndSpeakingPeer(transcript, `[${peerName}]`);
107
- clearTimeout(this.resetTextTimer);
108
- this.resetTextTimer = setTimeout(() => {
109
- this.resetTranscriptAndPeer();
110
- }, 5e3);
111
- }
112
- resetTranscriptAndPeer() {
113
- this.setTranscriptAndSpeakingPeer("", "");
114
- clearTimeout(this.resetTextTimer);
115
- }
116
- listen(retryCount = 0) {
117
- return __async(this, null, function* () {
118
- if (retryCount > 5) {
119
- console.error("transcription", "Max retry count reached!!", retryCount);
120
- this.cleanup();
121
- return;
122
- }
123
- try {
124
- let url = define_process_env_default.REACT_APP_DYNAMIC_STT_TOKEN_GENERATION_ENDPOINT;
125
- let res = yield fetch(url);
126
- let body = yield res.json();
127
- const authToken = body.token;
128
- if (authToken) {
129
- this.audioSocket = yield new WebSocket(
130
- `wss://api.assemblyai.com/v2/realtime/ws?sample_rate=${this.sttTuningConfig.desiredSampRate}&token=${authToken}`
131
- );
132
- this.resetTranscriptAndPeer();
133
- this.audioSocket.onmessage = (message) => {
134
- try {
135
- const res2 = JSON.parse(message.data);
136
- if (res2.text && this.enabled) {
137
- let messageText = res2.text.length >= 80 ? res2.text.split(" ").slice(Math.max(res2.text.split(" ").length - 10, 1)).join(" ") : res2.text;
138
- if (messageText) {
139
- this.setTranscriptAndPeerWithExpiry(messageText, this.localPeerName);
140
- }
141
- }
142
- } catch (err) {
143
- console.error("transcription", err);
144
- }
145
- };
146
- this.audioSocket.onerror = (event) => {
147
- console.error("transcription", event);
148
- this.audioSocket.close();
149
- };
150
- this.audioSocket.onclose = (event) => {
151
- try {
152
- console.log(event);
153
- this.audioSocket = null;
154
- if (this.enabled && event.code !== 4001) {
155
- this.listen(retryCount++);
156
- }
157
- } catch (err) {
158
- console.error("transcription", err);
159
- }
160
- };
161
- this.audioSocket.onopen = () => {
162
- this.observeLocalPeerTrack();
163
- };
164
- } else {
165
- console.error("Unable to fetch dynamic token!!");
166
- }
167
- } catch (err) {
168
- console.error("transcription", err);
169
- }
170
- });
171
- }
172
- observeLocalPeerTrack() {
173
- return __async(this, null, function* () {
174
- try {
175
- if (this.observingLocalPeerTrack) {
176
- return;
177
- }
178
- this.observingLocalPeerTrack = true;
179
- console.log("transcription - observing local peer track");
180
- let unsub = this.hmsStore.subscribe(this.getAndObserveStream, selectIsLocalAudioEnabled);
181
- this.unsubscribes.push(unsub);
182
- this.getAndObserveStream();
183
- } catch (err) {
184
- console.error("transcription - observing local peer track", err);
185
- }
186
- });
187
- }
188
- observeStream(stream) {
189
- return __async(this, null, function* () {
190
- this.recordRTCInstance = new RecordRTC(stream, __spreadProps(__spreadValues({}, this.sttTuningConfig), {
191
- type: "audio",
192
- mimeType: "audio/webm;codecs=pcm",
193
- recorderType: StereoAudioRecorder,
194
- ondataavailable: (blob) => {
195
- const reader = new FileReader();
196
- reader.onload = () => {
197
- const base64data = reader.result;
198
- if (this.audioSocket && this.enabled && this.audioSocket.readyState && this.audioSocket.readyState === 1) {
199
- try {
200
- this.audioSocket.send(JSON.stringify({ audio_data: base64data.split("base64,")[1] }));
201
- } catch (err) {
202
- console.error("transcription", err);
203
- }
204
- }
205
- };
206
- reader.readAsDataURL(blob);
207
- }
208
- }));
209
- this.recordRTCInstance.startRecording();
210
- });
211
- }
212
- cleanup() {
213
- console.log("transcription - cleanup");
214
- if (this.audioSocket) {
215
- try {
216
- this.audioSocket.close();
217
- this.audioSocket = null;
218
- } catch (err) {
219
- console.error("transcription cleanup - couldn't close socket", err);
220
- }
221
- }
222
- if (this.recordRTCInstance) {
223
- try {
224
- this.recordRTCInstance.destroy();
225
- this.recordRTCInstance = null;
226
- } catch (err) {
227
- console.error("transcription cleanup - couldn't stop recording", err);
228
- }
229
- }
230
- for (const unsub of this.unsubscribes) {
231
- unsub();
232
- }
233
- this.resetTranscriptAndPeer();
234
- }
235
- };
236
-
237
- // src/Prebuilt/plugins/transcription/TranscriptionButton.jsx
238
- function TranscriptionButton() {
239
- const transcriptionState = useHMSStore(selectSessionStore(SESSION_STORE_KEY.TRANSCRIPTION_STATE));
240
- const rawStore = useHMSVanillaStore();
241
- const isTranscriptionEnabled = !!(transcriptionState == null ? void 0 : transcriptionState.enabled);
242
- let transcript = "", speakingPeer = "";
243
- if (isTranscriptionEnabled) {
244
- transcript = transcriptionState.transcript || "";
245
- speakingPeer = transcriptionState.speakingPeer || "";
246
- }
247
- const transcriber = useRef(null);
248
- const hmsActions = useHMSActions();
249
- const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);
250
- useEffect(() => {
251
- hmsActions.sessionStore.observe(SESSION_STORE_KEY.TRANSCRIPTION_STATE);
252
- }, [hmsActions]);
253
- useEffect(() => {
254
- if (!transcriber.current) {
255
- transcriber.current = new Transcriber({
256
- hmsStore: rawStore,
257
- setTranscriptAndSpeakingPeer: (transcript2, peerName) => __async(this, null, function* () {
258
- var _a;
259
- const transcriptionCurrentEnabledState = !!((_a = rawStore.getState(
260
- selectSessionStore(SESSION_STORE_KEY.TRANSCRIPTION_STATE)
261
- )) == null ? void 0 : _a.enabled);
262
- yield hmsActions.sessionStore.set(SESSION_STORE_KEY.TRANSCRIPTION_STATE, {
263
- enabled: transcriptionCurrentEnabledState,
264
- transcript: transcript2,
265
- speakingPeer: peerName
266
- });
267
- }),
268
- setIsTranscriptionEnabled: (newEnabledState) => __async(this, null, function* () {
269
- yield hmsActions.sessionStore.set(SESSION_STORE_KEY.TRANSCRIPTION_STATE, {
270
- enabled: newEnabledState
271
- });
272
- })
273
- });
274
- }
275
- return () => {
276
- if (transcriber.current) {
277
- transcriber.current.cleanup();
278
- }
279
- };
280
- }, [hmsActions, rawStore]);
281
- useEffect(() => {
282
- if (isTranscriptionEnabled) {
283
- transcriber.current.enableTranscription(true);
284
- }
285
- }, [isTranscriptionEnabled]);
286
- const toggleTranscriptionState = useCallback(() => {
287
- transcriber.current.toggleTranscriptionState();
288
- }, []);
289
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
290
- Box,
291
- {
292
- css: {
293
- textAlign: "left",
294
- fontWeight: "$medium",
295
- bottom: "120px",
296
- position: "fixed",
297
- width: "100%",
298
- fontSize: "$20px",
299
- zIndex: "1000000",
300
- color: "white",
301
- textShadow: "0px 0px 6px #000",
302
- whiteSpace: "pre-line",
303
- paddingLeft: "40px"
304
- }
305
- }
306
- ), /* @__PURE__ */ React.createElement(
307
- Box,
308
- {
309
- css: {
310
- textAlign: "center",
311
- fontWeight: "$medium",
312
- bottom: "90px",
313
- position: "fixed",
314
- width: "100%",
315
- fontSize: "$20px",
316
- zIndex: "1000000",
317
- color: "white",
318
- textShadow: "0px 0px 6px #000",
319
- whiteSpace: "pre-line"
320
- }
321
- },
322
- /* @__PURE__ */ React.createElement(
323
- Text,
324
- {
325
- css: {
326
- color: "white",
327
- textShadow: "0px 0px 6px #000"
328
- }
329
- },
330
- transcript
331
- ),
332
- /* @__PURE__ */ React.createElement(
333
- Text,
334
- {
335
- css: {
336
- color: "#c0bbbb",
337
- textShadow: "0px 0px 6px #000",
338
- textTransform: "capitalize"
339
- }
340
- },
341
- speakingPeer
342
- )
343
- ), isAllowedToPublish.audio && /* @__PURE__ */ React.createElement(Tooltip, { title: `Turn ${!isTranscriptionEnabled ? "on" : "off"} transcription` }, /* @__PURE__ */ React.createElement(
344
- IconButton_default,
345
- {
346
- active: !isTranscriptionEnabled,
347
- onClick: toggleTranscriptionState,
348
- "data-testid": "transcription_btn"
349
- },
350
- /* @__PURE__ */ React.createElement(ClosedCaptionIcon, null)
351
- )));
352
- }
353
- export {
354
- TranscriptionButton as default
355
- };
356
- //# sourceMappingURL=transcription-RJA4V6PC.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/Prebuilt/plugins/transcription/index.jsx", "../src/Prebuilt/plugins/transcription/TranscriptionButton.jsx", "../src/Prebuilt/plugins/transcription/Transcriber.js"],
4
- "sourcesContent": ["export { TranscriptionButton as default } from './TranscriptionButton';\n", "import React, { useCallback, useEffect, useRef } from 'react';\nimport {\n selectIsAllowedToPublish,\n selectSessionStore,\n useHMSActions,\n useHMSStore,\n useHMSVanillaStore,\n} from '@100mslive/react-sdk';\nimport { ClosedCaptionIcon } from '@100mslive/react-icons';\nimport { Box } from '../../../Layout';\nimport { Text } from '../../../Text';\nimport { Tooltip } from '../../../Tooltip';\nimport IconButton from '../../IconButton';\nimport { Transcriber } from './Transcriber';\nimport { SESSION_STORE_KEY } from '../../common/constants';\n\nexport function TranscriptionButton() {\n const transcriptionState = useHMSStore(selectSessionStore(SESSION_STORE_KEY.TRANSCRIPTION_STATE));\n const rawStore = useHMSVanillaStore();\n const isTranscriptionEnabled = !!transcriptionState?.enabled;\n let transcript = '',\n speakingPeer = '';\n if (isTranscriptionEnabled) {\n transcript = transcriptionState.transcript || '';\n speakingPeer = transcriptionState.speakingPeer || '';\n }\n\n const transcriber = useRef(null);\n const hmsActions = useHMSActions();\n const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);\n\n useEffect(() => {\n hmsActions.sessionStore.observe(SESSION_STORE_KEY.TRANSCRIPTION_STATE);\n }, [hmsActions]);\n\n useEffect(() => {\n if (!transcriber.current) {\n // create transcriber with the current room state for transcription\n transcriber.current = new Transcriber({\n hmsStore: rawStore,\n setTranscriptAndSpeakingPeer: async (transcript, peerName) => {\n const transcriptionCurrentEnabledState = !!rawStore.getState(\n selectSessionStore(SESSION_STORE_KEY.TRANSCRIPTION_STATE),\n )?.enabled;\n await hmsActions.sessionStore.set(SESSION_STORE_KEY.TRANSCRIPTION_STATE, {\n enabled: transcriptionCurrentEnabledState,\n transcript,\n speakingPeer: peerName,\n });\n },\n setIsTranscriptionEnabled: async newEnabledState => {\n await hmsActions.sessionStore.set(SESSION_STORE_KEY.TRANSCRIPTION_STATE, {\n enabled: newEnabledState,\n });\n },\n });\n }\n return () => {\n if (transcriber.current) {\n transcriber.current.cleanup();\n }\n };\n }, [hmsActions, rawStore]);\n\n useEffect(() => {\n // remote enabled transcript\n if (isTranscriptionEnabled) {\n transcriber.current.enableTranscription(true);\n }\n }, [isTranscriptionEnabled]);\n\n const toggleTranscriptionState = useCallback(() => {\n transcriber.current.toggleTranscriptionState();\n }, []);\n\n return (\n <>\n <Box\n css={{\n textAlign: 'left',\n fontWeight: '$medium',\n bottom: '120px',\n position: 'fixed',\n width: '100%',\n fontSize: '$20px',\n zIndex: '1000000',\n color: 'white',\n textShadow: '0px 0px 6px #000',\n whiteSpace: 'pre-line',\n paddingLeft: '40px',\n }}\n />\n <Box\n css={{\n textAlign: 'center',\n fontWeight: '$medium',\n bottom: '90px',\n position: 'fixed',\n width: '100%',\n fontSize: '$20px',\n zIndex: '1000000',\n color: 'white',\n textShadow: '0px 0px 6px #000',\n whiteSpace: 'pre-line',\n }}\n >\n <Text\n css={{\n color: 'white',\n textShadow: '0px 0px 6px #000',\n }}\n >\n {transcript}\n </Text>\n <Text\n css={{\n color: '#c0bbbb',\n textShadow: '0px 0px 6px #000',\n textTransform: 'capitalize',\n }}\n >\n {speakingPeer}\n </Text>\n </Box>\n {isAllowedToPublish.audio && (\n <Tooltip title={`Turn ${!isTranscriptionEnabled ? 'on' : 'off'} transcription`}>\n <IconButton\n active={!isTranscriptionEnabled}\n onClick={toggleTranscriptionState}\n data-testid=\"transcription_btn\"\n >\n <ClosedCaptionIcon />\n </IconButton>\n </Tooltip>\n )}\n </>\n );\n}\n", "import RecordRTC, { StereoAudioRecorder } from 'recordrtc';\nimport { selectIsLocalAudioEnabled, selectLocalPeerName } from '@100mslive/react-sdk';\n\nexport class Transcriber {\n constructor({ hmsStore, setTranscriptAndSpeakingPeer, setIsTranscriptionEnabled }) {\n this.hmsStore = hmsStore;\n this.enabled = false;\n this.audioSocket = null; // this is the socket that will be used to send audio to the STT server\n this.setTranscriptAndSpeakingPeer = setTranscriptAndSpeakingPeer;\n this.setIsTranscriptionEnabled = setIsTranscriptionEnabled;\n this.sttTuningConfig = {\n timeSlice: 250,\n desiredSampRate: 8000,\n numberOfAudioChannels: 1,\n bufferSize: 256,\n };\n this.resetTextTimer = null; // used to reset the transcript after some time, if no new update comes\n this.localPeerName = hmsStore.getState(selectLocalPeerName);\n this.observingLocalPeerTrack = false;\n this.trackIdBeingObserved = null;\n this.recordRTCInstance = null;\n this.unsubscribes = [];\n }\n\n async toggleTranscriptionState() {\n await this.enableTranscription(!this.enabled);\n }\n\n async enableTranscription(enable) {\n if (enable === this.enabled) {\n return;\n }\n console.log('transcription enabled', enable);\n if (enable) {\n this.enabled = true;\n await this.setIsTranscriptionEnabled(true);\n await this.listen();\n } else {\n this.enabled = false;\n await this.setIsTranscriptionEnabled(false);\n this.cleanup();\n }\n }\n\n setTranscriptAndPeerWithExpiry(transcript, peerName) {\n if (!transcript) {\n return;\n }\n this.setTranscriptAndSpeakingPeer(transcript, `[${peerName}]`);\n // reset after some time if no new update comes\n clearTimeout(this.resetTextTimer);\n this.resetTextTimer = setTimeout(() => {\n this.resetTranscriptAndPeer();\n }, 5000);\n }\n\n resetTranscriptAndPeer() {\n this.setTranscriptAndSpeakingPeer('', '');\n clearTimeout(this.resetTextTimer);\n }\n\n async listen(retryCount = 0) {\n if (retryCount > 5) {\n console.error('transcription', 'Max retry count reached!!', retryCount);\n this.cleanup();\n return;\n }\n try {\n let url = process.env.REACT_APP_DYNAMIC_STT_TOKEN_GENERATION_ENDPOINT;\n let res = await fetch(url);\n let body = await res.json();\n const authToken = body.token;\n\n if (authToken) {\n this.audioSocket = await new WebSocket(\n `wss://api.assemblyai.com/v2/realtime/ws?sample_rate=${this.sttTuningConfig.desiredSampRate}&token=${authToken}`,\n );\n this.resetTranscriptAndPeer();\n this.audioSocket.onmessage = message => {\n try {\n const res = JSON.parse(message.data);\n if (res.text && this.enabled) {\n //Limiting the transcript size based on it's charecter length.\n let messageText =\n res.text.length >= 80\n ? res.text\n .split(' ')\n .slice(Math.max(res.text.split(' ').length - 10, 1))\n .join(' ')\n : res.text;\n if (messageText) {\n this.setTranscriptAndPeerWithExpiry(messageText, this.localPeerName);\n }\n }\n } catch (err) {\n console.error('transcription', err);\n }\n };\n\n this.audioSocket.onerror = event => {\n console.error('transcription', event);\n this.audioSocket.close();\n };\n\n this.audioSocket.onclose = event => {\n try {\n console.log(event);\n this.audioSocket = null;\n if (this.enabled && event.code !== 4001) {\n this.listen(retryCount++);\n }\n } catch (err) {\n console.error('transcription', err);\n }\n };\n\n this.audioSocket.onopen = () => {\n this.observeLocalPeerTrack();\n };\n } else {\n console.error('Unable to fetch dynamic token!!');\n }\n } catch (err) {\n console.error('transcription', err);\n }\n }\n\n async observeLocalPeerTrack() {\n try {\n if (this.observingLocalPeerTrack) {\n return;\n }\n this.observingLocalPeerTrack = true;\n console.log('transcription - observing local peer track');\n let unsub = this.hmsStore.subscribe(this.getAndObserveStream, selectIsLocalAudioEnabled);\n this.unsubscribes.push(unsub);\n this.getAndObserveStream(); // call it once to start observing initially\n } catch (err) {\n console.error('transcription - observing local peer track', err);\n }\n }\n\n /**\n * This method is used to get the local peer's stream and observe it for changes.\n * @returns {Promise<void>}\n */\n getAndObserveStream = async () => {\n // a hacky way to get the local peer's stream till we have a better way\n const localPeer = window.__hms.sdk.getLocalPeer();\n const mediaTrack = localPeer.audioTrack.nativeTrack;\n if (!mediaTrack || mediaTrack.id === this.trackIdBeingObserved) {\n return;\n }\n this.trackIdBeingObserved = mediaTrack.id;\n console.log('transcription - observing local peer track', mediaTrack.id);\n try {\n if (this.recordRTCInstance) {\n console.log('transcription - destroying earlier instance');\n this.recordRTCInstance.destroy();\n }\n this.recordRTCInstance = null;\n } catch (err) {\n console.error('transcription - in destroying earlier instance', err);\n }\n const stream = new MediaStream([mediaTrack]);\n await this.observeStream(stream);\n };\n\n async observeStream(stream) {\n this.recordRTCInstance = new RecordRTC(stream, {\n ...this.sttTuningConfig,\n type: 'audio',\n mimeType: 'audio/webm;codecs=pcm',\n recorderType: StereoAudioRecorder,\n ondataavailable: blob => {\n const reader = new FileReader();\n reader.onload = () => {\n const base64data = reader.result;\n if (this.audioSocket && this.enabled && this.audioSocket.readyState && this.audioSocket.readyState === 1) {\n try {\n this.audioSocket.send(JSON.stringify({ audio_data: base64data.split('base64,')[1] }));\n } catch (err) {\n console.error('transcription', err);\n }\n }\n };\n reader.readAsDataURL(blob);\n },\n });\n this.recordRTCInstance.startRecording();\n }\n\n cleanup() {\n console.log('transcription - cleanup');\n if (this.audioSocket) {\n try {\n this.audioSocket.close();\n this.audioSocket = null;\n } catch (err) {\n console.error(\"transcription cleanup - couldn't close socket\", err);\n }\n }\n if (this.recordRTCInstance) {\n try {\n this.recordRTCInstance.destroy();\n this.recordRTCInstance = null;\n } catch (err) {\n console.error(\"transcription cleanup - couldn't stop recording\", err);\n }\n }\n for (const unsub of this.unsubscribes) {\n unsub();\n }\n this.resetTranscriptAndPeer();\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["res", "transcript"]
7
- }
@@ -1,28 +0,0 @@
1
- import { useEffect, useRef, useState } from 'react';
2
- import { useHMSVanillaStore } from '@100mslive/react-sdk';
3
- import PeersSorter from './PeersSorter';
4
- import { useActiveSpeakerSorting } from '../components/AppData/useUISettings';
5
-
6
- function useSortedPeers({ peers, maxTileCount = 9 }) {
7
- const [sortedPeers, setSortedPeers] = useState([]);
8
- const store = useHMSVanillaStore();
9
- const activeSpeakerSorting = useActiveSpeakerSorting();
10
- const peerSortedRef = useRef(new PeersSorter(store));
11
- peerSortedRef.current.onUpdate(setSortedPeers);
12
-
13
- useEffect(() => {
14
- const peersSorter = peerSortedRef.current;
15
- if (peers?.length > 0 && maxTileCount && activeSpeakerSorting) {
16
- peersSorter.setPeersAndTilesPerPage({
17
- peers,
18
- tilesPerPage: maxTileCount,
19
- });
20
- } else if (!activeSpeakerSorting) {
21
- peersSorter.stop();
22
- }
23
- }, [maxTileCount, peers, activeSpeakerSorting]);
24
-
25
- return activeSpeakerSorting ? sortedPeers : peers;
26
- }
27
-
28
- export default useSortedPeers;
@@ -1,96 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import { CrossIcon } from '@100mslive/react-icons';
3
- import { Box, Flex, Popover, Text } from '../../..';
4
- import { getUpdatedHeight } from '../../common/utils';
5
-
6
- const BottomActionSheet = ({
7
- title = '',
8
- children = <></>,
9
- triggerContent,
10
- containerCSS = {},
11
- // By default the component starts just above the trigger.
12
- // A negative offset allows it to start from the bottom of the screen.
13
- sideOffset = -50,
14
- defaultHeight = 50,
15
- }) => {
16
- const MINIMUM_HEIGHT = 40; // vh
17
- const [sheetOpen, setSheetOpen] = useState(false);
18
- const [sheetHeight, setSheetHeight] = useState(`${Math.min(Math.max(MINIMUM_HEIGHT, defaultHeight), 100)}vh`);
19
- const closeRef = useRef(null);
20
-
21
- // Close the sheet if height goes under MINIMUM_HEIGHT
22
- useEffect(() => {
23
- if (closeRef?.current && parseFloat(sheetHeight.slice(0, -2)) <= MINIMUM_HEIGHT) {
24
- setSheetOpen(false);
25
- // Delay for showing the opacity animation, can be removed if not needed
26
- setTimeout(() => closeRef.current?.click(), 200);
27
- }
28
- }, [sheetHeight]);
29
-
30
- return (
31
- <>
32
- <Popover.Root
33
- onOpenChange={open => {
34
- if (!open) {
35
- setSheetHeight('0');
36
- }
37
- setSheetOpen(open);
38
- }}
39
- >
40
- <Popover.Trigger asChild>{triggerContent}</Popover.Trigger>
41
- <Popover.Portal>
42
- <Popover.Content sideOffset={sideOffset} style={{ zIndex: '2' }}>
43
- <Box
44
- css={{
45
- w: '100vw',
46
- py: '$8',
47
- opacity: sheetOpen ? '1' : '0.5',
48
- h: sheetHeight,
49
- minHeight: '50vh',
50
- overflowY: 'auto',
51
- backgroundColor: '$surface_default',
52
- transition: 'all 0.2s linear',
53
- ...containerCSS,
54
- }}
55
- >
56
- <Flex
57
- justify="between"
58
- onTouchMove={e => {
59
- const updatedSheetHeight = getUpdatedHeight(e, MINIMUM_HEIGHT);
60
- setSheetHeight(updatedSheetHeight);
61
- }}
62
- css={{
63
- borderBottom: '1px solid $border_bright',
64
- px: '$8',
65
- pb: '$4',
66
- mb: '$4',
67
- w: '100%',
68
- }}
69
- >
70
- <Text variant="h6" css={{ color: '$on_surface_high' }}>
71
- {title}
72
- </Text>
73
- <Popover.Close aria-label="Close">
74
- <Box
75
- ref={closeRef}
76
- css={{
77
- color: '$on_surface_high',
78
- bg: '$surface_bright',
79
- p: '$2',
80
- borderRadius: '$round',
81
- }}
82
- >
83
- <CrossIcon />
84
- </Box>
85
- </Popover.Close>
86
- </Flex>
87
- <Box css={{ px: '$8', maxHeight: '100%', overflowY: 'auto' }}>{children}</Box>
88
- </Box>
89
- </Popover.Content>
90
- </Popover.Portal>
91
- </Popover.Root>
92
- </>
93
- );
94
- };
95
-
96
- export default BottomActionSheet;
@@ -1,46 +0,0 @@
1
- import React, { ReactElement } from 'react';
2
- import { Meta } from '@storybook/react';
3
- import { Button } from '../../../Button';
4
- import { Box } from '../../../Layout';
5
- import { Text } from '../../../Text';
6
- import { CSS } from '../../../Theme';
7
- import BottomActionSheet from './BottomActionSheet';
8
-
9
- // WIP
10
-
11
- export default {
12
- title: 'Components/BottomActionSheet',
13
- component: BottomActionSheet,
14
- argTypes: {
15
- title: { control: 'text' },
16
- triggerContent: { control: 'jsx' },
17
- containerCSS: { control: 'object' },
18
- sideOffset: { control: 'number' },
19
- defaultHeight: { control: 'number' },
20
- },
21
- } as Meta;
22
-
23
- interface BottomActionSheetProps {
24
- title: string;
25
- triggerContent: ReactElement;
26
- children: ReactElement;
27
- containerCSS: CSS;
28
- sideOffset: number;
29
- defaultHeight: number;
30
- }
31
-
32
- const Template = (args: BottomActionSheetProps) => (
33
- <BottomActionSheet {...args}>
34
- <Box>
35
- <Text>This is the content of the BottomActionSheet.</Text>
36
- <Text>You can put any content you like here.</Text>
37
- </Box>
38
- </BottomActionSheet>
39
- );
40
-
41
- // Example story with default props
42
- export const Default = Template.bind({});
43
- Default.args = {
44
- title: 'Example BottomActionSheet',
45
- triggerContent: <Button>Open BottomActionSheet</Button>,
46
- };
@@ -1,101 +0,0 @@
1
- import React, { Fragment, Suspense, useState } from 'react';
2
- import { useMedia } from 'react-use';
3
- import { selectIsAllowedToPublish, useHMSStore, useScreenShare } from '@100mslive/react-sdk';
4
- import { MusicIcon } from '@100mslive/react-icons';
5
- import { config as cssConfig, Flex, Footer as AppFooter, Tooltip } from '../../../';
6
- import IconButton from '../../IconButton';
7
- import { AudioVideoToggle } from '../AudioVideoToggle';
8
- import { EmojiReaction } from '../EmojiReaction';
9
- import { LeaveRoom } from '../LeaveRoom';
10
- import MetaActions from '../MetaActions';
11
- import { MoreSettings } from '../MoreSettings/MoreSettings';
12
- import { PIP } from '../PIP';
13
- import { ScreenshareToggle } from '../ScreenShare';
14
- import { ScreenShareHintModal } from '../ScreenshareHintModal';
15
- import { ChatToggle } from './ChatToggle';
16
- import { useIsFeatureEnabled } from '../hooks/useFeatures';
17
- import { isScreenshareSupported } from '../../common/utils';
18
- import { FeatureFlags } from '../../services/FeatureFlags';
19
- import { FEATURE_LIST } from '../../common/constants';
20
-
21
- const TranscriptionButton = React.lazy(() => import('../../plugins/transcription'));
22
- const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground'));
23
-
24
- const ScreenshareAudio = () => {
25
- const {
26
- amIScreenSharing,
27
- screenShareVideoTrackId: video,
28
- screenShareAudioTrackId: audio,
29
- toggleScreenShare,
30
- } = useScreenShare();
31
- const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);
32
- const isAudioScreenshare = amIScreenSharing && !video && !!audio;
33
- const [showModal, setShowModal] = useState(false);
34
- const isFeatureEnabled = useIsFeatureEnabled(FEATURE_LIST.AUDIO_ONLY_SCREENSHARE);
35
- if (!isFeatureEnabled || !isAllowedToPublish.screen || !isScreenshareSupported()) {
36
- return null;
37
- }
38
- return (
39
- <Fragment>
40
- <Tooltip title={`${!isAudioScreenshare ? 'Start' : 'Stop'} audio sharing`} key="shareAudio">
41
- <IconButton
42
- active={!isAudioScreenshare}
43
- onClick={() => {
44
- if (amIScreenSharing) {
45
- toggleScreenShare();
46
- } else {
47
- setShowModal(true);
48
- }
49
- }}
50
- data-testid="screenshare_audio"
51
- >
52
- <MusicIcon />
53
- </IconButton>
54
- </Tooltip>
55
- {showModal && <ScreenShareHintModal onClose={() => setShowModal(false)} />}
56
- </Fragment>
57
- );
58
- };
59
-
60
- export const ConferencingFooter = () => {
61
- const isMobile = useMedia(cssConfig.media.md);
62
- return (
63
- <AppFooter.Root>
64
- <AppFooter.Left>
65
- <ScreenshareAudio />
66
- <Suspense fallback="">
67
- <VirtualBackground />
68
- </Suspense>
69
- {FeatureFlags.enableTranscription ? <TranscriptionButton /> : null}
70
- <Flex
71
- align="center"
72
- css={{
73
- display: 'none',
74
- '@md': {
75
- display: 'flex',
76
- gap: '$8',
77
- },
78
- }}
79
- >
80
- {isMobile && <EmojiReaction />}
81
- <MetaActions isMobile />
82
- </Flex>
83
- </AppFooter.Left>
84
- <AppFooter.Center>
85
- <AudioVideoToggle />
86
- <ScreenshareToggle />
87
- <PIP />
88
- <MoreSettings />
89
- <Flex align="center" css={{ display: 'none', '@md': { display: 'flex' } }}>
90
- <ChatToggle />
91
- </Flex>
92
- <LeaveRoom />
93
- </AppFooter.Center>
94
- <AppFooter.Right>
95
- {!isMobile && <EmojiReaction />}
96
- <MetaActions />
97
- <ChatToggle />
98
- </AppFooter.Right>
99
- </AppFooter.Root>
100
- );
101
- };