Skip to content

[FIX] 화면 간 쿼리키 동기화, 포커스 레이아웃, 모달 겹침 버그 수정#230

Open
jjangminii wants to merge 4 commits into
developfrom
fix/web/224-dev-qa-fixes
Open

[FIX] 화면 간 쿼리키 동기화, 포커스 레이아웃, 모달 겹침 버그 수정#230
jjangminii wants to merge 4 commits into
developfrom
fix/web/224-dev-qa-fixes

Conversation

@jjangminii

@jjangminii jjangminii commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

ISSUE 🔗

close #224



What is this PR? 🔍

개발자 QA에서 발견된 화면 간 동기화 문제 3건을 수정했습니다: 화면 전반의 React Query 쿼리키 미연동, 포커스 세션 메모가 길 때의 레이아웃 붕괴, 모달 중첩 시 오버레이 겹침입니다.

배경

  • 기존 구조: Today/Home/Focus/사이드바 타이머는 각자 별도의 React Query 쿼리키를 구독하면서도, 서로 겹치는 데이터(할 일 완료 상태, 타이머 실행 상태, 서브태스크 등)를 보여주고 있었습니다.
  • 발생 문제: 한 화면에서 타이머를 재생/정지하거나 할 일을 완료 처리해도, 그 변경이 반영돼야 할 다른 화면의 쿼리는 invalidate되지 않아 새로고침 전까지 반영되지 않았습니다. 또한 포커스 세션에서 공백 없는 긴 메모가 있으면 카드 레이아웃이 깨졌고, 모달이 중첩되면 아래 모달의 패널이 위 모달의 오버레이보다 낮은 z-index로 남아 겹쳐 보였습니다.
  • 해결 방향: 각 화면의 mutation onSuccess에서 관련된 다른 화면의 쿼리키도 함께 invalidate하도록 누락된 지점을 모두 채웠습니다. 레이아웃은 flex 아이템의 자동 최소 너비 계산 방식을 바로잡아 해결했고, 모달 겹침은 두 번째 수정 모달에도 스택 기반 z-index 로직을 동일하게 적용해 해결했습니다.

화면 간 쿼리키 동기화

  • 변경 요약: Home/Today/Focus/사이드바 타이머와 할 일 수정 모달 사이에서 누락돼 있던 React Query invalidate 호출을 모두 추가했습니다.
  • 이유: 각 화면이 타이머 시작/일시정지/재개/완료/정지, 할 일 완료 처리, 서브태스크 체크, 할 일 수정/삭제를 수행할 때 자기 화면의 쿼리만 invalidate하고 있어서, 같은 할 일을 보여주는 다른 화면(특히 Focus 탭과 수정 모달)이 새로고침 전까지 낡은 상태를 보여줬습니다.
  • 구현 방식: 각 훅에 이미 존재하던 invalidateXxx 헬퍼 패턴을 그대로 따라, 누락된 상대 쿼리키(getGetFocusTodoQueryKey, getGetTodayQueryKey, getGetTodoDetailQueryKey)를 해당 mutation의 onSuccess에 추가하는 방식으로 수정했습니다. 새로운 추상화나 공용 훅을 만들지 않고, 기존 파일별 로컬 invalidate 함수 컨벤션을 유지했습니다.
    • use-home-todos-by-date.ts, useTodayTodoList.ts: 타이머 재생/일시정지/재개 시 getGetFocusTodoQueryKey()를 함께 invalidate
    • use-focus-session.ts: 완료/정지/서브태스크 변경 시 getGetTodayQueryKey()getGetTodoDetailQueryKey()를 함께 invalidate
    • TimerPanel.tsx(사이드바 타이머): 완료/정지/할 일 상태 변경 시 getGetTodayQueryKey()getGetFocusTodoQueryKey()를 함께 invalidate
    • use-update-todo-submit.ts, use-delete-todo-submit.ts(수정 모달): 수정/삭제 성공 시 getGetFocusTodoQueryKey()를 함께 invalidate
  • 경계 · 제약: Home 쪽 타이머 재생/완료 흐름 등 이미 관련 쿼리를 invalidate하던 지점은 건드리지 않았고, 실제로 빠져 있던 지점만 보강했습니다.

포커스 세션 레이아웃

  • 변경 요약: 포커스 세션에서 공백 없는 긴 메모가 있을 때 할 일 카드가 타이머 패널 뒤로 사라지던 레이아웃 붕괴를 수정하고, 메모 영역에 자체 세로 스크롤을 추가했습니다.
  • 이유: overflow-wrap: break-word는 브라우저가 flex 아이템의 자동 최소 너비(intrinsic min-content)를 계산할 때는 반영되지 않는 스펙 특성이 있습니다. 그래서 공백 없는 긴 메모가 있으면 부모 flex 아이템의 자동 최소 너비가 카드의 의도된 최소 너비(min-w-80)가 아니라 메모 전체 길이만큼 부풀어 올랐고, 그 결과 카드가 타이머 패널 뒤로 완전히 가려지는 현상이 있었습니다.
  • 구현 방식: 제목·서브태스크·메모의 줄바꿈 클래스를 wrap-break-word(overflow-wrap: break-word)에서 wrap-anywhere(overflow-wrap: anywhere)로 교체했습니다. anywhere는 자동 최소 너비 계산에도 반영되는 값이라, 메모의 최소 너비 기여도가 낮아지고 카드의 명시적 min-w-80이 실제 하한으로 동작합니다. 이 조합을 로컬 정적 HTML로 재현해 여러 뷰포트 폭에서 검증했습니다: 평소엔 자연스럽게 반응형으로 줄어들다가, 320px 바닥에 닿으면 카드와 타이머 패널 전체가 가로 스크롤로 전환됩니다. 메모/서브태스크 영역에는 max-h-[40vh] overflow-y-auto를 추가해, 메모가 길어도 페이지 전체 높이가 늘어나지 않고 카드 내부에서만 세로 스크롤되도록 했습니다.
  • 경계 · 제약: 이 조합(부모에 min-w-0을 주지 않고, 자식에 명시적 min-w-80 + wrap-anywhere만 주는 방식)은 원래 #109에서 의도했던 "평소엔 반응형, 바닥 아래는 가로 스크롤" 동작을 그대로 복원한 것입니다. 로그인이 필요한 환경이라 실제 앱에서 라이브 스크린샷은 확보하지 못했고, 실제 소스 클래스와 동일한 컴파일된 Tailwind CSS를 사용한 격리된 재현 HTML로 레이아웃 동작만 검증했습니다.

모달 오버레이 겹침

  • 변경 요약: OverlayModal(태그 생성 모달 등에서 쓰는 두 번째 모달 구현체)에도 Modal 컴포넌트와 동일한 스택 기반 z-index 로직을 적용했습니다.
  • 이유: 디자인 시스템의 Modal 컴포넌트는 이미 acquireModalStackIndex()로 중첩된 모달의 오버레이/패널 z-index를 단계별로 올리고 있었지만, OverlayModal은 정적인 z-40/z-50 클래스만 쓰고 있어서, 이 컴포넌트를 쓰는 모달이 다른 모달 위에 중첩되면 아래 모달의 패널보다도 낮은 z-index로 렌더링돼 겹쳐 보였습니다.
  • 구현 방식: Modal.tsx와 동일한 BASE_OVERLAY_Z_INDEX/BASE_PANEL_Z_INDEX/MODAL_STACK_Z_INDEX_STEP 상수와 acquireModalStackIndex() 호출을 OverlayModal에도 추가하고, 정적 z-40/z-50 클래스를 stackIndex 기반 인라인 style={{ zIndex }}로 교체했습니다.



To Reviewers

포커스 세션 레이아웃 수정은 실제 로그인된 브라우저가 아니라 동일한 컴파일된 Tailwind 클래스를 쓴 격리된 정적 HTML 재현으로 검증했습니다. 실제 앱에서 좁은 화면 + 긴 메모 조합으로 한 번 더 확인해주시면 좋을 것 같습니다.

쿼리키 동기화는 여러 화면(Home/Today/Focus/사이드바/수정 모달)에 걸쳐 있어 변경 지점이 많은데, 모두 기존 파일의 로컬 invalidate 헬퍼 패턴을 그대로 따랐고 새 추상화는 추가하지 않았습니다.



Screenshot 📷

image



Test Checklist ✔

  • pnpm check-types 통과
  • pnpm lint 통과
  • 포커스 세션 레이아웃(반응형 축소 → 최소 너비 → 가로 스크롤) 격리된 정적 재현 HTML로 여러 뷰포트 폭에서 확인
  • 실제 앱에서 Today/Home/Focus/사이드바 타이머 간 실시간 동기화 확인 — 미실행: 로그인 필요 환경이라 리뷰어 확인 요청
  • 모달 중첩 시각 확인 — 미실행: 로그인 필요 환경이라 리뷰어 확인 요청

- OverlayModal에 Modal 컴포넌트와 동일한 스택 기반 z-index 로직을 적용했습니다
- 정적인 z-40/z-50 클래스를 acquireModalStackIndex 기반 동적 z-index로 교체했습니다
- 제목·서브태스크·메모의 줄바꿈을 wrap-break-word에서 wrap-anywhere로 교체해, 공백 없는 긴 텍스트가 flex 아이템의 자동 최소 너비를 부풀려 카드가 타이머 패널 뒤로 사라지는 문제를 해결했습니다
- 메모 영역에 max-h-[40vh]와 세로 스크롤을 추가해 긴 메모가 페이지 전체 높이를 늘리지 않도록 했습니다
- Home/Today 탭과 사이드바 타이머에서 재생·일시정지·재개·완료·정지 시 집중 페이지 쿼리를 함께 invalidate하도록 했습니다
- 집중 페이지에서 완료·서브태스크 변경 시 Today 탭과 할 일 수정 모달 쿼리를 함께 invalidate하도록 했습니다
- 할 일 수정 모달에서 수정·삭제 시 집중 페이지 쿼리를 함께 invalidate하도록 했습니다
@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
timo Ready Ready Preview, Comment Jul 15, 2026 1:12pm

Request Review

@github-actions github-actions Bot requested review from kimminna and yumin-kim2 July 15, 2026 12:49
@github-actions github-actions Bot added the ⏰ Timo-web Timo 웹 서비스 label Jul 15, 2026
@github-actions github-actions Bot added 🐛 Bug 기능이 정상적으로 작동하지 않는 문제 수정 ♠️ 정민 정민양 labels Jul 15, 2026
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jjangminii, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a2f22c56-a345-4c1f-bf54-8a3e99892318

📥 Commits

Reviewing files that changed from the base of the PR and between b0a25ef and 2cbb20c.

📒 Files selected for processing (5)
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts
  • apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts
  • apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx
  • apps/timo-web/hooks/timer/use-timer-query-invalidation.ts

Walkthrough

타이머와 할 일 변경 성공 시 Today·Focus·투두 상세 쿼리 무효화 범위를 확장했습니다. 중첩 모달에는 동적 z-index를 적용했고, FocusTaskItem의 줄바꿈과 서브태스크 스크롤 동작을 조정했습니다.

Changes

쿼리 캐시 동기화

Layer / File(s) Summary
홈·Today 변경 무효화
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/..., apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/...
타이머, 상태, 완료 및 서브투두 변경 성공 처리에서 Focus todo 쿼리 무효화를 추가했습니다.
Focus 세션 변경 무효화
apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts
타이머 완료·중지와 투두·서브태스크 상태 변경 시 Today 및 투두 상세 쿼리를 무효화합니다.
타이머 패널 연동
apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx
타이머 완료·중지·상태 변경 성공 처리에서 Today와 Focus todo 쿼리를 무효화합니다.
할 일 상세 변경 무효화
apps/timo-web/hooks/todo-modal/detail/*-todo-submit.ts
할 일 삭제와 수정 성공 처리에서 Focus todo 쿼리를 무효화합니다.

모달 스택 및 Focus 레이아웃

Layer / File(s) Summary
중첩 모달 z-index 계산
apps/timo-web/components/modal/OverlayModal.tsx
모달 스택 인덱스에 따라 오버레이와 패널의 z-index를 계산해 적용합니다.
Focus 할 일 레이아웃
apps/timo-web/app/[locale]/(main)/focus/_components/FocusTaskItem.tsx
텍스트에 wrap-anywhere를 적용하고 서브태스크 목록에 최대 높이와 세로 스크롤을 추가했습니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: ♥️ 혜원

Suggested reviewers: kimminna, ehye1, yumin-kim2

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Issue #224 범위를 넘는 포커스 레이아웃 수정과 Home/Focus/사이드바/모달까지의 추가 invalidate가 포함됩니다. 이슈별로 분리하거나, #224 범위에 해당하는 변경만 남기고 포커스 레이아웃 및 추가 화면 동기화는 별도 PR로 분리하세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #224의 Today/타이머 동기화와 모달 중첩 z-index 문제를 실제로 보강했습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed 쿼리키 동기화, 포커스 레이아웃, 모달 z-index 수정이라는 변경 범위를 정확히 담고 있습니다.
Description check ✅ Passed 설명은 Home/Today/Focus 동기화, 포커스 레이아웃, 중첩 모달 z-index 수정이라는 실제 변경과 잘 맞습니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/web/224-dev-qa-fixes

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ehye1 ehye1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동기화 신경쓰는 게 제일 어려운 것 같아요.
수정 수고하셨습니다 !! 굿뜨

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

Timo Performance Report

Bundle Size — timo-web
라우트 크기 First Load JS
/[locale]/home 210.22 kB 🔴 416.08 kB
/[locale]/today 194.46 kB 🔴 400.31 kB
/[locale]/focus 160.12 kB 🔴 365.97 kB
/[locale]/settings 166.66 kB 🔴 372.52 kB
/[locale]/statistics 232.94 kB 🔴 438.79 kB
/[locale]/[...rest] 0 B 🟡 205.85 kB
/[locale]/login 212.95 kB 🔴 418.80 kB
/[locale]/oauth/callback 119.64 kB 🟡 325.49 kB
/[locale]/onboarding 232.91 kB 🔴 438.77 kB
/[locale] 118.95 kB 🟡 324.81 kB
/[locale]/policy 125.08 kB 🟡 330.93 kB

공유 번들: 205.85 kB
🟢 < 200kB  |  🟡 < 350kB  |  🔴 ≥ 350kB (First Load JS · gzip)

Lighthouse — timo-web
URL Perf A11y LCP CLS TBT
/en/home 🔴 68 🟢 95 🔴 15.8s 🟢 0.000 🟡 287ms
/en/today 🔴 59 🟢 95 🔴 15.6s 🟢 0.000 🟡 588ms
/en/focus 🔴 60 🟢 95 🔴 15.3s 🟢 0.000 🟡 563ms
/en/statistics 🔴 59 🟢 95 🔴 15.3s 🟢 0.000 🔴 619ms

Perf ≥ 70 / A11y ≥ 85 목표
LCP 🟢 < 2.5s 🟡 < 4s 🔴 ≥ 4s  |  CLS 🟢 < 0.1 🟡 < 0.25 🔴 ≥ 0.25  |  TBT 🟢 < 200ms 🟡 < 600ms 🔴 ≥ 600ms

Image Optimization — timo-web
파일 크기 포맷 상태
favicon.png 27.84 kB PNG ⚠️ 🟢
images/google-calendar.png 36.20 kB PNG ⚠️ 🟢
images/google-logo.png 26.79 kB PNG ⚠️ 🟢

총 3개 · 90.84 kB  |  🟢 < 200KB  |  🟡 < 500KB  |  🔴 ≥ 500KB
⚠️ 3개 파일 WebP/AVIF 변환 권장

측정 커밋: 8e0cb4d

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx`:
- Around line 38-41: Extract the duplicated invalidateTodayView and
invalidateFocusTodo query invalidation callbacks into the existing
useTimerQueryInvalidation hook or another shared invalidation hook. In
apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx lines 38-41, remove
the local declarations and consume the shared callbacks; update
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts
lines 54-56 and
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts
lines 52-55 to use shared invalidateFocusTodo, and
apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts lines 50-51
to use shared invalidateTodayView.

In `@apps/timo-web/components/modal/OverlayModal.tsx`:
- Line 56: Update the useEffect containing setStackIndex and
acquireModalStackIndex so changes to the onExited callback do not rerun the
effect while the modal remains open. Store the latest onExited callback in a ref
or otherwise remove it safely from the effect dependencies, while preserving the
existing modal stack acquisition behavior for genuine open-state changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6e7ee0db-84b5-43d6-881c-fbfe74361e28

📥 Commits

Reviewing files that changed from the base of the PR and between 590c15d and b0a25ef.

📒 Files selected for processing (8)
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts
  • apps/timo-web/app/[locale]/(main)/focus/_components/FocusTaskItem.tsx
  • apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts
  • apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx
  • apps/timo-web/components/modal/OverlayModal.tsx
  • apps/timo-web/hooks/todo-modal/detail/use-delete-todo-submit.ts
  • apps/timo-web/hooks/todo-modal/detail/use-update-todo-submit.ts

Comment thread apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx Outdated
return () => clearTimeout(hideTimer);
}

setStackIndex(acquireModalStackIndex());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

useEffect 의존성 배열로 인한 불필요한 스택 인덱스 증가를 방지하세요.

현재 의존성 배열에 onExited가 포함되어 있어, 부모 컴포넌트에서 onExited 콜백의 참조가 바뀔 때마다 useEffect가 재실행될 위험이 있습니다. 모달이 이미 열려있는 상태(isOpen === true)임에도 불구하고 acquireModalStackIndex()가 반복 호출되면, 전역 스택 인덱스가 계속 증가하여 z-index 체계가 꼬이거나 불필요한 리렌더링이 발생할 수 있습니다.

리렌더링 시에도 안전하게 최신 콜백을 참조할 수 있도록 onExiteduseRef로 관리하거나, 의존성 배열에서 안전하게 분리하는 것을 권장합니다. (참고: React 공식 문서 - Effect에서 최신 props 및 state 읽기) 멋진 모달 중첩 로직이 더욱 견고해질 거예요! 😉

💡 제안하는 `useRef` 활용 수정안
   const [shouldRender, setShouldRender] = useState(isOpen);
   const [isVisible, setIsVisible] = useState(false);
   const [stackIndex, setStackIndex] = useState(0);
   const dialogRef = useRef<HTMLDivElement>(null);
   const wasFloatingLayerOpenRef = useRef(false);
+  const onExitedRef = useRef(onExited);
+  onExitedRef.current = onExited;
 
   useEffect(() => {
     if (!isOpen) {
       setIsVisible(false);
 
       const hideTimer = setTimeout(() => {
         setShouldRender(false);
-        onExited?.();
+        onExitedRef.current?.();
       }, EXIT_ANIMATION_DURATION);
 
       return () => clearTimeout(hideTimer);
     }
 
     setStackIndex(acquireModalStackIndex());
     setShouldRender(true);
 
     const showFrame = requestAnimationFrame(() => setIsVisible(true));
 
     return () => cancelAnimationFrame(showFrame);
-  }, [isOpen, onExited]);
+  }, [isOpen]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
setStackIndex(acquireModalStackIndex());
const [shouldRender, setShouldRender] = useState(isOpen);
const [isVisible, setIsVisible] = useState(false);
const [stackIndex, setStackIndex] = useState(0);
const dialogRef = useRef<HTMLDivElement>(null);
const wasFloatingLayerOpenRef = useRef(false);
const onExitedRef = useRef(onExited);
onExitedRef.current = onExited;
useEffect(() => {
if (!isOpen) {
setIsVisible(false);
const hideTimer = setTimeout(() => {
setShouldRender(false);
onExitedRef.current?.();
}, EXIT_ANIMATION_DURATION);
return () => clearTimeout(hideTimer);
}
setStackIndex(acquireModalStackIndex());
setShouldRender(true);
const showFrame = requestAnimationFrame(() => setIsVisible(true));
return () => cancelAnimationFrame(showFrame);
}, [isOpen]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/timo-web/components/modal/OverlayModal.tsx` at line 56, Update the
useEffect containing setStackIndex and acquireModalStackIndex so changes to the
onExited callback do not rerun the effect while the modal remains open. Store
the latest onExited callback in a ref or otherwise remove it safely from the
effect dependencies, while preserving the existing modal stack acquisition
behavior for genuine open-state changes.

- 4개 파일에 중복 정의돼 있던 invalidateTodayView/invalidateFocusTodo를 useTimerQueryInvalidation 훅으로 통합했습니다
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

♠️ 정민 정민양 🐛 Bug 기능이 정상적으로 작동하지 않는 문제 수정 🚬 QA QA 반영 ⏰ Timo-web Timo 웹 서비스

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] Today 탭-타이머 쿼리키 미연동 및 모달 오버레이 겹침 버그 수정

2 participants