Skip to content

Commit

Permalink
Merge pull request #733 from Vayras/FullScreen
Browse files Browse the repository at this point in the history
fix(#726): enable fullscreen for videos
  • Loading branch information
Rassl authored Jan 5, 2024
2 parents d58213b + 199299a commit 0da672a
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 10 deletions.
11 changes: 11 additions & 0 deletions public/svg-icons/ExitFullScreen.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions public/svg-icons/FullScreenIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { IconButton, Slider } from '@mui/material'
import { FC } from 'react'
import styled from 'styled-components'
import FullScreenIcon from '~/components/Icons/FullScreenIcon'
import ExitFullScreen from '~/components/Icons/ExitFullScreen'
import PauseIcon from '~/components/Icons/PauseIcon'
import PlayIcon from '~/components/Icons/PlayIcon'
import VolumeIcon from '~/components/Icons/VolumeIcon'
Expand All @@ -16,6 +18,8 @@ type Props = {
playingTime: number
duration: number
hasError: boolean
onFullScreenClick: () => void
showToolbar: boolean
}

export const Toolbar: FC<Props> = ({
Expand All @@ -26,6 +30,8 @@ export const Toolbar: FC<Props> = ({
handleProgressChange,
handleVolumeChange,
hasError,
onFullScreenClick,
showToolbar,
}) => (
<Flex>
<ProgressSlider
Expand All @@ -36,9 +42,11 @@ export const Toolbar: FC<Props> = ({
value={playingTime}
/>
{hasError ? (
<Wrapper className="error-wrapper">Error happened, please try later</Wrapper>
<Wrapper className="error-wrapper" showToolbar={showToolbar}>
Error happened, please try later
</Wrapper>
) : (
<Wrapper align="center" direction="row">
<Wrapper align="center" direction="row" showToolbar={showToolbar}>
<Action onClick={setIsPlaying} size="small">
{!isPlaying ? <PlayIcon /> : <PauseIcon />}
</Action>
Expand All @@ -59,14 +67,26 @@ export const Toolbar: FC<Props> = ({
/>
<VolumeIcon />
</VolumeControl>
<Fullscreen onClick={() => onFullScreenClick()}>
{!showToolbar ? <FullScreenIcon /> : <ExitFullScreen />}
</Fullscreen>
</Wrapper>
)}
</Flex>
)

const Wrapper = styled(Flex)`
const Wrapper = styled(Flex)<{ showToolbar: boolean }>`
height: 60px;
padding: 12px 16px;
${(props) =>
props.showToolbar &&
`
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 9999;
`}
&.error-wrapper {
color: ${colors.primaryRed};
Expand Down Expand Up @@ -120,6 +140,10 @@ const VolumeControl = styled(Flex)`
}
`

const Fullscreen = styled(Flex)`
cursor: pointer;
`

const ProgressSlider = styled(Slider)`
&& {
color: ${colors.white};
Expand Down
69 changes: 62 additions & 7 deletions src/components/App/SideBar/SidebarSubView/MediaPlayer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ type Props = {

const MediaPlayerComponent: FC<Props> = ({ hidden }) => {
const playerRef = useRef<ReactPlayer | null>(null)

const wrapperRef = useRef<HTMLDivElement | null>(null)
const [isFullScreen, setIsFullScreen] = useState(false)
const [isBuffering, setIsBuffering] = useState(false)
const [isReady, setIsReady] = useState(false)
const [isMouseNearBottom, setIsMouseNearBottom] = useState(false)

const [
isPlaying,
Expand Down Expand Up @@ -95,24 +97,75 @@ const MediaPlayerComponent: FC<Props> = ({ hidden }) => {
}
}

const handleVideoClick = () => {
if (isReady) {
togglePlay()
const toggleFullScreen = () => {
if (wrapperRef.current) {
if (!document.fullscreenElement) {
wrapperRef.current.requestFullscreen().then(() => {
document.addEventListener('fullscreenchange', handleFullScreenChange)
})
} else {
document.exitFullscreen()
setIsFullScreen(false)
}
}
}

const handleFullScreenChange = () => {
setIsFullScreen(!!document.fullscreenElement)
document.removeEventListener('fullscreenchange', handleFullScreenChange)
}

useEffect(() => () => {
document.removeEventListener('fullscreenchange', handleFullScreenChange)
})

useEffect(() => {
const handleMouseMove = (event: MouseEvent) => {
if (isFullScreen) {
const windowHeight = window.innerHeight
const mousePositionY = event.clientY
const distanceFromBottom = windowHeight - mousePositionY
const threshold = 100 // Adjust this value as needed

setIsMouseNearBottom(distanceFromBottom <= threshold)
}
}

document.addEventListener('mousemove', handleMouseMove)

return () => {
document.removeEventListener('mousemove', handleMouseMove)
}
}, [isFullScreen])

useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (isFullScreen && event.key === 'Escape') {
event.preventDefault()
event.stopPropagation()
}
}

document.addEventListener('fullscreenchange', handleFullScreenChange)
document.addEventListener('keydown', handleKeyDown)

return () => {
document.removeEventListener('fullscreenchange', handleFullScreenChange)
document.removeEventListener('keydown', handleKeyDown)
}
})

return playingNode ? (
<Wrapper hidden={hidden} onClick={handleVideoClick}>
<Wrapper ref={wrapperRef} hidden={hidden}>
<Cover>
<Avatar size={120} src={playingNode?.image_url || ''} type="clip" />
</Cover>
<ReactPlayer
ref={playerRef}
controls={false}
height="200px"
height={!isFullScreen ? '200px' : 'auto'}
onBuffer={() => setIsBuffering(true)}
onBufferEnd={() => setIsBuffering(false)}
onClick={() => handleVideoClick()}
onError={handleError}
onPause={handlePause}
onPlay={handlePlay}
Expand All @@ -130,8 +183,10 @@ const MediaPlayerComponent: FC<Props> = ({ hidden }) => {
handleVolumeChange={handleVolumeChange}
hasError={hasError}
isPlaying={isPlaying}
onFullScreenClick={toggleFullScreen}
playingTime={playingTime}
setIsPlaying={togglePlay}
showToolbar={isMouseNearBottom && isFullScreen} // New prop to conditionally show toolbar
/>
) : null}
{isBuffering || !isReady ? (
Expand Down
31 changes: 31 additions & 0 deletions src/components/Icons/ExitFullScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable */
import React from 'react';

const ExitFullScreen: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 32 32"
fill="currentColor"
>
<mask
id="mask0_4160_9271"
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="32"
height="32"
>
<rect width="1em" height="1em" fill="currentColor" />
</mask>
<g mask="url(#mask0_4160_9271)">
<path
d="M11 25V21H7V19H13V25H11ZM19 25V19H25V21H21V25H19ZM7 13V11H11V7H13V13H7ZM19 13V7H21V11H25V13H19Z"
fill="currentColor"
/>
</g>
</svg>
);

export default ExitFullScreen;
31 changes: 31 additions & 0 deletions src/components/Icons/FullScreenIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable */
import React from 'react';

const FullScreenIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 22 22"
fill="currentColor"
>
<mask
id="mask0_3130_18463"
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="22"
height="22"
>
<rect width="1em" height="1em" fill="currentColor" />
</mask>
<g mask="url(#mask0_3130_18463)">
<path
d="M4.58301 17.4166V12.8333H5.95798V16.0416H9.16634V17.4166H4.58301ZM4.58301 9.16658V4.58325H9.16634V5.95823H5.95798V9.16658H4.58301ZM12.833 17.4166V16.0416H16.0414V12.8333H17.4163V17.4166H12.833ZM16.0414 9.16658V5.95823H12.833V4.58325H17.4163V9.16658H16.0414Z"
fill="currentColor"
/>
</g>
</svg>
);

export default FullScreenIcon;

0 comments on commit 0da672a

Please sign in to comment.