Add ability to toggle object-fit: cover on videos by long-pressing
This commit is contained in:
parent
4a53a2fb55
commit
a025fcad43
@ -16,6 +16,7 @@ export interface VideoProps {
|
||||
|
||||
export default class Video extends React.PureComponent<VideoProps> {
|
||||
videoRef = React.createRef<HTMLVideoElement>()
|
||||
timeout?: number
|
||||
|
||||
static defaultProps = {
|
||||
muted: false,
|
||||
@ -23,8 +24,25 @@ export default class Video extends React.PureComponent<VideoProps> {
|
||||
}
|
||||
handleClick: ReactEventHandler<HTMLVideoElement> = e => {
|
||||
const { onClick, userId } = this.props
|
||||
this.props.play()
|
||||
onClick(userId)
|
||||
if (this.timeout) {
|
||||
// if the timeout was cancelled, execute click
|
||||
this.props.play()
|
||||
onClick(userId)
|
||||
}
|
||||
this.timeout = undefined
|
||||
}
|
||||
handleMouseDown: ReactEventHandler<HTMLVideoElement> = e => {
|
||||
this.timeout = window.setTimeout(this.toggleCover, 300)
|
||||
}
|
||||
handleMouseUp: ReactEventHandler<HTMLVideoElement> = e => {
|
||||
clearTimeout(this.timeout)
|
||||
}
|
||||
toggleCover = () => {
|
||||
this.timeout = undefined
|
||||
const v = this.videoRef.current
|
||||
if (v) {
|
||||
v.style.objectFit = v.style.objectFit ? '' : 'cover'
|
||||
}
|
||||
}
|
||||
componentDidMount () {
|
||||
this.componentDidUpdate()
|
||||
@ -52,6 +70,8 @@ export default class Video extends React.PureComponent<VideoProps> {
|
||||
id={`video-${socket.id}`}
|
||||
autoPlay
|
||||
onClick={this.handleClick}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onMouseUp={this.handleMouseUp}
|
||||
onLoadedMetadata={() => this.props.play()}
|
||||
playsInline
|
||||
ref={this.videoRef}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
jest.mock('../actions/CallActions')
|
||||
jest.mock('../socket')
|
||||
jest.mock('../window')
|
||||
jest.useFakeTimers()
|
||||
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
@ -108,9 +109,14 @@ describe('App', () => {
|
||||
})
|
||||
|
||||
describe('video', () => {
|
||||
it('can be activated', () => {
|
||||
beforeEach(() => {
|
||||
dispatchSpy.mockReset()
|
||||
})
|
||||
|
||||
it('can be activated', () => {
|
||||
const video = node.querySelector('video')!
|
||||
TestUtils.Simulate.mouseDown(video)
|
||||
TestUtils.Simulate.mouseUp(video)
|
||||
TestUtils.Simulate.click(video)
|
||||
expect(dispatchSpy.mock.calls[0][0].type).toBe(constants.MEDIA_PLAY)
|
||||
expect(dispatchSpy.mock.calls.slice(1)).toEqual([[{
|
||||
@ -118,6 +124,18 @@ describe('App', () => {
|
||||
payload: { userId: constants.ME + '_0' },
|
||||
}]])
|
||||
})
|
||||
|
||||
it('can toggle object-fit to/from cover by long-pressing', () => {
|
||||
['cover', ''].forEach(objectFit => {
|
||||
const video = node.querySelector('video')!
|
||||
TestUtils.Simulate.mouseDown(video)
|
||||
jest.runAllTimers()
|
||||
TestUtils.Simulate.mouseUp(video)
|
||||
TestUtils.Simulate.click(video)
|
||||
expect(video.style.objectFit).toBe(objectFit)
|
||||
expect(dispatchSpy.mock.calls.slice(1)).toEqual([])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@ -25,6 +25,10 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.video-actions {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.video-container.active {
|
||||
@ -43,6 +47,22 @@
|
||||
video {
|
||||
border-radius: 0;
|
||||
cursor: inherit;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.video-actions {
|
||||
display: inherit;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 1rem;
|
||||
font-family: monospace;
|
||||
user-select: none;
|
||||
|
||||
.action:hover {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -101,8 +101,8 @@ body.call {
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
font-size: 1rem;
|
||||
padding: 1rem 1rem 0.75rem;
|
||||
font-size: 1.2rem;
|
||||
padding: 1rem 0rem 0.75rem;
|
||||
width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
background: none;
|
||||
@ -120,9 +120,9 @@ body.call {
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
// font-family: $font-monospace;
|
||||
font-family: $font-monospace;
|
||||
@include button($color-primary, $color-warning);
|
||||
font-size: 1rem;
|
||||
font-size: 1.2rem;
|
||||
padding: 1rem 1rem;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user