-
Notifications
You must be signed in to change notification settings - Fork 1
[FIX] 타이머 오류 해결 #350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIX] 타이머 오류 해결 #350
Conversation
Walkthrough타이머 진행률 계산(initRawProgress)을 speakingTimer 존재 여부 기준으로 재구성하고, 숫자 폰트(tabular-nums)·크기·패딩 등 타이포그래피를 조정하며 일부 포매팅(useMemo 도입, 공백 라인 추가)을 적용했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as TimerPage UI
participant T as TimeBasedTimer
participant S as Timers (speakingTimer, totalTimer)
UI->>T: 렌더링 요청
T->>S: speakingTimer, totalTimer 조회
alt speakingTimer == null
alt item.timePerTeam && totalTimer 존재 및 >0
T->>T: progress = (item.timePerTeam - totalTimer) / item.timePerTeam * 100
else
T->>T: progress = 100
end
else speakingTimer != null
alt item.timePerSpeaking && speakingTimer 존재 및 >0
T->>T: progress = (item.timePerSpeaking - speakingTimer) / item.timePerSpeaking * 100
else
T->>T: progress = 100
end
end
T-->>UI: 렌더링 데이터 (progress, 숫자 스타일 변경)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Assessment against linked issues
Possibly related PRs
Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/page/TimerPage/components/TimeBasedTimer.tsx (3)
58-69: 완료/오버타임 경계 처리 보강 제안(음수 잔여 시간 포함)현재 조건이
totalTimer의 truthy 여부에 의존해 0일 때만 100%로 전환합니다. 타이머가 0 아래로 내려가는(오버타임) 순간에는 100%를 넘는 값이 계산될 수 있습니다. 훅(useCircularTimerAnimation)에서 0–100으로 clamp된다는 러닝 메모는 알고 있으나, 원값을 100으로 고정하면 불필요한 점프/보간을 줄일 수 있습니다.제안 diff:
- if (item.timePerTeam && totalTimer && item.timePerTeam > 0) { - // 팀당 발언 시간 타이머가 정상 동작 중이고 남은 시간이 있을 경우, 진행도를 계산 - return ((item.timePerTeam - totalTimer) / item.timePerTeam) * 100; + if (item.timePerTeam && item.timePerTeam > 0 && totalTimer !== null && totalTimer !== undefined) { + if (totalTimer <= 0) { + // 완료 또는 오버타임 시 100% 고정 + return 100; + } + return ((item.timePerTeam - totalTimer) / item.timePerTeam) * 100; } else { // 팀당 발언 시간 타이머가 멈추거나 완료된 경우, // 완료(100%)에 해당하는 진행도를 반환 return 100; }
71-85: 말풍선(1회당) 진행도 계산에서 totalTimer 의존 제거 검토1회당 발언 시간의 진행도는
speakingTimer와item.timePerSpeaking만으로 결정 가능합니다. 현재는totalTimer까지 truthy 여야 계산하도록 되어 있어, 드물게 전체 타이머가 0이 된 프레임에서speakingTimer가 아직 0이 아니라도 100%로 튀는 상황이 생길 여지가 있습니다. 안정성을 위해 의존 제거를 권합니다.제안 diff:
- if ( - item.timePerSpeaking && - speakingTimer && - totalTimer && - item.timePerSpeaking > 0 - ) { - // 1회당 발언 시간 타이머가 정상 동작 중이고 남은 시간이 있을 경우, 진행도를 계산 - return ( - ((item.timePerSpeaking - speakingTimer) / item.timePerSpeaking) * 100 - ); + if ( + item.timePerSpeaking && + item.timePerSpeaking > 0 && + speakingTimer !== null && + speakingTimer !== undefined + ) { + if (speakingTimer <= 0) { + return 100; + } + return ((item.timePerSpeaking - speakingTimer) / item.timePerSpeaking) * 100; } else { // 1회당 발언 시간 타이머가 멈추거나 완료된 경우, // 완료(100%)에 해당하는 진행도를 반환 return 100; }검증 포인트:
- 전체 타이머가 0에 도달하는 프레임과 1회당 타이머가 0이 되는 프레임이 엇갈릴 수 있는지.
- 만약 항상 동시에 0이 된다면(동기화 보장), 위 변경은 체감 영향이 없고 방어적 개선입니다.
133-137: 작은 화면에서 타이포그래피 축소 적용 LGTM + 숫자 정렬 가독성 향상 제안
text-[90px] (xl:110px)로의 조정은 요구사항에 부합합니다. 추가로 숫자 폭을 고정하면 점프/깜빡임이 줄어듭니다.미세 개선 diff(선택):
- <span className="flex w-full flex-row items-center justify-center p-[16px] text-[90px] font-bold text-default-black xl:text-[110px]"> + <span className="flex w-full flex-row items-center justify-center p-[16px] text-[90px] font-bold text-default-black tabular-nums xl:text-[110px]">Tailwind 기본
tabular-nums유틸이 활성화되어 있다면 적용 가능하며, 없으면 무시하셔도 됩니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/page/TimerPage/components/TimeBasedTimer.tsx(4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-08T14:21:17.745Z
Learnt from: i-meant-to-be
PR: debate-timer/debate-timer-fe#335
File: src/page/TimerPage/components/NormalTimer.tsx:50-54
Timestamp: 2025-08-08T14:21:17.745Z
Learning: Progress 퍼센트(원형 게이지)는 컴포넌트가 아닌 훅(src/page/TimerPage/hooks/useCircularTimerAnimation.ts)에서 0–100으로 clamp한다. 향후 리뷰에서는 컴포넌트 레벨에서의 중복 clamp 제안 대신 훅 사용을 권장한다.
Applied to files:
src/page/TimerPage/components/TimeBasedTimer.tsx
🪛 GitHub Check: test
src/page/TimerPage/components/TimeBasedTimer.tsx
[failure] 10-10:
'useMemo' is defined but never used
🪛 GitHub Actions: frontend-CI
src/page/TimerPage/components/TimeBasedTimer.tsx
[error] 10-10: ESLint: 'useMemo' is defined but never used. (no-unused-vars). Step: eslint .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/page/TimerPage/components/NormalTimer.tsx (1)
151-157: 불필요한 래핑 화살표 함수 제거로 미세 최적화
onReset={() => resetTimer()}대신 핸들러를 그대로 넘겨도 됩니다. 불필요한 클로저 생성을 줄입니다.적용 제안:
- onReset={() => resetTimer()} + onReset={resetTimer}src/page/TimerPage/components/TimeBasedTimer.tsx (1)
60-69: truthy 검사 대신 명시적 number 가드로 안전성 향상
totalTimer/speakingTimer에 대한 truthy 검사는 0을 의도적으로 “완료”로 처리하는 데에는 맞지만, 명시적 타입 가드가 가독성과 안전성(예: NaN)에서 더 낫습니다. 또한 speakingTimer 분기에서도<= 0처리 일관성을 맞추면 의도가 더 명확합니다.제안 diff:
- if (item.timePerTeam && totalTimer && item.timePerTeam > 0) { - // 팀당 발언 시간 타이머가 정상 동작 중이고 남은 시간이 있을 경우, 진행도를 계산 - if (totalTimer <= 0) { - return 100; - } - return ((item.timePerTeam - totalTimer) / item.timePerTeam) * 100; - } else { + if ( + typeof totalTimer === 'number' && + Number.isFinite(totalTimer) && + item.timePerTeam && + item.timePerTeam > 0 + ) { + if (totalTimer <= 0) return 100; + return ((item.timePerTeam - totalTimer) / item.timePerTeam) * 100; + } else { // 팀당 발언 시간 타이머가 멈추거나 완료된 경우, // 완료(100%)에 해당하는 진행도를 반환 return 100; } … - if (item.timePerSpeaking && speakingTimer && item.timePerSpeaking > 0) { - // 1회당 발언 시간 타이머가 정상 동작 중이고 남은 시간이 있을 경우, 진행도를 계산 - return ( - ((item.timePerSpeaking - speakingTimer) / item.timePerSpeaking) * 100 - ); - } else { + if ( + typeof speakingTimer === 'number' && + Number.isFinite(speakingTimer) && + item.timePerSpeaking && + item.timePerSpeaking > 0 + ) { + if (speakingTimer <= 0) return 100; + return ( + ((item.timePerSpeaking - speakingTimer) / item.timePerSpeaking) * 100 + ); + } else { // 1회당 발언 시간 타이머가 멈추거나 완료된 경우, // 완료(100%)에 해당하는 진행도를 반환 return 100; }Also applies to: 72-81
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
src/page/TimerPage/components/NormalTimer.tsx(1 hunks)src/page/TimerPage/components/TimeBasedTimer.tsx(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-08T14:21:17.745Z
Learnt from: i-meant-to-be
PR: debate-timer/debate-timer-fe#335
File: src/page/TimerPage/components/NormalTimer.tsx:50-54
Timestamp: 2025-08-08T14:21:17.745Z
Learning: Progress 퍼센트(원형 게이지)는 컴포넌트가 아닌 훅(src/page/TimerPage/hooks/useCircularTimerAnimation.ts)에서 0–100으로 clamp한다. 향후 리뷰에서는 컴포넌트 레벨에서의 중복 clamp 제안 대신 훅 사용을 권장한다.
Applied to files:
src/page/TimerPage/components/TimeBasedTimer.tsx
🔇 Additional comments (6)
src/page/TimerPage/components/NormalTimer.tsx (1)
136-139: tabular-nums 적용과 소형 화면 폰트 다운스케일링이 목적에 부합 — LGTM
- 숫자 폭을 고정(tabular-nums)해 자리수 변화 시 레이아웃 점프를 방지한 점이 좋습니다.
- 기본 text-[70px], xl:text-[110px]로의 반응형 조정도 의도(작은 화면에서 과대 표시 방지)에 맞습니다.
src/page/TimerPage/components/TimeBasedTimer.tsx (5)
57-86: 타이머 종료 시 진행도를 100%로 유지하도록 수정 — 핵심 버그 해결됨
- speakingTimer null(= 1회당 발언 시간 X)·not null(= O) 각각에서 “타이머 종료·멈춤·미설정” 시 100%를 반환하는 분기 덕분에, 완료 직후 0%로 돌아가던 문제를 해소했습니다.
- 참고: 이전 러닝(2025-08-08)대로 진행도 clamp(0–100)는 useCircularTimerAnimation 훅에서 처리하므로, 컴포넌트 레벨 중복 clamp가 없다는 점도 적절합니다.
128-135: 소형 화면 90px / XL 110px로의 반응형 조정 — PR 목적 1 충족작은 화면에서의 과대 표시 이슈를 해소하면서, XL에서는 기존 가독성(110px)을 유지한 구성으로 보입니다. 숫자 컨테이너에도 padding만 남기고 space-x를 제거해 밀집도를 안정화한 점도 👍
128-135: 오버타임(음수) 표기 정책 확인 요청현재 X 케이스(1회당 발언 시간 없음)에서
minute/second는Math.abs로 렌더링되고 음수 기호는 표시하지 않습니다. NormalTimer는 음수일 때 별도-를 노출하는데, TimeBasedTimer에서 의도적으로 숨기는 것인지 확인이 필요합니다. 오버타임 가시성이 필요하다면 아래처럼 일관화할 수 있습니다.적용 예시(diff):
- {speakingTimer === null && ( - <span className="flex w-full flex-row items-center justify-center p-[16px] text-[90px] font-bold tabular-nums text-default-black xl:text-[110px]"> - <p className="flex flex-1 items-center justify-center">{minute}</p> - <p className="flex items-center justify-center">:</p> - <p className="flex flex-1 items-center justify-center">{second}</p> - </span> - )} + {speakingTimer === null && ( + <span + className={clsx( + 'flex w-full flex-row items-center justify-center p-[16px] text-[90px] font-bold tabular-nums text-default-black xl:text-[110px]', + { 'space-x-[8px]': (totalTimer ?? 0) < 0 }, + { 'space-x-[16px]': (totalTimer ?? 0) >= 0 }, + )} + > + {(totalTimer ?? 0) < 0 && ( + <p className="flex items-center justify-center">-</p> + )} + <p className="flex flex-1 items-center justify-center">{minute}</p> + <p className="flex items-center justify-center">:</p> + <p className="flex flex-1 items-center justify-center">{second}</p> + </span> + )}디자인 정책상 음수 미표시가 맞다면, 이 코멘트는 무시하셔도 됩니다.
143-151: 전체 시간 블록에 tabular-nums 적용 — 숫자 폭 일관성 확보자릿수 변동(예: 10→9초) 시 레이아웃 점프를 방지합니다. 고정 폭 컨테이너(w-[80/120px])와도 잘 어울립니다.
165-172: 현재 시간 블록에도 tabular-nums 적용 — 시각적 안정성 개선가장 큰 숫자 영역에 적용되어 효과가 큽니다. 반응형 폰트 사이즈(ld/xl)와 고정 폭 컨테이너의 조합도 적절합니다.
jaeml06
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 확인했습니다. 정상작동되는 것 확인했습니다
useon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
크기 줄어든거랑 시간이 종료되어도 회색으로 유지되는 것 확인했습니다 !!!! 👍
🚩 연관 이슈
closed #348
📝 작업 내용
첫 번째 오류
🐞 상세 내용
1회당 발언 시간이 없는 시간 총량제 타이머의 남은 시간 텍스트 크기가, 작은 적응형 화면에서 비정상적으로 커 보였던 문제
🔍 원인
다른 타이머 UI 요소와는 다르게, 1회당 발언 시간 없는 시간 총량제 타이머의 텍스트에만 적응형이 적용되지 않았었음
⚒️ 해결
적응형 적용하여 큰 화면에서는 110 px(써니가 넘겨준 원래 규격), 작은 화면에서는 90 px로 렌더링되도록 수정
두 번째 오류
🐞 상세 내용
시간 총량제 타이머 발언 시간이 끝난 상태여도, 프로그레스 바가 원래대로 복원되었던 문제
🔍 원인
⚒️ 해결
2025-08-24.180541.mp4
타이머가 종료됐을 때, 타이머 애니메이션 진행도가 0%가 아닌 100%로 초기화되도록 수정
그 외 변경 사항
TailwindCSS의
tabular-nums태그를 두 타이머 - 시간 총량제 타이머와 일반 타이머 - 모두에 적용하여, 숫자가 동일한 너비를 차지하게 해 UI가 튀는 상황을 방지할 수 있게 했어요.🏞️ 스크린샷 (선택)
위에 첨부하였으므로 생략
🗣️ 리뷰 요구사항 (선택)
없음
Summary by CodeRabbit