[fix] 키보드 활성화 시 채팅 화면 상단 고정이 깨지고 빈 공간이 남는 문제 수정#234
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 17 minutes and 35 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
Walkthrough채팅방에서 외부 스크롤을 차단하고 내부만 스크롤되도록 레이아웃을 개선했습니다. Layout 컴포넌트에서 현재 경로가 Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
키보드 활성화(iOS Safari/웹뷰) 시 채팅 화면 레이아웃이 함께 밀리거나, 키보드 종료 후 빈 공간이 남는 현상을 줄이기 위해 채팅방의 스크롤 책임을 “외부 Layout(main) → 채팅 내부 메시지 영역”으로 재정의하고, 문서 루트 스크롤을 강제로 원복하는 로직을 보강한 PR입니다.
Changes:
- 채팅방에서는 Layout의
<main>스크롤을 차단하고(ChatRoom 내부만 스크롤) 컨테이너 overflow를 조정 useViewportHeightLock에서 focus/visualViewport/scroll 변화에 맞춰 문서 스크롤을 0으로 복구하는 루틴 추가- ChatRoom 루트에
overflow-hidden을 추가해 키보드 활성화 시 외부 컨테이너가 함께 밀리는 현상 완화
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/utils/hooks/useViewportHeightLock.ts | iOS에서 문서 루트가 밀리는 케이스를 줄이기 위해 focus/viewport/scroll 기반의 스크롤 원복 로직 추가 |
| src/pages/Chat/ChatRoom.tsx | 채팅방 루트 overflow를 숨김 처리하여 외부 레이아웃 이동/빈 공간 노출을 완화 |
| src/components/layout/index.tsx | 채팅방 경로에서 <main> 스크롤을 막고 내부 영역 스크롤로 전환 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
🧹 Nitpick comments (3)
src/utils/hooks/useViewportHeightLock.ts (3)
33-44: 스크롤 리셋 전략 검토
requestAnimationFrame2번 +setTimeout(180ms)조합은 iOS Safari의 비동기 스크롤 동작을 대응하기 위한 것으로 보입니다. 이 패턴은 경험적으로 검증된 것인지 확인이 필요합니다.180ms 타임아웃 값의 근거가 있다면 주석으로 남겨두면 향후 유지보수에 도움이 됩니다.
📝 주석 추가 제안
+ // iOS Safari에서 키보드 활성화 시 문서 스크롤이 비동기로 발생하므로 + // rAF 2회 + 180ms 지연으로 여러 타이밍에 리셋을 시도합니다. const scheduleDocumentScrollReset = () => {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/utils/hooks/useViewportHeightLock.ts` around lines 33 - 44, Add explanatory comments to scheduleDocumentScrollReset explaining why it uses two requestAnimationFrame calls and a 180ms setTimeout to handle iOS Safari asynchronous scroll behavior; mention the empirical/source rationale for the 180ms value (or mark as heuristic if no authoritative source) and make the timing a named constant (e.g., SCROLL_RESET_TIMEOUT) so the purpose is clearer when used with resetDocumentScroll, resetFrameId and trailingResetFrameId; keep the comment concise and colocated with the function for maintainability.
17-21:isTextInputElement함수 중복
src/utils/ts/viewport.ts에 동일한isTextInputElement헬퍼가 존재합니다. 공통 유틸로 추출하면 중복을 줄일 수 있습니다.♻️ 공유 유틸 추출 제안
// src/utils/ts/dom.ts export const isTextInputElement = (element: EventTarget | null): element is HTMLElement => { if (!(element instanceof HTMLElement)) return false; return element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element.isContentEditable; };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/utils/hooks/useViewportHeightLock.ts` around lines 17 - 21, Duplicate isTextInputElement helper exists in useViewportHeightLock.ts and src/utils/ts/viewport.ts; extract it into a shared module (e.g., export isTextInputElement from src/utils/ts/dom.ts) and replace the local implementations by importing that exported function. Update references in useViewportHeightLock (function name isTextInputElement) and in viewport.ts to import the new shared util, ensuring the exported signature and type guard remain identical.
81-86: 동일 이벤트에 여러 핸들러 등록 - 유지보수 명확화 권장
viewport.ts의 전역installViewportVars()와useViewportHeightLock훅이 동일한 이벤트(focusin,focusout,visualViewport resize/scroll)에 리스너를 등록합니다. 다만 각 핸들러의 목적이 다릅니다:
viewport.ts: CSS 변수 업데이트useViewportHeightLock: 스크롤 위치 초기화현재 ChatRoom에서만 사용되므로 기능상 문제는 없으나, 향후 이 훅을 다른 페이지에서 재사용할 때 의도가 명확하도록 주석이나 문서화를 추가하면 좋습니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/utils/hooks/useViewportHeightLock.ts` around lines 81 - 86, Both installViewportVars() and the useViewportHeightLock hook register handlers for the same global events (focusin/focusout and visualViewport resize/scroll), which can be confusing for future reuse; update useViewportHeightLock (and/or installViewportVars) to either (a) add a brief comment above the hook and its event registrations (handleFocusIn, handleFocusOut, handleViewportChange) explaining the different responsibilities (CSS var updates vs scroll-reset) and that duplication is intentional for ChatRoom-only usage, or (b) add a simple guard/option to avoid double-registration when installViewportVars() is active (e.g., a boolean flag or opt-in parameter) so consumers can explicitly choose exclusive behavior—make this change in useViewportHeightLock and document it near the event listener lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/utils/hooks/useViewportHeightLock.ts`:
- Around line 33-44: Add explanatory comments to scheduleDocumentScrollReset
explaining why it uses two requestAnimationFrame calls and a 180ms setTimeout to
handle iOS Safari asynchronous scroll behavior; mention the empirical/source
rationale for the 180ms value (or mark as heuristic if no authoritative source)
and make the timing a named constant (e.g., SCROLL_RESET_TIMEOUT) so the purpose
is clearer when used with resetDocumentScroll, resetFrameId and
trailingResetFrameId; keep the comment concise and colocated with the function
for maintainability.
- Around line 17-21: Duplicate isTextInputElement helper exists in
useViewportHeightLock.ts and src/utils/ts/viewport.ts; extract it into a shared
module (e.g., export isTextInputElement from src/utils/ts/dom.ts) and replace
the local implementations by importing that exported function. Update references
in useViewportHeightLock (function name isTextInputElement) and in viewport.ts
to import the new shared util, ensuring the exported signature and type guard
remain identical.
- Around line 81-86: Both installViewportVars() and the useViewportHeightLock
hook register handlers for the same global events (focusin/focusout and
visualViewport resize/scroll), which can be confusing for future reuse; update
useViewportHeightLock (and/or installViewportVars) to either (a) add a brief
comment above the hook and its event registrations (handleFocusIn,
handleFocusOut, handleViewportChange) explaining the different responsibilities
(CSS var updates vs scroll-reset) and that duplication is intentional for
ChatRoom-only usage, or (b) add a simple guard/option to avoid
double-registration when installViewportVars() is active (e.g., a boolean flag
or opt-in parameter) so consumers can explicitly choose exclusive behavior—make
this change in useViewportHeightLock and document it near the event listener
lines.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 4f6613b9-113b-4dd1-81d7-a235552582f2
📒 Files selected for processing (3)
src/components/layout/index.tsxsrc/pages/Chat/ChatRoom.tsxsrc/utils/hooks/useViewportHeightLock.ts
* 205 feat 이미지 전처리 기능 구현 (#206) * feat: 전처리 로직 및 WebWorker 구현 * feat: 전처리 적용 및 preview 동시성 제어 로직 추가 * refactor: 리뷰 반영 * [hotfix] 하단바 너비 수정 (#208) * hotfix: 하단바 너비 수정 * chore: 불필요한 값 제거 * refactor: 고정 gap 제거 * Reapply "[feat] 광고 배너 추가 (#200)" This reverts commit c51ec85. * [feat] 하단바 리디자인 (#213) * chore: asset 추가 * feat: 하단바 리디자인 반영 및 레이아웃 수정 * [refactor] 광고 카드 레이아웃 밀림 수정 (#215) * refactor: 광고 개수 측정 시기 변경 및 기본값 제거 * feat: 스켈레톤 UI 추가 * feat: 인앱 알림 페이지 및 토스트 구현 (#217) * feat: 알림 API 및 스트림 기반 추가 * feat: 인앱 알림 레이어 추가 * feat: 알림 페이지 및 헤더 진입 구현 * fix: 알림 스트림 401 재시도 조건 정리 * fix: 알림 목록 이동 차단 제거 * refactor: 알림 공용 훅 위치 정리 * fix: 알림 재연결 캐시 동기화 추가 * fix: 알림 목록 토스트 큐 누적 방지 * fix: 알림 읽음 카운트 감소 조건 보강 * [refactor] 도메인별 TanStack Query 훅 정리 (#219) * chore: pwa용 이미지 제거 * refactor: auth 도메인 쿼리와 뮤테이션 정리 * refactor: council과 schedule 조회 훅 정리 * refactor: chat과 notification 캐시 처리 정리 * refactor: club 조회와 지원 플로우 정리 * refactor: manager 도메인 캐시 처리 정리 * refactor: studyTime 도메인 쿼리와 뮤테이션 정리 * refactor: 광고와 업로드 도메인 훅 정리 * [refactor] mutaton query 및 hook 추가 수정 (#221) * refactor: auth와 user myInfo 훅 정리 * refactor: club과 schedule 조회 훅 정리 * refactor: chat과 notification 훅 구조 정리 * refactor: club 지원 뮤테이션 훅 정리 * refactor: manager 뮤테이션 훅 구조 정리 * refactor: mutation 훅 cache 정리 * refactor: 컨벤션 통일 * refactor: isRead 조건 정리 * fix: 채팅 스크롤 문제 수정 * refactor: 불필요한 코드 제거 * [fix] 모바일 환경 입력창과 키보드 간의 간격이 큰 문제 수정 (#223) * chore: 가공용 safeArea 변수 선언 * refactor: 고정 패딩 값 수정 및 safeArea 적용 변경 * feat: 키보드 활성화 감지 및 safeArea 적용 여부 기능 추가 * refactor: 매직넘버 상수화 및 가로모드 처리 * [fix] 키보드 활성화 시 화면 흔들림 문제 수정 (#225) * refactor: 채팅 viewport 훅 네이밍 정리 * refactor: viewport 높이 잠금 훅 적용 시점 조정 * [fix] 키보드 활성화 시 채팅 화면 전체가 흔들리는 문제 수정 (#227) * refactor: 채팅 viewport 훅 네이밍 정리 * refactor: viewport 높이 잠금 훅 적용 시점 조정 * fix: 채팅 화면 스크롤 잠금으로 키보드 흔들림 완화 * fix: 입력 포커스 중 viewport offset 고정 (#229) * fix: 문서 루트 스크롤 잠금으로 빈 공간 잔류 방지 (#232) * [fix] 키보드 활성화 시 채팅 화면 상단 고정이 깨지고 빈 공간이 남는 문제 수정 (#234) * fix: 채팅 화면 상단 고정 깨짐과 빈 공간 잔류 수정 * refactor: 라우트 조건 수정 * fix: 문서 스크롤 위치 감지 보강 * refactor: 입력 요소 판별 유틸과 스크롤 주석 정리 * [fix] 키보드 활성화 시 채팅 화면에서 문서 스크롤이 발생하는 문제 수정 (#236) * fix: 채팅 문서 스크롤 제스처 차단 * fix: 입력 요소 터치 동작 예외 처리 * [fix] 키보드 활성화 시 채팅방이 마지막 메시지 위치를 유지하지 못하는 문제 수정 (#238) * fix: 키보드 활성화 시 채팅 하단 정렬 유지 * refactor: 채팅 리사이즈 관찰 안정화 * fix: mypage 연계 약관 페이지 뒤로가기 수정 (#240) * refactor: alias import 경로 정리 * fix: query 설정과 suspense 분기 정리 * refactor: 관리자 화면 스타일 유틸 정리 * fix: 이미지 전처리 예외 처리 보강 * fix: 헤더와 회비 화면 동작 정리 * fix: 공통 유틸 안정성 개선 * fix: 이미지 전처리 실패 처리를 보정 * fix: 모집 공고 저장 후 설정 반영 순서 조정 * fix: 부원 직책 변경 실패 처리를 보강 * fix: 약관 링크 접근성을 개선 * fix: 공통 쿼리와 유틸 안정성을 보완 * [feat] 동적 버전 정보 표시 구현 (#211) * feat: 동적 버전 정보 표시 구현 * refactor: 버전 정보 미 존재시 v 표시 제거 * [feat] 메인화면 동아리 카드 디자인 수정 반영 (#242) * feat: 메인화면 동아리 카드 디자인 수정 * chore: 하단바 아이콘 수정 * refactor: 코드래빗 리뷰 반영 * refactor: and 연산자로 변경 * apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 (#244) * refactor: apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 * refactor: body 직렬화 가드를 plain object/array로 한정 * fix: body 읽기 중 AbortError가 ParseError로 오분류되는 문제 수정 * [refactor] 에러 처리 유틸 및 utils 구조 정리 (#246) * refactor: 에러 처리 유틸 및 공통 토스트 흐름 정리 * refactor: utils 폴더 구조를 역할별로 정리 * refactor: 코드래빗 리뷰 반영 * refactor: 코드래빗 리뷰 반영 * Update src/pages/Home/components/HomeClubSection.tsx * fix: 인증 세션 복구 흐름 정리 * fix: 홈 동아리 카드 레이아웃 정리 * [feat] 총동아리 페이지 리디자인 및 하단 오버레이 정리 (#249) * refactor: 하단 오버레이 처리 공통화 * feat: 총동아리 페이지와 헤더 리디자인 반영 * fix: 채팅 하단 여백과 외부 링크 속성 수정 * refactor: 총동아리 헤더 설정 정리 * fix: 총동아리 상세 접근성과 스타일 보완 * [feat] 마이페이지 관리자 카드 분리 및 채팅 미확인 배지 반영 (#251) * feat: 하단 채팅 배지 표시 및 조회 조건 보완 * refactor: 관리자 정보 카드 컴포넌트 분리 * feat: 채팅 페이지 리디자인 (#252) * feat: 채팅 페이지 리디자인 * fix:tailwind 문법 수정 * fix: 코드 수정 * fix: 폰트 색상 및 위치 수정 * fix: 채팅방 사람수 정렬 * fix: 오타 수정 * chore: conflict 해결 중 누락된 부분 수정 * [refactor] 광고 렌더링 조건 수정 (#254) * refactor: 광고 렌더링 조건 수정 * docs: 문서명 변경 --------- Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com>
* [배포] 이미지 전처리, 광고 기능, 하단바 리디자인, 인앱 알림 페이지 및 토스트 프로덕션 배포 (#230) * 205 feat 이미지 전처리 기능 구현 (#206) * feat: 전처리 로직 및 WebWorker 구현 * feat: 전처리 적용 및 preview 동시성 제어 로직 추가 * refactor: 리뷰 반영 * [hotfix] 하단바 너비 수정 (#208) * hotfix: 하단바 너비 수정 * chore: 불필요한 값 제거 * refactor: 고정 gap 제거 * Reapply "[feat] 광고 배너 추가 (#200)" This reverts commit c51ec85. * [feat] 하단바 리디자인 (#213) * chore: asset 추가 * feat: 하단바 리디자인 반영 및 레이아웃 수정 * [refactor] 광고 카드 레이아웃 밀림 수정 (#215) * refactor: 광고 개수 측정 시기 변경 및 기본값 제거 * feat: 스켈레톤 UI 추가 * feat: 인앱 알림 페이지 및 토스트 구현 (#217) * feat: 알림 API 및 스트림 기반 추가 * feat: 인앱 알림 레이어 추가 * feat: 알림 페이지 및 헤더 진입 구현 * fix: 알림 스트림 401 재시도 조건 정리 * fix: 알림 목록 이동 차단 제거 * refactor: 알림 공용 훅 위치 정리 * fix: 알림 재연결 캐시 동기화 추가 * fix: 알림 목록 토스트 큐 누적 방지 * fix: 알림 읽음 카운트 감소 조건 보강 * [refactor] 도메인별 TanStack Query 훅 정리 (#219) * chore: pwa용 이미지 제거 * refactor: auth 도메인 쿼리와 뮤테이션 정리 * refactor: council과 schedule 조회 훅 정리 * refactor: chat과 notification 캐시 처리 정리 * refactor: club 조회와 지원 플로우 정리 * refactor: manager 도메인 캐시 처리 정리 * refactor: studyTime 도메인 쿼리와 뮤테이션 정리 * refactor: 광고와 업로드 도메인 훅 정리 * [refactor] mutaton query 및 hook 추가 수정 (#221) * refactor: auth와 user myInfo 훅 정리 * refactor: club과 schedule 조회 훅 정리 * refactor: chat과 notification 훅 구조 정리 * refactor: club 지원 뮤테이션 훅 정리 * refactor: manager 뮤테이션 훅 구조 정리 * refactor: mutation 훅 cache 정리 * refactor: 컨벤션 통일 * refactor: isRead 조건 정리 * fix: 채팅 스크롤 문제 수정 * refactor: 불필요한 코드 제거 * [fix] 모바일 환경 입력창과 키보드 간의 간격이 큰 문제 수정 (#223) * chore: 가공용 safeArea 변수 선언 * refactor: 고정 패딩 값 수정 및 safeArea 적용 변경 * feat: 키보드 활성화 감지 및 safeArea 적용 여부 기능 추가 * refactor: 매직넘버 상수화 및 가로모드 처리 * [fix] 키보드 활성화 시 화면 흔들림 문제 수정 (#225) * refactor: 채팅 viewport 훅 네이밍 정리 * refactor: viewport 높이 잠금 훅 적용 시점 조정 * [fix] 키보드 활성화 시 채팅 화면 전체가 흔들리는 문제 수정 (#227) * refactor: 채팅 viewport 훅 네이밍 정리 * refactor: viewport 높이 잠금 훅 적용 시점 조정 * fix: 채팅 화면 스크롤 잠금으로 키보드 흔들림 완화 * fix: 입력 포커스 중 viewport offset 고정 (#229) * fix: 문서 루트 스크롤 잠금으로 빈 공간 잔류 방지 (#232) * [fix] 키보드 활성화 시 채팅 화면 상단 고정이 깨지고 빈 공간이 남는 문제 수정 (#234) * fix: 채팅 화면 상단 고정 깨짐과 빈 공간 잔류 수정 * refactor: 라우트 조건 수정 * fix: 문서 스크롤 위치 감지 보강 * refactor: 입력 요소 판별 유틸과 스크롤 주석 정리 * [fix] 키보드 활성화 시 채팅 화면에서 문서 스크롤이 발생하는 문제 수정 (#236) * fix: 채팅 문서 스크롤 제스처 차단 * fix: 입력 요소 터치 동작 예외 처리 * [fix] 키보드 활성화 시 채팅방이 마지막 메시지 위치를 유지하지 못하는 문제 수정 (#238) * fix: 키보드 활성화 시 채팅 하단 정렬 유지 * refactor: 채팅 리사이즈 관찰 안정화 * fix: mypage 연계 약관 페이지 뒤로가기 수정 (#240) * refactor: alias import 경로 정리 * fix: query 설정과 suspense 분기 정리 * refactor: 관리자 화면 스타일 유틸 정리 * fix: 이미지 전처리 예외 처리 보강 * fix: 헤더와 회비 화면 동작 정리 * fix: 공통 유틸 안정성 개선 * fix: 이미지 전처리 실패 처리를 보정 * fix: 모집 공고 저장 후 설정 반영 순서 조정 * fix: 부원 직책 변경 실패 처리를 보강 * fix: 약관 링크 접근성을 개선 * fix: 공통 쿼리와 유틸 안정성을 보완 * [feat] 동적 버전 정보 표시 구현 (#211) * feat: 동적 버전 정보 표시 구현 * refactor: 버전 정보 미 존재시 v 표시 제거 * [feat] 메인화면 동아리 카드 디자인 수정 반영 (#242) * feat: 메인화면 동아리 카드 디자인 수정 * chore: 하단바 아이콘 수정 * refactor: 코드래빗 리뷰 반영 * refactor: and 연산자로 변경 * apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 (#244) * refactor: apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 * refactor: body 직렬화 가드를 plain object/array로 한정 * fix: body 읽기 중 AbortError가 ParseError로 오분류되는 문제 수정 * [refactor] 에러 처리 유틸 및 utils 구조 정리 (#246) * refactor: 에러 처리 유틸 및 공통 토스트 흐름 정리 * refactor: utils 폴더 구조를 역할별로 정리 * refactor: 코드래빗 리뷰 반영 * refactor: 코드래빗 리뷰 반영 * Update src/pages/Home/components/HomeClubSection.tsx * fix: 인증 세션 복구 흐름 정리 * fix: 홈 동아리 카드 레이아웃 정리 * [feat] 총동아리 페이지 리디자인 및 하단 오버레이 정리 (#249) * refactor: 하단 오버레이 처리 공통화 * feat: 총동아리 페이지와 헤더 리디자인 반영 * fix: 채팅 하단 여백과 외부 링크 속성 수정 * refactor: 총동아리 헤더 설정 정리 * fix: 총동아리 상세 접근성과 스타일 보완 * [feat] 마이페이지 관리자 카드 분리 및 채팅 미확인 배지 반영 (#251) * feat: 하단 채팅 배지 표시 및 조회 조건 보완 * refactor: 관리자 정보 카드 컴포넌트 분리 * feat: 채팅 페이지 리디자인 (#252) * feat: 채팅 페이지 리디자인 * fix:tailwind 문법 수정 * fix: 코드 수정 * fix: 폰트 색상 및 위치 수정 * fix: 채팅방 사람수 정렬 * fix: 오타 수정 * chore: conflict 해결 중 누락된 부분 수정 * [refactor] 광고 렌더링 조건 수정 (#254) * refactor: 광고 렌더링 조건 수정 * docs: 문서명 변경 --------- Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com> * refactor: 가이드 페이지 이미지 변경 및 구조 개선 (#260) * hotfix: 가이드 이미지 경로 변경 --------- Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com>
✨ 요약
😎 해결한 이슈
Summary by CodeRabbit
버그 수정