Skip to content

[Feature/#57] 기록장 댓글 바텀시트 컴포넌트 #78

Open
holdn2 wants to merge 3 commits into
mainfrom
feature/#57/record-comment-component
Open

[Feature/#57] 기록장 댓글 바텀시트 컴포넌트 #78
holdn2 wants to merge 3 commits into
mainfrom
feature/#57/record-comment-component

Conversation

@holdn2
Copy link
Copy Markdown
Contributor

@holdn2 holdn2 commented May 17, 2026

📌 Related Issues

📄 Tasks

  • 기록장 댓글 바텀시트 RecordComment 구현
  • CustomBottomSheet, ChatInutBar, CommentRoot 컴포넌트 리팩토링
  • feed-detail 페이지와 비슷하게 구현
  • 입력창에 포커스 여부에 따라 바텀시트 높이 조정

📷 Screenshot

image image image

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 댓글 목록 및 입력 기능 추가: 댓글을 조회하고 작성할 수 있도록 개선
    • 댓글 답글 기능 추가: 특정 댓글에 대한 답글 작성 지원
    • 입력창 포커스 상태 개선: 키보드 높이 조정으로 더 나은 입력 경험 제공
  • 스타일

    • 상단 간격 및 리스트 레이아웃 조정: UI 일관성 개선
    • 헤더 표시 설정 최적화

Review Change Stack

@holdn2 holdn2 self-assigned this May 17, 2026
@holdn2 holdn2 added the feature Add new features label May 17, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

📝 Walkthrough

Walkthrough

이 PR은 기록장에 완전한 댓글 바텀시트 기능을 추가합니다. RecordBookLayout의 헤더 렌더링을 RecordBookScreen으로 이동하고, CustomBottomSheet·ChatInputBar·CommentRoot 등 공유 UI 컴포넌트를 확장하여 입력 포커스 추적, 동적 스타일링, 문맥별 렌더링을 지원합니다. RecordComment 컴포넌트는 댓글 목록, 입력 필드, 답글 기능, 키보드 높이 자동 조정을 구현하며, 더미 데이터로 댓글/대댓글을 제공합니다.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

💬 댓글이 흐르는 바텀시트 위로,
키보드 춤을 맞춰가며
답글 연쇄가 이어지고,
더미 데이터가 채워지니—
기록장의 목소리가 살아난다 🎉

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive 대부분의 변경사항은 댓글 바텀시트 구현과 관련된 범위 내이지만, 일부 스타일/구조 변경의 필요성 검토 필요합니다. RecordBookHeader 이동(layout.tsx → record-book-screen.tsx)과 상단 여백 조정(32→20)이 이슈 #57의 명시적 범위와의 관계를 확인해주세요.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경사항인 '기록장 댓글 바텀시트 컴포넌트'를 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 관련 이슈, 수행한 작업, 스크린샷을 포함한 템플릿의 필수 섹션을 모두 충족합니다.
Linked Issues check ✅ Passed RecordComment 바텀시트 구현, 키보드 대응, 엠티뷰, 컴포넌트 리팩토링 등 이슈 #57의 모든 코딩 요구사항을 충족합니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#57/record-comment-component

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
screens/record-book/components/record-comment/index.tsx (1)

19-30: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

P3: 바텀시트 재오픈 시 이전 입력/답글 상태가 남을 수 있어요

isVisiblefalse가 될 때 comment, replyCommentId, replyNickname, isInputFocus를 초기화하지 않아 이전 작성 컨텍스트가 다음 오픈에 이어질 수 있습니다. 닫힘 시점 reset 한 번만 넣으면 UX가 훨씬 안정적입니다.

예시 개선안
+ import { useEffect, useState } from "react";
...
+ useEffect(() => {
+   if (!isVisible) {
+     setComment("");
+     setReplyCommentId(null);
+     setReplyNickname("");
+     setIsInputFocus(false);
+   }
+ }, [isVisible]);

Also applies to: 58-66

🤖 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 `@screens/record-book/components/record-comment/index.tsx` around lines 19 -
30, When the RecordComment component's isVisible prop flips to false, the
previous draft and reply context remain; add a useEffect inside RecordComment
that watches isVisible and when it becomes false calls setComment(""),
setReplyCommentId(null), setReplyNickname(""), setIsInputFocus(false) (and any
other relevant reset like setInputBarHeight(0) if needed) to fully clear the
input state before the sheet is reopened; reference the RecordComment component
and the state setters (setComment, setReplyCommentId, setReplyNickname,
setIsInputFocus) to locate where to implement this reset.
🧹 Nitpick comments (1)
screens/record-book/components/record-comment/index.tsx (1)

31-117: ⚡ Quick win

P3: 상호작용 테스트 3가지만 추가하면 회귀 방어가 확 올라갑니다 🚀

기능 복잡도가 올라간 구간이라 아래 테스트를 추천합니다:

  1. 답글 선택 후 전송 시 targetName/reply 상태 초기화 확인
  2. isVisible false → true 전환 시 입력값/답글 상태 초기화 확인
  3. 포커스 변화(handleIsFocus)에 따라 container 높이 분기(0.7/0.93) 확인

As per coding guidelines 미작성한 테스트 코드 케이스가 있다면, 어떤 테스트가 필요한지 제안해주세요. (예: 컨트롤러는 E2E테스트, 나머지는 단위 테스트)

🤖 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 `@screens/record-book/components/record-comment/index.tsx` around lines 31 -
117, Add three tests: (1) unit test for RecordComment/handleSendText: simulate
selecting a reply via handlePressReply (set replyCommentId/replyNickname), type
a comment, call handleSendText and assert setComment becomes empty and
ChatInputBar receives targetName="" (reply cleared) and reply states reset; (2)
integration/unit test for visibility toggle: render the RecordComment component
with isVisible false → true and assert comment, replyCommentId, and
replyNickname are reset when isVisible becomes true (check ChatInputBar props
and internal states); (3) unit/test for layout behavior: simulate handleIsFocus
toggles (isInputFocus true/false) and assert CustomBottomSheet containerStyle
height equals height * 0.93 vs height * 0.7 respectively. Prefer unit tests for
ChatInputBar and CommentRoot/RecordComment logic; use an integration test for
the isVisible toggle to cover props/state interaction.
🤖 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 `@screens/record-book/components/record-comment/index.tsx`:
- Around line 47-50: handlePressReply currently only sets reply state
(setReplyCommentId, setReplyNickname) but doesn't ensure the target comment
stays visible when the keyboard opens; update handlePressReply to also call the
FlatList ref's scrollToIndex/scrollToOffset to bring the target comment into
view (use the same list ref used to render comments, compute the item's index
from the comments array or use getItemLayout for stable heights, and call
listRef.current?.scrollToIndex({ index, viewPosition: 0.3 }) with a try/catch
fallback to scrollToOffset if scrollToIndex fails); apply the same
visibility-scroll logic to the other reply entry path referenced in the
component so that both reply entry points guarantee the original comment is
visible.

---

Outside diff comments:
In `@screens/record-book/components/record-comment/index.tsx`:
- Around line 19-30: When the RecordComment component's isVisible prop flips to
false, the previous draft and reply context remain; add a useEffect inside
RecordComment that watches isVisible and when it becomes false calls
setComment(""), setReplyCommentId(null), setReplyNickname(""),
setIsInputFocus(false) (and any other relevant reset like setInputBarHeight(0)
if needed) to fully clear the input state before the sheet is reopened;
reference the RecordComment component and the state setters (setComment,
setReplyCommentId, setReplyNickname, setIsInputFocus) to locate where to
implement this reset.

---

Nitpick comments:
In `@screens/record-book/components/record-comment/index.tsx`:
- Around line 31-117: Add three tests: (1) unit test for
RecordComment/handleSendText: simulate selecting a reply via handlePressReply
(set replyCommentId/replyNickname), type a comment, call handleSendText and
assert setComment becomes empty and ChatInputBar receives targetName="" (reply
cleared) and reply states reset; (2) integration/unit test for visibility
toggle: render the RecordComment component with isVisible false → true and
assert comment, replyCommentId, and replyNickname are reset when isVisible
becomes true (check ChatInputBar props and internal states); (3) unit/test for
layout behavior: simulate handleIsFocus toggles (isInputFocus true/false) and
assert CustomBottomSheet containerStyle height equals height * 0.93 vs height *
0.7 respectively. Prefer unit tests for ChatInputBar and
CommentRoot/RecordComment logic; use an integration test for the isVisible
toggle to cover props/state interaction.
🪄 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: CHILL

Plan: Pro

Run ID: 6d9781ee-3ea4-48dd-b5d5-f44373f67ff5

📥 Commits

Reviewing files that changed from the base of the PR and between d567135 and b720a30.

📒 Files selected for processing (10)
  • app/record-book/_layout.tsx
  • screens/feed-detail/feed-detail-screen.tsx
  • screens/record-book/components/record-book-post-item/index.tsx
  • screens/record-book/components/record-book-top-tab-bar/index.tsx
  • screens/record-book/components/record-comment/index.tsx
  • screens/record-book/constants/index.ts
  • screens/record-book/record-book-screen.tsx
  • src/shared/ui/chat-input-bar/index.tsx
  • src/shared/ui/comment-list/comment-root.tsx
  • src/shared/ui/custom-bottom-sheet/index.tsx

Comment on lines +47 to +50
const handlePressReply = (commentId: number, replyNickname: string) => {
setReplyCommentId(commentId);
setReplyNickname(replyNickname);
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

P2: 답글 진입 시 대상 댓글 가시성 고정 로직이 빠져 있어요 (구현 방향은 아주 좋습니다 👏)

현재는 답글 대상 상태만 저장하고 있어, 키보드가 올라오면 원댓글이 화면 밖으로 밀릴 수 있습니다. 이 PR 목표(답글 시 관련 댓글 즉시 노출) 기준으로 FlatList ref + scrollToIndex/scrollToOffset 동작을 handlePressReply에 연결하는 쪽이 안전합니다. React Native FlatListscrollToIndex 문서 패턴을 그대로 가져오면 구현이 깔끔합니다.

예시 개선안
+ import { useRef } from "react";
+ import type { FlatList as RNFlatList } from "react-native";
...
+ const listRef = useRef<RNFlatList<CommentListType>>(null);

  const handlePressReply = (commentId: number, replyNickname: string) => {
    setReplyCommentId(commentId);
    setReplyNickname(replyNickname);
+   const index = DUMMY_RECORD_COMMENT_LIST.findIndex(
+     (item) => item.commentId === commentId,
+   );
+   if (index >= 0) {
+     listRef.current?.scrollToIndex({ index, animated: true, viewPosition: 0.2 });
+   }
  };
...
      <FlatList
+       ref={listRef}
        ...
      />

Also applies to: 76-92

🤖 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 `@screens/record-book/components/record-comment/index.tsx` around lines 47 -
50, handlePressReply currently only sets reply state (setReplyCommentId,
setReplyNickname) but doesn't ensure the target comment stays visible when the
keyboard opens; update handlePressReply to also call the FlatList ref's
scrollToIndex/scrollToOffset to bring the target comment into view (use the same
list ref used to render comments, compute the item's index from the comments
array or use getItemLayout for stable heights, and call
listRef.current?.scrollToIndex({ index, viewPosition: 0.3 }) with a try/catch
fallback to scrollToOffset if scrollToIndex fails); apply the same
visibility-scroll logic to the other reply entry path referenced in the
component so that both reply entry points guarantee the original comment is
visible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Add new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 기록장 댓글 바텀시트 컴포넌트

1 participant