Skip to content

Commit 72afe3c

Browse files
authored
Merge pull request #125 from Team-Senifit/release-1.0.1
배포
2 parents 70df0f9 + 68454d2 commit 72afe3c

3 files changed

Lines changed: 80 additions & 5 deletions

File tree

src/app/(with-container)/(exercise)/exercise/members/panel/MemberInfo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const MemberInfo = ({ name, birthDate, gender, memberRank }: IMember) => {
4040
</Typography>
4141
<Typography
4242
variant={isDesktop ? "Heading1" : "Headline1"}
43-
sx={{ color: "label.neutral", width: "6rem" }}
43+
sx={{ color: "label.neutral", width: "8rem" }}
4444
>
4545
{gradeLabel[memberRank]}
4646
</Typography>

src/components/VideoPlayer.tsx

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface IVideoHandle {
1919
toggle: () => void;
2020
mute: (m?: boolean) => void;
2121
seek: (timeSec: number) => void;
22+
toggleFullscreen: () => void;
2223
getEl: () => HTMLVideoElement | null;
2324
}
2425

@@ -78,6 +79,8 @@ const VideoPlayer = forwardRef<IVideoHandle, IVideoPlayerProps>(
7879
ref,
7980
) {
8081
const videoRef = useRef<HTMLVideoElement>(null);
82+
const wrapperRef = useRef<HTMLDivElement>(null);
83+
const [isFullscreen, setIsFullscreen] = useState(false);
8184
// controlsRef removed; controls are separate component
8285

8386
// 재생/일시정지 플래시 아이콘
@@ -100,6 +103,43 @@ const VideoPlayer = forwardRef<IVideoHandle, IVideoPlayerProps>(
100103
}, 650);
101104
};
102105

106+
const handleToggleFullscreen = useCallback(() => {
107+
if (!wrapperRef.current) return;
108+
109+
if (!document.fullscreenElement) {
110+
wrapperRef.current.requestFullscreen().catch((err) => {
111+
console.error(
112+
`Error attempting to enable full-screen mode: ${err.message}`,
113+
);
114+
});
115+
} else {
116+
document.exitFullscreen();
117+
}
118+
}, []);
119+
120+
useEffect(() => {
121+
const handleFullscreenChange = () => {
122+
setIsFullscreen(!!document.fullscreenElement);
123+
};
124+
125+
document.addEventListener("fullscreenchange", handleFullscreenChange);
126+
document.addEventListener(
127+
"webkitfullscreenchange",
128+
handleFullscreenChange,
129+
);
130+
131+
return () => {
132+
document.removeEventListener(
133+
"fullscreenchange",
134+
handleFullscreenChange,
135+
);
136+
document.removeEventListener(
137+
"webkitfullscreenchange",
138+
handleFullscreenChange,
139+
);
140+
};
141+
}, []);
142+
103143
const {
104144
playing,
105145
muted,
@@ -127,6 +167,7 @@ const VideoPlayer = forwardRef<IVideoHandle, IVideoPlayerProps>(
127167
toggle: () => toggle?.(),
128168
mute: (m?: boolean) => mute?.(m),
129169
seek: (t: number) => seek?.(t),
170+
toggleFullscreen: handleToggleFullscreen,
130171
getEl: () => videoRef.current,
131172
}));
132173

@@ -193,24 +234,42 @@ const VideoPlayer = forwardRef<IVideoHandle, IVideoPlayerProps>(
193234
const ratioNum = parseAspectRatioToNumber(aspectRatio);
194235
const aspectCss =
195236
typeof aspectRatio === "number" ? aspectRatio : (aspectRatio ?? "16 / 9");
196-
const maxWFromHeightExpr = `calc((100dvh - ${viewportOffsetPx}px) * ${ratioNum})`;
237+
const maxWFromHeightExpr = `calc((100dvh - ${isFullscreen ? 0 : viewportOffsetPx}px) * ${ratioNum})`;
197238
return (
198-
<Stack spacing={1} sx={{ width: "100%", color: "common.white" }}>
239+
<Stack
240+
spacing={isFullscreen ? 0 : 1}
241+
sx={{
242+
width: "100%",
243+
height: isFullscreen ? "100%" : "auto",
244+
color: "common.white",
245+
}}
246+
>
199247
{/* 비디오 영역: 남은 높이를 꽉 채우되 16:9 유지 */}
200248
<Box
249+
ref={wrapperRef}
201250
sx={{
202-
width: fitViewport ? `min(100%, ${maxWFromHeightExpr})` : "100%",
251+
width:
252+
fitViewport && !isFullscreen
253+
? `min(100%, ${maxWFromHeightExpr})`
254+
: "100%",
255+
height: isFullscreen ? "100dvh" : "auto",
203256
mx: "auto",
204257
alignSelf: "center",
258+
display: "flex",
259+
flexDirection: "column",
260+
justifyContent: "center",
261+
bgcolor: "black",
205262
}}
206263
>
207264
<Box
208265
sx={{
209266
position: "relative",
210267
width: "100%",
268+
height: isFullscreen ? "auto" : "100%",
269+
maxHeight: isFullscreen ? "100dvh" : "unset",
211270
overflow: "hidden",
212271
bgcolor: "black",
213-
aspectRatio: aspectCss,
272+
aspectRatio: isFullscreen ? "unset" : aspectCss,
214273
}}
215274
onPointerEnter={() => showControls()}
216275
onPointerMove={() => showControls()}
@@ -316,6 +375,8 @@ const VideoPlayer = forwardRef<IVideoHandle, IVideoPlayerProps>(
316375
v.currentTime = next;
317376
setScrub(null);
318377
}}
378+
isFullscreen={isFullscreen}
379+
onToggleFullscreen={handleToggleFullscreen}
319380
visible={controlsVisible}
320381
/>
321382

src/components/video-player/VideoControls.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import PlayArrowRounded from "@mui/icons-material/PlayArrowRounded";
44
import PauseRounded from "@mui/icons-material/PauseRounded";
55
import VolumeUpRounded from "@mui/icons-material/VolumeUpRounded";
66
import VolumeOffRounded from "@mui/icons-material/VolumeOffRounded";
7+
import FullscreenRounded from "@mui/icons-material/FullscreenRounded";
8+
import FullscreenExitRounded from "@mui/icons-material/FullscreenExitRounded";
79

810
const formatTime = (sec: number) =>
911
Number.isFinite(sec)
@@ -25,6 +27,8 @@ interface Props {
2527
onToggleMute: () => void;
2628
setScrub: (v: number | null) => void;
2729
onSeek: (sec: number) => void;
30+
isFullscreen: boolean;
31+
onToggleFullscreen: () => void;
2832
visible?: boolean;
2933
}
3034

@@ -43,6 +47,8 @@ export default function VideoControls({
4347
onToggleMute,
4448
setScrub,
4549
onSeek,
50+
isFullscreen,
51+
onToggleFullscreen,
4652
visible = true,
4753
}: Props) {
4854
return (
@@ -110,6 +116,14 @@ export default function VideoControls({
110116
},
111117
}}
112118
/>
119+
120+
<IconButton
121+
onClick={onToggleFullscreen}
122+
aria-label={isFullscreen ? "전체화면 종료" : "전체화면"}
123+
sx={{ color: "common.white" }}
124+
>
125+
{isFullscreen ? <FullscreenExitRounded /> : <FullscreenRounded />}
126+
</IconButton>
113127
</Box>
114128
);
115129
}

0 commit comments

Comments
 (0)