@100mslive/react-sdk 0.0.2-alpha → 0.0.3-alpha.3
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/dist/hooks/HmsRoomProvider.d.ts +6 -4
- package/dist/hooks/store.d.ts +4 -2
- package/dist/hooks/types.d.ts +3 -3
- package/dist/hooks/useAudioLevel.d.ts +1 -0
- package/dist/hooks/usePreview.d.ts +1 -0
- package/dist/hooks/useVideo.d.ts +1 -1
- package/dist/hooks/useVideoList.d.ts +3 -3
- package/dist/hooks/useVideoTile.d.ts +3 -3
- package/dist/index.cjs.js +44 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +44 -0
- package/package.json +37 -34
- package/dist/hooks/useVideoListLayout.d.ts +0 -26
- package/dist/node_modules/react-intersection-observer/react-intersection-observer.m.js +0 -244
- package/dist/node_modules/zustand/esm/shallow.js +0 -1
- package/dist/packages/react-sdk/src/hooks/HmsRoomProvider.js +0 -131
- package/dist/packages/react-sdk/src/hooks/store.js +0 -25
- package/dist/packages/react-sdk/src/hooks/useAVToggle.js +0 -35
- package/dist/packages/react-sdk/src/hooks/useAudioLevel.js +0 -24
- package/dist/packages/react-sdk/src/hooks/useDevices.js +0 -62
- package/dist/packages/react-sdk/src/hooks/usePreview.js +0 -40
- package/dist/packages/react-sdk/src/hooks/useVideo.js +0 -44
- package/dist/packages/react-sdk/src/hooks/useVideoListLayout.js +0 -65
- package/dist/packages/react-sdk/src/hooks/useVideoTile.js +0 -36
- package/dist/packages/react-sdk/src/index.js +0 -9
- package/dist/packages/react-sdk/src/utils/isBrowser.js +0 -2
- package/dist/packages/react-sdk/src/utils/layout.js +0 -434
- package/dist/packages/react-sdk/src/utils/logger.js +0 -74
- package/dist/src/hooks/HmsRoomProvider.js +0 -1
- package/dist/src/hooks/store.js +0 -1
- package/dist/src/hooks/useAVToggle.js +0 -1
- package/dist/src/hooks/useAudioLevel.js +0 -1
- package/dist/src/hooks/useDevices.js +0 -1
- package/dist/src/hooks/usePreview.js +0 -1
- package/dist/src/hooks/useVideo.js +0 -1
- package/dist/src/hooks/useVideoList.js +0 -1
- package/dist/src/hooks/useVideoListLayout.js +0 -65
- package/dist/src/hooks/useVideoTile.js +0 -1
- package/dist/src/index.js +0 -1
- package/dist/src/utils/isBrowser.js +0 -1
- package/dist/src/utils/layout.js +0 -1
- package/dist/src/utils/logger.js +0 -1
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useEffect } from 'react';
|
|
3
|
-
var observerMap = new Map();
|
|
4
|
-
var RootIds = new WeakMap();
|
|
5
|
-
var rootId = 0;
|
|
6
|
-
var unsupportedValue = undefined;
|
|
7
|
-
/**
|
|
8
|
-
* Generate a unique ID for the root element
|
|
9
|
-
* @param root
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
function getRootId(root) {
|
|
13
|
-
if (!root) return '0';
|
|
14
|
-
if (RootIds.has(root)) return RootIds.get(root);
|
|
15
|
-
rootId += 1;
|
|
16
|
-
RootIds.set(root, rootId.toString());
|
|
17
|
-
return RootIds.get(root);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Convert the options to a string Id, based on the values.
|
|
21
|
-
* Ensures we can reuse the same observer when observing elements with the same options.
|
|
22
|
-
* @param options
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
function optionsToId(options) {
|
|
27
|
-
return Object.keys(options).sort().filter(function (key) {
|
|
28
|
-
return options[key] !== undefined;
|
|
29
|
-
}).map(function (key) {
|
|
30
|
-
return key + "_" + (key === 'root' ? getRootId(options.root) : options[key]);
|
|
31
|
-
}).toString();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function createObserver(options) {
|
|
35
|
-
// Create a unique ID for this observer instance, based on the root, root margin and threshold.
|
|
36
|
-
var id = optionsToId(options);
|
|
37
|
-
var instance = observerMap.get(id);
|
|
38
|
-
|
|
39
|
-
if (!instance) {
|
|
40
|
-
// Create a map of elements this observer is going to observe. Each element has a list of callbacks that should be triggered, once it comes into view.
|
|
41
|
-
var elements = new Map();
|
|
42
|
-
var thresholds;
|
|
43
|
-
var observer = new IntersectionObserver(function (entries) {
|
|
44
|
-
entries.forEach(function (entry) {
|
|
45
|
-
var _elements$get; // While it would be nice if you could just look at isIntersecting to determine if the component is inside the viewport, browsers can't agree on how to use it.
|
|
46
|
-
// -Firefox ignores `threshold` when considering `isIntersecting`, so it will never be false again if `threshold` is > 0
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
var inView = entry.isIntersecting && thresholds.some(function (threshold) {
|
|
50
|
-
return entry.intersectionRatio >= threshold;
|
|
51
|
-
}); // @ts-ignore support IntersectionObserver v2
|
|
52
|
-
|
|
53
|
-
if (options.trackVisibility && typeof entry.isVisible === 'undefined') {
|
|
54
|
-
// The browser doesn't support Intersection Observer v2, falling back to v1 behavior.
|
|
55
|
-
// @ts-ignore
|
|
56
|
-
entry.isVisible = inView;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
(_elements$get = elements.get(entry.target)) == null ? void 0 : _elements$get.forEach(function (callback) {
|
|
60
|
-
callback(inView, entry);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
}, options); // Ensure we have a valid thresholds array. If not, use the threshold from the options
|
|
64
|
-
|
|
65
|
-
thresholds = observer.thresholds || (Array.isArray(options.threshold) ? options.threshold : [options.threshold || 0]);
|
|
66
|
-
instance = {
|
|
67
|
-
id: id,
|
|
68
|
-
observer: observer,
|
|
69
|
-
elements: elements
|
|
70
|
-
};
|
|
71
|
-
observerMap.set(id, instance);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return instance;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* @param element - DOM Element to observe
|
|
78
|
-
* @param callback - Callback function to trigger when intersection status changes
|
|
79
|
-
* @param options - Intersection Observer options
|
|
80
|
-
* @param fallbackInView - Fallback inView value.
|
|
81
|
-
* @return Function - Cleanup function that should be triggered to unregister the observer
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
function observe(element, callback, options, fallbackInView) {
|
|
86
|
-
if (options === void 0) {
|
|
87
|
-
options = {};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (fallbackInView === void 0) {
|
|
91
|
-
fallbackInView = unsupportedValue;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (typeof window.IntersectionObserver === 'undefined' && fallbackInView !== undefined) {
|
|
95
|
-
var bounds = element.getBoundingClientRect();
|
|
96
|
-
callback(fallbackInView, {
|
|
97
|
-
isIntersecting: fallbackInView,
|
|
98
|
-
target: element,
|
|
99
|
-
intersectionRatio: typeof options.threshold === 'number' ? options.threshold : 0,
|
|
100
|
-
time: 0,
|
|
101
|
-
boundingClientRect: bounds,
|
|
102
|
-
intersectionRect: bounds,
|
|
103
|
-
rootBounds: bounds
|
|
104
|
-
});
|
|
105
|
-
return function () {// Nothing to cleanup
|
|
106
|
-
};
|
|
107
|
-
} // An observer with the same options can be reused, so lets use this fact
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
var _createObserver = createObserver(options),
|
|
111
|
-
id = _createObserver.id,
|
|
112
|
-
observer = _createObserver.observer,
|
|
113
|
-
elements = _createObserver.elements; // Register the callback listener for this element
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
var callbacks = elements.get(element) || [];
|
|
117
|
-
|
|
118
|
-
if (!elements.has(element)) {
|
|
119
|
-
elements.set(element, callbacks);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
callbacks.push(callback);
|
|
123
|
-
observer.observe(element);
|
|
124
|
-
return function unobserve() {
|
|
125
|
-
// Remove the callback from the callback list
|
|
126
|
-
callbacks.splice(callbacks.indexOf(callback), 1);
|
|
127
|
-
|
|
128
|
-
if (callbacks.length === 0) {
|
|
129
|
-
// No more callback exists for element, so destroy it
|
|
130
|
-
elements["delete"](element);
|
|
131
|
-
observer.unobserve(element);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (elements.size === 0) {
|
|
135
|
-
// No more elements are being observer by this instance, so destroy it
|
|
136
|
-
observer.disconnect();
|
|
137
|
-
observerMap["delete"](id);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* React Hooks make it easy to monitor the `inView` state of your components. Call
|
|
143
|
-
* the `useInView` hook with the (optional) [options](#options) you need. It will
|
|
144
|
-
* return an array containing a `ref`, the `inView` status and the current
|
|
145
|
-
* [`entry`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry).
|
|
146
|
-
* Assign the `ref` to the DOM element you want to monitor, and the hook will
|
|
147
|
-
* report the status.
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```jsx
|
|
151
|
-
* import React from 'react';
|
|
152
|
-
* import { useInView } from 'react-intersection-observer';
|
|
153
|
-
*
|
|
154
|
-
* const Component = () => {
|
|
155
|
-
* const { ref, inView, entry } = useInView({
|
|
156
|
-
* threshold: 0,
|
|
157
|
-
* });
|
|
158
|
-
*
|
|
159
|
-
* return (
|
|
160
|
-
* <div ref={ref}>
|
|
161
|
-
* <h2>{`Header inside viewport ${inView}.`}</h2>
|
|
162
|
-
* </div>
|
|
163
|
-
* );
|
|
164
|
-
* };
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
function useInView(_temp) {
|
|
170
|
-
var _ref = _temp === void 0 ? {} : _temp,
|
|
171
|
-
threshold = _ref.threshold,
|
|
172
|
-
delay = _ref.delay,
|
|
173
|
-
trackVisibility = _ref.trackVisibility,
|
|
174
|
-
rootMargin = _ref.rootMargin,
|
|
175
|
-
root = _ref.root,
|
|
176
|
-
triggerOnce = _ref.triggerOnce,
|
|
177
|
-
skip = _ref.skip,
|
|
178
|
-
initialInView = _ref.initialInView,
|
|
179
|
-
fallbackInView = _ref.fallbackInView;
|
|
180
|
-
|
|
181
|
-
var unobserve = React.useRef();
|
|
182
|
-
|
|
183
|
-
var _React$useState = React.useState({
|
|
184
|
-
inView: !!initialInView
|
|
185
|
-
}),
|
|
186
|
-
state = _React$useState[0],
|
|
187
|
-
setState = _React$useState[1];
|
|
188
|
-
|
|
189
|
-
var setRef = React.useCallback(function (node) {
|
|
190
|
-
if (unobserve.current !== undefined) {
|
|
191
|
-
unobserve.current();
|
|
192
|
-
unobserve.current = undefined;
|
|
193
|
-
} // Skip creating the observer
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (skip) return;
|
|
197
|
-
|
|
198
|
-
if (node) {
|
|
199
|
-
unobserve.current = observe(node, function (inView, entry) {
|
|
200
|
-
setState({
|
|
201
|
-
inView: inView,
|
|
202
|
-
entry: entry
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
if (entry.isIntersecting && triggerOnce && unobserve.current) {
|
|
206
|
-
// If it should only trigger once, unobserve the element after it's inView
|
|
207
|
-
unobserve.current();
|
|
208
|
-
unobserve.current = undefined;
|
|
209
|
-
}
|
|
210
|
-
}, {
|
|
211
|
-
root: root,
|
|
212
|
-
rootMargin: rootMargin,
|
|
213
|
-
threshold: threshold,
|
|
214
|
-
// @ts-ignore
|
|
215
|
-
trackVisibility: trackVisibility,
|
|
216
|
-
// @ts-ignore
|
|
217
|
-
delay: delay
|
|
218
|
-
}, fallbackInView);
|
|
219
|
-
}
|
|
220
|
-
}, // We break the rule here, because we aren't including the actual `threshold` variable
|
|
221
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
222
|
-
[// If the threshold is an array, convert it to a string so it won't change between renders.
|
|
223
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
224
|
-
Array.isArray(threshold) ? threshold.toString() : threshold, root, rootMargin, triggerOnce, skip, trackVisibility, fallbackInView, delay]);
|
|
225
|
-
/* eslint-disable-next-line */
|
|
226
|
-
|
|
227
|
-
useEffect(function () {
|
|
228
|
-
if (!unobserve.current && state.entry && !triggerOnce && !skip) {
|
|
229
|
-
// If we don't have a ref, then reset the state (unless the hook is set to only `triggerOnce` or `skip`)
|
|
230
|
-
// This ensures we correctly reflect the current state - If you aren't observing anything, then nothing is inView
|
|
231
|
-
setState({
|
|
232
|
-
inView: !!initialInView
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
var result = [setRef, state.inView, state.entry]; // Support object destructuring, by adding the specific values.
|
|
237
|
-
|
|
238
|
-
result.ref = result[0];
|
|
239
|
-
result.inView = result[1];
|
|
240
|
-
result.entry = result[2];
|
|
241
|
-
return result;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export { observe, useInView };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function t(t,e){if(Object.is(t,e))return!0;if("object"!=typeof t||null===t||"object"!=typeof e||null===e)return!1;const r=Object.keys(t);if(r.length!==Object.keys(e).length)return!1;for(let n=0;n<r.length;n++)if(!Object.prototype.hasOwnProperty.call(e,r[n])||!Object.is(t[r[n]],e[r[n]]))return!1;return!0}export{t as default};
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
-
|
|
3
|
-
import React__default, { createContext, useEffect, useContext, useState } from 'react';
|
|
4
|
-
import { HMSReactiveStore } from '@100mslive/hms-video-store';
|
|
5
|
-
import create from 'zustand';
|
|
6
|
-
import { makeHMSStoreHook, hooksErrorMessage } from './store.js';
|
|
7
|
-
import { isBrowser } from '../utils/isBrowser.js';
|
|
8
|
-
/**
|
|
9
|
-
* only one context is being created currently. This would need to be changed if multiple
|
|
10
|
-
* rooms have to be supported, where every room will have its own context, provider, store and actions.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const HMSContext = createContext(null);
|
|
14
|
-
let providerProps;
|
|
15
|
-
|
|
16
|
-
const HMSRoomProvider = ({
|
|
17
|
-
children,
|
|
18
|
-
actions,
|
|
19
|
-
store,
|
|
20
|
-
notifications
|
|
21
|
-
}) => {
|
|
22
|
-
if (!providerProps) {
|
|
23
|
-
if (actions && store) {
|
|
24
|
-
providerProps = {
|
|
25
|
-
actions,
|
|
26
|
-
store
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
if (notifications) {
|
|
30
|
-
providerProps.notifications = notifications;
|
|
31
|
-
}
|
|
32
|
-
} else {
|
|
33
|
-
const hmsReactiveStore = new HMSReactiveStore(); // adding a dummy function for setstate and destroy because zustan'd create expects them
|
|
34
|
-
// to be present but we don't expose them from the store.
|
|
35
|
-
|
|
36
|
-
const errFn = () => {
|
|
37
|
-
throw new Error('modifying store is not allowed');
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
providerProps = {
|
|
41
|
-
actions: hmsReactiveStore.getHMSActions(),
|
|
42
|
-
store: create(_extends({}, hmsReactiveStore.getStore(), {
|
|
43
|
-
setState: errFn,
|
|
44
|
-
destroy: errFn
|
|
45
|
-
})),
|
|
46
|
-
notifications: hmsReactiveStore.getNotifications()
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
if (isBrowser) {
|
|
53
|
-
window.onunload = () => {
|
|
54
|
-
providerProps.actions.leave();
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
}, []);
|
|
58
|
-
return React__default.createElement(HMSContext.Provider, {
|
|
59
|
-
value: providerProps
|
|
60
|
-
}, children);
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* `useHMSStore` is a read only hook which can be passed a selector to read data.
|
|
64
|
-
* The hook can only be used in a component if HMSRoomProvider is present in its ancestors.
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const useHMSStore = makeHMSStoreHook(HMSContext);
|
|
69
|
-
/**
|
|
70
|
-
* `useHMSVanillaStore` is a read only hook which returns the vanilla HMSStore.
|
|
71
|
-
* Usage:
|
|
72
|
-
* ```
|
|
73
|
-
* const hmsStore = useHMSVanillaStore();
|
|
74
|
-
* const dominantSpeaker = hmsStore.getState(selectDominantSpeaker);
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
|
-
* Note: There's no need to use the vanilla hmsStore in React components.
|
|
78
|
-
* This is used in rare cases where the store needs to be accessed outside a React component.
|
|
79
|
-
* For almost every case, `useHMSStore` would get the job done.
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
const useHMSVanillaStore = () => {
|
|
83
|
-
const HMSContextConsumer = useContext(HMSContext);
|
|
84
|
-
|
|
85
|
-
if (!HMSContextConsumer) {
|
|
86
|
-
throw new Error(hooksErrorMessage);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return HMSContextConsumer.store;
|
|
90
|
-
};
|
|
91
|
-
/*
|
|
92
|
-
* `useHMSActions` is a write only hook which can be used to dispatch actions.
|
|
93
|
-
*/
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const useHMSActions = () => {
|
|
97
|
-
const HMSContextConsumer = useContext(HMSContext);
|
|
98
|
-
|
|
99
|
-
if (!HMSContextConsumer) {
|
|
100
|
-
throw new Error(hooksErrorMessage);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return HMSContextConsumer.actions;
|
|
104
|
-
};
|
|
105
|
-
/**
|
|
106
|
-
* `useHMSNotifications` is a read only hook which gives the latest notification(HMSNotification) received.
|
|
107
|
-
*/
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const useHMSNotifications = () => {
|
|
111
|
-
const HMSContextConsumer = useContext(HMSContext);
|
|
112
|
-
const [notification, setNotification] = useState(null);
|
|
113
|
-
|
|
114
|
-
if (!HMSContextConsumer) {
|
|
115
|
-
throw new Error(hooksErrorMessage);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
if (!HMSContextConsumer.notifications) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const unsubscribe = HMSContextConsumer.notifications.onNotification( // eslint-disable-next-line @typescript-eslint/no-shadow
|
|
124
|
-
notification => setNotification(notification)); // eslint-disable-next-line consistent-return
|
|
125
|
-
|
|
126
|
-
return unsubscribe;
|
|
127
|
-
}, [HMSContextConsumer.notifications]);
|
|
128
|
-
return notification;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export { HMSRoomProvider, useHMSActions, useHMSNotifications, useHMSStore, useHMSVanillaStore };
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
import shallow from '../../../../node_modules/zustand/esm/shallow.js';
|
|
3
|
-
import HMSLogger from '../utils/logger.js';
|
|
4
|
-
const hooksErrorMessage = 'It seems like you forgot to add your component within a top level HMSRoomProvider, please refer to 100ms react docs(https://docs.100ms.live/javascript/v2/features/integration#react-hooks) to check on the required steps for using this hook.';
|
|
5
|
-
|
|
6
|
-
function makeHMSStoreHook(hmsContext) {
|
|
7
|
-
const useHMSStore = (selector, equalityFn = shallow) => {
|
|
8
|
-
if (!selector) {
|
|
9
|
-
HMSLogger.w('fetching full store without passing any selector may have a heavy performance impact on your website.');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const HMSContextConsumer = useContext(hmsContext);
|
|
13
|
-
|
|
14
|
-
if (!HMSContextConsumer) {
|
|
15
|
-
throw new Error(hooksErrorMessage);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const useStore = HMSContextConsumer.store;
|
|
19
|
-
return useStore(selector, equalityFn);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
return useHMSStore;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export { hooksErrorMessage, makeHMSStoreHook };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { selectIsLocalAudioEnabled, selectIsLocalVideoEnabled, selectIsAllowedToPublish } from '@100mslive/hms-video-store';
|
|
2
|
-
import { useCallback } from 'react';
|
|
3
|
-
import { useHMSStore, useHMSActions } from './HmsRoomProvider.js';
|
|
4
|
-
|
|
5
|
-
const useAVToggle = () => {
|
|
6
|
-
const isLocalAudioEnabled = useHMSStore(selectIsLocalAudioEnabled);
|
|
7
|
-
const isLocalVideoEnabled = useHMSStore(selectIsLocalVideoEnabled);
|
|
8
|
-
const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);
|
|
9
|
-
const hmsActions = useHMSActions();
|
|
10
|
-
const toggleAudio = useCallback(async () => {
|
|
11
|
-
try {
|
|
12
|
-
await hmsActions.setLocalAudioEnabled(!isLocalAudioEnabled);
|
|
13
|
-
} catch (err) {
|
|
14
|
-
console.error('Cannot toggle audio', err);
|
|
15
|
-
}
|
|
16
|
-
}, [isLocalAudioEnabled]); //eslint-disable-line
|
|
17
|
-
|
|
18
|
-
const toggleVideo = useCallback(async () => {
|
|
19
|
-
try {
|
|
20
|
-
await hmsActions.setLocalVideoEnabled(!isLocalVideoEnabled);
|
|
21
|
-
} catch (err) {
|
|
22
|
-
console.error('Cannot toggle video', err);
|
|
23
|
-
}
|
|
24
|
-
}, [isLocalVideoEnabled]); //eslint-disable-line
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
isLocalAudioEnabled,
|
|
28
|
-
isLocalVideoEnabled,
|
|
29
|
-
toggleAudio,
|
|
30
|
-
toggleVideo,
|
|
31
|
-
isAllowedToPublish
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export { useAVToggle };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import { selectTrackAudioByID } from '@100mslive/hms-video-store';
|
|
3
|
-
import { useHMSVanillaStore } from './HmsRoomProvider.js';
|
|
4
|
-
|
|
5
|
-
function useAudioLevel({
|
|
6
|
-
trackId,
|
|
7
|
-
getStyle,
|
|
8
|
-
ref
|
|
9
|
-
}) {
|
|
10
|
-
const store = useHMSVanillaStore();
|
|
11
|
-
useEffect(() => store.subscribe(level => {
|
|
12
|
-
if (!ref.current) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const styles = getStyle(level);
|
|
17
|
-
|
|
18
|
-
for (const key in styles) {
|
|
19
|
-
ref.current.style[key] = styles[key];
|
|
20
|
-
}
|
|
21
|
-
}, selectTrackAudioByID(trackId)), [trackId]);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export { useAudioLevel };
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { selectDevices, selectLocalMediaSettings, selectIsAllowedToPublish, selectIsAllowedToSubscribe } from '@100mslive/hms-video-store';
|
|
2
|
-
import { useHMSActions, useHMSStore } from './HmsRoomProvider.js';
|
|
3
|
-
|
|
4
|
-
const useDevices = () => {
|
|
5
|
-
const hmsActions = useHMSActions();
|
|
6
|
-
const devices = useHMSStore(selectDevices);
|
|
7
|
-
const selectedDevices = useHMSStore(selectLocalMediaSettings);
|
|
8
|
-
const {
|
|
9
|
-
video: showVideo,
|
|
10
|
-
audio: showAudio
|
|
11
|
-
} = useHMSStore(selectIsAllowedToPublish);
|
|
12
|
-
const isSubscribing = useHMSStore(selectIsAllowedToSubscribe); // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
-
|
|
14
|
-
const handleInputChange = event => {
|
|
15
|
-
const selectedDevice = event.currentTarget.value;
|
|
16
|
-
const {
|
|
17
|
-
name
|
|
18
|
-
} = event.currentTarget;
|
|
19
|
-
|
|
20
|
-
if (selectedDevice !== selectedDevices[name]) {
|
|
21
|
-
switch (name) {
|
|
22
|
-
case 'audioInputDeviceId':
|
|
23
|
-
hmsActions.setAudioSettings({
|
|
24
|
-
deviceId: selectedDevice
|
|
25
|
-
});
|
|
26
|
-
break;
|
|
27
|
-
|
|
28
|
-
case 'videoInputDeviceId':
|
|
29
|
-
hmsActions.setVideoSettings({
|
|
30
|
-
deviceId: selectedDevice
|
|
31
|
-
});
|
|
32
|
-
break;
|
|
33
|
-
|
|
34
|
-
case 'audioOutputDeviceId':
|
|
35
|
-
hmsActions.setAudioOutputDevice(selectedDevice);
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const videoInput = devices.videoInput || [];
|
|
42
|
-
const audioInput = devices.audioInput || [];
|
|
43
|
-
const audioOutput = devices.audioOutput || [];
|
|
44
|
-
const showSettings = [showVideo, showAudio, isSubscribing].some(val => !!val);
|
|
45
|
-
|
|
46
|
-
if (!showSettings) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
showVideo,
|
|
52
|
-
videoInput,
|
|
53
|
-
showAudio,
|
|
54
|
-
audioInput,
|
|
55
|
-
audioOutput,
|
|
56
|
-
isSubscribing,
|
|
57
|
-
selectedDevices,
|
|
58
|
-
handleInputChange
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export { useDevices };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { isBrowser } from '@100mslive/hms-video';
|
|
2
|
-
import { selectLocalPeer, selectRoomState, selectIsLocalAudioEnabled, selectIsLocalVideoDisplayEnabled, selectIsAllowedToPublish, HMSRoomState } from '@100mslive/hms-video-store';
|
|
3
|
-
import { useState, useEffect } from 'react';
|
|
4
|
-
import { useHMSActions, useHMSStore } from './HmsRoomProvider.js';
|
|
5
|
-
|
|
6
|
-
const usePreview = (authToken, userName) => {
|
|
7
|
-
const [inProgress, setInProgress] = useState(false);
|
|
8
|
-
const actions = useHMSActions();
|
|
9
|
-
const localPeer = useHMSStore(selectLocalPeer);
|
|
10
|
-
const roomState = useHMSStore(selectRoomState);
|
|
11
|
-
const audioEnabled = useHMSStore(selectIsLocalAudioEnabled);
|
|
12
|
-
const videoEnabled = useHMSStore(selectIsLocalVideoDisplayEnabled);
|
|
13
|
-
const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);
|
|
14
|
-
const disableJoin = inProgress || roomState !== HMSRoomState.Preview;
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
// Call preview only when roomState is in disconnected state
|
|
17
|
-
if (roomState === HMSRoomState.Disconnected) {
|
|
18
|
-
actions.preview({
|
|
19
|
-
userName,
|
|
20
|
-
authToken
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (isBrowser) {
|
|
25
|
-
window.onunload = () => actions.leave();
|
|
26
|
-
}
|
|
27
|
-
}, [roomState, actions, authToken]);
|
|
28
|
-
return {
|
|
29
|
-
localPeer,
|
|
30
|
-
roomState,
|
|
31
|
-
audioEnabled,
|
|
32
|
-
videoEnabled,
|
|
33
|
-
isAllowedToPublish,
|
|
34
|
-
disableJoin,
|
|
35
|
-
actions,
|
|
36
|
-
setInProgress
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export { usePreview };
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { selectTrackByID } from '@100mslive/hms-video-store';
|
|
2
|
-
import { useRef, useCallback, useEffect } from 'react';
|
|
3
|
-
import { useInView } from '../../../../node_modules/react-intersection-observer/react-intersection-observer.m.js';
|
|
4
|
-
import { useHMSActions, useHMSStore } from './HmsRoomProvider.js';
|
|
5
|
-
|
|
6
|
-
const useVideo = trackId => {
|
|
7
|
-
const actions = useHMSActions();
|
|
8
|
-
const videoRef = useRef(null);
|
|
9
|
-
const {
|
|
10
|
-
ref: inViewRef,
|
|
11
|
-
inView
|
|
12
|
-
} = useInView({
|
|
13
|
-
threshold: 0.5
|
|
14
|
-
});
|
|
15
|
-
const setRefs = useCallback(node => {
|
|
16
|
-
videoRef.current = node;
|
|
17
|
-
inViewRef(node);
|
|
18
|
-
}, [inViewRef]);
|
|
19
|
-
const hmsStoreVideoTrack = useHMSStore(selectTrackByID(trackId));
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
(async () => {
|
|
22
|
-
if (videoRef.current && hmsStoreVideoTrack) {
|
|
23
|
-
if (inView) {
|
|
24
|
-
if (hmsStoreVideoTrack.enabled) {
|
|
25
|
-
console.log('****** ENABLE VIDEO *******'); // attach when in view and enabled
|
|
26
|
-
|
|
27
|
-
await actions.attachVideo(hmsStoreVideoTrack.id, videoRef.current);
|
|
28
|
-
} else {
|
|
29
|
-
console.log('****** DETACH VIDEO *******'); // detach when in view but not enabled
|
|
30
|
-
|
|
31
|
-
await actions.detachVideo(hmsStoreVideoTrack.id, videoRef.current);
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
// detach when not in view
|
|
35
|
-
console.log('****** DETACH VIDEO *******');
|
|
36
|
-
await actions.detachVideo(hmsStoreVideoTrack.id, videoRef.current);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
})();
|
|
40
|
-
}, [inView, videoRef, hmsStoreVideoTrack == null ? void 0 : hmsStoreVideoTrack.id, hmsStoreVideoTrack == null ? void 0 : hmsStoreVideoTrack.enabled, hmsStoreVideoTrack == null ? void 0 : hmsStoreVideoTrack.deviceID, hmsStoreVideoTrack == null ? void 0 : hmsStoreVideoTrack.plugins]);
|
|
41
|
-
return setRefs;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export { useVideo };
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { selectTracksMap } from '@100mslive/hms-video-store';
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
|
-
import { getVideoTracksFromPeers, getModeAspectRatio, calculateLayoutSizes, chunkElements } from '../utils/layout.js';
|
|
4
|
-
import { useHMSVanillaStore } from './HmsRoomProvider.js';
|
|
5
|
-
|
|
6
|
-
const useVideoList = ({
|
|
7
|
-
maxTileCount,
|
|
8
|
-
maxColCount,
|
|
9
|
-
maxRowCount,
|
|
10
|
-
width,
|
|
11
|
-
height,
|
|
12
|
-
showScreenFn,
|
|
13
|
-
peers,
|
|
14
|
-
overflow,
|
|
15
|
-
aspectRatio
|
|
16
|
-
}) => {
|
|
17
|
-
const store = useHMSVanillaStore();
|
|
18
|
-
const tracksMap = store.getState(selectTracksMap);
|
|
19
|
-
const tracksWithPeer = getVideoTracksFromPeers(peers, tracksMap, showScreenFn);
|
|
20
|
-
const finalAspectRatio = useMemo(() => {
|
|
21
|
-
if (aspectRatio) {
|
|
22
|
-
return aspectRatio;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const modeAspectRatio = getModeAspectRatio(tracksWithPeer); // Default to 1 if there are no video tracks
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
width: modeAspectRatio || 1,
|
|
29
|
-
height: 1
|
|
30
|
-
};
|
|
31
|
-
}, [aspectRatio, tracksWithPeer]);
|
|
32
|
-
const count = tracksWithPeer.length;
|
|
33
|
-
const {
|
|
34
|
-
tilesInFirstPage,
|
|
35
|
-
defaultWidth,
|
|
36
|
-
defaultHeight,
|
|
37
|
-
lastPageWidth,
|
|
38
|
-
lastPageHeight,
|
|
39
|
-
isLastPageDifferentFromFirstPage
|
|
40
|
-
} = useMemo(() => // Flooring since there's a bug in react-slick where it converts widdh into a number
|
|
41
|
-
calculateLayoutSizes({
|
|
42
|
-
count,
|
|
43
|
-
parentWidth: Math.floor(width),
|
|
44
|
-
parentHeight: Math.floor(height),
|
|
45
|
-
maxTileCount,
|
|
46
|
-
maxRowCount,
|
|
47
|
-
maxColCount,
|
|
48
|
-
aspectRatio: finalAspectRatio
|
|
49
|
-
}), [count, width, height, maxTileCount, maxRowCount, maxColCount, finalAspectRatio]);
|
|
50
|
-
const chunkedTracksWithPeer = useMemo(() => chunkElements({
|
|
51
|
-
elements: tracksWithPeer,
|
|
52
|
-
tilesInFirstPage,
|
|
53
|
-
onlyOnePage: overflow === 'hidden',
|
|
54
|
-
isLastPageDifferentFromFirstPage,
|
|
55
|
-
defaultWidth,
|
|
56
|
-
defaultHeight,
|
|
57
|
-
lastPageWidth,
|
|
58
|
-
lastPageHeight
|
|
59
|
-
}), [tracksWithPeer, tilesInFirstPage, overflow, isLastPageDifferentFromFirstPage, defaultWidth, defaultHeight, lastPageWidth, lastPageHeight]);
|
|
60
|
-
return {
|
|
61
|
-
chunkedTracksWithPeer
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export { useVideoList };
|