diff --git a/README.md b/README.md
index 2e49028e..f95511d3 100644
--- a/README.md
+++ b/README.md
@@ -65,7 +65,7 @@ This application provides features for common conferencing use cases, such as:
-
- Background effects in meeting and waiting room. You can set predefined images, custom image or slight/strong background blur. Images can be uploaded from local device or URL in these formats: JPG, PNG, GIF or BMP.
+ Background effects in meeting and waiting room. You can set predefined images, custom image or slight/strong background blur. Images can be uploaded from local device or URL in these formats: JPG, PNG, GIF or BMP. Background effects are not supported in non-Chromium-based browsers or on iOS.
-
diff --git a/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.spec.tsx b/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.spec.tsx
index 8377a411..203628e5 100644
--- a/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.spec.tsx
+++ b/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.spec.tsx
@@ -1,6 +1,31 @@
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { vi, describe, it, expect, beforeAll } from 'vitest';
import AddBackgroundEffectLayout from './AddBackgroundEffectLayout';
+import enTranslations from '../../../../locales/en.json';
+
+vi.mock('react-i18next', () => ({
+ useTranslation: () => ({
+ t: (key: string, options?: Record) => {
+ const translations: Record = {
+ 'backgroundEffects.invalidFileType': enTranslations['backgroundEffects.invalidFileType'],
+ 'backgroundEffects.fileTooLarge': enTranslations['backgroundEffects.fileTooLarge'],
+ 'backgroundEffects.linkPlaceholder': enTranslations['backgroundEffects.linkPlaceholder'],
+ 'backgroundEffects.dragDropText': enTranslations['backgroundEffects.dragDropText'],
+ 'backgroundEffects.maxSize': enTranslations['backgroundEffects.maxSize'],
+ };
+
+ let translation = translations[key] || key;
+
+ if (options && typeof translation === 'string') {
+ Object.keys(options).forEach((param) => {
+ translation = translation.replace(`{{${param}}}`, String(options[param]));
+ });
+ }
+
+ return translation;
+ },
+ }),
+}));
vi.mock('../../../../utils/useImageStorage/useImageStorage', () => ({
__esModule: true,
diff --git a/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.tsx b/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.tsx
index 1e1d108f..1cde720d 100644
--- a/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.tsx
+++ b/frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.tsx
@@ -9,6 +9,7 @@ import {
import { ChangeEvent, ReactElement, useState } from 'react';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import LinkIcon from '@mui/icons-material/Link';
+import { useTranslation } from 'react-i18next';
import FileUploader from '../../FileUploader/FileUploader';
import { ALLOWED_TYPES, MAX_SIZE_MB } from '../../../../utils/constants';
import useImageStorage from '../../../../utils/useImageStorage/useImageStorage';
@@ -32,6 +33,7 @@ const AddBackgroundEffectLayout = ({
const [imageLink, setImageLink] = useState('');
const [linkLoading, setLinkLoading] = useState(false);
const { storageError, handleImageFromFile, handleImageFromLink } = useImageStorage();
+ const { t } = useTranslation();
type HandleFileChangeType = ChangeEvent | { target: { files: FileList } };
@@ -47,12 +49,12 @@ const AddBackgroundEffectLayout = ({
}
if (!ALLOWED_TYPES.includes(file.type)) {
- setFileError('Only JPG, PNG, GIF, or BMP images are allowed.');
+ setFileError(t('backgroundEffects.invalidFileType'));
return;
}
if (file.size > MAX_SIZE_MB * 1024 * 1024) {
- setFileError(`Image must be less than ${MAX_SIZE_MB}MB.`);
+ setFileError(t('backgroundEffects.fileTooLarge', { maxSize: MAX_SIZE_MB }));
return;
}
@@ -63,7 +65,7 @@ const AddBackgroundEffectLayout = ({
customBackgroundImageChange(newImage.dataUrl);
}
} catch {
- setFileError('Failed to process uploaded image.');
+ setFileError(t('backgroundEffects.processingError'));
}
};
@@ -76,7 +78,7 @@ const AddBackgroundEffectLayout = ({
setFileError('');
customBackgroundImageChange(newImage.dataUrl);
} else {
- setFileError('Failed to store image.');
+ setFileError(t('backgroundEffects.storageError'));
}
} catch {
// error handled in hook
@@ -103,7 +105,7 @@ const AddBackgroundEffectLayout = ({
setImageLink(e.target.value)}
diff --git a/frontend/src/components/BackgroundEffects/BackgroundEffectTabs/BackgroundEffectTabs.tsx b/frontend/src/components/BackgroundEffects/BackgroundEffectTabs/BackgroundEffectTabs.tsx
index 6a1541e8..e6220b46 100644
--- a/frontend/src/components/BackgroundEffects/BackgroundEffectTabs/BackgroundEffectTabs.tsx
+++ b/frontend/src/components/BackgroundEffects/BackgroundEffectTabs/BackgroundEffectTabs.tsx
@@ -1,6 +1,7 @@
import { Box, Tabs, Tab } from '@mui/material';
import { Publisher } from '@vonage/client-sdk-video';
import { ReactElement } from 'react';
+import { useTranslation } from 'react-i18next';
import EffectOptionButtons from '../EffectOptionButtons/EffectOptionButtons';
import BackgroundGallery from '../BackgroundGallery/BackgroundGallery';
import AddBackgroundEffectLayout from '../AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout';
@@ -58,6 +59,7 @@ const BackgroundEffectTabs = ({
setBackgroundSelected(value);
};
const isTabletViewport = useIsTabletViewport();
+ const { t } = useTranslation();
return (
setTabSelected(newValue)}
- aria-label="backgrounds tabs"
+ aria-label={t('backgroundEffects.title.tabs')}
>
-
-
+
+
diff --git a/frontend/src/components/BackgroundEffects/BackgroundEffectsLayout/BackgroundEffectsLayout.spec.tsx b/frontend/src/components/BackgroundEffects/BackgroundEffectsLayout/BackgroundEffectsLayout.spec.tsx
index dc25fb33..23d10a3a 100644
--- a/frontend/src/components/BackgroundEffects/BackgroundEffectsLayout/BackgroundEffectsLayout.spec.tsx
+++ b/frontend/src/components/BackgroundEffects/BackgroundEffectsLayout/BackgroundEffectsLayout.spec.tsx
@@ -12,6 +12,9 @@ vi.mock('react-i18next', () => ({
const translations: Record = {
'backgroundEffects.title': enTranslations['backgroundEffects.title'],
'backgroundEffects.choice': enTranslations['backgroundEffects.choice'],
+ 'backgroundEffects.tabs.backgrounds': enTranslations['backgroundEffects.tabs.backgrounds'],
+ 'backgroundEffects.tabs.addBackground':
+ enTranslations['backgroundEffects.tabs.addBackground'],
'button.cancel': enTranslations['button.cancel'],
'button.apply': enTranslations['button.apply'],
};
diff --git a/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.spec.tsx b/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.spec.tsx
index 43baa6a4..1e0385bd 100644
--- a/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.spec.tsx
+++ b/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.spec.tsx
@@ -1,13 +1,29 @@
import { describe, expect, it, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import BackgroundGallery, { backgrounds } from './BackgroundGallery';
+import BackgroundGallery from './BackgroundGallery';
+import enTranslations from '../../../locales/en.json';
const customImages = [
{ id: 'custom1', dataUrl: 'data:image/png;base64,custom1' },
{ id: 'custom2', dataUrl: 'data:image/png;base64,custom2' },
];
+const backgrounds = [
+ {
+ id: 'bg4',
+ file: 'hogwarts.jpg',
+ name: enTranslations['backgroundEffects.backgrounds.hogwarts'],
+ },
+ { id: 'bg5', file: 'library.jpg', name: enTranslations['backgroundEffects.backgrounds.library'] },
+ {
+ id: 'bg6',
+ file: 'new-york.jpg',
+ name: enTranslations['backgroundEffects.backgrounds.newYork'],
+ },
+ { id: 'bg7', file: 'plane.jpg', name: enTranslations['backgroundEffects.backgrounds.plane'] },
+];
+
const mockDeleteImageFromStorage = vi.fn();
const mockGetImagesFromStorage = vi.fn(() => customImages);
diff --git a/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.tsx b/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.tsx
index bb5d4a84..9f0adfd1 100644
--- a/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.tsx
+++ b/frontend/src/components/BackgroundEffects/BackgroundGallery/BackgroundGallery.tsx
@@ -1,21 +1,11 @@
import { ReactElement, useEffect, useState } from 'react';
import { Box, IconButton, Tooltip } from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
+import { useTranslation } from 'react-i18next';
import { BACKGROUNDS_PATH } from '../../../utils/constants';
import SelectableOption from '../SelectableOption';
import useImageStorage, { StoredImage } from '../../../utils/useImageStorage/useImageStorage';
-export const backgrounds = [
- { id: 'bg1', file: 'bookshelf-room.jpg', name: 'Bookshelf Room' },
- { id: 'bg2', file: 'busy-room.jpg', name: 'Busy Room' },
- { id: 'bg3', file: 'dune-view.jpg', name: 'Dune View' },
- { id: 'bg4', file: 'hogwarts.jpg', name: 'Hogwarts' },
- { id: 'bg5', file: 'library.jpg', name: 'Library' },
- { id: 'bg6', file: 'new-york.jpg', name: 'New York' },
- { id: 'bg7', file: 'plane.jpg', name: 'Plane' },
- { id: 'bg8', file: 'white-room.jpg', name: 'White Room' },
-];
-
export type BackgroundGalleryProps = {
backgroundSelected: string;
setBackgroundSelected: (dataUrl: string) => void;
@@ -39,6 +29,22 @@ const BackgroundGallery = ({
}: BackgroundGalleryProps): ReactElement => {
const { getImagesFromStorage, deleteImageFromStorage } = useImageStorage();
const [customImages, setCustomImages] = useState([]);
+ const { t } = useTranslation();
+
+ const backgrounds = [
+ {
+ id: 'bg1',
+ file: 'bookshelf-room.jpg',
+ name: t('backgroundEffects.backgrounds.bookshelfRoom'),
+ },
+ { id: 'bg2', file: 'busy-room.jpg', name: t('backgroundEffects.backgrounds.busyRoom') },
+ { id: 'bg3', file: 'dune-view.jpg', name: t('backgroundEffects.backgrounds.duneView') },
+ { id: 'bg4', file: 'hogwarts.jpg', name: t('backgroundEffects.backgrounds.hogwarts') },
+ { id: 'bg5', file: 'library.jpg', name: t('backgroundEffects.backgrounds.library') },
+ { id: 'bg6', file: 'new-york.jpg', name: t('backgroundEffects.backgrounds.newYork') },
+ { id: 'bg7', file: 'plane.jpg', name: t('backgroundEffects.backgrounds.plane') },
+ { id: 'bg8', file: 'white-room.jpg', name: t('backgroundEffects.backgrounds.whiteRoom') },
+ ];
useEffect(() => {
setCustomImages(getImagesFromStorage());
@@ -67,7 +73,7 @@ const BackgroundGallery = ({
>
setBackgroundSelected(dataUrl)}
image={dataUrl}
@@ -75,14 +81,14 @@ const BackgroundGallery = ({
{
e.stopPropagation();
if (!isSelected) {
diff --git a/frontend/src/components/BackgroundEffects/EffectOptionButtons/EffectOptionButtons.tsx b/frontend/src/components/BackgroundEffects/EffectOptionButtons/EffectOptionButtons.tsx
index 55d0dea2..3a9e6084 100644
--- a/frontend/src/components/BackgroundEffects/EffectOptionButtons/EffectOptionButtons.tsx
+++ b/frontend/src/components/BackgroundEffects/EffectOptionButtons/EffectOptionButtons.tsx
@@ -1,18 +1,9 @@
import { ReactElement } from 'react';
import BlockIcon from '@mui/icons-material/Block';
import BlurOnIcon from '@mui/icons-material/BlurOn';
+import { useTranslation } from 'react-i18next';
import SelectableOption from '../SelectableOption';
-const options = [
- { key: 'none', icon: , name: 'Remove background' },
- { key: 'low-blur', icon: , name: 'Slight background blur' },
- {
- key: 'high-blur',
- icon: ,
- name: 'Strong background blur',
- },
-];
-
export type EffectOptionButtonsProps = {
backgroundSelected: string;
setBackgroundSelected: (key: string) => void;
@@ -31,6 +22,20 @@ const EffectOptionButtons = ({
backgroundSelected,
setBackgroundSelected,
}: EffectOptionButtonsProps): ReactElement => {
+ const { t } = useTranslation();
+ const options = [
+ {
+ key: 'none',
+ icon: ,
+ name: t('backgroundEffects.removeBackground'),
+ },
+ { key: 'low-blur', icon: , name: t('backgroundEffects.slightBlur') },
+ {
+ key: 'high-blur',
+ icon: ,
+ name: t('backgroundEffects.strongBlur'),
+ },
+ ];
return (
<>
{options.map(({ key, icon, name }) => (
diff --git a/frontend/src/components/BackgroundEffects/FileUploader/FileUploader.tsx b/frontend/src/components/BackgroundEffects/FileUploader/FileUploader.tsx
index 188b1fe4..98bc099c 100644
--- a/frontend/src/components/BackgroundEffects/FileUploader/FileUploader.tsx
+++ b/frontend/src/components/BackgroundEffects/FileUploader/FileUploader.tsx
@@ -1,6 +1,7 @@
import { ChangeEvent, useState, DragEvent, ReactElement } from 'react';
import { Box, Typography } from '@mui/material';
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
+import { useTranslation } from 'react-i18next';
import { MAX_SIZE_MB } from '../../../utils/constants';
export type FileUploaderProps = {
@@ -19,6 +20,7 @@ export type FileUploaderProps = {
*/
const FileUploader = ({ handleFileChange }: FileUploaderProps): ReactElement => {
const [dragOver, setDragOver] = useState(false);
+ const { t } = useTranslation();
const onDragOver = (e: DragEvent) => {
e.preventDefault();
@@ -69,9 +71,9 @@ const FileUploader = ({ handleFileChange }: FileUploaderProps): ReactElement =>
<>
- Drag and drop, or click here to upload image,
+ {t('backgroundEffects.dragDropText')}
- Max {MAX_SIZE_MB}MB
+ {t('backgroundEffects.maxSize', { maxSize: MAX_SIZE_MB })}
>
diff --git a/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.spec.tsx b/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.spec.tsx
index bf7ee28f..66099d9c 100644
--- a/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.spec.tsx
+++ b/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.spec.tsx
@@ -9,6 +9,7 @@ import usePublisherContext from '../../../hooks/usePublisherContext';
import DeviceControlButton from './DeviceControlButton';
import useConfigContext from '../../../hooks/useConfigContext';
import { ConfigContextType } from '../../../Context/ConfigProvider';
+import enTranslations from '../../../locales/en.json';
vi.mock('../../../hooks/usePublisherContext.tsx');
vi.mock('../../../hooks/useSpeakingDetector.tsx');
@@ -22,6 +23,22 @@ vi.mock('../../../hooks/useBackgroundPublisherContext', () => {
});
vi.mock('../../../hooks/useConfigContext');
+vi.mock('react-i18next', () => ({
+ useTranslation: () => ({
+ t: (key: string) => {
+ const translations: Record = {
+ 'devices.audio.microphone.full': enTranslations['devices.audio.microphone.full'],
+ 'devices.video.camera.full': enTranslations['devices.video.camera.full'],
+ 'devices.settings.ariaLabel': enTranslations['devices.settings.ariaLabel'],
+ 'devices.video.disabled': enTranslations['devices.video.disabled'],
+ 'devices.audio.disabled': enTranslations['devices.audio.disabled'],
+ 'mutedAlert.message.muted': enTranslations['mutedAlert.message.muted'],
+ };
+ return translations[key] || key;
+ },
+ }),
+}));
+
const mockUsePublisherContext = usePublisherContext as Mock<[], PublisherContextType>;
const mockUseSpeakingDetector = useSpeakingDetector as Mock<[], boolean>;
const mockHandleToggleBackgroundEffects = vi.fn();
@@ -103,7 +120,7 @@ describe('DeviceControlButton', () => {
toggleBackgroundEffects={mockHandleToggleBackgroundEffects}
/>
);
- const cameraButton = screen.getByLabelText('camera');
+ const cameraButton = screen.getByLabelText('Camera');
cameraButton.click();
expect(toggleVideoMock).toHaveBeenCalled();
expect(toggleBackgroundVideoPublisherMock).toHaveBeenCalled();
@@ -117,7 +134,7 @@ describe('DeviceControlButton', () => {
toggleBackgroundEffects={mockHandleToggleBackgroundEffects}
/>
);
- const micButton = screen.getByLabelText('microphone');
+ const micButton = screen.getByLabelText('Microphone');
expect(micButton).toBeInTheDocument();
expect(micButton).not.toBeDisabled();
@@ -132,7 +149,7 @@ describe('DeviceControlButton', () => {
toggleBackgroundEffects={mockHandleToggleBackgroundEffects}
/>
);
- const micButton = screen.getByLabelText('microphone');
+ const micButton = screen.getByLabelText('Microphone');
expect(micButton).toBeInTheDocument();
expect(micButton).toBeDisabled();
@@ -153,7 +170,7 @@ describe('DeviceControlButton', () => {
/>
);
- const videoButton = screen.getByLabelText('camera');
+ const videoButton = screen.getByLabelText('Camera');
expect(videoButton).toBeInTheDocument();
expect(videoButton).not.toBeDisabled();
@@ -169,7 +186,7 @@ describe('DeviceControlButton', () => {
/>
);
- const videoButton = screen.getByLabelText('camera');
+ const videoButton = screen.getByLabelText('Camera');
expect(videoButton).toBeInTheDocument();
expect(videoButton).toBeDisabled();
diff --git a/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.tsx b/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.tsx
index 26100e79..3f90ed4c 100644
--- a/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.tsx
+++ b/frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.tsx
@@ -127,7 +127,9 @@ const DeviceControlButton = ({
onClick={handleDeviceStateChange}
disabled={isButtonDisabled}
edge="start"
- aria-label={isAudio ? 'microphone' : 'camera'}
+ aria-label={
+ isAudio ? t('devices.audio.microphone.full') : t('devices.video.camera.full')
+ }
size="small"
className="m-[3px] size-[50px] rounded-full shadow-md"
>
diff --git a/frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx b/frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx
index 52e70ac6..6aee4ad1 100644
--- a/frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx
+++ b/frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx
@@ -346,7 +346,7 @@ describe('DeviceSettingsMenu Component', () => {
await waitFor(() => {
expect(screen.queryByTestId('dropdown-separator')).toBeVisible();
- expect(screen.queryByText('Background effects')).toBeVisible();
+ expect(screen.queryByText('Background Effects')).toBeVisible();
});
});
@@ -365,7 +365,7 @@ describe('DeviceSettingsMenu Component', () => {
await waitFor(() => {
expect(screen.queryByTestId('dropdown-separator')).not.toBeInTheDocument();
- expect(screen.queryByText('Background effects')).not.toBeInTheDocument();
+ expect(screen.queryByText('Background Effects')).not.toBeInTheDocument();
});
});
@@ -394,7 +394,7 @@ describe('DeviceSettingsMenu Component', () => {
await waitFor(() => {
expect(screen.queryByTestId('dropdown-separator')).not.toBeInTheDocument();
- expect(screen.queryByText('Background effects')).not.toBeInTheDocument();
+ expect(screen.queryByText('Background Effects')).not.toBeInTheDocument();
});
});
});
diff --git a/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.spec.tsx b/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.spec.tsx
index 18a36020..da66c024 100644
--- a/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.spec.tsx
+++ b/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.spec.tsx
@@ -1,6 +1,18 @@
import { describe, it, vi, expect, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent, cleanup } from '@testing-library/react';
import VideoDevicesOptions from './VideoDevicesOptions';
+import enTranslations from '../../../locales/en.json';
+
+vi.mock('react-i18next', () => ({
+ useTranslation: () => ({
+ t: (key: string) => {
+ const translations: Record = {
+ 'backgroundEffects.title': enTranslations['backgroundEffects.title'],
+ };
+ return translations[key] || key;
+ },
+ }),
+}));
describe('VideoDevicesOptions', () => {
const toggleBackgroundEffects = vi.fn();
@@ -15,7 +27,7 @@ describe('VideoDevicesOptions', () => {
it('renders the background effects menu item', () => {
render();
- expect(screen.getByTestId('background-effects-text')).toHaveTextContent('Background effects');
+ expect(screen.getByTestId('background-effects-text')).toHaveTextContent('Background Effects');
expect(screen.getByRole('menuitem')).toBeInTheDocument();
});
diff --git a/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.tsx b/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.tsx
index 762ca2c2..f7c34c87 100644
--- a/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.tsx
+++ b/frontend/src/components/MeetingRoom/VideoDevicesOptions/VideoDevicesOptions.tsx
@@ -1,6 +1,7 @@
import { Typography, MenuList, MenuItem } from '@mui/material';
import { ReactElement } from 'react';
import PortraitIcon from '@mui/icons-material/Portrait';
+import { useTranslation } from 'react-i18next';
export type VideoDevicesOptionsProps = {
toggleBackgroundEffects: () => void;
@@ -17,6 +18,8 @@ export type VideoDevicesOptionsProps = {
const VideoDevicesOptions = ({
toggleBackgroundEffects,
}: VideoDevicesOptionsProps): ReactElement => {
+ const { t } = useTranslation();
+
return (
- Background effects
+ {t('backgroundEffects.title')}
diff --git a/frontend/src/components/WaitingRoom/BackgroundEffects/BackgroundEffectsButton/BackgroundEffectsButton.tsx b/frontend/src/components/WaitingRoom/BackgroundEffects/BackgroundEffectsButton/BackgroundEffectsButton.tsx
index 90632e24..821542b9 100644
--- a/frontend/src/components/WaitingRoom/BackgroundEffects/BackgroundEffectsButton/BackgroundEffectsButton.tsx
+++ b/frontend/src/components/WaitingRoom/BackgroundEffects/BackgroundEffectsButton/BackgroundEffectsButton.tsx
@@ -2,6 +2,7 @@ import { Box, Tooltip } from '@mui/material';
import { hasMediaProcessorSupport } from '@vonage/client-sdk-video';
import { ReactElement } from 'react';
import PortraitIcon from '@mui/icons-material/Portrait';
+import { useTranslation } from 'react-i18next';
import VideoContainerButton from '../../VideoContainerButton';
import useConfigContext from '../../../../hooks/useConfigContext';
@@ -23,6 +24,7 @@ const BackgroundEffectsButton = ({
const config = useConfigContext();
const { allowBackgroundEffects } = config.videoSettings;
const shouldDisplayBackgroundEffects = hasMediaProcessorSupport() && allowBackgroundEffects;
+ const { t } = useTranslation();
return (
shouldDisplayBackgroundEffects && (
@@ -40,7 +42,7 @@ const BackgroundEffectsButton = ({
transition: 'transform 0.2s ease-in-out',
}}
>
-
+
{
setIsBackgroundEffectsOpen(false);
};
+ const { t } = useTranslation();
return (