Skip to content

[TASK] useTimer 훅 분리 및 시간 동기화 로직 구현 #175

Description

@DDINGJOO

Parent Story

Task 개요

타이머 로직을 독립적인 훅으로 분리하여 재사용성을 높이고,
서버-클라이언트 시간 동기화 로직을 구현합니다.

생성 파일

  • src/domains/catchmind/hooks/useTimer.js (신규)

구현 내용

```javascript
import { useState, useEffect } from 'react';

/**

  • 서버 시간 동기화 기반 타이머 훅

  • @param {number} roundStartTime - 라운드 시작 시간 (ms)

  • @param {number} roundDuration - 라운드 시간 (초)

  • @param {number} serverTime - 서버 현재 시간 (ms, 선택)

  • @returns {number} 남은 시간 (초)
    */
    export function useTimer(roundStartTime, roundDuration, serverTime) {
    const [remainingTime, setRemainingTime] = useState(roundDuration);

    useEffect(() => {
    if (!roundStartTime || !roundDuration) {
    setRemainingTime(roundDuration || 0);
    return;
    }

     // 서버-클라이언트 시간 차이 계산
     const timeOffset = serverTime ? (Date.now() - serverTime) : 0;
    
     const updateTimer = () => {
         const adjustedNow = Date.now() - timeOffset;
         const elapsed = Math.floor((adjustedNow - roundStartTime) / 1000);
         const remaining = Math.max(0, roundDuration - elapsed);
         setRemainingTime(remaining);
         return remaining;
     };
    
     // 초기값 설정
     updateTimer();
    
     // 100ms 간격으로 업데이트 (부드러운 UI)
     const interval = setInterval(() => {
         const remaining = updateTimer();
         if (remaining <= 0) {
             clearInterval(interval);
         }
     }, 100);
    
     return () => clearInterval(interval);
    

    }, [roundStartTime, roundDuration, serverTime]);

    return remainingTime;
    }

export default useTimer;
```

사용 예시

```javascript
// GameModePanel.jsx
const remainingTime = useTimer(
gameState?.roundStartTime,
gameState?.roundDuration || 60,
gameState?.serverTime
);

// Timer 표시
{remainingTime}초
```

Acceptance Criteria

  • useTimer 훅 생성 및 export
  • serverTime이 있으면 시간 오프셋 계산
  • 100ms 간격 업데이트
  • 0 이하로 내려가지 않음
  • roundStartTime/roundDuration 변경 시 리셋
  • cleanup 시 interval 정리

테스트 시나리오

  1. roundStartTime + 60초 duration → 60초부터 카운트다운
  2. serverTime 차이 2초 → 보정된 타이머 표시
  3. roundStartTime 변경 → 타이머 리셋
  4. 컴포넌트 언마운트 → interval 정리

예상 작업량

  • 1시간

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions