Skip to content

[REFACTOR] 1차 QA#107

Merged
rbqks529 merged 16 commits intoTHIP-TextHip:developfrom
Nico1eKim:refactor/#101-qa
Aug 18, 2025
Merged

[REFACTOR] 1차 QA#107
rbqks529 merged 16 commits intoTHIP-TextHip:developfrom
Nico1eKim:refactor/#101-qa

Conversation

@Nico1eKim
Copy link
Member

@Nico1eKim Nico1eKim commented Aug 18, 2025

➕ 이슈 링크


🔎 작업 내용

  • 1차 QA 진행했습니다.
  • 피드, 피드 댓글, 기록장, 기록장 댓글, 진행중인 모임방 독서메이트 리스트 등에 위치하는 프로필 클릭 -> 해당 유저 피드 페이지로 이동하도록 수정
  • 기록장에서 기록 간 간격 수정
  • 피드 게시글 댓글 작성 시 textfield가 위로 올라오지 않는 문제 수정
  • 기록장 상단 메뉴탭 잘리는 문제 해결
  • 기록 생성 시 페이지 초과 시 뜨는 에러메시지가 잘리는 문제, 툴팁 경계에 선이 생기는 문제, 페이지 초과 에러 떴을 때 총평 토글 키면 에러 초기화 안되는 문제 해결
  • 댓글 작성 시 바텀시트 최상단이 위로 올라오지 않는 문제 해결
  • 오늘의 한마디 더보기 바텀시트에서 수정하기 메뉴 빼기
  • 진행중인 모임방에서 독서메이트 버튼 간격 수정

📸 스크린샷


😢 해결하지 못한 과제

  • 일단 제 파트 QA는 끝났는데 시간안에 못끝낼거같은거 있으면 빨리 말씀해주세요 후딱 끝내보겠습니다


📢 리뷰어들에게

  • 참고해야 할 사항들을 적어주세요

Summary by CodeRabbit

  • New Features
    • 피드/댓글/그룹노트/그룹룸 구성원 화면에서 프로필 영역을 탭해 사용자 프로필로 이동 가능.
    • 피드 댓글 화면에 하단 시트 액션(작성자: 수정 제거, 삭제 유지 / 비작성자: 신고) 및 삭제 확인 팝업·토스트 메시지 추가.
    • 프로필 바 요소 클릭 가능(Feed/Reply/Comment 카드 등), 저장한 피드 카드에도 프로필 탭 핸들러 추가.
  • Improvements
    • 책 페이지 입력 오류 상태를 명확히 표시(빨간 테두리·고정 에러 문구).
    • 댓글 화면에서 빈 공간 탭 시 키보드 숨김, 목록 구조 정리.
    • 하단 시트 높이 반응형(최대 화면 80%), 레이아웃 패딩·너비 제약으로 가독성 개선.

@coderabbitai
Copy link

coderabbitai bot commented Aug 18, 2025

Walkthrough

여러 데이터 모델에서 사용자/작성자 ID 타입을 Int→Long으로 확장하고, 프로필 클릭 네비게이션을 위해 다양한 UI 컴포저블과 화면에 onClick/onNavigate 콜백을 추가·전파했습니다. 댓글/피드/그룹 노트·룸 관련 화면과 네비게이션을 이에 맞게 재구성했으며, 입력 폼 에러 처리를 외부 제어 방식으로 변경했습니다.

Changes

Cohort / File(s) Change Summary
ID 타입 확장 (Int→Long)
.../data/model/comments/response/CommentsCreateResponse.kt, .../data/model/comments/response/CommentsResponse.kt, .../data/model/feed/response/AllFeedResponse.kt, .../data/model/feed/response/FeedDetailResponse.kt, .../data/model/rooms/response/RoomsPostsResponse.kt, .../data/model/rooms/response/RoomsUsersResponse.kt
creatorId/userId를 Int/Int?에서 Long/Long?으로 변경. 공개 데이터 클래스 시그니처 업데이트.
프로필 바/피드 헤더 업데이트
.../ui/common/header/ProfileBar.kt, .../ui/common/header/ProfileBarFeed.kt
ProfileBar: profileImage 타입 String→String? 변경. ProfileBarFeed: 상위 Row에 clickable 추가, onClick 콜백 공개 파라미터 추가.
댓글 컴포넌트에 프로필 클릭 전파
.../ui/group/note/component/CommentBottomSheet.kt, CommentItem.kt, CommentSection.kt, ReplyItem.kt
onProfileClick 콜백 추가 및 하위로 전파. 리스트/아이템에서 ProfileBarFeed의 클릭을 통해 호출. 레이아웃 일부(height→fillMaxHeight 비율) 조정.
그룹 노트 카드 컴포넌트
.../TextCommentCard.kt, .../VoteCommentCard.kt
onProfileClick 콜백 추가, ProfileBar에 onClick 연결. 프로필 이미지 소스 data.profileImageUrl 사용. 여백 일부 조정.
스크린: 피드/댓글/그룹 노트
.../ui/feed/screen/FeedScreen.kt, .../ui/feed/screen/FeedCommentScreen.kt, .../ui/group/note/screen/GroupNoteScreen.kt
onNavigateToUserProfile 콜백 추가 및 아이템/프로필 클릭 시 userId(Long)로 호출. FeedScreen에서 mySubscriptionViewModel 제거. 댓글 화면 레이아웃 재구성(LazyColumn/IME 패딩/하단 입력 필드/바텀시트/다이얼로그).
네비게이션 연결
.../ui/navigator/navigations/FeedNavigation.kt, .../ui/navigator/navigations/GroupNavigation.kt
onNavigateToUserProfile를 navController.navigateToUserProfile(userId)로 연결. 관련 import 추가. 일부 collectAsStateWithLifecycle 사용 제거.
그룹 룸: 멤버 클릭/레이아웃/메뉴
.../ui/group/room/component/GroupRoomMatesList.kt, .../ui/group/room/screen/GroupRoomMatesScreen.kt, .../ui/group/room/component/GroupRoomHeader.kt, .../ui/group/room/screen/GroupRoomChatScreen.kt
onUserClick 타입 Int→Long으로 변경 및 전파. 헤더에 widthIn 제약 추가, 아이콘 버튼 제거(주변 Column 클릭에 의존). 채팅 바텀시트에서 수정 항목 제거.
입력 폼 에러 외부 제어
.../ui/common/forms/BookPageTextField.kt, .../ui/group/note/component/PageInputSection.kt
BookPageTextField에 isError(Boolean) 공개 파라미터 추가 및 내부 상태 제거. PageInputSection에서 isError 계산해 전달. 에러 UI/문구 고정 처리.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant UI as ProfileBar/Feed Item/Comment
  participant Screen as Feed/FeedComment/GroupNote Screen
  participant Nav as Feed/Group Navigations
  participant NC as NavController
  participant UPS as UserProfileScreen

  User->>UI: 프로필 영역 탭
  UI->>Screen: onClick/onProfileClick(creatorId/userId: Long)
  Screen->>Nav: onNavigateToUserProfile(userId)
  Nav->>NC: navigateToUserProfile(userId)
  NC-->>UPS: Navigate
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

🎨 UI

Suggested reviewers

  • JJUYAAA
  • rbqks529

Poem

귀 쫑긋, 탭 한 번에 길이 열렸지요 🐇
Int는 좁다며 Long으로 훌쩍—쩜쩜쩜
프로필 따라 폴짝폴짝, 화면을 건너
댓글과 피드 사이, 당근빛 네비게이션 ✨
오류 테두리 붉게, 길 안내는 또렷하게!

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 Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 2

🔭 Outside diff range comments (3)
app/src/main/java/com/texthip/thip/ui/common/forms/BookPageTextField.kt (1)

43-50: BookPageTextField API 호환성 보장: isError에 기본값(false) 추가 필수

기존 호출부(PageInputSection.kt 및 자체 프리뷰)에서 isError를 전달하지 않아 빌드가 깨집니다. 하위 호환성을 위해 함수 시그니처를 아래처럼 수정하세요.

파일: app/src/main/java/com/texthip/thip/ui/common/forms/BookPageTextField.kt

 fun BookPageTextField(
     modifier: Modifier = Modifier,
     bookTotalPage: Int,
     enabled: Boolean = true,
     text: String,
-    isError: Boolean,
+    isError: Boolean = false,
     onValueChange: (String) -> Unit,
 )
  • 이 변경으로 기존 호출부는 기본값(false)을 사용하므로 별도 수정 없이 빌드가 유지됩니다.
  • 필요 시 특정 호출부에 대해 명시적 isError 값 전달 여부를 검토하세요.
app/src/main/java/com/texthip/thip/ui/group/note/component/TextCommentCard.kt (1)

43-49: isLocked 상태 변경 시 롱프레스 제스처가 갱신되지 않는 버그 가능성

pointerInput(Unit)은 키가 고정되어 있어 isLocked가 런타임에 변경돼도 제스처가 갱신되지 않습니다. 키를 isLocked로 변경해 주세요.

-            .pointerInput(Unit) {
+            .pointerInput(isLocked) {
                 if (!isLocked) {
                     detectTapGestures(onLongPress = { onLongPress() })
                 }
             }
app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt (1)

106-127: Preview 코드의 userId 리터럴을 Long 타입에 맞춰 수정해주세요

PostList.userIdLong으로 선언되어 있어, 현재 userId = 1(Int) 리터럴은 타입 불일치가 발생합니다. 아래 위치를 수정해 주세요.

• 파일: app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt
• 함수: VoteCommentCardPreview

@Preview
@Composable
private fun VoteCommentCardPreview() {
    VoteCommentCard(
        data = PostList(
            postId = 1,
            postType = "group",
            page = 132,
            postDate = "12시간 전",
            nickName = "user.01",
            profileImageUrl = "https://example.com/profile.jpg",
            content = "내 생각에 이 부분이 가장 어려운 것 같다. 비유도 난해하고 잘 이해가 가지 않는데 다른 메이트들은 어떻게 읽었나요?",
            likeCount = 123,
            commentCount = 123,
-           userId = 1,
+           userId = 1L,
            isLiked = true,
            isWriter = false,
            isLocked = false,
            isOverview = false,
            voteItems = emptyList()
        )
    )
}
🧹 Nitpick comments (29)
app/src/main/java/com/texthip/thip/ui/group/note/component/PageInputSection.kt (2)

46-52: 페이지 입력 경계값(1..bookTotalPage) 검증 보강 필요

현재는 bookTotalPage 초과만 오류 처리합니다. 0페이지(혹은 "000")도 허용되어 논리적으로 잘못된 값이 통과할 수 있습니다. 1 이상 bookTotalPage 이하 범위만 유효로 보도록 보강을 권장합니다. 공백 입력(trim)도 함께 처리하면 안전합니다.

아래와 같이 수정 제안드립니다:

-    val isError = remember(pageText, bookTotalPage, isGeneralReview) {
-        if (isGeneralReview) {
-            false
-        } else {
-            pageText.toIntOrNull()?.let { it > bookTotalPage } ?: false
-        }
-    }
+    val isError = remember(pageText, bookTotalPage, isGeneralReview) {
+        if (isGeneralReview) {
+            false
+        } else {
+            pageText.trim().toIntOrNull()?.let { it < 1 || it > bookTotalPage } ?: false
+        }
+    }

108-115: 토글 시 입력 상태(pageText) 변경 제거 고려

토글 시 pageText를 "전체 범위" 문자열 또는 ""로 바꾸면, 숫자만 유지돼야 할 상태에 비숫자 문자열이 섞이거나, 사용자가 입력하던 값을 잃습니다. 이미 TextField의 표시 텍스트는 isGeneralReview 조건으로 분기하고 있으므로, 상태 자체는 건드리지 않는 편이 깔끔합니다.

아래처럼 onPageTextChange 호출을 제거해도 UI 동작은 동일하며, 토글 해제 시 기존 입력이 그대로 복원됩니다.

-                    onToggleChange = { checked ->
-                        onGeneralReviewToggle(checked)
-                        onPageTextChange(if (checked) allRangeText else "")
-                    },
+                    onToggleChange = { checked ->
+                        onGeneralReviewToggle(checked)
+                    },
app/src/main/java/com/texthip/thip/ui/common/forms/BookPageTextField.kt (4)

69-76: 에러 시 커스텀 레드 보더 적용: OK. OutlinedTextField의 isError도 함께 전달 추천

커스텀 보더로 시각적 피드백은 충분합니다. 접근성/상태 일관성을 위해 OutlinedTextField의 isError 파라미터도 true로 넘기면 내부 semantics가 함께 반영됩니다.

예시:

OutlinedTextField(
    // ...
    isError = isError,
    // ...
)

92-103: 비활성 상태에서도 X 아이콘 클릭이 동작하여 텍스트가 지워짐

enabled=false(예: 전체리뷰)에서도 trailingIcon의 clickable이 활성이라 텍스트가 지워질 수 있습니다. 비활성 상태에서는 클릭을 막고, 시각적으로도 비활성 Tint를 주는 것을 권장합니다.

수정 예:

-                Icon(
+                Icon(
                     painter = painterResource(id = R.drawable.ic_x_circle_grey),
                     contentDescription = "Clear text",
-                    modifier = Modifier.clickable {
-                        if (text.isNotEmpty()) {
-                            onValueChange("")
-                        }
-                    },
-                    tint = Color.Unspecified
+                    modifier = if (enabled && text.isNotEmpty()) {
+                        Modifier.clickable { onValueChange("") }
+                    } else {
+                        Modifier
+                    },
+                    tint = if (enabled && text.isNotEmpty()) Color.Unspecified else colors.Grey02
                 )

94-96: 접근성 문자열 하드코딩(i18n) — stringResource로 변경 권장

contentDescription = "Clear text"는 현지화에서 누락됩니다. stringResource로 교체를 권장합니다.

예시:

contentDescription = stringResource(R.string.a11y_clear_text)

추가로 R.string.a11y_clear_text 리소스를 생성해 주세요.


106-114: 에러 메시지 고정 문구 단일화 — 상황별 메시지가 필요하면 파라미터화 고려

현 구현은 isError=true일 때 항상 error_page_over만 노출합니다. 추후 하한 위반(0 이하) 등 케이스를 구분하려면, 에러 메시지를 호출부에서 주입하도록 파라미터화를 고려해도 좋습니다(기본값 유지).

예시 시그니처:

fun BookPageTextField(
    // ...
    isError: Boolean = false,
    errorMessageRes: Int = R.string.error_page_over,
    onValueChange: (String) -> Unit,
)
app/src/main/java/com/texthip/thip/data/model/comments/response/CommentsCreateResponse.kt (1)

8-8: creatorId: Long?로 확장 — null 처리 경계 케이스 점검 권장

  • 타입 확장은 적절합니다. 다만 nullable 유지로 인해 UI/도메인에서 해당 값에 의존하는 로직이 있다면 안전 호출/대체값 처리가 보장되는지 확인해 주세요. 특히 프로필 이동(onProfileClick) 경로에서 null 전달 가능성 고려가 필요합니다.
  • 동 모델군(CommentsResponse의 CommentList/ReplyList 등)과 nullability 일관성도 검토해 주세요. 서버 계약이 “항상 제공”이라면 non-null로 정리하는 방안도 고려할 수 있습니다.
app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsUsersResponse.kt (1)

12-12: UserList.userId Long 전환 OK — 공통 UserId 타입 도입 고려(선택)

ID 타입 확장이 여러 계층과 파일에 걸쳐 반복되고 있어, 다음 중 하나로 공통 타입을 도입하면 유지보수성이 좋아집니다.

  • 간단: typealias
typealias UserId = Long
  • 더 견고: Inline value class
@JvmInline
value class UserId(val value: Long)

후자를 쓰면 오용 방지에 유리하며, Nav/Serialization/DB 경계에서의 변환 위치가 명확해집니다. 적용은 선택 사항입니다.

app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomHeader.kt (2)

120-123: 참여자 섹션을 Column 클릭으로 합친 변경 OK. 접근성 Role 부여 권장

컬럼 전체를 클릭 타깃으로 확대한 점은 터치 영역 측면에서 긍정적입니다. 스크린리더에서 버튼으로 인지되도록 Role을 부여하면 더 좋습니다.

아래처럼 semantics를 추가해 주세요:

                 modifier = Modifier
                     .widthIn(max = 180.dp)
-                    .clickable { onNavigateToMates() }
+                    .semantics { role = Role.Button }
+                    .clickable { onNavigateToMates() }

추가로 필요한 import:

import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.semantics

144-148: Chevron 아이콘은 장식용 → contentDescription null 권장

컬럼 전체에 클릭이 걸려있어 아이콘 자체의 설명은 중복 낭독될 수 있습니다. 장식용이면 null로 비워 주세요.

-                    Icon(
-                        painter = painterResource(R.drawable.ic_chevron),
-                        contentDescription = "Participant Icon",
-                        tint = colors.White
-                    )
+                    Icon(
+                        painter = painterResource(R.drawable.ic_chevron),
+                        contentDescription = null,
+                        tint = colors.White
+                    )
app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomMatesList.kt (2)

29-46: 길어질 수 있는 목록은 LazyColumn + key 사용을 고려

현재 Column + forEachIndexed는 항목이 많아지면 재구성/측정 비용이 커질 수 있습니다. LazyColumn과 key(member.userId)를 사용하면 성능과 상태 보존에 유리합니다.

예시:

LazyColumn(
  verticalArrangement = Arrangement.spacedBy(16.dp),
  modifier = Modifier.fillMaxWidth().padding(20.dp)
) {
  itemsIndexed(members.userList, key = { _, m -> m.userId }) { index, member ->
    ProfileBar(/* ... */) { onUserClick(member.userId) }
    if (index != members.userList.lastIndex) {
      HorizontalDivider(color = colors.DarkGrey02, thickness = 1.dp)
    }
  }
}

58-67: 미세: Preview의 userId 리터럴은 1L/2L로 표기하면 가독성↑

타입 추론상 문제는 없지만, Long임을 명시하면 독자에게 의도가 더 분명해집니다.

app/src/main/java/com/texthip/thip/ui/group/note/component/CommentItem.kt (2)

59-61: 불필요한 단독 식(‘data’) 제거 권장

해당 줄은 부수효과 없이 값만 평가되는 식으로 보이며 혼동을 줄 수 있습니다. 삭제해 주세요.

-                data

54-56: long-press 제스처는 combinedClickable로 일원화하면 접근성/충돌 면에서 안전

pointerInput+detectTapGestures는 하위 clickable과 이벤트 소비 충돌이 발생할 수 있고, 접근성 속성도 자동 부여되지 않습니다. combinedClickable을 권장합니다.

-            Column(
-                modifier = modifier.pointerInput(Unit) {
-                    detectTapGestures(onLongPress = { onLongPress() })
-                },
+            Column(
+                modifier = modifier.combinedClickable(
+                    onLongClick = onLongPress,
+                    onClick = { /* no-op: 하위 요소에 위임 */ }
+                ),

필요 import:

import androidx.compose.foundation.combinedClickable
app/src/main/java/com/texthip/thip/ui/mypage/component/SavedFeedCard.kt (1)

51-53: 기본 프로필 이미지에 외부 URL 하드코딩은 지양 권장

실행 환경에서 null일 때 example.com으로 네트워크 요청이 나갈 수 있습니다. ProfileBar 내부에서 placeholder 처리(리소스/로컬 디폴트)하거나 null을 그대로 넘기고 내부에서 Coil placeholder로 대응하는 쪽이 안전합니다.

예:

ProfileBar(
  profileImage = feedItem.userProfileImage, // null 허용
  /* ... */
)
app/src/main/java/com/texthip/thip/ui/group/note/component/ReplyItem.kt (1)

68-70: 상위 onLongPress(pointerInput)와 하위 clickable 간 제스처 충돌 가능성 점검

상위 Column의 detectTapGestures(onLongPress)가 포인터 이벤트를 선점하면, 자식 ProfileBarFeed.clickable이 간헐적으로 동작하지 않을 수 있습니다. 실제 단말에서 프로필 클릭이 항상 인식되는지 확인해 주세요. 필요 시 onLongPress 범위를 아래 내용 영역(Row)로 한정하거나 combinedClickable(onLongClick = ...)로 대체하는 방안을 고려해볼 수 있습니다.

app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarFeed.kt (1)

38-41: 접근성 라벨 추가 제안

스크린 리더 안내를 위해 클릭 라벨을 부여하는 것을 권장합니다. 예: clickable(onClickLabel = stringResource(R.string.navigate_to_profile)) { onClick() }

app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomMatesScreen.kt (1)

96-125: Preview에서 Long 리터럴 표기 명확화 제안

userId = 1은 컴파일상 문제는 없지만(필드가 Long이어도 상수 추론), 가독성을 위해 1L로 표기하면 타입 의도가 더 분명합니다.

-                        userId = 1,
+                        userId = 1L,
...
-                        userId = 2,
+                        userId = 2L,
app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt (2)

55-57: 네비게이션 호출 방식 통일 제안

여기는 직접 navigate(FeedRoutes.Others(userId))를 사용 중입니다. 확장 함수 navigateToUserProfile(userId)로 통일하면 라우트 포맷 변경 시 단일 진입점만 수정하면 되어 리스크가 줄어듭니다.

-            onNavigateToUserProfile = { userId ->
-                navController.navigate(FeedRoutes.Others(userId))
-            }
+            onNavigateToUserProfile = { userId ->
+                navController.navigateToUserProfile(userId)
+            }

122-125: Comment 라우트에서도 toRoute 사용 고려

Write와 동일하게 toRoute<FeedRoutes.Comment>()를 사용하면 인자 키 의존을 제거하고 타입 안정성을 높일 수 있습니다.

-        val route = backStackEntry.arguments?.let {
-            FeedRoutes.Comment(it.getInt("feedId"))
-        } ?: return@composable
+        val route = backStackEntry.toRoute<FeedRoutes.Comment>()
app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (1)

47-53: null 이미지 대비 placeholder/error/fallback 처리를 권장합니다

profileImage가 null이거나 잘못된 URL일 때의 UI 폴백을 지정하면 사용자 경험이 좋아집니다. 접근성 측면에서 contentDescription도 stringResource로의 치환을 고려해주세요.

-        AsyncImage(
-            model = profileImage,
-            contentDescription = "프로필 이미지",
-            modifier = Modifier
-                .size(36.dp)
-                .clip(CircleShape)
-        )
+        AsyncImage(
+            model = profileImage,
+            contentDescription = stringResource(R.string.profile_image_content_description),
+            modifier = Modifier
+                .size(36.dp)
+                .clip(CircleShape),
+            // Coil 2.x API: 필요 시 crossfade 등도 고려
+            // placeholder = painterResource(R.drawable.ic_default_avatar),
+            // error = painterResource(R.drawable.ic_default_avatar),
+            // fallback = painterResource(R.drawable.ic_default_avatar),
+        )

참고: 위 리소스 ID들은 프로젝트 내 존재 여부에 따라 적절히 치환해주세요.

app/src/main/java/com/texthip/thip/ui/group/note/component/CommentBottomSheet.kt (1)

73-75: 중첩된 fillMaxHeight(0.8f)로 인한 이중 제약 가능성

바깥 Column에 .fillMaxHeight(0.8f)가 적용된 상태에서, 내부 스크롤 컨테이너 쪽 Column도 .fillMaxHeight(0.8f)를 적용하고 있습니다. 현재는 동작하더라도, 부모/자식 간 높이 계산이 이중으로 적용되어 의도치 않은 공간 축소가 발생할 수 있습니다. 내부 Column에는 weight(1f)만 유지하고 fillMaxHeight는 제거하는 구성을 권장합니다.

Also applies to: 79-80

app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt (2)

31-31: onProfileClick 콜백 추가는 적절하지만, userId를 인자로 받는 형태를 권장

상위에서 캡처 클로저로 구현할 수 있으나, 다른 컴포넌트(CommentSection 등)와 API 일관성을 위해 (userId: Long) -> Unit 형태로 맞추면 사용성이 좋아집니다.

-    onProfileClick: () -> Unit = {}
+    onProfileClick: (userId: Long) -> Unit = {}

56-63: ProfileBar 바인딩 개선: 이미지/시간/클릭 연결 LGTM

  • profileImage = data.profileImageUrl로 실제 데이터 바인딩한 점 좋습니다.
  • hoursAgo = data.postDate도 자연스러운 연결입니다.
  • onClick으로 프로필 이동 트리거 연결도 적절합니다.

다만 위에서 제안한 대로 onProfileClick 시그니처를 (Long) -> Unit으로 바꾸는 경우, 아래처럼 호출하는 편이 일관됩니다.

-            onClick = onProfileClick
+            onClick = { onProfileClick(data.userId) }
app/src/main/java/com/texthip/thip/ui/group/note/screen/GroupNoteScreen.kt (1)

439-445: 하드코딩된 레이아웃 상수화 제안(120.dp, 76.dp)

상단 고정 영역과 오버레이 높이가 매직 넘버로 산재해 있어 유지보수에 불리합니다. 파일 상단(또는 companion object)에 상수로 분리하면 의도 전달과 테마 연계가 좋아집니다.

아래와 같이 치환을 권장합니다:

-                        .padding(top = 120.dp)
+                        .padding(top = FilterAreaTopPadding)
...
-                            .height(76.dp)
+                            .height(FilterAreaHeight)

파일 내 상단(또는 적절한 스코프)에 다음을 추가:

private val FilterAreaTopPadding = 120.dp
private val FilterAreaHeight = 76.dp
app/src/main/java/com/texthip/thip/ui/feed/screen/FeedCommentScreen.kt (4)

137-141: 루트 컨테이너에 advancedImePadding 적용 OK

루트 박스에서 안전영역을 보장해 입력창이 가려지지 않습니다. 필요 시 systemBarsPadding과의 조합도 고려해 볼 수 있습니다.


175-183: ProfileBar에 프로필 네비게이션 연결 OK, 프로필 이미지 null 처리 제안

현재 profileImage = feedDetail.creatorProfileImageUrl ?: ""로 빈 문자열을 전달합니다. ProfileBarString?를 받으므로 null을 그대로 전달해 불필요한 이미지 로딩 시도를 피하는 편이 낫습니다.

다음 변경을 권장합니다:

-                                profileImage = feedDetail.creatorProfileImageUrl ?: "",
+                                profileImage = feedDetail.creatorProfileImageUrl,

204-225: 이미지 리스트 뷰어 연결 OK, 접근성 텍스트(nit) 고려

contentDescription = null은 스크린리더 무시를 의미합니다. 접근성 필요 시 간단한 설명을 추가하는 것을 고려해 주세요(예: “피드 이미지 1/3”).


355-393: 바텀시트 항목 클릭 시 중복 상태 변경(nit)

각 항목 onClick에서 isBottomSheetVisible = false를 설정하고, 동시에 MenuBottomSheetonDismiss에서도 동일 처리를 하고 있어 중복입니다. 하나로 일원화하면 코드가 간결해집니다.

-                        onClick = {
-                            isBottomSheetVisible = false
-                            onNavigateToFeedEdit(feedDetail.feedId)
-                        }
+                        onClick = {
+                            onNavigateToFeedEdit(feedDetail.feedId)
+                        }

onDismiss = { isBottomSheetVisible = false } 유지

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 359f86a and 5a598ec.

📒 Files selected for processing (26)
  • app/src/main/java/com/texthip/thip/data/model/comments/response/CommentsCreateResponse.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/data/model/comments/response/CommentsResponse.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/data/model/feed/response/AllFeedResponse.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/data/model/feed/response/FeedDetailResponse.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsPostsResponse.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsUsersResponse.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/forms/BookPageTextField.kt (3 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarFeed.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/feed/screen/FeedCommentScreen.kt (3 hunks)
  • app/src/main/java/com/texthip/thip/ui/feed/screen/FeedScreen.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/CommentBottomSheet.kt (5 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/CommentItem.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/CommentSection.kt (3 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/PageInputSection.kt (3 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/ReplyItem.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/TextCommentCard.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/screen/GroupNoteScreen.kt (8 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomHeader.kt (4 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomMatesList.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomChatScreen.kt (0 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomMatesScreen.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/mypage/component/SavedFeedCard.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt (3 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt (13 hunks)
💤 Files with no reviewable changes (1)
  • app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomChatScreen.kt
🧰 Additional context used
🧬 Code Graph Analysis (4)
app/src/main/java/com/texthip/thip/ui/group/note/component/TextCommentCard.kt (1)
app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (1)
  • ProfileBar (29-101)
app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt (1)
app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (1)
  • ProfileBar (29-101)
app/src/main/java/com/texthip/thip/ui/feed/screen/FeedCommentScreen.kt (6)
app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt (1)
  • DefaultTopAppBar (22-69)
app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (1)
  • ProfileBar (29-101)
app/src/main/java/com/texthip/thip/ui/group/note/component/CommentSection.kt (1)
  • CommentSection (19-87)
app/src/main/java/com/texthip/thip/ui/common/forms/CommentTextField.kt (1)
  • CommentTextField (42-152)
app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (1)
  • DialogPopup (22-71)
app/src/main/java/com/texthip/thip/ui/feed/component/ImageViewerModal.kt (1)
  • ImageViewerModal (32-120)
app/src/main/java/com/texthip/thip/ui/group/note/screen/GroupNoteScreen.kt (1)
app/src/main/java/com/texthip/thip/ui/common/buttons/FilterButton.kt (1)
  • FilterButton (37-128)
🔇 Additional comments (46)
app/src/main/java/com/texthip/thip/ui/group/note/component/PageInputSection.kt (1)

74-76: 외부 에러 플래그 연동: 방향성 좋습니다

BookPageTextField에 isError를 직접 주입하면서 enabled와 결합한 제어가 명확해졌습니다. "전체리뷰" 토글 시 오류가 즉시 해제되는 PR 목적과도 일치합니다.

app/src/main/java/com/texthip/thip/ui/common/forms/BookPageTextField.kt (1)

157-159: 프리뷰 업데이트 LGTM

새 파라미터(isError=false) 반영이 적절합니다.

app/src/main/java/com/texthip/thip/data/model/feed/response/FeedDetailResponse.kt (1)

9-9: FeedDetailResponse.creatorId Long 전환 OK — 내비게이션 인자 타입 일치 확인

UI에서 프로필 클릭 시 전달되는 userId/creatorId가 NavGraph에서 NavType.LongType으로 선언되어 있어야 런타임 타입 불일치가 없습니다. 위 파일에서 제안한 스크립트의 NavType 검사로 함께 확인 부탁드립니다.

app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsPostsResponse.kt (1)

21-21: PostList.userId Long 전환 OK — 리스트 키/정렬/비교 로직 영향 확인

  • DiffUtil 키, stable key, 정렬/그룹핑(예: userId 기준) 로직에서 Int 전제나 toInt() 변환이 남아있지 않은지 점검 부탁드립니다.
  • 내비게이션(onUserClick) 시그니처가 Long으로 통일되었다면 런타임 불일치는 없을 것입니다.
app/src/main/java/com/texthip/thip/data/model/comments/response/CommentsResponse.kt (1)

33-34: ReplyList.creatorId가 비-null(Long)로 강화됨 — 서버 응답과의 계약 재확인 권장

이 필드가 서버에서 항상 내려온다는 보장이 없다면 역직렬화 실패 위험이 있습니다. API 계약이 확실히 non-null이라면 그대로 유지하시고, 아니라면 Long?로의 완화나 디폴트값 설계를 검토해 주세요.

app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomHeader.kt (1)

90-92: widthIn 도입으로 레이아웃 안정성 개선 LGTM

180.dp 상한으로 정보 블록 폭을 고정해 오버플로우를 방지하는 접근이 이번 PR 목표(여백/정렬 보정)에 부합합니다.

app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomMatesList.kt (1)

21-22: onUserClick의 Long 시그니처 전파 LGTM

데이터 모델(RoomsUsersResponse.userId: Long)에 맞춰 콜백 타입을 Long으로 확장한 점 일관적입니다. GroupRoomMatesScreen 등 상위 호출부도 동일 시그니처로 맞춘 것으로 보입니다.

app/src/main/java/com/texthip/thip/ui/group/note/component/CommentItem.kt (1)

39-40: 프로필 클릭 핸들러 추가 및 ProfileBarFeed 와이어링 적절

onProfileClick을 시그니처에 추가하고 ProfileBarFeed의 onClick으로 연결한 변경이 네비게이션 전파 패턴과 일관적입니다. postDate의 null 가드 처리도 OK.

Also applies to: 65-67

app/src/main/java/com/texthip/thip/ui/mypage/component/SavedFeedCard.kt (1)

40-42: 프로필 클릭 콜백 추가 및 ProfileBar 연동 LGTM

마이페이지 저장 피드 카드에서도 프로필 탭을 외부로 전파하도록 한 점이 전체 네비게이션 흐름과 잘 맞습니다. hoursAgo 전달도 무난합니다.

Also applies to: 57-59

app/src/main/java/com/texthip/thip/ui/group/note/component/ReplyItem.kt (2)

41-41: 프로필 클릭 콜백 추가·전달 LGTM

기존 호출부와의 호환성을 유지하는 디폴트 람다와 함께 ProfileBarFeed로 깔끔히 전달되었습니다.


68-68: date 문자열 포맷 일관성 확인 요청

여기서는 data.postDate가 그대로 표시됩니다. 다른 화면(TextCommentCard 등)에서는 “N시간 전” 형태가 사용됩니다. 서버 ISO 형태가 올 수 있는 경우(Preview 참고) 사용자 노출 전에 상위에서 포맷팅이 보장되는지 확인 부탁드립니다.

app/src/main/java/com/texthip/thip/ui/group/note/component/TextCommentCard.kt (3)

29-31: 프로필 클릭 콜백 추가 LGTM

상위에서 post.userId를 캡처하여 네비게이션으로 연결하기 용이한 구조입니다. 기본값 유지로 기존 호출부 영향도 없습니다.


53-61: ProfileBar 바인딩(이미지/시간/클릭) 정리 좋습니다

  • profileImage = data.profileImageUrl로 데이터 사용 일관화
  • hoursAgo = data.postDate 매핑
  • onClick = onProfileClick 전달
    호출/표시 책임이 명확합니다.

49-49: 상단 패딩 증대(40dp) 영향 범위 확인

리스트 아이템 간 수직 리듬/스크롤 위치 계산(예: 스티키 헤더 간격)에 영향이 없는지 화면 단에서 한 번 확인 부탁드립니다.

app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarFeed.kt (1)

35-36: Row clickable 도입 및 콜백 공개 LGTM

타입/디폴트 처리로 기존 호출부 안전하며, 전체 Row 클릭 영역화로 UX도 일관됩니다.

Also applies to: 38-41

app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomMatesScreen.kt (1)

33-34: userId 콜백 타입 Long 전환 LGTM

도메인 전반의 ID Long 확장과 일치하며, 리스트→화면→네비게이션으로 콜백이 잘 전파됩니다.

Also applies to: 72-73

app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt (2)

45-47: Feed 목록에서 프로필 네비게이션 배선 LGTM

onNavigateToUserProfilenavigateToUserProfile(userId)로 연결하여 확장 함수 경로를 일관되게 사용한 점 좋습니다.


134-136: 댓글 화면에서 프로필 네비게이션 배선 LGTM

FeedCommentScreen에서도 동일한 경로로 통일되어 유지보수성에 이점이 있습니다.

app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (1)

32-32: profileImage를 nullable로 확장한 변경은 합리적입니다

Coil AsyncImage가 null model을 허용하므로 NPE 위험을 줄이고, 콜사이트에서 값이 없을 수 있는 상황을 안전하게 처리할 수 있습니다. 콜사이트 타입 일관성만 확인하면 됩니다.

app/src/main/java/com/texthip/thip/ui/group/note/component/CommentBottomSheet.kt (4)

48-50: 댓글 전송 시 replyToNickname 추가 전파: OK

onSendReply에 replyToNickname까지 전달하도록 확장한 점 좋습니다. 기본 동작(backfill)도 유지되어 호환성 문제가 없겠습니다.


73-75: 고정 높이에서 비율 기반으로 전환: 사용자 환경 개선에 긍정적

.sheet 영역을 0.8f 비율로 전환하여 다양한 디바이스/키보드 상황에서 레이아웃 적응성이 좋아집니다.


113-115: 프로필 클릭 콜백 전파 제대로 연결됨

리스트 아이템에서 프로필 클릭 시 외부 핸들러로 userId를 전달할 수 있도록 잘 배선되었습니다.


202-204: CommentLazyList의 onProfileClick API 추가: 일관성 OK

상위에서 받은 onProfileClick을 섹션/아이템으로 전파하는 구조가 명확합니다. 이후 호출부에서 Long ID 타입 전달 일관성만 확인하면 됩니다.

app/src/main/java/com/texthip/thip/ui/group/note/component/CommentSection.kt (4)

26-27: onProfileClick(userId: Long) 도입 타당

댓글/답글에서 프로필 탭을 통한 네비게이션 요구사항을 충족하는 API 확장입니다. 기본값도 제공되어 기존 호출부와의 호환성에 문제 없어 보입니다.


57-59: 댓글의 작성자 ID null-safety 처리 적절

commentItem.creatorId?.let { onProfileClick(it) }로 안전하게 처리했습니다. 데이터 모델 상 nullable일 수 있는 경우에 대한 방어가 되어 있습니다.


20-30: 파라미터 순서 변경에 따른 호출부 확인 요청

CommentSectiononProfileClick 파라미터가 actionMode 앞에 중간 삽입되어, 위치 기반 인자로 호출하는 경우 컴파일 오류가 발생할 수 있습니다. 전체 호출부를 아래 스크립트로 확인하고, named argument를 모두 사용하고 있는지 수동으로 검증해주세요.

  • 실행 스크립트:
    #!/bin/bash
    # CommentSection 호출부 전체를 출력합니다.
    rg -nP '\bCommentSection\s*\(' -n --type-add 'kt:*.kt'
  • 출력된 각 호출부에서 모든 인자를 named argument 형태로 사용하고 있는지 수동 점검
    (예: commentItem = ..., onProfileClick = ... 등)

78-79: Reply.creatorId는 non-nullable이며 추가 null 체크 불필요합니다

ReplyList.creatorIdCommentList.creatorIdLong(non-nullable)로 정의되어 있고, CommentSectiononProfileClick 시그니처도 (Long) -> Unit이기 때문에
기존 호출

onProfileClick = { onProfileClick(reply.creatorId) }

은 안전합니다. 제안되었던 null-safe 래핑(?.let { … })은 불필요하므로 제거해 주세요.

app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt (3)

47-47: User Profile 네비게이션 익스텐션 import 추가: OK

해당 import로 하위 화면에서 프로필로의 라우팅을 통합할 수 있어 가독성과 재사용성이 좋아집니다.


356-358: GroupNoteScreen의 onNavigateToUserProfile → 프로필 네비게이션 연결: OK, 다만 타입 확인

위와 동일하게 userId 파라미터 타입이 GroupNoteScreen, navigateToUserProfile, 데이터 모델(Post/Comment 등) 전반에서 일치하는지 확인해 주세요.


299-301: GroupRoomMatesScreen의 onUserClick → 프로필 네비게이션 타입 일관성 확인 요청

  • 위치: app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt (299–301행)
        onUserClick = { userId ->
            navController.navigateToUserProfile(userId)
        }
  • 문제: onUserClick 파라미터는 (Long) → Unit으로 정의되어 있으나, navigateToUserProfile 확장 함수/메서드의 시그니처가 Long을 받는지 확인되지 않습니다.
  • 조치:
    1. 코드베이스에서 fun NavController.navigateToUserProfile(...) 정의를 찾아, 파라미터 타입이 Long인지 String인지 검증
    2. 타입이 혼재할 경우 전역적으로 Long으로 통일하거나, Long/String 오버로드(또는 적절한 변환 로직)를 제공하도록 개선
app/src/main/java/com/texthip/thip/ui/group/note/screen/GroupNoteScreen.kt (5)

82-82: 프로필 네비게이션 콜백 추가 및 전달: API 안정성과 사용성에 유리합니다

  • onNavigateToUserProfile: (Long) -> Unit = {} 기본값 제공으로 기존 호출부 호환성 유지
  • GroupNoteContent로의 전파와 카드(onProfileClick)에서의 사용까지 일관성 있게 연결되어 있습니다

Also applies to: 157-157, 170-170


449-452: FilterButton 하단 패딩 추가는 UX에 긍정적입니다

드롭다운과 주변 요소 간 간격이 개선되어 터치 영역 및 가독성이 좋아졌습니다.


522-524: 댓글 바텀시트에서도 프로필 네비게이션 일관 적용 OK

댓글/답글 영역에서의 onProfileClick 전달이 FeedCommentScreen과 패턴 일치합니다.


653-655: 프리뷰 파라미터 추가 OK, 다만 userId 타입 호환성 확인 필요

프리뷰에서 onNavigateToUserProfile 인자 제공으로 컴파일 안정성이 유지됩니다. 같은 프리뷰 블록 내 PostList의 userId 리터럴이 Long 타입이라면 1L로 표기되어야 합니다(모델이 Long일 경우).

프리뷰의 PostList(userId = 1, ...)가 Long 타입이라면 다음과 같이 수정이 필요합니다:

- userId = 1,
+ userId = 1L,

394-398: 프로필 클릭 네비게이션: 타입 일치 확인 완료

  • app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsPostsResponse.kt:21 에서 val userId: Long으로 선언되어 있어
    post.userId를 넘기는 네비게이션 호출 시 타입이 일치합니다.
  • TextCommentCard.kt(30), VoteCommentCard.kt(31) 컴포넌트의 onProfileClick: () -> Unit 시그니처는
    클로저로 캡처된 post.userId를 호출하는 형태로 올바르게 구현되어 있습니다.

추가 수정사항 없이 머지 가능합니다.

app/src/main/java/com/texthip/thip/ui/feed/screen/FeedScreen.kt (2)

70-70: onNavigateToUserProfile 콜백 추가로 API 확장성 확보

기본값을 제공해 호출부 호환성을 지키면서도 프로필 네비게이션을 외부로 노출한 점 좋습니다.


352-356: SavedFeedCard의 프로필 클릭 → 사용자 프로필 네비게이션 연결 OK

allFeed.creatorId를 그대로 전달하여 ID 타입 정합성과 네비게이션 의도가 명확합니다.

app/src/main/java/com/texthip/thip/ui/feed/screen/FeedCommentScreen.kt (9)

61-61: IME 대응 패딩(advancedImePadding) 도입 적절

키보드 표시 시 입력창/내용 가림 이슈에 대한 명확한 해결입니다.


70-70: 프로필 네비게이션 콜백 도입으로 상단 프로필/댓글 프로필 전반 일관성 확보

외부 네비게이션에 위임하는 구조가 재사용/테스트에 유리합니다.


143-156: 바깥 터치 시 키보드 숨김 및 선택 해제 로직 적절

pointerInput + detectTapGestures로 포커스/선택 상태 초기화가 명확합니다. 스크롤 제스처와의 충돌도 없어 보입니다.


246-257: 댓글 로딩 상태 처리 LGTM

상태 분기와 인디케이터 표기가 명확합니다.


259-281: 댓글 없음 상태 UX 명확

제목/서브텍스트로 의도 전달이 명확합니다.


284-309: CommentSection에 onProfileClick 전파 일관 적용 OK

댓글/답글에서 사용자 프로필로 진입 경로가 확보되어 기대 동작과 일치합니다.


315-340: 댓글 입력/답글 워크플로 완성도 좋음

  • replyingToCommentId/nickname 상태 관리와 전송 후 초기화 흐름이 자연스럽습니다.
  • IME 포커스 해제 타이밍도 적절합니다.

396-417: 외부 영역 클릭으로 다이얼로그 닫기 UX 적용 OK

오버레이에 clickable을 부여해 외곽 터치 시 닫히는 패턴이 일관됩니다. 스크롤/터치 이벤트 전파 차단도 적절합니다.


426-432: 이미지 뷰어 모달 연결 OK

상단 이미지 리스트와 동일한 take(3)를 사용해 인덱스 정합성 문제가 없습니다. 추후 전체 이미지 보기 요구가 있다면 take(3) → 전체 리스트로 확장만 검토하시면 됩니다.

필요 시 전체 이미지 뷰 지원으로 확장할지 확인 부탁드립니다.

Comment on lines +15 to 16
val creatorId: Long?,
val creatorProfileImageUrl: String?,
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

ID Int→Long 전환은 방향성 OK. 잔존 Int 참조/캐스팅 흔적 점검 제안

모델의 ID 타입 확장은 합리적입니다. 다만 호출부·콜백·네비게이션 파라미터에서 Int 시그니처가 남아 있거나 toInt()/toLong() 캐스팅으로 임시 대응한 곳이 없는지 확인 부탁드립니다. 아래 스크립트로 빠르게 훑어볼 수 있어요.

Also applies to: 33-34


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) 남아있는 Int 타입 ID 필드 검색 (userId/creatorId)..."
rg -nP --type=kt -C2 '\b(creatorId|userId)\s*:\s*Int\??\b' || true

echo "2) 사용자 프로필 네비게이션 콜백이 Int를 받는 곳 검색..."
rg -nP --type=kt -C2 '\b(onNavigateToUserProfile|onUserClick|onProfileClick)\s*:\s*\(\s*Int\??\s*\)\s*->' || true

echo "3) ID 변환 캐스팅 흔적 검색(.toInt()/.toLong())..."
rg -nP --type=kt -C2 '\.(toInt|toLong)\s*\(' || true

echo "4) GroupRoomMatesList 호출부 점검"
rg -nP --type=kt -C3 'GroupRoomMatesList\s*\(' || true

Length of output: 764


추가 검증: .kt 파일 전체에서 Int → Long 변경 후 남아있는 Int 참조 및 캐스팅 여부 재검색


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "1) 남아있는 Int 타입 ID 필드 검색 (creatorId/userId)..."
rg -g '*.kt' -nP -C2 '\b(creatorId|userId)\s*:\s*Int\??\b' || true

echo "2) 네비게이션/콜백에서 Int 파라미터 사용 검색 (onNavigateToUserProfile/onUserClick/onProfileClick)..."
rg -g '*.kt' -nP -C2 '\b(onNavigateToUserProfile|onUserClick|onProfileClick)\s*\(\s*Int\??\s*\)' || true

echo "3) ID 변환 캐스팅 흔적 검색 (.toInt()/.toLong())..."
rg -g '*.kt' -nP -C2 '\.(toInt|toLong)\s*\(' || true

echo "4) GroupRoomMatesList 호출부 점검..."
rg -g '*.kt' -nP -C3 'GroupRoomMatesList\s*\(' || true

Length of output: 13674


ID 타입 확장(Int→Long) 추가 반영 필요
모델·콜백·호출부에 여전히 Int 필드 및 .toLong() 캐스팅이 남아 있어, 일관된 Long 시그니처로 변경하고 불필요한 캐스팅을 제거해주세요.

점검 대상 파일 및 필드:

  • app/src/main/java/com/texthip/thip/data/model/users/response/UserSearchResponse.kt
    @SerializedName("userId") val userId: IntLong
  • app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsDailyGreetingResponse.kt
    val attendanceCheckId: Int, val creatorId: IntLong
  • app/src/main/java/com/texthip/thip/data/model/feed/response/RelatedBooksResponse.kt
    @SerialName("feedId") val feedId: Int, @SerialName("creatorId") val creatorId: IntLong
  • app/src/main/java/com/texthip/thip/data/model/feed/response/FeedUsersInfoResponse.kt
    val creatorId: IntLong
  • app/src/main/java/com/texthip/thip/data/model/feed/response/FeedMineInfoResponse.kt
    @SerialName("creatorId") val creatorId: IntLong
  • app/src/main/java/com/texthip/thip/data/model/comments/response/CommentsResponse.kt (15–16, 33–34)
    val creatorId: Int?, val replyId: Int? 등 → Long?
  • UI 호출부
    • FeedCommentScreen.kt → commentsViewModel.initialize(postId = feedId.toLong(), …)
    • GroupNoteScreen.kt → commentsViewModel.initialize(postId = post.postId.toLong(), …)
      ⇒ 시그니처를 Long으로 변경 후 .toLong() 제거
  • ViewModel
    • CommentsViewModel.kt → deleteComment(commentId.toLong()), likeComment(commentId.toLong(), …)
      ⇒ 파라미터 타입을 Long으로 변경하고 캐스팅 제거

※ AdvancedImePadding.kt, SearchBookDetailScreen.kt 등의 toInt() 호출은 ID 변환이 아닌 UI 좌표 로직이므로 그대로 두셔도 됩니다.

🤖 Prompt for AI Agents
app/src/main/java/com/texthip/thip/data/model/comments/response/CommentsResponse.kt
(lines 15–16 and 33–34) 및 리뷰에 나열된 모든 위치: 모델 필드가 Int/Int?로 남아 있고 호출부에서 .toLong()
캐스팅을 사용하고 있어 ID 타입 변경(Int→Long)이 완전히 반영되지 않았습니다. 각 모델 파일의 ID 관련 프로퍼티를 Int/Int?에서
Long/Long?으로 변경하고(예: UserSearchResponse.userId,
RoomsDailyGreetingResponse.attendanceCheckId/creatorId,
RelatedBooksResponse.feedId/creatorId, FeedUsersInfoResponse.creatorId,
FeedMineInfoResponse.creatorId, CommentsResponse.creatorId/replyId 등),
ViewModel과 UI 호출부(CommentsViewModel, FeedCommentScreen, GroupNoteScreen 등)의 해당
파라미터 시그니처를 Long으로 변경한 뒤 모든 불필요한 .toLong() 호출을 제거하세요; nullable 여부는 기존 로직과 일치하도록
유지하세요. Ensure serialization annotations remain correct and run a build to fix
any remaining type mismatches.

data class AllFeedItem(
@SerialName("feedId") val feedId: Int,
@SerialName("creatorId") val creatorId: Int,
@SerialName("creatorId") val creatorId: Long,
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

creatorId를 Long으로 확장한 변경 적절 — 교차 계층 호환성만 빠르게 점검해 주세요

  • 대용량 ID 대응과 오버플로 방지 측면에서 적절한 변경입니다. Kotlinx Serialization에서도 숫자(JSON number)라면 문제없이 역직렬화됩니다.
  • 다음 누락 포인트만 점검 부탁드립니다:
    • 서버가 드물게 문자열(JSON string)로 ID를 보내는지 여부(그럴 경우 커스텀 serializer 필요).
    • NavGraph 인자 타입이 NavType.LongType으로 교체되었는지.
    • SavedStateHandle/Bundle에서 putInt/getInt → putLong/getLong 전환 누락 여부.
    • 캐시/DB/도메인 모델/매퍼에 남아있는 Int 타입 및 toInt() 변환 호출.

필요 시 아래 스크립트를 루트에서 실행해 잔존 Int 사용 지점을 빠르게 확인할 수 있습니다.

필요하시면 스크립트 결과 기반으로 후속 패치(diff)까지 정리해 드리겠습니다.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Int 타입으로 남아있는 ID 필드 정의 검사 ==="
rg -n --type=kt -C2 $'\b(creatorId|userId)\s*:\s*Int\??\b'

echo
echo "=== toInt() 변환 사용 검사 (ID 관련) ==="
rg -n --type=kt -C2 $'\b(creatorId|userId)\b.*\.toInt\('

echo
echo "=== NavType.IntType 사용 검사 ==="
rg -n --type=kt -C3 'NavType\.IntType'

echo
echo "=== Bundle/SavedStateHandle Int 사용 패턴 검사 ==="
rg -n --type=kt -C2 $'\b(putInt|getInt)\(\s*"userId"'
rg -n --type=kt -C2 $'SavedStateHandle.*get<Int>\\("userId"\\)'

echo
echo "=== 함수/파라미터 시그니처에서 Int ID 잔존 검사 ==="
rg -n --type=kt -C2 $'\b(fun|val|var)\b[^\n]*\b(creatorId|userId)\s*:\s*Int\??\b'

Length of output: 180


아래 스크립트로 .kt 파일을 glob 필터링하여 다시 검사해 주세요.


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "=== Int 타입으로 남아있는 ID 필드 정의 검사 ==="
rg -n -C2 -g '*.kt' '\b(creatorId|userId)\s*:\s*Int\??\b'

echo
echo "=== toInt() 변환 사용 검사 (ID 관련) ==="
rg -n -C2 -g '*.kt' '\b(creatorId|userId)\b.*\.toInt\('

echo
echo "=== NavType.IntType 사용 검사 ==="
rg -n -C3 -g '*.kt' 'NavType\.IntType'

echo
echo "=== Bundle/SavedStateHandle Int 사용 패턴 검사 ==="
rg -n -C2 -g '*.kt' '\b(putInt|getInt)\(\s*"userId"'
rg -n -C2 -g '*.kt' 'SavedStateHandle.*get<Int>\("userId"\)'

echo
echo "=== 함수/파라미터 시그니처에서 Int ID 잔존 검사 ==="
rg -n -C2 -g '*.kt' '\b(fun|val|var)\b[^\n]*\b(creatorId|userId)\s*:\s*Int\??\b'

Length of output: 3450


Int 타입 ID 필드 전부 Long으로 변경 필요

다음 데이터 모델 클래스에 여전히 Int로 선언된 ID 필드가 남아 있습니다. 큰 값 대응을 위해 모두 Long으로 변경해주세요.

  • app/src/main/java/com/texthip/thip/data/model/users/response/UserSearchResponse.kt
    • line 12: val userId: Int
  • app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsDailyGreetingResponse.kt
    • line 14: val attendanceCheckId: Int
    • line 15: val creatorId: Int
  • app/src/main/java/com/texthip/thip/data/model/feed/response/RelatedBooksResponse.kt
    • line 15: val feedId: Int
    • line 16: val creatorId: Int
  • app/src/main/java/com/texthip/thip/data/model/feed/response/FeedUsersInfoResponse.kt
    • line 7: val creatorId: Int
  • app/src/main/java/com/texthip/thip/data/model/feed/response/FeedMineInfoResponse.kt
    • line 8: val creatorId: Int

추가로 아래 부분도 누락 없는지 검토 바랍니다:

  • NavGraph 인자 → NavType.LongType 전환
  • Bundle/SavedStateHandle → putLong/getLong
  • 매퍼나 뷰모델에서의 .toInt() 호출

위 수정 후 다시 직렬화·내비게이션 동작을 점검해주세요.

🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/users/response/UserSearchResponse.kt
line 12;
app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsDailyGreetingResponse.kt
lines 14-15;
app/src/main/java/com/texthip/thip/data/model/feed/response/RelatedBooksResponse.kt
lines 15-16;
app/src/main/java/com/texthip/thip/data/model/feed/response/FeedUsersInfoResponse.kt
line 7; and
app/src/main/java/com/texthip/thip/data/model/feed/response/FeedMineInfoResponse.kt
line 8 change the ID properties declared as Int to Long, update any Kotlin
serialization types/signatures accordingly, and adjust all call sites: switch
NavGraph arguments to NavType.LongType, replace Bundle/SavedStateHandle put/get
usages with putLong/getLong, and remove or replace any .toInt() conversions used
for IDs (use .toLong() or avoid conversion) so serialization, navigation and
viewmodel mappers remain consistent; after edits run serialization and
navigation flows to verify behavior.

Copy link
Collaborator

@rbqks529 rbqks529 left a comment

Choose a reason for hiding this comment

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

코드 수정 확인했습니다 이것저것 수정이 많이 된것 같네요 해당 pr 머지되면 저도 이어받아서 해보겠습니다

Copy link
Collaborator

Choose a reason for hiding this comment

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

이게 잘 확인은 안되는데 프로필 이미지를 터치했을 때 해당 유저의 피드 게시글로 이동하는거 맞나요?

Copy link
Collaborator

Choose a reason for hiding this comment

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

이런 코드 수정이 많아 보이는데 Long으로 바꾼 이유가 있을까요? QA에서는 확인이 안되는디

Copy link
Collaborator

Choose a reason for hiding this comment

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

에러 필드 수정 고생했습니다..

@rbqks529 rbqks529 merged commit fb3692c into THIP-TextHip:develop Aug 18, 2025
1 check passed
@coderabbitai coderabbitai bot mentioned this pull request Aug 20, 2025
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants