Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VIDCS-3392: BG blur state is not saved for the waiting room #70

Merged
merged 14 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { act, cleanup, renderHook } from '@testing-library/react';
import { afterAll, afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest';
import { initPublisher, Publisher } from '@vonage/client-sdk-video';
import { hasMediaProcessorSupport, initPublisher, Publisher } from '@vonage/client-sdk-video';
import EventEmitter from 'events';
import usePreviewPublisher from './usePreviewPublisher';
import { UserContextType } from '../../user';
Expand All @@ -19,7 +19,6 @@ vi.mock('@vonage/client-sdk-video');
vi.mock('../../../hooks/useUserContext.tsx');
vi.mock('../../../hooks/usePermissions.tsx');
vi.mock('../../../hooks/useDevices.tsx');

const mockUseUserContext = useUserContext as Mock<[], UserContextType>;
const mockUsePermissions = usePermissions as Mock<[], PermissionsHookType>;
const mockUseDevices = useDevices as Mock<
Expand All @@ -31,7 +30,7 @@ const defaultSettings = {
publishAudio: false,
publishVideo: false,
name: '',
blur: false,
blur: true,
noiseSuppression: true,
};
const mockUserContextWithDefaultSettings = {
Expand All @@ -46,14 +45,15 @@ describe('usePreviewPublisher', () => {
getVideoSource: () => defaultVideoDevice,
}) as unknown as Publisher;
const mockedInitPublisher = vi.fn();
const mockedHasMediaProcessorSupport = vi.fn();
const consoleErrorSpy = vi.spyOn(console, 'error');
const mockSetAccessStatus = vi.fn();

beforeEach(() => {
vi.resetAllMocks();

mockUseUserContext.mockImplementation(() => mockUserContextWithDefaultSettings);
(initPublisher as Mock).mockImplementation(mockedInitPublisher);
(hasMediaProcessorSupport as Mock).mockImplementation(mockedHasMediaProcessorSupport);
mockUseDevices.mockReturnValue({
getAllMediaDevices: vi.fn(),
allMediaDevices,
Expand Down Expand Up @@ -93,6 +93,45 @@ describe('usePreviewPublisher', () => {
});
expect(consoleErrorSpy).toHaveBeenCalledWith('initPublisher error: ', error);
});

it('should apply background blur when initialized if set to true', () => {
mockedHasMediaProcessorSupport.mockReturnValue(true);
(hasMediaProcessorSupport as Mock).mockImplementation(mockedHasMediaProcessorSupport);
mockedInitPublisher.mockReturnValue(mockPublisher);
(initPublisher as Mock).mockImplementation(mockedInitPublisher);
const { result } = renderHook(() => usePreviewPublisher());
act(() => {
result.current.initLocalPublisher();
});
expect(mockedInitPublisher).toHaveBeenCalledWith(
undefined,
expect.objectContaining({
videoFilter: expect.objectContaining({
type: 'backgroundBlur',
blurStrength: 'high',
}),
}),
expect.any(Function)
);
});

it('should not apply background blur when initialized if the device does not support it', () => {
mockedHasMediaProcessorSupport.mockReturnValue(false);
(hasMediaProcessorSupport as Mock).mockImplementation(mockedHasMediaProcessorSupport);
mockedInitPublisher.mockReturnValue(mockPublisher);
(initPublisher as Mock).mockImplementation(mockedInitPublisher);
const { result } = renderHook(() => usePreviewPublisher());
act(() => {
result.current.initLocalPublisher();
});
expect(mockedInitPublisher).toHaveBeenCalledWith(
undefined,
expect.objectContaining({
videoFilter: undefined,
}),
expect.any(Function)
);
});
});

describe('on accessDenied', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { useState, useRef, useCallback, useEffect } from 'react';
import { Publisher, Event, initPublisher } from '@vonage/client-sdk-video';
import {
Publisher,
Event,
initPublisher,
VideoFilter,
hasMediaProcessorSupport,
} from '@vonage/client-sdk-video';
import setMediaDevices from '../../../utils/mediaDeviceUtils';
import useDevices from '../../../hooks/useDevices';
import usePermissions from '../../../hooks/usePermissions';
Expand Down Expand Up @@ -47,7 +53,7 @@ export type PreviewPublisherContextType = {
* @returns {PreviewPublisherContextType} preview context
*/
const usePreviewPublisher = (): PreviewPublisherContextType => {
const { setUser } = useUserContext();
const { setUser, user } = useUserContext();
const { allMediaDevices, getAllMediaDevices } = useDevices();
const [publisherVideoElement, setPublisherVideoElement] = useState<
HTMLVideoElement | HTMLObjectElement
Expand All @@ -57,7 +63,8 @@ const usePreviewPublisher = (): PreviewPublisherContextType => {
const { setAccessStatus, accessStatus } = usePermissions();
const publisherRef = useRef<Publisher | null>(null);
const [isPublishing, setIsPublishing] = useState(false);
const [localBlur, setLocalBlur] = useState(false);
const initialLocalBlurRef = useRef<boolean>(user.defaultSettings.blur);
const [localBlur, setLocalBlur] = useState(user.defaultSettings.blur);
const [isVideoEnabled, setIsVideoEnabled] = useState(true);
const [isAudioEnabled, setIsAudioEnabled] = useState(true);
const [localVideoSource, setLocalVideoSource] = useState<string | undefined>(undefined);
Expand Down Expand Up @@ -89,6 +96,7 @@ const usePreviewPublisher = (): PreviewPublisherContextType => {
});
}
setLocalBlur(!localBlur);
window.localStorage.setItem('backgroundBlur', JSON.stringify(!localBlur));
if (setUser) {
setUser((prevUser: UserType) => ({
...prevUser,
Expand Down Expand Up @@ -212,14 +220,26 @@ const usePreviewPublisher = (): PreviewPublisherContextType => {
return;
}

publisherRef.current = initPublisher(undefined, { insertDefaultUI: false }, (err: unknown) => {
if (err instanceof Error) {
publisherRef.current = null;
if (err.name === 'OT_USER_MEDIA_ACCESS_DENIED') {
console.error('initPublisher error: ', err);
const videoFilter: VideoFilter | undefined =
initialLocalBlurRef.current && hasMediaProcessorSupport()
? {
type: 'backgroundBlur',
blurStrength: 'high',
}
: undefined;

publisherRef.current = initPublisher(
undefined,
{ insertDefaultUI: false, videoFilter },
(err: unknown) => {
if (err instanceof Error) {
publisherRef.current = null;
if (err.name === 'OT_USER_MEDIA_ACCESS_DENIED') {
console.error('initPublisher error: ', err);
}
}
}
});
);
addPublisherListeners(publisherRef.current);
}, [addPublisherListeners]);

Expand Down