Skip to content

Commit de83208

Browse files
committed
Add "fullscreen" button
Adds "fullscreen" buttons to the videos in the cutting tab. The goal is to give users a simple way to zoom in on a video in case they need to perceive details, like for example small text on a blackboard. TODO: Fullscreen button positioning
1 parent bd7d4fc commit de83208

File tree

2 files changed

+62
-22
lines changed

2 files changed

+62
-22
lines changed

src/main/SubtitleVideoArea.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ const SubtitleVideoArea: React.FC<{
142142
subtitleUrl={subtitleUrl}
143143
first={true}
144144
last={true}
145+
isFullscreenPossible={false}
146+
fullscreenPlayerIndex={undefined}
147+
setFullscreenPlayerIndex={() => {}}
145148
selectIsPlaying={selectIsPlaying}
146149
selectIsMuted={selectIsMuted}
147150
selectCurrentlyAtInSeconds={selectCurrentlyAtInSeconds}

src/main/VideoPlayers.tsx

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ import { ActionCreatorWithPayload, AsyncThunk } from "@reduxjs/toolkit";
3636

3737
import { useTheme } from "../themes";
3838

39-
import { backgroundBoxStyle } from "../cssStyles";
39+
import { backgroundBoxStyle, basicButtonStyle } from "../cssStyles";
4040
import { BaseReactPlayerProps } from "react-player/base";
4141
import { ErrorBox } from "@opencast/appkit";
42+
import { LuFullscreen } from "react-icons/lu";
4243

4344
const VideoPlayers: React.FC<{
4445
refs?: React.MutableRefObject<(VideoPlayerForwardRef | null)[]>,
@@ -56,6 +57,7 @@ const VideoPlayers: React.FC<{
5657
const videoCount = useAppSelector(selectVideoCount);
5758

5859
const [videoPlayers, setVideoPlayers] = useState<JSX.Element[]>([]);
60+
const [fullscreenPlayerIndex, setFullscreenPlayerIndex] = useState<number | undefined>(undefined);
5961

6062
const videoPlayerAreaStyle = css({
6163
display: "flex",
@@ -65,7 +67,9 @@ const VideoPlayers: React.FC<{
6567
borderRadius: "5px",
6668
gap: "10px",
6769

68-
maxHeight: maxHeightInPixel + "px",
70+
maxHeight: fullscreenPlayerIndex === undefined
71+
? maxHeightInPixel + "px"
72+
: maxHeightInPixel * 2 + "px",
6973
});
7074

7175
// Initialize video players
@@ -81,6 +85,9 @@ const VideoPlayers: React.FC<{
8185
subtitleUrl={""}
8286
first={i === 0}
8387
last={i === videoCount - 1}
88+
isFullscreenPossible={true}
89+
fullscreenPlayerIndex={fullscreenPlayerIndex}
90+
setFullscreenPlayerIndex={setFullscreenPlayerIndex}
8491
selectIsPlaying={selectIsPlaying}
8592
selectIsMuted={selectIsMuted}
8693
selectVolume={selectVolume}
@@ -103,7 +110,7 @@ const VideoPlayers: React.FC<{
103110
);
104111
}
105112
setVideoPlayers(videoPlayers);
106-
}, [primaryIndex, refs, videoCount, videos]);
113+
}, [primaryIndex, refs, videoCount, videos, fullscreenPlayerIndex]);
107114

108115

109116
return (
@@ -125,6 +132,9 @@ interface VideoPlayerProps {
125132
subtitleUrl: string,
126133
first: boolean,
127134
last: boolean,
135+
isFullscreenPossible: boolean,
136+
fullscreenPlayerIndex: number | undefined,
137+
setFullscreenPlayerIndex: (index: number | undefined) => void,
128138
selectIsPlaying: (state: RootState) => boolean,
129139
selectIsMuted: (state: RootState) => boolean,
130140
selectVolume: (state: RootState) => number,
@@ -167,6 +177,9 @@ export const VideoPlayer = React.forwardRef<VideoPlayerForwardRef, VideoPlayerPr
167177
subtitleUrl,
168178
first,
169179
last,
180+
isFullscreenPossible,
181+
fullscreenPlayerIndex,
182+
setFullscreenPlayerIndex,
170183
selectCurrentlyAtInSeconds,
171184
selectPreviewTriggered,
172185
selectClickTriggered,
@@ -391,6 +404,7 @@ export const VideoPlayer = React.forwardRef<VideoPlayerForwardRef, VideoPlayerPr
391404
}));
392405

393406
const reactPlayerStyle = css({
407+
position: "relative", // For fullscreen button
394408
aspectRatio: "16 / 9", // Hard-coded for now because there are problems with updating this value at runtime
395409

396410
overflow: "hidden", // Required for borderRadius to show
@@ -404,10 +418,12 @@ export const VideoPlayer = React.forwardRef<VideoPlayerForwardRef, VideoPlayerPr
404418
},
405419
});
406420

421+
const shouldHide = fullscreenPlayerIndex !== undefined && fullscreenPlayerIndex !== dataKey;
422+
407423
const videoPlayerWrapperStyles = css({
408424
height: "100%",
409425
width: "100%",
410-
display: "flex",
426+
display: shouldHide ? "none" : "flex",
411427

412428
// For single video, center!
413429
...(first && last) && { justifyContent: "center" },
@@ -420,30 +436,51 @@ export const VideoPlayer = React.forwardRef<VideoPlayerForwardRef, VideoPlayerPr
420436

421437
// For multi videos, in between, fit content and center!
422438
...(!first && !last) && { justifyContent: "center", flexBasis: "fit-content" },
439+
440+
// If fullscreen, treat like single video
441+
...fullscreenPlayerIndex !== undefined && { justifyContent: "center" },
423442
});
424443

425444
const render = () => {
426445
if (!errorState) {
427446
return (
428447
<div css={videoPlayerWrapperStyles}>
429-
<ReactPlayer url={url}
430-
css={[backgroundBoxStyle(theme), reactPlayerStyle]}
431-
ref={ref}
432-
width="unset"
433-
height="100%"
434-
playing={isPlaying}
435-
volume={volume}
436-
muted={!isPrimary || isMuted}
437-
onProgress={onProgressCallback}
438-
progressInterval={100}
439-
onReady={onReadyCallback}
440-
onPlay={onPlay}
441-
onEnded={onEndedCallback}
442-
onError={onErrorCallback}
443-
tabIndex={-1}
444-
config={playerConfig}
445-
disablePictureInPicture
446-
/>
448+
{/* wrapper for positioning fullscreen button*/}
449+
<div css={[backgroundBoxStyle(theme), reactPlayerStyle]}>
450+
<ReactPlayer url={url}
451+
// css={[backgroundBoxStyle(theme), reactPlayerStyle]} // moved to wrapper
452+
ref={ref}
453+
width="unset"
454+
height="100%"
455+
playing={isPlaying}
456+
volume={volume}
457+
muted={!isPrimary || isMuted}
458+
onProgress={onProgressCallback}
459+
progressInterval={100}
460+
onReady={onReadyCallback}
461+
onPlay={onPlay}
462+
onEnded={onEndedCallback}
463+
onError={onErrorCallback}
464+
tabIndex={-1}
465+
config={playerConfig}
466+
disablePictureInPicture
467+
/>
468+
{isFullscreenPossible &&
469+
<button css={[basicButtonStyle(theme), css({
470+
position: "absolute",
471+
bottom: "10px",
472+
right: "10px",
473+
})]}
474+
onClick={() => {
475+
if (fullscreenPlayerIndex === undefined) {
476+
setFullscreenPlayerIndex(dataKey);
477+
} else {
478+
setFullscreenPlayerIndex(undefined);
479+
}
480+
}}
481+
><LuFullscreen /></button>
482+
}
483+
</div>
447484
</div>
448485
);
449486
} else {

0 commit comments

Comments
 (0)