@whereby.com/browser-sdk 2.0.0-beta4 → 2.1.0-beta1
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/README.md +15 -0
- package/dist/{v2-beta4.js → cdn/v2-embed-beta1.js} +5 -5
- package/dist/cdn/v2-react-beta1.js +3 -0
- package/dist/embed/index.d.ts +63 -3
- package/dist/embed/index.esm.js +3 -3
- package/dist/react/index.d.ts +12 -6
- package/dist/react/index.esm.js +56 -17
- package/package.json +2 -1
package/dist/embed/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { ReactHTMLElement } from 'react';
|
|
2
|
+
|
|
3
|
+
interface WherebyEmbedElementAttributes extends ReactHTMLElement<HTMLElement> {
|
|
2
4
|
audio: string;
|
|
3
5
|
avatarUrl: string;
|
|
4
6
|
background: string;
|
|
@@ -35,10 +37,68 @@ interface WherebyEmbedAttributes {
|
|
|
35
37
|
video: string;
|
|
36
38
|
virtualBackgroundUrl: string;
|
|
37
39
|
}
|
|
40
|
+
interface WherebyEmbedElementEventMap {
|
|
41
|
+
ready: CustomEvent;
|
|
42
|
+
knock: CustomEvent;
|
|
43
|
+
participantupdate: CustomEvent<{
|
|
44
|
+
count: number;
|
|
45
|
+
}>;
|
|
46
|
+
join: CustomEvent;
|
|
47
|
+
leave: CustomEvent<{
|
|
48
|
+
removed: boolean;
|
|
49
|
+
}>;
|
|
50
|
+
participant_join: CustomEvent<{
|
|
51
|
+
participant: {
|
|
52
|
+
metadata: string;
|
|
53
|
+
};
|
|
54
|
+
}>;
|
|
55
|
+
participant_leave: CustomEvent<{
|
|
56
|
+
participant: {
|
|
57
|
+
metadata: string;
|
|
58
|
+
};
|
|
59
|
+
}>;
|
|
60
|
+
microphone_toggle: CustomEvent<{
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
}>;
|
|
63
|
+
camera_toggle: CustomEvent<{
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
}>;
|
|
66
|
+
chat_toggle: CustomEvent<{
|
|
67
|
+
open: boolean;
|
|
68
|
+
}>;
|
|
69
|
+
pip_toggle: CustomEvent<{
|
|
70
|
+
open: boolean;
|
|
71
|
+
}>;
|
|
72
|
+
deny_device_permission: CustomEvent<{
|
|
73
|
+
denied: boolean;
|
|
74
|
+
}>;
|
|
75
|
+
screenshare_toggle: CustomEvent<{
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
}>;
|
|
78
|
+
streaming_status_change: CustomEvent<{
|
|
79
|
+
status: string;
|
|
80
|
+
}>;
|
|
81
|
+
connection_status_change: CustomEvent<{
|
|
82
|
+
status: "stable" | "unstable";
|
|
83
|
+
}>;
|
|
84
|
+
}
|
|
85
|
+
interface WherebyEmbedElementCommands {
|
|
86
|
+
startRecording: () => void;
|
|
87
|
+
stopRecording: () => void;
|
|
88
|
+
startStreaming: () => void;
|
|
89
|
+
stopStreaming: () => void;
|
|
90
|
+
toggleCamera: (enabled?: boolean) => void;
|
|
91
|
+
toggleMicrophone: (enabled?: boolean) => void;
|
|
92
|
+
toggleScreenshare: (enabled?: boolean) => void;
|
|
93
|
+
toogleChat: (enabled?: boolean) => void;
|
|
94
|
+
}
|
|
95
|
+
interface WherebyEmbedElement extends HTMLIFrameElement, WherebyEmbedElementCommands {
|
|
96
|
+
addEventListener<K extends keyof (WherebyEmbedElementEventMap & HTMLElementEventMap)>(type: K, listener: (this: HTMLIFrameElement, ev: (WherebyEmbedElementEventMap & HTMLElementEventMap)[K]) => void, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
97
|
+
}
|
|
38
98
|
declare global {
|
|
39
99
|
namespace JSX {
|
|
40
100
|
interface IntrinsicElements {
|
|
41
|
-
["whereby-embed"]: Partial<
|
|
101
|
+
["whereby-embed"]: Partial<WherebyEmbedElementAttributes>;
|
|
42
102
|
}
|
|
43
103
|
}
|
|
44
104
|
}
|
|
@@ -46,4 +106,4 @@ declare const _default: {
|
|
|
46
106
|
sdkVersion: string;
|
|
47
107
|
};
|
|
48
108
|
|
|
49
|
-
export { _default as default };
|
|
109
|
+
export { type WherebyEmbedElement, _default as default };
|
package/dist/embed/index.esm.js
CHANGED
|
@@ -20,7 +20,7 @@ function parseRoomUrlAndSubdomain(roomAttribute, subdomainAttribute) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const sdkVersion = "2.
|
|
23
|
+
const sdkVersion = "2.1.0-beta1";
|
|
24
24
|
|
|
25
25
|
const boolAttrs = [
|
|
26
26
|
"audio",
|
|
@@ -119,7 +119,7 @@ define("WherebyEmbed", {
|
|
|
119
119
|
toggleChat(enabled) {
|
|
120
120
|
this._postCommand("toggle_chat", [enabled]);
|
|
121
121
|
},
|
|
122
|
-
onmessage({ origin, data }) {
|
|
122
|
+
onmessage({ origin, data, }) {
|
|
123
123
|
if (!this.roomUrl || origin !== this.roomUrl.origin)
|
|
124
124
|
return;
|
|
125
125
|
const { type, payload: detail } = data;
|
|
@@ -147,7 +147,7 @@ define("WherebyEmbed", {
|
|
|
147
147
|
title=${title || "Video calling component"}
|
|
148
148
|
ref=${this.iframe}
|
|
149
149
|
src=${this.roomUrl}
|
|
150
|
-
allow="autoplay; camera; microphone; fullscreen; speaker; display-capture" />
|
|
150
|
+
allow="autoplay; camera; microphone; fullscreen; speaker; display-capture; media-capture" />
|
|
151
151
|
`;
|
|
152
152
|
},
|
|
153
153
|
});
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import React__default from 'react';
|
|
1
|
+
import * as React$1 from 'react';
|
|
3
2
|
import _whereby_jslib_media_src_utils_ServerSocket, { ChatMessage as ChatMessage$2 } from '@whereby/jslib-media/src/utils/ServerSocket';
|
|
4
3
|
import * as redux_thunk from 'redux-thunk';
|
|
5
4
|
import { AxiosRequestConfig } from 'axios';
|
|
@@ -13,15 +12,18 @@ interface VideoViewSelfProps {
|
|
|
13
12
|
stream: MediaStream;
|
|
14
13
|
muted?: boolean;
|
|
15
14
|
mirror?: boolean;
|
|
16
|
-
style?:
|
|
15
|
+
style?: React$1.CSSProperties;
|
|
17
16
|
onResize?: ({ width, height, stream }: {
|
|
18
17
|
width: number;
|
|
19
18
|
height: number;
|
|
20
19
|
stream: MediaStream;
|
|
21
20
|
}) => void;
|
|
21
|
+
onSetAspectRatio?: ({ aspectRatio }: {
|
|
22
|
+
aspectRatio: number;
|
|
23
|
+
}) => void;
|
|
22
24
|
}
|
|
23
|
-
type VideoViewProps = VideoViewSelfProps &
|
|
24
|
-
declare const _default: ({ muted, mirror, stream, onResize, ...rest }: VideoViewProps) =>
|
|
25
|
+
type VideoViewProps = VideoViewSelfProps & React$1.DetailedHTMLProps<React$1.VideoHTMLAttributes<HTMLVideoElement>, HTMLVideoElement>;
|
|
26
|
+
declare const _default: ({ muted, mirror, stream, onResize, onSetAspectRatio, ...rest }: VideoViewProps) => React$1.JSX.Element;
|
|
25
27
|
|
|
26
28
|
interface RoomParticipantData {
|
|
27
29
|
displayName: string;
|
|
@@ -584,6 +586,10 @@ type ConnectionStatus$1 = "initializing" | "connecting" | "connected" | "reconne
|
|
|
584
586
|
* Reducer
|
|
585
587
|
*/
|
|
586
588
|
interface RoomConnectionState$1 {
|
|
589
|
+
session: {
|
|
590
|
+
createdAt: string;
|
|
591
|
+
id: string;
|
|
592
|
+
} | null;
|
|
587
593
|
status: ConnectionStatus$1;
|
|
588
594
|
error: unknown;
|
|
589
595
|
}
|
|
@@ -809,7 +815,6 @@ interface RoomConnectionActions {
|
|
|
809
815
|
stopCloudRecording(): void;
|
|
810
816
|
stopScreenshare(): void;
|
|
811
817
|
}
|
|
812
|
-
|
|
813
818
|
type VideoViewComponentProps = Omit<React.ComponentProps<typeof _default>, "onResize">;
|
|
814
819
|
interface RoomConnectionComponents {
|
|
815
820
|
VideoView: (props: VideoViewComponentProps) => ReturnType<typeof _default>;
|
|
@@ -820,6 +825,7 @@ type RoomConnectionRef = {
|
|
|
820
825
|
components: RoomConnectionComponents;
|
|
821
826
|
_ref: Store;
|
|
822
827
|
};
|
|
828
|
+
|
|
823
829
|
declare function useRoomConnection(roomUrl: string, roomConnectionOptions?: UseRoomConnectionOptions): RoomConnectionRef;
|
|
824
830
|
|
|
825
831
|
declare function useLocalMedia(optionsOrStream?: UseLocalMediaOptions | MediaStream): UseLocalMediaResult;
|
package/dist/react/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
3
3
|
import { createListenerMiddleware, createSlice, createAsyncThunk, createAction, createSelector, isAnyOf, combineReducers, configureStore } from '@reduxjs/toolkit';
|
|
4
4
|
import { io } from 'socket.io-client';
|
|
5
5
|
import adapter from 'webrtc-adapter';
|
|
@@ -85,19 +85,26 @@ function debounce(fn, { delay = 500, edges } = {}) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
var VideoView = (_a) => {
|
|
88
|
-
var { muted, mirror = false, stream, onResize } = _a, rest = __rest(_a, ["muted", "mirror", "stream", "onResize"]);
|
|
89
|
-
const videoEl = useRef(null);
|
|
90
|
-
useEffect(() => {
|
|
91
|
-
if (!videoEl.current
|
|
88
|
+
var { muted, mirror = false, stream, onResize, onSetAspectRatio } = _a, rest = __rest(_a, ["muted", "mirror", "stream", "onResize", "onSetAspectRatio"]);
|
|
89
|
+
const videoEl = React.useRef(null);
|
|
90
|
+
React.useEffect(() => {
|
|
91
|
+
if (!videoEl.current) {
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
const resizeObserver = new ResizeObserver(debounce(() => {
|
|
95
95
|
if (videoEl.current && (stream === null || stream === void 0 ? void 0 : stream.id)) {
|
|
96
|
-
onResize
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
if (onResize) {
|
|
97
|
+
onResize({
|
|
98
|
+
width: videoEl.current.clientWidth,
|
|
99
|
+
height: videoEl.current.clientHeight,
|
|
100
|
+
stream,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const h = videoEl.current.videoHeight;
|
|
104
|
+
const w = videoEl.current.videoWidth;
|
|
105
|
+
if (w && h && w + h > 20 && onSetAspectRatio) {
|
|
106
|
+
onSetAspectRatio({ aspectRatio: w / h });
|
|
107
|
+
}
|
|
101
108
|
}
|
|
102
109
|
}, { delay: 1000, edges: true }));
|
|
103
110
|
resizeObserver.observe(videoEl.current);
|
|
@@ -105,7 +112,7 @@ var VideoView = (_a) => {
|
|
|
105
112
|
resizeObserver.disconnect();
|
|
106
113
|
};
|
|
107
114
|
}, [stream]);
|
|
108
|
-
useEffect(() => {
|
|
115
|
+
React.useEffect(() => {
|
|
109
116
|
if (!videoEl.current) {
|
|
110
117
|
return;
|
|
111
118
|
}
|
|
@@ -118,7 +125,7 @@ var VideoView = (_a) => {
|
|
|
118
125
|
videoEl.current.muted = Boolean(muted);
|
|
119
126
|
}
|
|
120
127
|
}, [muted, stream, videoEl]);
|
|
121
|
-
return (
|
|
128
|
+
return (React.createElement("video", Object.assign({ ref: videoEl, autoPlay: true, playsInline: true }, rest, { style: Object.assign({ transform: mirror ? "scaleX(-1)" : "none", width: "100%", height: "100%" }, rest.style) })));
|
|
122
129
|
};
|
|
123
130
|
|
|
124
131
|
const listenerMiddleware = createListenerMiddleware();
|
|
@@ -218,6 +225,7 @@ const signalEvents = {
|
|
|
218
225
|
newClient: createSignalEventAction("newClient"),
|
|
219
226
|
roomJoined: createSignalEventAction("roomJoined"),
|
|
220
227
|
roomKnocked: createSignalEventAction("roomKnocked"),
|
|
228
|
+
roomSessionEnded: createSignalEventAction("roomSessionEnded"),
|
|
221
229
|
screenshareStarted: createSignalEventAction("screenshareStarted"),
|
|
222
230
|
screenshareStopped: createSignalEventAction("screenshareStopped"),
|
|
223
231
|
streamingStopped: createSignalEventAction("streamingStopped"),
|
|
@@ -413,6 +421,7 @@ function forwardSocketEvents(socket, dispatch) {
|
|
|
413
421
|
socket.on("chat_message", (payload) => dispatch(signalEvents.chatMessage(payload)));
|
|
414
422
|
socket.on("disconnect", () => dispatch(signalEvents.disconnect()));
|
|
415
423
|
socket.on("room_knocked", (payload) => dispatch(signalEvents.roomKnocked(payload)));
|
|
424
|
+
socket.on("room_session_ended", (payload) => dispatch(signalEvents.roomSessionEnded(payload)));
|
|
416
425
|
socket.on("knocker_left", (payload) => dispatch(signalEvents.knockerLeft(payload)));
|
|
417
426
|
socket.on("knock_handled", (payload) => dispatch(signalEvents.knockHandled(payload)));
|
|
418
427
|
socket.on("screenshare_started", (payload) => dispatch(signalEvents.screenshareStarted(payload)));
|
|
@@ -1432,7 +1441,7 @@ const doStartLocalMedia = createAppAsyncThunk("localMedia/doStartLocalMedia", (p
|
|
|
1432
1441
|
const onDeviceChange = debounce(() => {
|
|
1433
1442
|
dispatch(doUpdateDeviceList());
|
|
1434
1443
|
}, { delay: 500 });
|
|
1435
|
-
if (
|
|
1444
|
+
if (navigator.mediaDevices) {
|
|
1436
1445
|
navigator.mediaDevices.addEventListener("devicechange", onDeviceChange);
|
|
1437
1446
|
}
|
|
1438
1447
|
// Resolve if existing stream is passed
|
|
@@ -1464,7 +1473,7 @@ const doStopLocalMedia = createAppThunk(() => (dispatch, getState) => {
|
|
|
1464
1473
|
stream === null || stream === void 0 ? void 0 : stream.getTracks().forEach((track) => {
|
|
1465
1474
|
track.stop();
|
|
1466
1475
|
});
|
|
1467
|
-
if (
|
|
1476
|
+
if (navigator.mediaDevices && onDeviceChange) {
|
|
1468
1477
|
navigator.mediaDevices.removeEventListener("devicechange", onDeviceChange);
|
|
1469
1478
|
}
|
|
1470
1479
|
dispatch(localMediaStopped());
|
|
@@ -2038,6 +2047,7 @@ const selectScreenshares = createSelector(selectLocalScreenshareStream, selectRe
|
|
|
2038
2047
|
});
|
|
2039
2048
|
|
|
2040
2049
|
const initialState$6 = {
|
|
2050
|
+
session: null,
|
|
2041
2051
|
status: "initializing",
|
|
2042
2052
|
error: null,
|
|
2043
2053
|
};
|
|
@@ -2051,12 +2061,24 @@ const roomConnectionSlice = createSlice({
|
|
|
2051
2061
|
},
|
|
2052
2062
|
extraReducers: (builder) => {
|
|
2053
2063
|
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
2064
|
+
var _a, _b;
|
|
2054
2065
|
//TODO: Handle error
|
|
2055
2066
|
const { error, isLocked } = action.payload;
|
|
2056
2067
|
if (error === "room_locked" && isLocked) {
|
|
2057
2068
|
return Object.assign(Object.assign({}, state), { status: "room_locked" });
|
|
2058
2069
|
}
|
|
2059
|
-
return Object.assign(Object.assign({}, state), { status: "connected" });
|
|
2070
|
+
return Object.assign(Object.assign({}, state), { status: "connected", session: (_b = (_a = action.payload.room) === null || _a === void 0 ? void 0 : _a.session) !== null && _b !== void 0 ? _b : null });
|
|
2071
|
+
});
|
|
2072
|
+
builder.addCase(signalEvents.newClient, (state, action) => {
|
|
2073
|
+
var _a, _b;
|
|
2074
|
+
return Object.assign(Object.assign({}, state), { session: (_b = (_a = action.payload.room) === null || _a === void 0 ? void 0 : _a.session) !== null && _b !== void 0 ? _b : null });
|
|
2075
|
+
});
|
|
2076
|
+
builder.addCase(signalEvents.roomSessionEnded, (state, action) => {
|
|
2077
|
+
var _a;
|
|
2078
|
+
if (((_a = state.session) === null || _a === void 0 ? void 0 : _a.id) !== action.payload.roomSessionId) {
|
|
2079
|
+
return state;
|
|
2080
|
+
}
|
|
2081
|
+
return Object.assign(Object.assign({}, state), { session: null });
|
|
2060
2082
|
});
|
|
2061
2083
|
builder.addCase(socketReconnecting, (state) => {
|
|
2062
2084
|
return Object.assign(Object.assign({}, state), { status: "reconnect" });
|
|
@@ -2128,6 +2150,7 @@ const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
|
|
|
2128
2150
|
});
|
|
2129
2151
|
dispatch(connectionStatusChanged("connecting"));
|
|
2130
2152
|
});
|
|
2153
|
+
const selectRoomConnectionSessionId = (state) => { var _a; return (_a = state.roomConnection.session) === null || _a === void 0 ? void 0 : _a.id; };
|
|
2131
2154
|
const selectRoomConnectionStatus = (state) => state.roomConnection.status;
|
|
2132
2155
|
/**
|
|
2133
2156
|
* Reactors
|
|
@@ -7384,6 +7407,12 @@ const rtcAnalyticsCustomEvents = {
|
|
|
7384
7407
|
getValue: (state) => selectSignalStatus(state),
|
|
7385
7408
|
getOutput: (value) => ({ status: value }),
|
|
7386
7409
|
},
|
|
7410
|
+
roomSessionId: {
|
|
7411
|
+
action: null,
|
|
7412
|
+
rtcEventName: "roomSessionId",
|
|
7413
|
+
getValue: (state) => selectRoomConnectionSessionId(state),
|
|
7414
|
+
getOutput: (value) => ({ roomSessionId: value }),
|
|
7415
|
+
},
|
|
7387
7416
|
rtcConnectionStatus: {
|
|
7388
7417
|
action: null,
|
|
7389
7418
|
rtcEventName: "rtcConnectionStatus",
|
|
@@ -7422,6 +7451,16 @@ const doRtcAnalyticsCustomEventsInitialize = createAppThunk(() => (dispatch, get
|
|
|
7422
7451
|
const rtcManager = selectRtcConnectionRaw(state).rtcManager;
|
|
7423
7452
|
if (!rtcManager)
|
|
7424
7453
|
return;
|
|
7454
|
+
// RTC stats require a `insightsStats` event to be sent to set the timestamp.
|
|
7455
|
+
// This is a temporary workaround, we just send one dummy event on initialization.
|
|
7456
|
+
rtcManager.sendStatsCustomEvent("insightsStats", {
|
|
7457
|
+
_time: Date.now(),
|
|
7458
|
+
ls: 0,
|
|
7459
|
+
lr: 0,
|
|
7460
|
+
bs: 0,
|
|
7461
|
+
br: 0,
|
|
7462
|
+
cpu: 0,
|
|
7463
|
+
});
|
|
7425
7464
|
Object.values(rtcAnalyticsCustomEvents).forEach(({ rtcEventName, getValue, getOutput }) => {
|
|
7426
7465
|
var _a;
|
|
7427
7466
|
const value = getValue(state);
|
|
@@ -7554,7 +7593,7 @@ const doRejectWaitingParticipant = createAppThunk((payload) => (dispatch, getSta
|
|
|
7554
7593
|
const selectWaitingParticipants = (state) => state.waitingParticipants.waitingParticipants;
|
|
7555
7594
|
|
|
7556
7595
|
var _a;
|
|
7557
|
-
const IS_DEV = (_a =
|
|
7596
|
+
const IS_DEV = (_a = undefined === "true") !== null && _a !== void 0 ? _a : false;
|
|
7558
7597
|
const rootReducer = combineReducers({
|
|
7559
7598
|
app: appSlice.reducer,
|
|
7560
7599
|
chat: chatSlice.reducer,
|
|
@@ -8651,7 +8690,7 @@ const selectRoomConnectionState = createSelector(selectChatMessages, selectCloud
|
|
|
8651
8690
|
return state;
|
|
8652
8691
|
});
|
|
8653
8692
|
|
|
8654
|
-
const sdkVersion = "2.
|
|
8693
|
+
const sdkVersion = "2.1.0-beta1";
|
|
8655
8694
|
|
|
8656
8695
|
const initialState$1 = {
|
|
8657
8696
|
chatMessages: [],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whereby.com/browser-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0-beta1",
|
|
4
4
|
"description": "Modules for integration Whereby video in web apps",
|
|
5
5
|
"author": "Whereby AS",
|
|
6
6
|
"license": "MIT",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"rimraf": "^3.0.2",
|
|
97
97
|
"rollup": "^4.3.0",
|
|
98
98
|
"rollup-plugin-dts": "^6.1.0",
|
|
99
|
+
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
99
100
|
"rollup-plugin-terser": "^7.0.2",
|
|
100
101
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
101
102
|
"storybook": "^7.5.2",
|