Skip to content

Commit

Permalink
refactor : 불필요한 currentTime,totalTime 삭제, mouseEvent로 공통부분 통합
Browse files Browse the repository at this point in the history
  • Loading branch information
godhyzzang committed Oct 9, 2024
1 parent 7cf1df1 commit a484381
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 70 deletions.
23 changes: 5 additions & 18 deletions demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ function App() {
}
};

const handleProgress = (state: { playedSeconds: number }) => {
setCurrentTime(state.playedSeconds);
};

// --- todo : ControlBar에서만 쓰이는 속성 ControlBar로 내부로 이동
const [isPlaying, setIsPlaying] = useState(false);
const [volume, setVolume] = useState(0.5);
Expand All @@ -47,19 +43,10 @@ function App() {
};
// todo : 리팩토링 -> handleSeekForward, handleSeekBackward 공통함수로 빼기

const handleSeekForward = () => {
if (playerRef.current) {
playerRef.current.seekTo(
(playerRef.current.getCurrentTime() || 0) + 10,
'seconds',
);
}
};

const handleSeekBackward = () => {
const handleSeek = (seconds: number) => {
if (playerRef.current) {
playerRef.current.seekTo(
(playerRef.current.getCurrentTime() || 0) - 10,
(playerRef.current.getCurrentTime() || 0) + seconds,
'seconds',
);
}
Expand All @@ -68,8 +55,8 @@ function App() {
const BasicControlBarProps = {
handlePlayPause,
handleVolumeChange,
handleSeekBackward,
handleSeekForward,
handleSeekForward: () => handleSeek(10),
handleSeekBackward: () => handleSeek(-10),
isPlaying,
volume,
setPlayBackRate,
Expand All @@ -88,7 +75,7 @@ function App() {
onPlay={() => setIsPlaying(true)}
onStart={() => setIsPlaying(true)}
onPause={() => setIsPlaying(false)}
onProgress={handleProgress}
onProgress={({ playedSeconds }) => setCurrentTime(playedSeconds)}
volume={volume}
controls={false} // 유튜브 자체 컨트롤러 안 뜨게
playbackRate={playbackRate}
Expand Down
85 changes: 33 additions & 52 deletions demo/src/components/ControlBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export default function ControlBar({
playerRef,
BasicControlBarProps,
}: ControlBarProps) {
const [currentTime, setCurrentTime] = useState<number | null>(null);
const [totalTime, setTotalTime] = useState<number | null>(null);
const [isDragging, setIsDragging] = useState(false);

const {
Expand All @@ -40,45 +38,32 @@ export default function ControlBar({
setPlayBackRate,
} = BasicControlBarProps;

useEffect(() => {
// todo : 리팩토링-> getCurrentTime setInterval로 1초마다 업데이트하는 방식 대신 ReactPlayer에서 onProgress 콜백 함수를 사용해서 currentTime을 받아오는 값을 ControlBar에 넘기는 방식 고려해보기
const interval = setInterval(() => {
if (playerRef.current && !isDragging) {
setCurrentTime(playerRef.current.getCurrentTime());
setTotalTime(playerRef.current.getDuration());
}
}, 1000); // 1초마다 업데이트
// useEffect(() => {
// // todo : 리팩토링-> getCurrentTime setInterval로 1초마다 업데이트하는 방식 대신 ReactPlayer에서 onProgress 콜백 함수를 사용해서 currentTime을 받아오는 값을 ControlBar에 넘기는 방식 고려해보기
// const interval = setInterval(() => {
// if ( !isDragging) {
// setCurrentTime(playerRef.current.getCurrentTime());
// }
// }, 1000); // 1초마다 업데이트

return () => clearInterval(interval);
}, [playerRef, isDragging]);
// return () => clearInterval(interval);
// }, [playerRef, isDragging]);

// todo : 마우스 이벤트 핸들러 -> mouseDown, mouseUp, 공통함수로 만들기
const handleMouseDown = () => {
const handleMouseEvent = (
e: React.MouseEvent<HTMLDivElement>,
action: 'down' | 'up' | 'move',
) => {
if (!playerRef.current || action === 'down') {
setIsDragging(true);
};

const handleMouseUp = (e: React.MouseEvent<HTMLDivElement>) => {
if (playerRef.current && totalTime) {
const progressBar = e.currentTarget; // progressBar 자체에서 좌표를 가져옴
} else if (action === 'up') {
setIsDragging(false);
const progressBar = e.currentTarget;
const progressBarRect = progressBar.getBoundingClientRect();
const clickPosition = e.clientX - progressBarRect.left; //전체 브라우저 기준 X좌표-프로그래스바의 X좌표
const newTime = (clickPosition / progressBarRect.width) * totalTime;
const newTime =
((e.clientX - progressBarRect.left) / progressBarRect.width) *
playerRef.current.getDuration();
playerRef.current.seekTo(newTime);
setCurrentTime(newTime);
}
setIsDragging(false);
};
// todo : 이벤트 호출 최적화 필요 -> 디바운싱?
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
if (isDragging && playerRef.current && totalTime) {
const progressBar = e.currentTarget; // progressBar 자체에서 좌표를 가져옴
const progressBarRect = progressBar.getBoundingClientRect();
const dragPosition = e.clientX - progressBarRect.left; //전체 브라우저 기준 X좌표-프로그래스바의 X좌표
const newTime = Math.min(
Math.max((dragPosition / progressBarRect.width) * totalTime, 0),
totalTime,
);
setCurrentTime(newTime);
}
};
const [showPlaybackRate, setShowPlaybackRate] = useState(false);
Expand Down Expand Up @@ -106,25 +91,21 @@ export default function ControlBar({
</div>

<span className={S.timeViewBox}>
{`${formatTime(currentTime)} / ${formatTime(totalTime)}`}
{`${formatTime(playerRef.current?.getCurrentTime() ?? 0)} / ${formatTime(playerRef.current?.getDuration() ?? 0)}`}
</span>
</div>

<div className={S.centerControlBar}>
<button onClick={handleSeekBackward}>
<Rewind fill="white" />
</button>
<button onClick={handlePlayPause}>
{isPlaying ? <Pause fill="white" /> : <Play fill="white" />}
</button>
<button onClick={handleSeekForward}>
<FastForward fill="white" />
</button>
<Rewind fill="white" onClick={handleSeekBackward} />
{isPlaying ? (
<Pause fill="white" onClick={handlePlayPause} />
) : (
<Play fill="white" onClick={handlePlayPause} />
)}
<FastForward fill="white" onClick={handleSeekForward} />
</div>
<div className={S.rightControlBar}>
<button onClick={handleShowPlaybackRate}>
<Gauge />
</button>
<Gauge onClick={handleShowPlaybackRate} />
{showPlaybackRate && (
<div className={S.playbackRateButton}>
<label className={S.playbackRateLabel}>
Expand Down Expand Up @@ -181,17 +162,17 @@ export default function ControlBar({
{/* 드래그 가능한 진행 바 */}
<div
className={S.progressBar}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
onMouseDown={(e) => handleMouseEvent(e, 'down')}
onMouseMove={(e) => isDragging && handleMouseEvent(e, 'move')}
onMouseUp={(e) => handleMouseEvent(e, 'up')}
onMouseLeave={() => setIsDragging(false)} // 드래그 상태 해제
role="progressbar"
aria-label="Progress"
>
<div
className={S.progressFill}
style={{
width: `${currentTime && totalTime ? (currentTime / totalTime) * 100 : 0}%`,
width: `${playerRef.current?.getCurrentTime() && playerRef.current?.getDuration() ? (playerRef.current?.getCurrentTime() / playerRef.current.getDuration()) * 100 : 0}%`,
}}
></div>
</div>
Expand Down

0 comments on commit a484381

Please sign in to comment.