Skip to content
14 changes: 13 additions & 1 deletion src/screens/Watch/Components/ControlBar/VolumeControl/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { connect } from 'dva';
import React from 'react';
import React, { useRef, useEffect } from 'react';
import { Popup } from 'semantic-ui-react';
import './index.scss';
import './slider.scss';
Expand Down Expand Up @@ -28,6 +28,17 @@ function VolumeControl({ muted = false, volume = true, dispatch }) {
}
};

const sliderRef = useRef();
useEffect(() => {
window.focusVolumeSlider = () => {
sliderRef.current?.focus();
};

return () => {
delete window.focusVolumeSlider;
};
}, []);

const iconName =
muted || volume < 0.04 ? 'volume_off' : volume >= 0.6 ? 'volume_up' : 'volume_down';

Expand Down Expand Up @@ -70,6 +81,7 @@ function VolumeControl({ muted = false, volume = true, dispatch }) {
content={<strong>Volume: {Math.floor(volume * 100)}%</strong>}
trigger={
<input
ref={sliderRef}
id="volume-slider"
className="volume-slider"
aria-label={`Volume at ${Math.floor(volume * 100)} %`}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import dva from 'dva';
import { Provider } from 'react-redux';

import VolumeControl from './index';

// Create a DVA app similar to your main app
const createApp = (initialState) => {
const app = dva({
initialState: {
playerpref: { volume: 0.5, ...initialState }
}
});

app.model({
namespace: 'playerpref',
state: { volume: 0.5, ...initialState }
});

app.router(({ history }) => {
return <VolumeControl />;
});

return app;
};

// Helper function to render with DVA
const renderWithDva = (initialState = {}) => {
const app = createApp(initialState);
return {
...render(
<Provider store={app._store}>
<VolumeControl />
</Provider>
),
app
};
};

describe('VolumeControl', () => {
beforeEach(() => {
delete window.focusVolumeSlider;
});

it('sets up focus handler on mount', () => {
renderWithDva();
expect(window.focusVolumeSlider).toBeDefined();
});

it('cleans up focus handler on unmount', () => {
const { unmount } = renderWithDva();
unmount();
expect(window.focusVolumeSlider).toBeUndefined();
});

it('focuses slider when focusVolumeSlider is called', () => {
const { container } = renderWithDva();
const slider = container.querySelector('.volume-slider');
expect(slider).not.toBeNull();
window.focusVolumeSlider();
expect(document.activeElement).toBe(slider);
});

it('displays correct volume percentage', () => {
const { container } = renderWithDva({ volume: 0.75 });
const slider = container.querySelector('.volume-slider');
expect(slider).not.toBeNull();

console.log('Container HTML:', container.innerHTML); // eslint-disable-line
console.log('Slider element:', slider); // eslint-disable-line

expect(slider.getAttribute('aria-label')).toBe('Volume at 75 %');
});
});
4 changes: 2 additions & 2 deletions src/screens/Watch/Utils/keydown.control.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ export const keydownControl = {
* Function for handling down-arrow key down
*/
handleDownArrow(e) {
// If there is no menu opening - decrease the volume by 0.1 each time
// If there is no menu opening - decrease the volume by slider amount each time
if (!this.isMenuOpen()) {
$('#volume-slider').focus(); // NEED TO MODIFY
window.focusVolumeSlider?.();
return;
}

Expand Down
Loading
Loading