@stream-io/video-react-sdk 0.3.47 → 0.4.0
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/CHANGELOG.md +15 -0
- package/README.md +1 -1
- package/dist/index.cjs.js +324 -882
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +325 -867
- package/dist/index.es.js.map +1 -1
- package/dist/src/components/Notification/SpeakingWhileMutedNotification.d.ts +3 -0
- package/dist/src/components/{Video → VideoPreview}/VideoPreview.d.ts +1 -9
- package/dist/src/components/index.d.ts +1 -1
- package/dist/src/core/components/ParticipantView/ParticipantView.d.ts +3 -9
- package/dist/src/core/components/ParticipantView/ParticipantViewContext.d.ts +9 -0
- package/dist/src/core/components/ParticipantView/index.d.ts +1 -0
- package/dist/src/core/components/StreamCall/StreamCall.d.ts +2 -11
- package/dist/src/core/hooks/index.d.ts +0 -2
- package/dist/src/core/hooks/useDevices.d.ts +0 -99
- package/dist/src/core/index.d.ts +0 -1
- package/dist/src/hooks/index.d.ts +1 -3
- package/dist/src/hooks/usePersistedDevicePreferences.d.ts +13 -0
- package/dist/src/translations/index.d.ts +2 -0
- package/index.ts +2 -2
- package/package.json +3 -3
- package/src/components/CallControls/CallControls.tsx +6 -8
- package/src/components/CallControls/ScreenShareButton.tsx +14 -10
- package/src/components/CallControls/ToggleAudioButton.tsx +21 -24
- package/src/components/CallControls/ToggleAudioOutputButton.tsx +1 -1
- package/src/components/CallControls/ToggleVideoButton.tsx +21 -22
- package/src/components/CallParticipantsList/CallParticipantsList.tsx +1 -1
- package/src/components/DeviceSettings/DeviceSelectorAudio.tsx +20 -26
- package/src/components/DeviceSettings/DeviceSelectorVideo.tsx +9 -8
- package/src/components/Icon/Icon.tsx +1 -1
- package/src/components/Notification/SpeakingWhileMutedNotification.tsx +5 -49
- package/src/components/VideoPreview/VideoPreview.tsx +67 -0
- package/src/components/index.ts +1 -1
- package/src/core/components/CallLayout/PaginatedGridLayout.tsx +2 -5
- package/src/core/components/ParticipantView/DefaultParticipantViewUI.tsx +7 -6
- package/src/core/components/ParticipantView/ParticipantView.tsx +2 -19
- package/src/core/components/ParticipantView/ParticipantViewContext.tsx +17 -0
- package/src/core/components/ParticipantView/index.ts +1 -0
- package/src/core/components/StreamCall/StreamCall.tsx +2 -28
- package/src/core/hooks/index.ts +0 -2
- package/src/core/hooks/useDevices.ts +0 -195
- package/src/core/index.ts +0 -1
- package/src/hooks/index.ts +1 -3
- package/src/hooks/usePersistedDevicePreferences.ts +118 -0
- package/src/translations/en.json +3 -0
- package/dist/src/core/contexts/MediaDevicesContext.d.ts +0 -180
- package/dist/src/core/contexts/index.d.ts +0 -1
- package/dist/src/core/hooks/useAudioPublisher.d.ts +0 -12
- package/dist/src/core/hooks/useVideoPublisher.d.ts +0 -12
- package/dist/src/hooks/useToggleAudioMuteState.d.ts +0 -4
- package/dist/src/hooks/useToggleScreenShare.d.ts +0 -5
- package/dist/src/hooks/useToggleVideoMuteState.d.ts +0 -4
- package/src/components/Video/VideoPreview.tsx +0 -152
- package/src/core/contexts/MediaDevicesContext.tsx +0 -416
- package/src/core/contexts/index.ts +0 -1
- package/src/core/hooks/useAudioPublisher.ts +0 -146
- package/src/core/hooks/useVideoPublisher.ts +0 -177
- package/src/hooks/useToggleAudioMuteState.ts +0 -34
- package/src/hooks/useToggleScreenShare.ts +0 -43
- package/src/hooks/useToggleVideoMuteState.ts +0 -34
- /package/dist/src/components/{Video → VideoPreview}/index.d.ts +0 -0
- /package/src/components/{Video → VideoPreview}/index.ts +0 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
2
|
export type SpeakingWhileMutedNotificationProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Text message displayed by the notification.
|
|
5
|
+
*/
|
|
3
6
|
text?: string;
|
|
4
7
|
};
|
|
5
8
|
export declare const SpeakingWhileMutedNotification: ({ children, text, }: PropsWithChildren<SpeakingWhileMutedNotificationProps>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
|
-
type VideoErrorPreviewProps = {
|
|
3
|
-
message?: string;
|
|
4
|
-
};
|
|
5
2
|
export type VideoPreviewProps = {
|
|
6
3
|
/**
|
|
7
4
|
* Component rendered when user turns off the video.
|
|
@@ -19,10 +16,5 @@ export type VideoPreviewProps = {
|
|
|
19
16
|
* Component rendered above the BaseVideo until the video is ready (meaning until the play event is emitted).
|
|
20
17
|
*/
|
|
21
18
|
StartingCameraPreview?: ComponentType;
|
|
22
|
-
/**
|
|
23
|
-
* Component rendered when the video stream could not be retrieved.
|
|
24
|
-
*/
|
|
25
|
-
VideoErrorPreview?: ComponentType<VideoErrorPreviewProps>;
|
|
26
19
|
};
|
|
27
|
-
export declare const VideoPreview: ({ mirror, DisabledVideoPreview, NoCameraPreview, StartingCameraPreview,
|
|
28
|
-
export {};
|
|
20
|
+
export declare const VideoPreview: ({ mirror, DisabledVideoPreview, NoCameraPreview, StartingCameraPreview, }: VideoPreviewProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { ComponentType, ReactElement } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { StreamVideoParticipant, VideoTrackType } from '@stream-io/video-client';
|
|
3
3
|
import { VideoProps } from '../Video';
|
|
4
|
-
export type ParticipantViewContextValue = Required<Pick<ParticipantViewProps, 'participant' | 'trackType'>> & {
|
|
5
|
-
participantViewElement: HTMLDivElement | null;
|
|
6
|
-
videoElement: HTMLVideoElement | null;
|
|
7
|
-
videoPlaceholderElement: HTMLDivElement | null;
|
|
8
|
-
};
|
|
9
|
-
export declare const useParticipantViewContext: () => ParticipantViewContextValue;
|
|
10
4
|
export type ParticipantViewProps = {
|
|
11
5
|
/**
|
|
12
6
|
* The participant whose video/audio stream we want to play.
|
|
13
7
|
*/
|
|
14
|
-
participant: StreamVideoParticipant
|
|
8
|
+
participant: StreamVideoParticipant;
|
|
15
9
|
/**
|
|
16
10
|
* Override the default UI for rendering participant information/actions.
|
|
17
11
|
* pass `null` if you wish to not render anything
|
|
@@ -42,7 +36,7 @@ export declare const ParticipantView: import("react").ForwardRefExoticComponent<
|
|
|
42
36
|
/**
|
|
43
37
|
* The participant whose video/audio stream we want to play.
|
|
44
38
|
*/
|
|
45
|
-
participant: StreamVideoParticipant
|
|
39
|
+
participant: StreamVideoParticipant;
|
|
46
40
|
/**
|
|
47
41
|
* Override the default UI for rendering participant information/actions.
|
|
48
42
|
* pass `null` if you wish to not render anything
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ParticipantViewProps } from './ParticipantView';
|
|
3
|
+
export type ParticipantViewContextValue = Required<Pick<ParticipantViewProps, 'participant' | 'trackType'>> & {
|
|
4
|
+
participantViewElement: HTMLDivElement | null;
|
|
5
|
+
videoElement: HTMLVideoElement | null;
|
|
6
|
+
videoPlaceholderElement: HTMLDivElement | null;
|
|
7
|
+
};
|
|
8
|
+
export declare const ParticipantViewContext: import("react").Context<ParticipantViewContextValue | undefined>;
|
|
9
|
+
export declare const useParticipantViewContext: () => ParticipantViewContextValue;
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { MediaDevicesProviderProps } from '../../contexts';
|
|
4
|
-
export type StreamCallProps = {
|
|
5
|
-
call: Call;
|
|
6
|
-
/**
|
|
7
|
-
* An optional props to pass to the `MediaDevicesProvider`.
|
|
8
|
-
*/
|
|
9
|
-
mediaDevicesProviderProps?: MediaDevicesProviderProps;
|
|
10
|
-
};
|
|
11
|
-
export declare const StreamCall: ({ children, call, mediaDevicesProviderProps, }: PropsWithChildren<StreamCallProps>) => import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const StreamCall: (props: import("react").PropsWithChildren<import("@stream-io/video-react-bindings").StreamCallProviderProps>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,100 +1 @@
|
|
|
1
|
-
import { Observable } from 'rxjs';
|
|
2
1
|
export declare const useHasBrowserPermissions: (permissionName: PermissionName) => boolean;
|
|
3
|
-
/**
|
|
4
|
-
* Observes changes in connected devices and maintains an up-to-date array of connected MediaDeviceInfo objects.
|
|
5
|
-
* @param observeDevices
|
|
6
|
-
* @category Device Management
|
|
7
|
-
*/
|
|
8
|
-
export declare const useDevices: (observeDevices: () => Observable<MediaDeviceInfo[]>) => MediaDeviceInfo[];
|
|
9
|
-
/**
|
|
10
|
-
* Observes changes and maintains an array of connected video input devices
|
|
11
|
-
* @category Device Management
|
|
12
|
-
*/
|
|
13
|
-
export declare const useVideoDevices: () => MediaDeviceInfo[];
|
|
14
|
-
/**
|
|
15
|
-
* Observes changes and maintains an array of connected audio input devices
|
|
16
|
-
* @category Device Management
|
|
17
|
-
*/
|
|
18
|
-
export declare const useAudioInputDevices: () => MediaDeviceInfo[];
|
|
19
|
-
/**
|
|
20
|
-
* Observes changes and maintains an array of connected audio output devices
|
|
21
|
-
* @category Device Management
|
|
22
|
-
*/
|
|
23
|
-
export declare const useAudioOutputDevices: () => MediaDeviceInfo[];
|
|
24
|
-
/**
|
|
25
|
-
* Verifies that newly selected device id exists among the registered devices.
|
|
26
|
-
* If the selected device id is not found among existing devices, switches to the default device.
|
|
27
|
-
* The media devices are observed only if a given permission ('camera' resp. 'microphone') is granted in browser.
|
|
28
|
-
* Regardless of current permissions settings, an intent to observe devices will take place in Firefox.
|
|
29
|
-
* This is due to the fact that Firefox does not allow to query for 'camera' and 'microphone' permissions.
|
|
30
|
-
* @param canObserve
|
|
31
|
-
* @param devices$
|
|
32
|
-
* @param switchToDefaultDevice
|
|
33
|
-
* @param selectedDeviceId
|
|
34
|
-
* @category Device Management
|
|
35
|
-
*/
|
|
36
|
-
export declare const useDeviceFallback: (canObserve: boolean, devices$: Observable<MediaDeviceInfo[]>, switchToDefaultDevice: () => void, selectedDeviceId?: string) => void;
|
|
37
|
-
/**
|
|
38
|
-
* Verifies that newly selected video device id exists among the registered devices.
|
|
39
|
-
* If the selected device id is not found among existing devices, switches to the default video device.
|
|
40
|
-
* The media devices are observed only if 'camera' permission is granted in browser.
|
|
41
|
-
* It is integrators responsibility to instruct users how to enable required permissions.
|
|
42
|
-
* Regardless of current permissions settings, an intent to observe devices will take place in Firefox.
|
|
43
|
-
* This is due to the fact that Firefox does not allow to query for 'camera' and 'microphone' permissions.
|
|
44
|
-
* @param switchToDefaultDevice
|
|
45
|
-
* @param canObserve
|
|
46
|
-
* @param selectedDeviceId
|
|
47
|
-
* @category Device Management
|
|
48
|
-
*/
|
|
49
|
-
export declare const useVideoDeviceFallback: (switchToDefaultDevice: () => void, canObserve: boolean, selectedDeviceId?: string) => void;
|
|
50
|
-
/**
|
|
51
|
-
* Verifies that newly selected audio input device id exists among the registered devices.
|
|
52
|
-
* If the selected device id is not found among existing devices, switches to the default audio input device.
|
|
53
|
-
* The media devices are observed only if 'microphone' permission is granted in browser.
|
|
54
|
-
* It is integrators responsibility to instruct users how to enable required permissions.
|
|
55
|
-
* Regardless of current permissions settings, an intent to observe devices will take place in Firefox.
|
|
56
|
-
* This is due to the fact that Firefox does not allow to query for 'camera' and 'microphone' permissions.
|
|
57
|
-
* @param switchToDefaultDevice
|
|
58
|
-
* @param canObserve
|
|
59
|
-
* @param selectedDeviceId
|
|
60
|
-
* @category Device Management
|
|
61
|
-
*/
|
|
62
|
-
export declare const useAudioInputDeviceFallback: (switchToDefaultDevice: () => void, canObserve: boolean, selectedDeviceId?: string) => void;
|
|
63
|
-
/**
|
|
64
|
-
* Verifies that newly selected audio output device id exists among the registered devices.
|
|
65
|
-
* If the selected device id is not found among existing devices, switches to the default audio output device.
|
|
66
|
-
* The media devices are observed only if 'microphone' permission is granted in browser.
|
|
67
|
-
* It is integrators responsibility to instruct users how to enable required permissions.
|
|
68
|
-
* Regardless of current permissions settings, an intent to observe devices will take place in Firefox.
|
|
69
|
-
* This is due to the fact that Firefox does not allow to query for 'camera' and 'microphone' permissions.
|
|
70
|
-
* @param switchToDefaultDevice
|
|
71
|
-
* @param canObserve
|
|
72
|
-
* @param selectedDeviceId
|
|
73
|
-
* @category Device Management
|
|
74
|
-
*/
|
|
75
|
-
export declare const useAudioOutputDeviceFallback: (switchToDefaultDevice: () => void, canObserve: boolean, selectedDeviceId?: string) => void;
|
|
76
|
-
/**
|
|
77
|
-
* Observes devices of certain kind are made unavailable and executes onDisconnect callback.
|
|
78
|
-
* @param observeDevices
|
|
79
|
-
* @param onDisconnect
|
|
80
|
-
* @category Device Management
|
|
81
|
-
*/
|
|
82
|
-
export declare const useOnUnavailableDevices: (observeDevices: Observable<MediaDeviceInfo[]>, onDisconnect: () => void) => void;
|
|
83
|
-
/**
|
|
84
|
-
* Observes disconnect of all video devices and executes onDisconnect callback.
|
|
85
|
-
* @param onDisconnect
|
|
86
|
-
* @category Device Management
|
|
87
|
-
*/
|
|
88
|
-
export declare const useOnUnavailableVideoDevices: (onDisconnect: () => void) => void;
|
|
89
|
-
/**
|
|
90
|
-
* Observes disconnect of all audio input devices and executes onDisconnect callback.
|
|
91
|
-
* @param onDisconnect
|
|
92
|
-
* @category Device Management
|
|
93
|
-
*/
|
|
94
|
-
export declare const useOnUnavailableAudioInputDevices: (onDisconnect: () => void) => void;
|
|
95
|
-
/**
|
|
96
|
-
* Observes disconnect of all audio output devices and executes onDisconnect callback.
|
|
97
|
-
* @param onDisconnect
|
|
98
|
-
* @category Device Management
|
|
99
|
-
*/
|
|
100
|
-
export declare const useOnUnavailableAudioOutputDevices: (onDisconnect: () => void) => void;
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export * from './useFloatingUIPreset';
|
|
2
|
+
export * from './usePersistedDevicePreferences';
|
|
2
3
|
export * from './useScrollPosition';
|
|
3
|
-
export * from './useToggleAudioMuteState';
|
|
4
|
-
export * from './useToggleVideoMuteState';
|
|
5
|
-
export * from './useToggleScreenShare';
|
|
6
4
|
export * from './useToggleCallRecording';
|
|
7
5
|
export * from './useRequestPermission';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type LocalDevicePreference = {
|
|
2
|
+
selectedDeviceId: string;
|
|
3
|
+
muted: boolean;
|
|
4
|
+
};
|
|
5
|
+
export type LocalDevicePreferences = {
|
|
6
|
+
[type in 'mic' | 'camera' | 'speaker']: LocalDevicePreference;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* This hook will apply and persist the device preferences from local storage.
|
|
10
|
+
*
|
|
11
|
+
* @param key the key to use for local storage.
|
|
12
|
+
*/
|
|
13
|
+
export declare const usePersistedDevicePreferences: (key?: string) => void;
|
package/index.ts
CHANGED
|
@@ -11,8 +11,8 @@ export * from './src/translations';
|
|
|
11
11
|
export {
|
|
12
12
|
useHorizontalScrollPosition,
|
|
13
13
|
useVerticalScrollPosition,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
useRequestPermission,
|
|
15
|
+
usePersistedDevicePreferences,
|
|
16
16
|
} from './src/hooks';
|
|
17
17
|
|
|
18
18
|
const [major, minor, patch] = (
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"packageManager": "yarn@3.2.4",
|
|
5
5
|
"main": "./dist/index.cjs.js",
|
|
6
6
|
"module": "./dist/index.es.js",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@floating-ui/react": "^0.22.0",
|
|
32
32
|
"@nivo/core": "^0.80.0",
|
|
33
33
|
"@nivo/line": "^0.80.0",
|
|
34
|
-
"@stream-io/video-client": "^0.
|
|
35
|
-
"@stream-io/video-react-bindings": "^0.
|
|
34
|
+
"@stream-io/video-client": "^0.4.0",
|
|
35
|
+
"@stream-io/video-react-bindings": "^0.3.0",
|
|
36
36
|
"clsx": "^2.0.0",
|
|
37
37
|
"prop-types": "^15.8.1",
|
|
38
38
|
"rxjs": "~7.8.1"
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CallStatsButton,
|
|
3
|
-
CancelCallButton,
|
|
4
|
-
RecordCallButton,
|
|
5
|
-
ScreenShareButton,
|
|
6
|
-
ToggleAudioPublishingButton,
|
|
7
|
-
ToggleVideoPublishingButton,
|
|
8
|
-
} from './index';
|
|
9
1
|
import { SpeakingWhileMutedNotification } from '../Notification';
|
|
2
|
+
import { RecordCallButton } from './RecordCallButton';
|
|
3
|
+
import { CallStatsButton } from './CallStatsButton';
|
|
4
|
+
import { ScreenShareButton } from './ScreenShareButton';
|
|
5
|
+
import { ToggleAudioPublishingButton } from './ToggleAudioButton';
|
|
6
|
+
import { ToggleVideoPublishingButton } from './ToggleVideoButton';
|
|
7
|
+
import { CancelCallButton } from './CancelCallButton';
|
|
10
8
|
|
|
11
9
|
export type CallControlsProps = {
|
|
12
10
|
onLeave?: () => void;
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import { OwnCapability } from '@stream-io/video-client';
|
|
2
2
|
import {
|
|
3
3
|
Restricted,
|
|
4
|
-
useCall,
|
|
5
4
|
useCallStateHooks,
|
|
6
5
|
useI18n,
|
|
7
6
|
} from '@stream-io/video-react-bindings';
|
|
8
7
|
import { CompositeButton, IconButton } from '../Button/';
|
|
9
8
|
import { PermissionNotification } from '../Notification';
|
|
10
|
-
import {
|
|
9
|
+
import { useRequestPermission } from '../../hooks';
|
|
11
10
|
|
|
12
11
|
export type ScreenShareButtonProps = {
|
|
13
12
|
caption?: string;
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
export const ScreenShareButton = (props: ScreenShareButtonProps) => {
|
|
17
|
-
const call = useCall();
|
|
18
|
-
const { useHasOngoingScreenShare } = useCallStateHooks();
|
|
19
|
-
const isSomeoneScreenSharing = useHasOngoingScreenShare();
|
|
20
|
-
|
|
21
16
|
const { t } = useI18n();
|
|
22
17
|
const { caption = t('Screen Share') } = props;
|
|
23
18
|
|
|
24
|
-
const {
|
|
25
|
-
|
|
19
|
+
const { useHasOngoingScreenShare, useScreenShareState } = useCallStateHooks();
|
|
20
|
+
const isSomeoneScreenSharing = useHasOngoingScreenShare();
|
|
21
|
+
const { hasPermission, requestPermission, isAwaitingPermission } =
|
|
22
|
+
useRequestPermission(OwnCapability.SCREENSHARE);
|
|
26
23
|
|
|
24
|
+
const { screenShare, isMute: isScreenSharing } = useScreenShareState();
|
|
27
25
|
return (
|
|
28
26
|
<Restricted requiredGrants={[OwnCapability.SCREENSHARE]}>
|
|
29
27
|
<PermissionNotification
|
|
@@ -37,8 +35,14 @@ export const ScreenShareButton = (props: ScreenShareButtonProps) => {
|
|
|
37
35
|
<IconButton
|
|
38
36
|
icon={isScreenSharing ? 'screen-share-on' : 'screen-share-off'}
|
|
39
37
|
title={t('Share screen')}
|
|
40
|
-
disabled={
|
|
41
|
-
onClick={
|
|
38
|
+
disabled={!isScreenSharing && isSomeoneScreenSharing}
|
|
39
|
+
onClick={async () => {
|
|
40
|
+
if (!hasPermission) {
|
|
41
|
+
await requestPermission();
|
|
42
|
+
} else {
|
|
43
|
+
await screenShare.toggle();
|
|
44
|
+
}
|
|
45
|
+
}}
|
|
42
46
|
/>
|
|
43
47
|
</CompositeButton>
|
|
44
48
|
</PermissionNotification>
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { ComponentType } from 'react';
|
|
2
|
-
import { OwnCapability
|
|
2
|
+
import { OwnCapability } from '@stream-io/video-client';
|
|
3
3
|
import {
|
|
4
4
|
Restricted,
|
|
5
5
|
useCallStateHooks,
|
|
6
6
|
useI18n,
|
|
7
7
|
} from '@stream-io/video-react-bindings';
|
|
8
|
-
|
|
9
|
-
import { useMediaDevices } from '../../core';
|
|
10
8
|
import { DeviceSelectorAudioInput } from '../DeviceSettings';
|
|
11
9
|
import { CompositeButton, IconButton } from '../Button';
|
|
12
10
|
import { PermissionNotification } from '../Notification';
|
|
13
|
-
import {
|
|
11
|
+
import { useRequestPermission } from '../../hooks';
|
|
14
12
|
|
|
15
13
|
export type ToggleAudioPreviewButtonProps = {
|
|
16
14
|
caption?: string;
|
|
@@ -20,20 +18,17 @@ export type ToggleAudioPreviewButtonProps = {
|
|
|
20
18
|
export const ToggleAudioPreviewButton = (
|
|
21
19
|
props: ToggleAudioPreviewButtonProps,
|
|
22
20
|
) => {
|
|
23
|
-
const { initialAudioEnabled, toggleInitialAudioMuteState } =
|
|
24
|
-
useMediaDevices();
|
|
25
21
|
const { t } = useI18n();
|
|
26
22
|
const { caption = t('Mic'), Menu = DeviceSelectorAudioInput } = props;
|
|
27
23
|
|
|
24
|
+
const { useMicrophoneState } = useCallStateHooks();
|
|
25
|
+
const { microphone, isMute } = useMicrophoneState();
|
|
26
|
+
|
|
28
27
|
return (
|
|
29
|
-
<CompositeButton
|
|
30
|
-
Menu={Menu}
|
|
31
|
-
active={!initialAudioEnabled}
|
|
32
|
-
caption={caption || t('Mic')}
|
|
33
|
-
>
|
|
28
|
+
<CompositeButton Menu={Menu} active={isMute} caption={caption || t('Mic')}>
|
|
34
29
|
<IconButton
|
|
35
|
-
icon={
|
|
36
|
-
onClick={
|
|
30
|
+
icon={!isMute ? 'mic' : 'mic-off'}
|
|
31
|
+
onClick={() => microphone.toggle()}
|
|
37
32
|
/>
|
|
38
33
|
</CompositeButton>
|
|
39
34
|
);
|
|
@@ -47,18 +42,14 @@ export type ToggleAudioPublishingButtonProps = {
|
|
|
47
42
|
export const ToggleAudioPublishingButton = (
|
|
48
43
|
props: ToggleAudioPublishingButtonProps,
|
|
49
44
|
) => {
|
|
50
|
-
const { useLocalParticipant } = useCallStateHooks();
|
|
51
|
-
const localParticipant = useLocalParticipant();
|
|
52
45
|
const { t } = useI18n();
|
|
53
|
-
|
|
54
46
|
const { caption = t('Mic'), Menu = DeviceSelectorAudioInput } = props;
|
|
55
47
|
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
);
|
|
48
|
+
const { hasPermission, requestPermission, isAwaitingPermission } =
|
|
49
|
+
useRequestPermission(OwnCapability.SEND_AUDIO);
|
|
59
50
|
|
|
60
|
-
const {
|
|
61
|
-
|
|
51
|
+
const { useMicrophoneState } = useCallStateHooks();
|
|
52
|
+
const { microphone, isMute } = useMicrophoneState();
|
|
62
53
|
|
|
63
54
|
return (
|
|
64
55
|
<Restricted requiredGrants={[OwnCapability.SEND_AUDIO]}>
|
|
@@ -69,10 +60,16 @@ export const ToggleAudioPublishingButton = (
|
|
|
69
60
|
messageAwaitingApproval={t('Awaiting for an approval to speak.')}
|
|
70
61
|
messageRevoked={t('You can no longer speak.')}
|
|
71
62
|
>
|
|
72
|
-
<CompositeButton Menu={Menu} active={
|
|
63
|
+
<CompositeButton Menu={Menu} active={isMute} caption={caption}>
|
|
73
64
|
<IconButton
|
|
74
|
-
icon={
|
|
75
|
-
onClick={
|
|
65
|
+
icon={isMute ? 'mic-off' : 'mic'}
|
|
66
|
+
onClick={async () => {
|
|
67
|
+
if (!hasPermission) {
|
|
68
|
+
await requestPermission();
|
|
69
|
+
} else {
|
|
70
|
+
await microphone.toggle();
|
|
71
|
+
}
|
|
72
|
+
}}
|
|
76
73
|
/>
|
|
77
74
|
</CompositeButton>
|
|
78
75
|
</PermissionNotification>
|
|
@@ -15,7 +15,7 @@ export const ToggleAudioOutputButton = (
|
|
|
15
15
|
const { caption = t('Speakers'), Menu = DeviceSelectorAudioOutput } = props;
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
|
-
<CompositeButton Menu={Menu}
|
|
18
|
+
<CompositeButton Menu={Menu} caption={caption}>
|
|
19
19
|
<IconButton icon="speaker" />
|
|
20
20
|
</CompositeButton>
|
|
21
21
|
);
|
|
@@ -5,12 +5,11 @@ import {
|
|
|
5
5
|
useI18n,
|
|
6
6
|
} from '@stream-io/video-react-bindings';
|
|
7
7
|
|
|
8
|
-
import { OwnCapability
|
|
8
|
+
import { OwnCapability } from '@stream-io/video-client';
|
|
9
9
|
import { CompositeButton, IconButton } from '../Button/';
|
|
10
|
-
import { useMediaDevices } from '../../core';
|
|
11
10
|
import { DeviceSelectorVideo } from '../DeviceSettings';
|
|
12
11
|
import { PermissionNotification } from '../Notification';
|
|
13
|
-
import {
|
|
12
|
+
import { useRequestPermission } from '../../hooks';
|
|
14
13
|
|
|
15
14
|
export type ToggleVideoPreviewButtonProps = {
|
|
16
15
|
caption?: string;
|
|
@@ -20,19 +19,17 @@ export type ToggleVideoPreviewButtonProps = {
|
|
|
20
19
|
export const ToggleVideoPreviewButton = (
|
|
21
20
|
props: ToggleVideoPreviewButtonProps,
|
|
22
21
|
) => {
|
|
23
|
-
const { toggleInitialVideoMuteState, initialVideoState } = useMediaDevices();
|
|
24
22
|
const { t } = useI18n();
|
|
25
23
|
const { caption = t('Video'), Menu = DeviceSelectorVideo } = props;
|
|
26
24
|
|
|
25
|
+
const { useCameraState } = useCallStateHooks();
|
|
26
|
+
const { camera, isMute } = useCameraState();
|
|
27
|
+
|
|
27
28
|
return (
|
|
28
|
-
<CompositeButton
|
|
29
|
-
Menu={Menu}
|
|
30
|
-
active={!initialVideoState.enabled}
|
|
31
|
-
caption={caption}
|
|
32
|
-
>
|
|
29
|
+
<CompositeButton Menu={Menu} active={isMute} caption={caption}>
|
|
33
30
|
<IconButton
|
|
34
|
-
icon={
|
|
35
|
-
onClick={
|
|
31
|
+
icon={!isMute ? 'camera' : 'camera-off'}
|
|
32
|
+
onClick={() => camera.toggle()}
|
|
36
33
|
/>
|
|
37
34
|
</CompositeButton>
|
|
38
35
|
);
|
|
@@ -46,18 +43,14 @@ type ToggleVideoPublishingButtonProps = {
|
|
|
46
43
|
export const ToggleVideoPublishingButton = (
|
|
47
44
|
props: ToggleVideoPublishingButtonProps,
|
|
48
45
|
) => {
|
|
49
|
-
const { useLocalParticipant } = useCallStateHooks();
|
|
50
|
-
const localParticipant = useLocalParticipant();
|
|
51
46
|
const { t } = useI18n();
|
|
52
|
-
|
|
53
47
|
const { caption = t('Video'), Menu = DeviceSelectorVideo } = props;
|
|
54
48
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
);
|
|
49
|
+
const { hasPermission, requestPermission, isAwaitingPermission } =
|
|
50
|
+
useRequestPermission(OwnCapability.SEND_VIDEO);
|
|
58
51
|
|
|
59
|
-
const {
|
|
60
|
-
|
|
52
|
+
const { useCameraState } = useCallStateHooks();
|
|
53
|
+
const { camera, isMute } = useCameraState();
|
|
61
54
|
|
|
62
55
|
return (
|
|
63
56
|
<Restricted requiredGrants={[OwnCapability.SEND_VIDEO]}>
|
|
@@ -70,10 +63,16 @@ export const ToggleVideoPublishingButton = (
|
|
|
70
63
|
)}
|
|
71
64
|
messageRevoked={t('You can no longer share your video.')}
|
|
72
65
|
>
|
|
73
|
-
<CompositeButton Menu={Menu} active={
|
|
66
|
+
<CompositeButton Menu={Menu} active={isMute} caption={caption}>
|
|
74
67
|
<IconButton
|
|
75
|
-
icon={
|
|
76
|
-
onClick={
|
|
68
|
+
icon={isMute ? 'camera-off' : 'camera'}
|
|
69
|
+
onClick={async () => {
|
|
70
|
+
if (!hasPermission) {
|
|
71
|
+
await requestPermission();
|
|
72
|
+
} else {
|
|
73
|
+
await camera.toggle();
|
|
74
|
+
}
|
|
75
|
+
}}
|
|
77
76
|
/>
|
|
78
77
|
</CompositeButton>
|
|
79
78
|
</PermissionNotification>
|
|
@@ -1,28 +1,25 @@
|
|
|
1
|
+
import { useCallStateHooks, useI18n } from '@stream-io/video-react-bindings';
|
|
1
2
|
import { DeviceSelector } from './DeviceSelector';
|
|
2
|
-
import {
|
|
3
|
-
useMediaDevices,
|
|
4
|
-
useAudioInputDevices,
|
|
5
|
-
useAudioOutputDevices,
|
|
6
|
-
} from '../../core';
|
|
7
3
|
|
|
8
4
|
export type DeviceSelectorAudioInputProps = {
|
|
9
5
|
title?: string;
|
|
10
6
|
};
|
|
11
7
|
|
|
12
8
|
export const DeviceSelectorAudioInput = ({
|
|
13
|
-
title
|
|
9
|
+
title,
|
|
14
10
|
}: DeviceSelectorAudioInputProps) => {
|
|
15
|
-
const {
|
|
16
|
-
const
|
|
11
|
+
const { t } = useI18n();
|
|
12
|
+
const { useMicrophoneState } = useCallStateHooks();
|
|
13
|
+
const { microphone, selectedDevice, devices } = useMicrophoneState();
|
|
17
14
|
|
|
18
15
|
return (
|
|
19
16
|
<DeviceSelector
|
|
20
|
-
devices={
|
|
21
|
-
selectedDeviceId={
|
|
22
|
-
onChange={(deviceId) => {
|
|
23
|
-
|
|
17
|
+
devices={devices || []}
|
|
18
|
+
selectedDeviceId={selectedDevice}
|
|
19
|
+
onChange={async (deviceId) => {
|
|
20
|
+
await microphone.select(deviceId);
|
|
24
21
|
}}
|
|
25
|
-
title={title}
|
|
22
|
+
title={title || t('Select a Mic')}
|
|
26
23
|
/>
|
|
27
24
|
);
|
|
28
25
|
};
|
|
@@ -32,26 +29,23 @@ export type DeviceSelectorAudioOutputProps = {
|
|
|
32
29
|
};
|
|
33
30
|
|
|
34
31
|
export const DeviceSelectorAudioOutput = ({
|
|
35
|
-
title
|
|
32
|
+
title,
|
|
36
33
|
}: DeviceSelectorAudioOutputProps) => {
|
|
37
|
-
const {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
} = useMediaDevices();
|
|
42
|
-
|
|
43
|
-
const audioOutputDevices = useAudioOutputDevices();
|
|
34
|
+
const { t } = useI18n();
|
|
35
|
+
const { useSpeakerState } = useCallStateHooks();
|
|
36
|
+
const { speaker, selectedDevice, devices, isDeviceSelectionSupported } =
|
|
37
|
+
useSpeakerState();
|
|
44
38
|
|
|
45
|
-
if (!
|
|
39
|
+
if (!isDeviceSelectionSupported) return null;
|
|
46
40
|
|
|
47
41
|
return (
|
|
48
42
|
<DeviceSelector
|
|
49
|
-
devices={
|
|
50
|
-
selectedDeviceId={
|
|
43
|
+
devices={devices}
|
|
44
|
+
selectedDeviceId={selectedDevice}
|
|
51
45
|
onChange={(deviceId) => {
|
|
52
|
-
|
|
46
|
+
speaker.select(deviceId);
|
|
53
47
|
}}
|
|
54
|
-
title={title}
|
|
48
|
+
title={title || t('Select Speakers')}
|
|
55
49
|
/>
|
|
56
50
|
);
|
|
57
51
|
};
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { DeviceSelector } from './DeviceSelector';
|
|
2
|
-
import {
|
|
2
|
+
import { useCallStateHooks, useI18n } from '@stream-io/video-react-bindings';
|
|
3
3
|
|
|
4
4
|
export type DeviceSelectorVideoProps = {
|
|
5
5
|
title?: string;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
export const DeviceSelectorVideo = ({ title }: DeviceSelectorVideoProps) => {
|
|
9
|
-
const {
|
|
10
|
-
const
|
|
9
|
+
const { t } = useI18n();
|
|
10
|
+
const { useCameraState } = useCallStateHooks();
|
|
11
|
+
const { camera, devices, selectedDevice } = useCameraState();
|
|
11
12
|
|
|
12
13
|
return (
|
|
13
14
|
<DeviceSelector
|
|
14
|
-
devices={
|
|
15
|
-
selectedDeviceId={
|
|
16
|
-
onChange={(deviceId) => {
|
|
17
|
-
|
|
15
|
+
devices={devices || []}
|
|
16
|
+
selectedDeviceId={selectedDevice}
|
|
17
|
+
onChange={async (deviceId) => {
|
|
18
|
+
await camera.select(deviceId);
|
|
18
19
|
}}
|
|
19
|
-
title={title || 'Select a Camera'}
|
|
20
|
+
title={title || t('Select a Camera')}
|
|
20
21
|
/>
|
|
21
22
|
);
|
|
22
23
|
};
|