[deploy] Fixed broken video capabilities of Connect (#8922)
* Fixes the broken video capabilities of Connect. * Added tests for fullscreen check. * Added tests. * Fixed a typo. Co-authored-by: Ben Halpern <bendhalpern@gmail.com>
This commit is contained in:
parent
a7c56034a2
commit
8e1dd6e323
3 changed files with 143 additions and 52 deletions
77
app/javascript/chat/__tests__/VideoContent.test.jsx
Normal file
77
app/javascript/chat/__tests__/VideoContent.test.jsx
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import { h } from 'preact';
|
||||
import { axe } from 'jest-axe';
|
||||
import { render } from '@testing-library/preact';
|
||||
import { VideoContent } from '../videoContent';
|
||||
|
||||
describe('<VideoContent />', () => {
|
||||
it('should have no a11y violations', async () => {
|
||||
const { container } = render(
|
||||
<VideoContent
|
||||
videoPath="/some-video-path"
|
||||
fullscreen="false"
|
||||
onTriggerVideoContent={jest.fn()}
|
||||
/>,
|
||||
);
|
||||
const results = await axe(container);
|
||||
|
||||
expect(results).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it('should render in fullscreen', () => {
|
||||
const { queryByLabelText } = render(
|
||||
<VideoContent
|
||||
videoPath="/some-video-path"
|
||||
fullscreen
|
||||
onTriggerVideoContent={jest.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(queryByLabelText('Leave fullscreen')).toBeNull();
|
||||
expect(queryByLabelText('Fullscreen')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not render in fullscreen', () => {
|
||||
const { queryByLabelText } = render(
|
||||
<VideoContent
|
||||
videoPath="/some-video-path"
|
||||
fullscreen={false}
|
||||
onTriggerVideoContent={jest.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(queryByLabelText('Fullscreen')).toBeNull();
|
||||
expect(queryByLabelText('Leave fullscreen')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should trigger video content when clicked', () => {
|
||||
const onTriggerVideoContent = jest.fn();
|
||||
|
||||
const { getByTestId } = render(
|
||||
<VideoContent
|
||||
videoPath="/some-video-path"
|
||||
fullscreen
|
||||
onTriggerVideoContent={onTriggerVideoContent}
|
||||
/>,
|
||||
);
|
||||
|
||||
getByTestId('connect-video').click();
|
||||
|
||||
expect(onTriggerVideoContent).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should load the given video', () => {
|
||||
const onTriggerVideoContent = jest.fn();
|
||||
|
||||
const { getByTitle } = render(
|
||||
<VideoContent
|
||||
videoPath="/some-video-path"
|
||||
fullscreen
|
||||
onTriggerVideoContent={onTriggerVideoContent}
|
||||
/>,
|
||||
);
|
||||
|
||||
const videoFrame = getByTitle('Video display');
|
||||
|
||||
expect(videoFrame.getAttribute('src')).toEqual('/some-video-path');
|
||||
});
|
||||
});
|
||||
|
|
@ -36,7 +36,7 @@ import Compose from './compose';
|
|||
import Message from './message';
|
||||
import ActionMessage from './actionMessage';
|
||||
import Content from './content';
|
||||
import VideoContent from './videoContent';
|
||||
import { VideoContent } from './videoContent';
|
||||
|
||||
export default class Chat extends Component {
|
||||
static propTypes = {
|
||||
|
|
|
|||
|
|
@ -1,55 +1,69 @@
|
|||
import { h, Component } from 'preact';
|
||||
import { h } from 'preact';
|
||||
|
||||
export default class VideoContent extends Component {
|
||||
render() {
|
||||
if (!this.props.videoPath) {
|
||||
return '';
|
||||
}
|
||||
const smartSvgIcon = (content, d) => (
|
||||
<svg
|
||||
data-content={content}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path data-content={content} fill="none" d="M0 0h24v24H0z" />
|
||||
<path data-content={content} d={d} />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const smartSvgIcon = (content, d) => (
|
||||
<svg
|
||||
data-content={content}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path data-content={content} fill="none" d="M0 0h24v24H0z" />
|
||||
<path data-content={content} d={d} />
|
||||
</svg>
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className="activechatchannel__activecontent activechatchannel__activecontent--video"
|
||||
id="chat_activecontent_video"
|
||||
onClick={this.props.onTriggerVideoContent}
|
||||
>
|
||||
<button
|
||||
className="activechatchannel__activecontentexitbutton crayons-btn crayons-btn--secondary"
|
||||
data-content="exit"
|
||||
>
|
||||
{smartSvgIcon(
|
||||
'exit',
|
||||
'M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z',
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
className="activechatchannel__activecontentexitbutton activechatchannel__activecontentexitbutton--fullscreen crayons-btn crayons-btn--secondary"
|
||||
data-content="fullscreen"
|
||||
style={{ left: '39px' }}
|
||||
>
|
||||
{fullscreen
|
||||
? smartSvgIcon(
|
||||
'fullscreen',
|
||||
'M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z',
|
||||
)
|
||||
: smartSvgIcon(
|
||||
'fullscreen',
|
||||
'M20 3h2v6h-2V5h-4V3h4zM4 3h4v2H4v4H2V3h2zm16 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z',
|
||||
)}
|
||||
</button>
|
||||
<iframe src={this.props.videoPath} />
|
||||
</div>
|
||||
);
|
||||
/**
|
||||
* Displays video in Connect.
|
||||
*
|
||||
* @param {string} props.videoPath The URL of a video
|
||||
* @param {function} props.onTriggerVideoContent Fires when a video is clicked on
|
||||
* @param {boolean} props.fullscreen Whether or not to show the video in fullscreen
|
||||
*
|
||||
* @returns A video component
|
||||
*/
|
||||
export function VideoContent(props) {
|
||||
const { videoPath, onTriggerVideoContent, fullscreen } = props;
|
||||
|
||||
if (!videoPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
data-testid="connect-video"
|
||||
role="presentation"
|
||||
className="activechatchannel__activecontent activechatchannel__activecontent--video"
|
||||
id="chat_activecontent_video"
|
||||
onClick={onTriggerVideoContent}
|
||||
>
|
||||
<button
|
||||
aria-label="Exit"
|
||||
className="activechatchannel__activecontentexitbutton crayons-btn crayons-btn--secondary"
|
||||
data-content="exit"
|
||||
>
|
||||
{smartSvgIcon(
|
||||
'exit',
|
||||
'M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z',
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
aria-label={fullscreen ? 'Fullscreen' : 'Leave fullscreen'}
|
||||
className="activechatchannel__activecontentexitbutton activechatchannel__activecontentexitbutton--fullscreen crayons-btn crayons-btn--secondary"
|
||||
data-content="fullscreen"
|
||||
style={{ left: '39px' }}
|
||||
>
|
||||
{fullscreen
|
||||
? smartSvgIcon(
|
||||
'fullscreen',
|
||||
'M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z',
|
||||
)
|
||||
: smartSvgIcon(
|
||||
'fullscreen',
|
||||
'M20 3h2v6h-2V5h-4V3h4zM4 3h4v2H4v4H2V3h2zm16 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z',
|
||||
)}
|
||||
</button>
|
||||
<iframe title="Video display" src={videoPath} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue