Skip to content

Commit e35780b

Browse files
Merge pull request #244 from ateendra24/fix-issue-226
feat: add fullscreen video player
2 parents a8bb0e8 + eae3f11 commit e35780b

File tree

5 files changed

+57
-5
lines changed

5 files changed

+57
-5
lines changed

src/components/video-editor/PlaybackControls.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Pause, Play } from "lucide-react";
1+
import { Maximize, Minimize, Pause, Play } from "lucide-react";
22
import { useScopedT } from "@/contexts/I18nContext";
33
import { cn } from "@/lib/utils";
44
import { Button } from "../ui/button";
@@ -7,6 +7,8 @@ interface PlaybackControlsProps {
77
isPlaying: boolean;
88
currentTime: number;
99
duration: number;
10+
isFullscreen?: boolean;
11+
onToggleFullscreen?: () => void;
1012
onTogglePlayPause: () => void;
1113
onSeek: (time: number) => void;
1214
}
@@ -15,6 +17,8 @@ export default function PlaybackControls({
1517
isPlaying,
1618
currentTime,
1719
duration,
20+
isFullscreen = false,
21+
onToggleFullscreen,
1822
onTogglePlayPause,
1923
onSeek,
2024
}: PlaybackControlsProps) {
@@ -87,6 +91,21 @@ export default function PlaybackControls({
8791
<span className="text-[9px] font-medium text-slate-500 tabular-nums w-[30px]">
8892
{formatTime(duration)}
8993
</span>
94+
95+
{onToggleFullscreen && (
96+
<Button
97+
onClick={onToggleFullscreen}
98+
size="icon"
99+
className="w-7 h-7 rounded-full transition-all duration-200 border border-transparent hover:bg-white/10 text-white hover:border-white/10 shrink-0 shadow-none ml-0.5"
100+
aria-label={isFullscreen ? t("playback.exitFullscreen") : t("playback.fullscreen")}
101+
>
102+
{isFullscreen ? (
103+
<Minimize className="w-3.5 h-3.5" />
104+
) : (
105+
<Maximize className="w-3.5 h-3.5" />
106+
)}
107+
</Button>
108+
)}
90109
</div>
91110
);
92111
}

src/components/video-editor/VideoEditor.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,11 @@ export default function VideoEditor() {
119119
fileName: string;
120120
format: string;
121121
} | null>(null);
122+
const [isFullscreen, setIsFullscreen] = useState(false);
122123

124+
const playerContainerRef = useRef<HTMLDivElement>(null);
123125
const videoPlaybackRef = useRef<VideoPlaybackRef>(null);
126+
124127
const nextZoomIdRef = useRef(1);
125128
const nextTrimIdRef = useRef(1);
126129
const nextSpeedIdRef = useRef(1);
@@ -539,6 +542,21 @@ export default function VideoEditor() {
539542
}
540543
}
541544

545+
const toggleFullscreen = useCallback(() => {
546+
setIsFullscreen((prev) => !prev);
547+
}, []);
548+
549+
useEffect(() => {
550+
if (!isFullscreen) return;
551+
const handleKeyDown = (e: KeyboardEvent) => {
552+
if (e.key === "Escape") {
553+
setIsFullscreen(false);
554+
}
555+
};
556+
window.addEventListener("keydown", handleKeyDown);
557+
return () => window.removeEventListener("keydown", handleKeyDown);
558+
}, [isFullscreen]);
559+
542560
function handleSeek(time: number) {
543561
const video = videoPlaybackRef.current?.video;
544562
if (!video) return;
@@ -1425,7 +1443,14 @@ export default function VideoEditor() {
14251443
<PanelGroup direction="vertical" className="gap-3">
14261444
{/* Top section: video preview and controls */}
14271445
<Panel defaultSize={70} maxSize={70} minSize={40}>
1428-
<div className="w-full h-full flex flex-col items-center justify-center bg-black/40 rounded-2xl border border-white/5 shadow-2xl overflow-hidden">
1446+
<div
1447+
ref={playerContainerRef}
1448+
className={
1449+
isFullscreen
1450+
? "fixed inset-0 z-[99999] w-full h-full flex flex-col items-center justify-center bg-[#09090b]"
1451+
: "w-full h-full flex flex-col items-center justify-center bg-black/40 rounded-2xl border border-white/5 shadow-2xl overflow-hidden relative"
1452+
}
1453+
>
14291454
{/* Video preview */}
14301455
<div className="w-full flex justify-center items-center flex-auto mt-1.5">
14311456
<div
@@ -1487,6 +1512,8 @@ export default function VideoEditor() {
14871512
isPlaying={isPlaying}
14881513
currentTime={currentTime}
14891514
duration={duration}
1515+
isFullscreen={isFullscreen}
1516+
onToggleFullscreen={toggleFullscreen}
14901517
onTogglePlayPause={togglePlayPause}
14911518
onSeek={handleSeek}
14921519
/>

src/i18n/locales/en/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
},
1919
"playback": {
2020
"play": "Play",
21-
"pause": "Pause"
21+
"pause": "Pause",
22+
"fullscreen": "Fullscreen",
23+
"exitFullscreen": "Exit Fullscreen"
2224
},
2325
"locale": {
2426
"name": "English",

src/i18n/locales/es/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
},
1919
"playback": {
2020
"play": "Reproducir",
21-
"pause": "Pausar"
21+
"pause": "Pausar",
22+
"fullscreen": "Pantalla completa",
23+
"exitFullscreen": "Salir de pantalla completa"
2224
},
2325
"locale": {
2426
"name": "Español",

src/i18n/locales/zh-CN/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
},
1919
"playback": {
2020
"play": "播放",
21-
"pause": "暂停"
21+
"pause": "暂停",
22+
"fullscreen": "全屏",
23+
"exitFullscreen": "退出全屏"
2224
},
2325
"locale": {
2426
"name": "中文",

0 commit comments

Comments
 (0)