- 
                Notifications
    
You must be signed in to change notification settings  - Fork 9
 
VIDSOL-105: Background Replacement Support for Web VERA - Custom Images #201
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
          
     Merged
      
      
            OscarFava
  merged 62 commits into
  develop
from
vidsol-105/background-replacement-custom-images
  
      
      
   
  Oct 1, 2025 
      
    
  
     Merged
                    Changes from all commits
      Commits
    
    
            Show all changes
          
          
            62 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      3841fd7
              
                initial background replacement
              
              
                OscarFava 55af7e2
              
                Modify folder structure + add background video container
              
              
                OscarFava 506acb5
              
                Implemented background replacement and blur effects for video calls, …
              
              
                OscarFava 8f359b0
              
                Refactored background effects for better layout and responsiveness, a…
              
              
                OscarFava 45020d0
              
                Add custom background images initial button
              
              
                OscarFava f60b121
              
                Minor fix
              
              
                OscarFava 0b5e785
              
                Remove blurButton
              
              
                OscarFava d40aa17
              
                unit testing
              
              
                OscarFava 3a51e0e
              
                removed
              
              
                OscarFava 21077e5
              
                Add unit testing
              
              
                OscarFava 7570983
              
                Fix unit testing and first review (clean code and add comments)
              
              
                OscarFava ceffe18
              
                Merge remote-tracking branch 'origin/develop' into vidsol-105/backgro…
              
              
                OscarFava a9ba4d2
              
                Remove unfound file
              
              
                OscarFava 310abf1
              
                Reduce duplicated lines
              
              
                OscarFava cfff835
              
                Reduce duplicated lines
              
              
                OscarFava d36d700
              
                Fix unit testing
              
              
                OscarFava 2639977
              
                Clean code and give appropiate names
              
              
                OscarFava 965c1fe
              
                Improve reliability
              
              
                OscarFava b7c582b
              
                Fix lint
              
              
                OscarFava 835c2b5
              
                Fix kint
              
              
                OscarFava 714c562
              
                Fix testing
              
              
                OscarFava 3d1af88
              
                Fix integration
              
              
                OscarFava 574ac90
              
                Fix unit testing + clean code + Fix docs typo + minor fixes
              
              
                OscarFava 9f5e3f4
              
                Fix unit testing + add doc + minor bug fixs
              
              
                OscarFava 8092cdc
              
                Tabs layout
              
              
                OscarFava 75f145e
              
                Improve CSS responsive
              
              
                OscarFava 3afadd5
              
                Start 'Add custom background effects layout'
              
              
                OscarFava 651cff2
              
                Fix unit testing + add doc + minor bug fixs
              
              
                OscarFava 6b7031f
              
                Clean code
              
              
                OscarFava 8f9211b
              
                Merge branch 'vidsol-105/background-replacement' into vidsol-105/back…
              
              
                OscarFava 54081f6
              
                Improve visibility of add background + store images on LocalStorage a…
              
              
                OscarFava 05b808e
              
                Tooltip in add background + automatic apply when uploading image + cl…
              
              
                OscarFava cf7502d
              
                Tooltip in backgrounds boxes + align cancel and apply buttons margins…
              
              
                OscarFava e4b58ec
              
                Add cross to close dialog + improve responsive layout
              
              
                OscarFava 72bf9ac
              
                Merge
              
              
                OscarFava f5e4392
              
                Add comment
              
              
                OscarFava baa4ce2
              
                Fix unit testing and clean code
              
              
                OscarFava 9287c09
              
                Fix crypto and duplicated code
              
              
                OscarFava dfa5506
              
                Fix test
              
              
                OscarFava 8650c99
              
                Reduce duplicated code
              
              
                OscarFava 973d82d
              
                Reduce duplicated code
              
              
                OscarFava 6fc8c7e
              
                Merge remote-tracking branch 'origin/develop' into vidsol-105/backgro…
              
              
                OscarFava 03cf685
              
                Add margin to not enabled video
              
              
                OscarFava 001ce74
              
                Minor fixes, move constants and add missing JSDOC
              
              
                OscarFava b3b55fa
              
                Fix typo
              
              
                OscarFava 97e2a71
              
                Fix testing
              
              
                OscarFava f0531fc
              
                Clean code and  fix tests
              
              
                OscarFava 628315c
              
                Fix warning
              
              
                OscarFava fac9129
              
                Merge remote-tracking branch 'origin/develop' into vidsol-105/backgro…
              
              
                OscarFava aabeab8
              
                Fix bug
              
              
                OscarFava 314a1ff
              
                Merge remote-tracking branch 'origin/develop' into vidsol-105/backgro…
              
              
                OscarFava cb26d88
              
                Unify Background Effects Layout
              
              
                OscarFava 89c163a
              
                Merge remote-tracking branch 'origin/develop' into vidsol-105/backgro…
              
              
                OscarFava b18b150
              
                Fix testing and minor bugs
              
              
                OscarFava 18dd322
              
                Improve CSS and give shorter names
              
              
                OscarFava ad998b1
              
                Merge remote-tracking branch 'origin/develop' into vidsol-105/backgro…
              
              
                OscarFava 81fa0d3
              
                Update image upload validation to include GIF and BMP formats; refact…
              
              
                OscarFava 27820f6
              
                lint fix
              
              
                OscarFava 1e07403
              
                Refactor background effect descriptions, improve file size error mess…
              
              
                OscarFava c53c6b0
              
                missing test
              
              
                OscarFava 6fb542b
              
                Update README
              
              
                OscarFava 4247f58
              
                Update README
              
              
                OscarFava File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
      
      Loading
      
  Sorry, something went wrong. Reload?
      Sorry, we cannot display this file.
      Sorry, this file is invalid so it cannot be displayed.
      
    
      
      Loading
      
  Sorry, something went wrong. Reload?
      Sorry, we cannot display this file.
      Sorry, this file is invalid so it cannot be displayed.
      
    
        
          
          
            35 changes: 0 additions & 35 deletions
          
          35 
        
  frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffect.spec.tsx
  
  
      
      
   
        
      
      
    This file was deleted.
      
      Oops, something went wrong.
      
    
  
        
          
          
            50 changes: 0 additions & 50 deletions
          
          50 
        
  frontend/src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffect.tsx
  
  
      
      
   
        
      
      
    This file was deleted.
      
      Oops, something went wrong.
      
    
  
        
          
          
            67 changes: 67 additions & 0 deletions
          
          67 
        
  ...dEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.spec.tsx
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| import { render, screen, fireEvent, waitFor } from '@testing-library/react'; | ||
| import { vi, describe, it, expect, beforeAll } from 'vitest'; | ||
| import AddBackgroundEffectLayout from './AddBackgroundEffectLayout'; | ||
| 
     | 
||
| vi.mock('../../../../utils/useImageStorage/useImageStorage', () => ({ | ||
| __esModule: true, | ||
| default: () => ({ | ||
| storageError: '', | ||
| handleImageFromFile: vi.fn(async () => ({ | ||
| dataUrl: 'data:image/png;base64,MOCKED', | ||
| })), | ||
| handleImageFromLink: vi.fn(async () => ({ | ||
| dataUrl: 'data:image/png;base64,MOCKED_LINK', | ||
| })), | ||
| }), | ||
| })); | ||
| 
     | 
||
| describe('AddBackgroundEffectLayout', () => { | ||
| const cb = vi.fn(); | ||
| 
     | 
||
| beforeAll(() => { | ||
| vi.clearAllMocks(); | ||
| }); | ||
| 
     | 
||
| it('should render', () => { | ||
| render(<AddBackgroundEffectLayout customBackgroundImageChange={vi.fn()} />); | ||
| expect(screen.getByText(/Drag and drop, or click here to upload image/i)).toBeInTheDocument(); | ||
| expect(screen.getByPlaceholderText(/Link from the web/i)).toBeInTheDocument(); | ||
| expect(screen.getByTestId('background-effect-link-submit-button')).toBeInTheDocument(); | ||
| }); | ||
| 
     | 
||
| it('shows error for invalid file type', async () => { | ||
| render(<AddBackgroundEffectLayout customBackgroundImageChange={vi.fn()} />); | ||
| const input = screen.getByLabelText(/upload/i); | ||
| const file = new File(['dummy'], 'test.txt', { type: 'text/plain' }); | ||
| fireEvent.change(input, { target: { files: [file] } }); | ||
| expect( | ||
| await screen.findByText(/Only JPG, PNG, GIF, or BMP images are allowed/i) | ||
| ).toBeInTheDocument(); | ||
| }); | ||
| 
     | 
||
| it('shows error for file size too large', async () => { | ||
| render(<AddBackgroundEffectLayout customBackgroundImageChange={vi.fn()} />); | ||
| const input = screen.getByLabelText(/upload/i); | ||
| const file = new File(['x'.repeat(3 * 1024 * 1024)], 'big.png', { type: 'image/png' }); | ||
| Object.defineProperty(file, 'size', { value: 3 * 1024 * 1024 }); | ||
| fireEvent.change(input, { target: { files: [file] } }); | ||
| expect(await screen.findByText(/Image must be less than 2MB/i)).toBeInTheDocument(); | ||
| }); | ||
| 
     | 
||
| it('handles valid image file upload', async () => { | ||
| render(<AddBackgroundEffectLayout customBackgroundImageChange={cb} />); | ||
| const input = screen.getByLabelText(/upload/i); | ||
| const file = new File(['dummy'], 'test.png', { type: 'image/png' }); | ||
| fireEvent.change(input, { target: { files: [file] } }); | ||
| await waitFor(() => expect(cb).toHaveBeenCalledWith('data:image/png;base64,MOCKED')); | ||
| }); | ||
| 
     | 
||
| it('handles valid link submit', async () => { | ||
| render(<AddBackgroundEffectLayout customBackgroundImageChange={cb} />); | ||
| const input = screen.getByPlaceholderText(/Link from the web/i); | ||
| fireEvent.change(input, { target: { value: 'https://example.com/image.png' } }); | ||
| const button = screen.getByTestId('background-effect-link-submit-button'); | ||
| fireEvent.click(button); | ||
| await waitFor(() => expect(cb).toHaveBeenCalledWith('data:image/png;base64,MOCKED_LINK')); | ||
| }); | ||
| }); | 
        
          
          
            138 changes: 138 additions & 0 deletions
          
          138 
        
  ...groundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/AddBackgroundEffectLayout.tsx
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| import { | ||
| Box, | ||
| Button, | ||
| CircularProgress, | ||
| InputAdornment, | ||
| TextField, | ||
| Typography, | ||
| } from '@mui/material'; | ||
| import { ChangeEvent, ReactElement, useState } from 'react'; | ||
| import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; | ||
| import LinkIcon from '@mui/icons-material/Link'; | ||
| import FileUploader from '../../FileUploader/FileUploader'; | ||
| import { ALLOWED_TYPES, MAX_SIZE_MB } from '../../../../utils/constants'; | ||
| import useImageStorage from '../../../../utils/useImageStorage/useImageStorage'; | ||
| 
     | 
||
| export type AddBackgroundEffectLayoutProps = { | ||
| customBackgroundImageChange: (dataUrl: string) => void; | ||
| }; | ||
| 
     | 
||
| /** | ||
| * AddBackgroundEffectLayout Component | ||
| * | ||
| * This component manages the UI for adding background effects. | ||
| * @param {AddBackgroundEffectLayoutProps} props - The props for the component. | ||
| * @property {Function} customBackgroundImageChange - Callback function to handle background image change. | ||
| * @returns {ReactElement} The add background effect layout component. | ||
| */ | ||
| const AddBackgroundEffectLayout = ({ | ||
| customBackgroundImageChange, | ||
| }: AddBackgroundEffectLayoutProps): ReactElement => { | ||
| const [fileError, setFileError] = useState<string>(''); | ||
| const [imageLink, setImageLink] = useState<string>(''); | ||
| const [linkLoading, setLinkLoading] = useState<boolean>(false); | ||
| const { storageError, handleImageFromFile, handleImageFromLink } = useImageStorage(); | ||
| 
     | 
||
| type HandleFileChangeType = ChangeEvent<HTMLInputElement> | { target: { files: FileList } }; | ||
| 
     | 
||
| const handleFileChange = async (e: HandleFileChangeType) => { | ||
| const { files } = e.target; | ||
| if (!files || files.length === 0) { | ||
| return; | ||
| } | ||
| 
     | 
||
| const file = files[0]; | ||
| if (!file) { | ||
| return; | ||
| } | ||
| 
     | 
||
| if (!ALLOWED_TYPES.includes(file.type)) { | ||
| setFileError('Only JPG, PNG, GIF, or BMP images are allowed.'); | ||
| return; | ||
| } | ||
| 
     | 
||
| if (file.size > MAX_SIZE_MB * 1024 * 1024) { | ||
| setFileError(`Image must be less than ${MAX_SIZE_MB}MB.`); | ||
| return; | ||
| } | ||
| 
     | 
||
| try { | ||
| const newImage = await handleImageFromFile(file); | ||
| if (newImage) { | ||
| setFileError(''); | ||
| customBackgroundImageChange(newImage.dataUrl); | ||
| } | ||
| } catch { | ||
| setFileError('Failed to process uploaded image.'); | ||
| } | ||
| }; | ||
| 
     | 
||
| const handleLinkSubmit = async () => { | ||
| setFileError(''); | ||
| setLinkLoading(true); | ||
| try { | ||
| const newImage = await handleImageFromLink(imageLink); | ||
| if (newImage) { | ||
| setFileError(''); | ||
| customBackgroundImageChange(newImage.dataUrl); | ||
| } else { | ||
| setFileError('Failed to store image.'); | ||
| } | ||
| } catch { | ||
| // error handled in hook | ||
| } finally { | ||
| setLinkLoading(false); | ||
| } | ||
| }; | ||
| 
     | 
||
| return ( | ||
| <Box | ||
| sx={{ | ||
| overflow: 'auto', | ||
| }} | ||
| > | ||
| <FileUploader handleFileChange={handleFileChange} /> | ||
| 
     | 
||
| {(fileError || storageError) && ( | ||
| <Typography color="error" mt={1} fontSize={14}> | ||
| {fileError || storageError} | ||
| </Typography> | ||
| )} | ||
| 
     | 
||
| <Box mt={2} display="flex" alignItems="center" gap={1}> | ||
| <TextField | ||
| fullWidth | ||
| size="small" | ||
| placeholder="Link from the web" | ||
| className="add-background-effect-input" | ||
| value={imageLink} | ||
| onChange={(e) => setImageLink(e.target.value)} | ||
| InputProps={{ | ||
| startAdornment: ( | ||
| <InputAdornment position="start"> | ||
| {linkLoading ? <CircularProgress size={24} /> : <LinkIcon sx={{ fontSize: 24 }} />} | ||
| </InputAdornment> | ||
| ), | ||
| }} | ||
| /> | ||
| 
     | 
||
| <Button | ||
| data-testid="background-effect-link-submit-button" | ||
| variant="contained" | ||
| color="primary" | ||
| onClick={handleLinkSubmit} | ||
| disabled={linkLoading} | ||
| style={{ minWidth: 0, padding: '8px 12px' }} | ||
| > | ||
| {linkLoading ? ( | ||
| <CircularProgress size={24} color="inherit" /> | ||
| ) : ( | ||
| <ArrowForwardIcon sx={{ fontSize: 24 }} /> | ||
| )} | ||
| </Button> | ||
| </Box> | ||
| </Box> | ||
| ); | ||
| }; | ||
| 
     | 
||
| export default AddBackgroundEffectLayout; | ||
        
          
          
            3 changes: 3 additions & 0 deletions
          
          3 
        
  .../src/components/BackgroundEffects/AddBackgroundEffect/AddBackgroundEffectLayout/Index.tsx
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| import AddBackgroundEffectLayout from './AddBackgroundEffectLayout'; | ||
| 
     | 
||
| export default AddBackgroundEffectLayout; | 
        
          
          
            3 changes: 0 additions & 3 deletions
          
          3 
        
  frontend/src/components/BackgroundEffects/AddBackgroundEffect/Index.tsx
  
  
      
      
   
        
      
      
    This file was deleted.
      
      Oops, something went wrong.
      
    
  
        
          
          
            63 changes: 63 additions & 0 deletions
          
          63 
        
  frontend/src/components/BackgroundEffects/BackgroundEffectTabs/BackgroundEffectTabs.spec.tsx
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import { render, screen } from '@testing-library/react'; | ||
| import userEvent from '@testing-library/user-event'; | ||
| import { vi, describe, it, expect } from 'vitest'; | ||
| import BackgroundEffectTabs from './BackgroundEffectTabs'; | ||
| 
     | 
||
| describe('BackgroundEffectTabs', () => { | ||
| const setTabSelected = vi.fn(); | ||
| const setBackgroundSelected = vi.fn(); | ||
| const clearBgWhenSelectedDeleted = vi.fn(); | ||
| const customBackgroundImageChange = vi.fn(); | ||
| 
     | 
||
| it('renders tabs and defaults to Backgrounds tab', () => { | ||
                
      
                  OscarFava marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| render( | ||
| <BackgroundEffectTabs | ||
| mode="meeting" | ||
| tabSelected={0} | ||
| setTabSelected={setTabSelected} | ||
| backgroundSelected="" | ||
| setBackgroundSelected={setBackgroundSelected} | ||
| cleanupSelectedBackgroundReplacement={clearBgWhenSelectedDeleted} | ||
| customBackgroundImageChange={customBackgroundImageChange} | ||
| /> | ||
| ); | ||
| expect(screen.getByRole('tab', { name: /Backgrounds/i })).toBeInTheDocument(); | ||
| expect(screen.getByRole('tab', { name: /Add Background/i })).toBeInTheDocument(); | ||
| expect(screen.getByRole('tab', { name: /Backgrounds/i })).toHaveAttribute( | ||
| 'aria-selected', | ||
| 'true' | ||
| ); | ||
| }); | ||
| 
     | 
||
| it('switches to Add Background tab when clicked', async () => { | ||
| render( | ||
| <BackgroundEffectTabs | ||
| mode="meeting" | ||
| tabSelected={0} | ||
| setTabSelected={setTabSelected} | ||
| backgroundSelected="" | ||
| setBackgroundSelected={setBackgroundSelected} | ||
| cleanupSelectedBackgroundReplacement={clearBgWhenSelectedDeleted} | ||
| customBackgroundImageChange={customBackgroundImageChange} | ||
| /> | ||
| ); | ||
| const addTab = screen.getByRole('tab', { name: /Add Background/i }); | ||
| await userEvent.click(addTab); | ||
| expect(setTabSelected).toHaveBeenCalledWith(1); | ||
| }); | ||
| 
     | 
||
| it('renders AddBackgroundEffectLayout when Add Background tab is selected', () => { | ||
| render( | ||
| <BackgroundEffectTabs | ||
| mode="waiting" | ||
| tabSelected={1} | ||
| setTabSelected={setTabSelected} | ||
| backgroundSelected="" | ||
| setBackgroundSelected={setBackgroundSelected} | ||
| cleanupSelectedBackgroundReplacement={clearBgWhenSelectedDeleted} | ||
| customBackgroundImageChange={customBackgroundImageChange} | ||
| /> | ||
| ); | ||
| expect(screen.getByText(/upload/i)).toBeInTheDocument(); | ||
| }); | ||
| }); | ||
      
      Oops, something went wrong.
        
    
  
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.