Skip to content

[UI] 데이터 없는 페이지들 구현#56

Merged
rbqks529 merged 27 commits intoTHIP-TextHip:developfrom
Nico1eKim:ui/#50-blank_pages
Jul 27, 2025
Merged

[UI] 데이터 없는 페이지들 구현#56
rbqks529 merged 27 commits intoTHIP-TextHip:developfrom
Nico1eKim:ui/#50-blank_pages

Conversation

@Nico1eKim
Copy link
Member

@Nico1eKim Nico1eKim commented Jul 24, 2025

➕ 이슈 링크


🔎 작업 내용

  • 투표내용이 없을 때
  • 오늘의 한마디가 없을 때
  • 기록이 없을 때
  • 댓글이 없을 때
  • 기타 QA 우선 진행했습니다

📸 스크린샷

모임방 화면

  • 투표 없을 때
스크린샷 2025-07-24 오후 9 23 05
  • 투표 화면 3개로 고정
  • 투표 안되게 수정
2025-07-24.9.23.17.mov
  • 방 주인일 때와 아닐 때 분리해서 bottom sheet 뜨기
2025-07-24.9.24.41.mov
2025-07-24.9.25.15.mov

오늘의 한마디

  • 오늘의 한마디 없을 때
스크린샷 2025-07-24 오후 10 01 09
  • 오늘의 한마디 날짜에 따라 안뜨던 문제 수정
  • 댓글 주인 여부에 따라 bottom sheet 다르게 뜨기
2025-07-24.9.26.17.mov

기록장

  • 그룹기록에 모든 기록 뜨도록 수정
  • 내 기록에 필터 버튼 없애기
  • 총평 보기 버튼 누르면 나오는 toast에 애니메이션 적용
  • 댓글 바텀시트 textfield 늘어나게 수정
  • 내 기록은 pin 할 수 있고 모달 뜨도록 수정
2025-07-24.10.03.06.mov
2025-07-24.10.38.41.mov

😢 해결하지 못한 과제

  • TASK


📢 리뷰어들에게

  • QA 진행 전 최대한 다 수정해보려고 했는데 아직 놓친 부분이 있을 수도 있습니다 ..! 꼼꼼한 리뷰 부탁드립니두 ~

Summary by CodeRabbit

새로운 기능

  • 메뉴 및 댓글, 투표 카드에서 롱프레스(길게 누르기) 제스처 지원 및 잠금 상태에 따른 상호작용 제어가 추가되었습니다.
  • 투표 카드, 채팅, 기록 등 다양한 목록이 비어 있을 때 안내 메시지 및 상태 UI가 개선되었습니다.
  • 메뉴/댓글 바텀시트, 토스트 알림, 그룹룸 나가기/삭제 확인 다이얼로그 등 다양한 모달 및 알림 기능이 추가되었습니다.
  • 댓글 입력창이 여러 줄 입력 및 자동 높이 조절을 지원합니다.
  • 투표 카드가 읽기 전용으로 단순화되고, 클릭 시 외부 처리 콜백이 추가되었습니다.
  • 필터, 옵션 버튼, 상단바 등 주요 UI 컴포넌트에 커스텀 콜백 및 modifier 확장성이 추가되었습니다.
  • 채팅 및 기록 화면에서 소유자/참여자에 따라 메뉴 옵션이 다르게 표시됩니다.
  • 기록 카드에 핀 기능과 핀 클릭 콜백이 추가되었고, 핀 관련 모달이 도입되었습니다.
  • 그룹룸 채팅 및 기록 화면에서 메뉴 바텀시트가 컨텍스트에 맞게 동작하며, 핀 다이얼로그와 토스트 알림이 추가되었습니다.

기능 개선 및 변경

  • 댓글 입력창이 여러 줄 입력 및 자동 높이 조절을 지원합니다.
  • 투표 카드가 읽기 전용으로 단순화되고, 클릭 시 외부 처리 콜백이 추가되었습니다.
  • 필터, 옵션 버튼, 상단바 등 주요 UI 컴포넌트에 커스텀 콜백 및 modifier 확장성이 추가되었습니다.
  • 채팅 및 기록 화면에서 소유자/참여자에 따라 메뉴 옵션이 다르게 표시됩니다.
  • 메뉴 바텀시트 내 항목 클릭 영역 및 레이아웃이 개선되어 사용자 경험이 향상되었습니다.
  • 그룹 노트 및 채팅 화면의 UI 구조가 재정비되어 가독성과 유지보수성이 향상되었습니다.

버그 수정 및 스타일

  • 레이아웃 패딩, 정렬, 블러 효과, UI 정렬 등 세부 스타일이 개선되었습니다.
  • 패키지 및 함수 명칭이 일관되게 정리되었습니다.
  • 다이얼로그 및 모달 레이아웃이 단순화되고, 불필요한 중첩 구조가 제거되었습니다.

문서 및 리소스

  • 다양한 상태, 안내, 모달용 텍스트 리소스가 추가 및 보강되었습니다.
  • 투표, 그룹룸, 댓글, 핀 기능 관련 신규 문자열이 다수 추가되었습니다.

Nico1eKim added 23 commits July 23, 2025 01:08
@coderabbitai
Copy link

coderabbitai bot commented Jul 24, 2025

"""

Walkthrough

이 변경 사항은 그룹 노트, 채팅, 투표, 댓글 등 여러 화면에서 데이터가 없을 때의 UI와 상호작용을 개선하고, 메뉴/모달/바텀시트의 제어 흐름을 세분화합니다. 여러 컴포저블 함수의 파라미터가 확장되거나 시그니처가 변경되었으며, 데이터 클래스와 목 데이터도 보강되었습니다. 문자열 리소스가 대폭 추가 및 수정되었습니다.

Changes

파일/경로 그룹 변경 요약
.../MenuBottomSheet.kt 메뉴 바텀시트 레이아웃 계층 구조 및 클릭 영역 변경
.../OptionChipButton.kt onDisabledClick 파라미터 추가, 클릭 처리 로직 분기
.../CardCommentGroup.kt onMenuClick 파라미터 추가, 프리뷰 데이터 isMine 적용
.../CardVote.kt 내부 상태 제거, onVoteClick 파라미터 추가, 빈 상태 UI 추가
.../CommentTextField.kt 멀티라인 입력, 동적 높이 조정, 레이아웃 개선
.../DefaultTopAppBar.kt modifier 파라미터 추가, 내부 modifier 적용 방식 변경
.../CommentBottomSheet.kt 레이아웃 구조 개선, 빈 댓글 시 안내 메시지 추가
.../CommentSection.kt CommentList에 modifier 파라미터 추가
.../FilterHeaderSection.kt onDisabledClick 파라미터 추가 및 OptionChipButton에 전달
.../TextCommentCard.kt, .../VoteCommentCard.kt onLongPress 파라미터 추가, 잠금 상태(isLocked)에 따른 상호작용 제어, 블러 효과 적용
.../GroupNoteScreen.kt 탭 필터링, 바텀시트 상태 분리, 메뉴 바텀시트/토스트/빈 상태 UI/애니메이션 등 대규모 리팩토링
.../GroupRoomChatData.kt isMine 필드 추가, mockMessages 샘플 리스트 추가
.../VoteData.kt mockVoteData 내 일부 VoteItem 주석 처리
.../GroupRoomChatScreen.kt mockMessages 사용, 빈 채팅 메시지 안내, 메뉴 바텀시트 및 블러 효과 추가
.../GroupRoomRecruitScreen.kt, .../GroupRoomUnlockScreen.kt 패키지명 및 함수명 일괄 정정, 프리뷰 함수명 일치화
.../GroupRoomScreen.kt 방 나가기/삭제 다이얼로그 상태 및 UI 추가, 메뉴 항목 동적 생성, 블러 효과 확장
.../GroupEmptyResult.kt, .../GroupFilteredSearchResult.kt, .../GroupLiveSearchResult.kt 패키지명 변경, 불필요 import 제거
.../GroupRecentSearch.kt import 및 포매팅 정리
.../GroupSearchScreen.kt 패키지명 및 import 정정
.../strings.xml 다수의 신규/수정 문자열 리소스 추가(투표, 모임방, 댓글, 모달 등)
.../DialogPopup.kt 레이아웃 구조 단순화 및 불필요 컴포저블 제거, 내부 구조 평탄화

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GroupNoteScreen
    participant MenuBottomSheet
    participant CommentBottomSheet
    participant Toast
    participant DataSource

    User->>GroupNoteScreen: 탭 선택/필터/카드 클릭/롱프레스
    alt 카드 롱프레스
        GroupNoteScreen->>MenuBottomSheet: 메뉴 바텀시트 표시
        User->>MenuBottomSheet: 메뉴 항목 클릭(삭제/신고)
        MenuBottomSheet->>GroupNoteScreen: 액션 처리 및 바텀시트 닫기
    else 카드 클릭
        GroupNoteScreen->>CommentBottomSheet: 댓글 바텀시트 표시
    end
    alt 필터 비활성 클릭
        GroupNoteScreen->>Toast: 안내 토스트 표시(애니메이션)
        Toast-->>GroupNoteScreen: 6초 후 자동 숨김
    end
    GroupNoteScreen->>DataSource: 데이터 요청/필터링
    DataSource-->>GroupNoteScreen: 결과 반환(없을 시 안내 메시지)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40분

Possibly related PRs

Suggested labels

✅ OK merge

Poem

🐰
데이터가 없을 땐 걱정 마,
빈 화면에도 토끼가 인사하라!
바텀시트, 토스트, 메뉴도 척척,
롱프레스엔 메뉴가 뾰로롱~
새로워진 화면에 깡총깡총,
리뷰어님, 오늘도 힘내세요!
🥕✨
"""

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ 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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

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

…into ui/THIP-TextHip#50-blank_pages

# Conflicts:
#	app/src/main/java/com/texthip/thip/ui/group/search/component/GroupRecentSearch.kt
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: 4

🔭 Outside diff range comments (1)
app/src/main/java/com/texthip/thip/ui/group/search/component/GroupRecentSearch.kt (1)

5-12: 중복 import로 인한 컴파일 오류 발생 가능

FlowRow, Spacer, height 를 두 번씩 import 하고 있어요. Kotlin 컴파일러는 중복 import 를 오류로 처리하므로 반드시 하나만 남기세요.

-import androidx.compose.foundation.layout.FlowRow
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.height
...
 import androidx.compose.foundation.layout.FlowRow
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.height

위처럼 57 라인을 제거하거나 1012 라인을 제거해 중복을 해소해 주세요.

🧹 Nitpick comments (11)
app/src/main/java/com/texthip/thip/ui/group/room/mock/VoteData.kt (1)

16-18: 주석 처리된 코드보다는 별도의 mock 데이터 세트 고려

테스트를 위해 vote item을 주석 처리하는 것보다는, 다양한 시나리오를 위한 별도의 mock 데이터 세트를 만드는 것이 좋겠습니다. 예를 들어 mockVoteDataMinimal, mockVoteDataFull 등으로 분리하여 관리하면 더 명확하고 유지보수하기 좋을 것 같습니다.

+val mockVoteDataMinimal = listOf(
+    VoteData(
+        description = "투표 내용입니다...",
+        voteItems = listOf(
+            VoteItem(1, "김땡땡", 50, false),
+            VoteItem(2, "이땡땡", 10, false)
+        )
+    )
+)
+
 val mockVoteData = listOf(
     VoteData(
         description = "투표 내용입니다...",
         voteItems = listOf(
             VoteItem(1, "김땡땡", 50, false),
             VoteItem(2, "이땡땡", 10, false),
-//            VoteItem(3, "박땡땡", 20, false),
-//            VoteItem(4, "최땡땡", 15, false),
-//            VoteItem(5, "정땡땡", 5, false)
+            VoteItem(3, "박땡땡", 20, false),
+            VoteItem(4, "최땡땡", 15, false),
+            VoteItem(5, "정땡땡", 5, false)
         )
     ),
app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomChatData.kt (1)

57-57: 날짜 정렬 방식 개선 검토 필요

문자열 형태의 날짜를 sortedByDescending으로 정렬하고 있는데, "2024.04.27", "2024.04.28", "2024.04.30" 형식에서는 문제가 없지만, 향후 날짜 형식이 변경되거나 월/일이 한 자리 수가 되면 정렬이 제대로 되지 않을 수 있습니다.

실제 Date 객체나 LocalDate를 사용하거나, 최소한 "yyyy.MM.dd" 형식으로 통일하는 것을 고려해보세요:

-).sortedByDescending { it.date }
+).sortedByDescending { 
+    // ISO 형식으로 변환하여 정렬
+    it.date.replace(".", "-")
+}
app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt (1)

73-73: 하드코딩된 최대 항목 수 개선 고려

take(3)으로 최대 3개 항목으로 제한하고 있는데, 이 값을 매개변수로 받아서 구성 가능하게 만드는 것을 고려해보세요.

 @Composable
 fun CardVote(
     voteData: List<VoteData>,
+    maxVoteItems: Int = 3,
     onVoteClick: (VoteData) -> Unit = {}
 ) {
     // ...
-                val voteItems = vote.voteItems.take(3) // 최대 3개만
+                val voteItems = vote.voteItems.take(maxVoteItems)
app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomChatScreen.kt (2)

38-38: 주석 처리된 코드를 제거하는 것을 고려해보세요.

개발 중 참고용으로 남겨두었을 수 있지만, 코드 정리를 위해 제거하는 것이 좋겠습니다.

-//    val mockMessages = emptyList<GroupRoomChatData>()

46-54: 블러 효과 구현을 개선할 수 있습니다.

현재 조건부로 Modifier를 생성하는 방식보다는 하나의 Modifier를 사용하는 것이 더 효율적입니다.

-    Box(
-        if (isBottomSheetVisible) {
-            Modifier
-                .fillMaxSize()
-                .blur(5.dp)
-        } else {
-            Modifier.fillMaxSize()
-        }
-    ) {
+    Box(
+        modifier = Modifier
+            .fillMaxSize()
+            .then(if (isBottomSheetVisible) Modifier.blur(5.dp) else Modifier)
+    ) {
app/src/main/java/com/texthip/thip/ui/common/forms/CommentTextField.kt (1)

110-110: 코드 주석을 영어로 통일하는 것을 고려해보세요.

코드베이스의 일관성을 위해 주석을 영어로 작성하는 것이 좋겠습니다.

-                    .wrapContentHeight(),  // 높이 자동 확장
+                    .wrapContentHeight(),  // Auto-expand height
app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt (2)

138-176: 다이얼로그 래퍼 중복 코드 리팩토링 제안

두 다이얼로그 모두 동일한 Box 래퍼 구조를 사용하고 있습니다. 재사용 가능한 컴포넌트로 추출하면 코드 중복을 줄일 수 있습니다.

다음과 같이 리팩토링할 수 있습니다:

+@Composable
+private fun DialogWrapper(
+    content: @Composable () -> Unit
+) {
+    Box(
+        modifier = Modifier.fillMaxSize(),
+        contentAlignment = Alignment.Center
+    ) {
+        content()
+    }
+}

-    if (isLeaveDialogVisible) {
-        Box(
-            modifier = Modifier
-                .fillMaxSize(),
-            contentAlignment = Alignment.Center
-        ) {
+    if (isLeaveDialogVisible) {
+        DialogWrapper {
             DialogPopup(
                 title = stringResource(R.string.leave_room_modal_title),
                 description = stringResource(R.string.leave_room_modal_content),
                 onConfirm = {
                     // 방 나가기 로직
                     isLeaveDialogVisible = false
                 },
                 onCancel = {
                     isLeaveDialogVisible = false
                 }
             )
         }
     }

-    if (isDeleteDialogVisible) {
-        Box(
-            modifier = Modifier
-                .fillMaxSize(),
-            contentAlignment = Alignment.Center
-        ) {
+    if (isDeleteDialogVisible) {
+        DialogWrapper {
             DialogPopup(
                 title = stringResource(R.string.delete_room_modal_title),
                 description = stringResource(R.string.delete_room_modal_content),
                 onConfirm = {
                     // 방 삭제하기 로직
                     isDeleteDialogVisible = false
                 },
                 onCancel = {
                     isDeleteDialogVisible = false
                 }
             )
         }
     }

127-127: 실제 동작 로직 구현 필요

신고, 방 나가기, 방 삭제하기의 실제 로직이 구현되지 않았습니다. 서버 API 호출 및 에러 처리가 필요합니다.

각 액션에 대한 API 호출 로직을 생성해드릴까요? 에러 처리와 로딩 상태 관리도 포함하여 구현할 수 있습니다.

Also applies to: 148-149, 168-169

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

86-91: 토스트 표시 시간 검토 필요

현재 토스트가 6초(2초 진입 + 4초 노출) 동안 표시되도록 설정되어 있습니다. 주석과 실제 구현이 일치하지 않으며, 일반적인 토스트 표시 시간보다 깁니다.

-    // 토스트 3초
+    // 토스트 총 6초 (2초 진입 애니메이션 + 2초 노출 + 2초 종료 애니메이션)
     LaunchedEffect(showToast) {
         if (showToast) {
-            delay(6000) // 2초 등장, 4초 노출
+            delay(4000) // 2초 노출 (애니메이션 시간 제외)
             showToast = false // exit 에니메이션 2초
         }
     }

305-305: 메뉴 액션 구현 필요

삭제 및 신고 처리 로직이 구현되지 않았습니다. 실제 API 호출과 성공/실패 처리가 필요합니다.

삭제 및 신고 API 호출 로직을 구현해드릴까요? 로딩 상태와 에러 처리도 포함할 수 있습니다.

Also applies to: 317-317


230-258: 필터 섹션 레이아웃 개선 제안

현재 필터 섹션이 고정 위치(padding-top: 119.dp)로 배치되어 있어 다양한 화면 크기에서 레이아웃 문제가 발생할 수 있습니다.

LazyColumn의 stickyHeader를 사용하여 더 안정적인 레이아웃을 구현할 수 있습니다:

-            if (selectedTabIndex == 0) {
-                Box(
-                    modifier = Modifier
-                        .fillMaxWidth()
-                        .padding(top = 119.dp)
-                        .background(color = colors.Black)
-                        .padding(top = 20.dp)
-                ) {
-                    // Filter content...
-                }
-            }

             LazyColumn(modifier = Modifier.fillMaxSize()) {
+                if (selectedTabIndex == 0) {
+                    stickyHeader {
+                        Box(
+                            modifier = Modifier
+                                .fillMaxWidth()
+                                .background(color = colors.Black)
+                                .padding(vertical = 20.dp)
+                        ) {
+                            // Filter content...
+                        }
+                    }
+                }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6c3bc1 and d9f7223.

📒 Files selected for processing (24)
  • app/src/main/java/com/texthip/thip/ui/common/bottomsheet/MenuBottomSheet.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/cards/CardCommentGroup.kt (3 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt (5 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/forms/CommentTextField.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/CommentBottomSheet.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/CommentSection.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/FilterHeaderSection.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/TextCommentCard.kt (4 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt (6 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/screen/GroupNoteScreen.kt (6 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomChatData.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/mock/VoteData.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomChatScreen.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomRecruitScreen.kt (8 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt (4 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomUnlockScreen.kt (4 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupEmptyResult.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupFilteredSearchResult.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupLiveSearchResult.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupRecentSearch.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt (2 hunks)
  • app/src/main/res/values/strings.xml (3 hunks)
🧰 Additional context used
🧠 Learnings (9)
app/src/main/java/com/texthip/thip/ui/group/search/component/GroupRecentSearch.kt (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

app/src/main/res/values/strings.xml (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

🧬 Code Graph Analysis (3)
app/src/main/java/com/texthip/thip/ui/group/search/component/GroupRecentSearch.kt (1)
app/src/main/java/com/texthip/thip/ui/theme/Theme.kt (1)
  • ThipTheme (41-69)
app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomUnlockScreen.kt (1)
app/src/main/java/com/texthip/thip/ui/theme/Theme.kt (1)
  • ThipTheme (41-69)
app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt (2)
app/src/main/java/com/texthip/thip/ui/common/bottomsheet/MenuBottomSheet.kt (1)
  • MenuBottomSheet (22-59)
app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (1)
  • DialogPopup (26-84)
🔇 Additional comments (42)
app/src/main/java/com/texthip/thip/ui/group/search/component/GroupRecentSearch.kt (1)

75-87: 프리뷰용 리스트 상태는 mutableStateListOf 사용이 가독성·성능 측면에서 유리

mutableStateOf(listOf(...)) 후 매번 새 리스트를 할당하면 불필요한 객체가 반복해서 만들어집니다. mutableStateListOf 로 초기화하면 in-place 수정이 가능해 Compose diff 가 더 효율적으로 동작합니다.

-    var searches by remember {
-        mutableStateOf(listOf("해리포터", "소설", "추리소설", "로맨스", "SF", "판타지"))
-    }
+    val searches = remember {
+        mutableStateListOf("해리포터", "소설", "추리소설", "로맨스", "SF", "판타지")
+    }

그리고 삭제 콜백에서도 리스트 재생성 대신 remove(keyword) 를 호출하면 됩니다.

-    onRemove = { keyword ->
-        searches = searches.filter { it != keyword }
-    }
+    onRemove = { keyword -> searches.remove(keyword) }

[ suggest_optional_refactor ]

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

9-11: 데이터 클래스 확장이 적절합니다

isMine 속성 추가로 메시지 소유권 기반의 컨텍스트 메뉴 처리가 가능해졌습니다. UI에서 수정/삭제와 신고 기능을 구분하는데 유용할 것 같습니다.

app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt (2)

39-39: 비활성화 상태 클릭 핸들링 개선

onDisabledClick 매개변수 추가로 비활성화된 버튼 클릭 시에도 커스텀 동작이 가능해졌습니다. 사용자 피드백 개선에 도움이 될 것 같습니다.


73-80: 명시적인 상태 처리 로직 개선

enabled 매개변수를 clickable 수정자에서 제거하고 클릭 람다 내에서 명시적으로 처리하는 방식이 더 명확합니다. 활성화/비활성화 상태에 따른 동작이 잘 구분되어 있습니다.

app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt (2)

32-35: 상태 관리 리팩토링 잘 되었습니다

내부 상태 관리를 제거하고 콜백 기반으로 변경한 것이 좋습니다. 컴포넌트의 재사용성과 테스트 가능성이 향상되었습니다.


62-62: 하드코딩된 문자열을 리소스로 추출 필요

이전 학습 내용에 따르면 하드코딩된 UI 문자열보다는 StringResource 파일로 추출을 선호하신다고 했습니다. stringResource(R.string.no_vote)가 이미 사용되고 있어 좋습니다.

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

1-1: 패키지 재구성이 적절합니다.

검색 관련 UI 컴포넌트들을 전용 search 패키지로 이동시킨 것은 코드 구조를 개선하고 모듈성을 향상시킵니다.

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

1-1: 패키지 재구성과 불필요한 import 제거가 적절합니다.

검색 컴포넌트들의 일관된 패키지 이동과 함께 사용하지 않는 import를 정리한 것이 좋습니다.

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

1-1: 패키지 이동과 코드 정리가 적절합니다.

다른 검색 컴포넌트들과 일관된 패키지 구조로 이동하고 불필요한 import를 제거한 것이 좋습니다.

app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt (2)

1-1: 검색 화면의 패키지 재구성이 완료되었습니다.

검색 관련 화면과 컴포넌트들이 모두 search 패키지로 일관되게 이동되어 코드 구조가 개선되었습니다.


32-35: import 문 업데이트가 적절합니다.

검색 컴포넌트들의 새로운 패키지 위치에 맞게 import 문이 올바르게 업데이트되었습니다. GroupCardItemRoomData는 공유 데이터이므로 myroom.mock에 그대로 두는 것이 합리적입니다.

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

34-34: 비활성화된 버튼 클릭 처리 파라미터 추가가 적절합니다.

onDisabledClick 파라미터를 추가하여 비활성화된 상태에서의 사용자 상호작용을 처리할 수 있게 되었습니다. 기본값을 빈 구현으로 제공하여 기존 코드와의 호환성을 유지한 것이 좋습니다.


67-68: OptionChipButton에 새 파라미터 전달이 올바릅니다.

새로 추가된 onDisabledClick 파라미터가 OptionChipButton 컴포넌트에 올바르게 전달되어 비활성화된 버튼의 클릭 이벤트를 적절히 처리할 수 있습니다.

app/src/main/java/com/texthip/thip/ui/common/cards/CardCommentGroup.kt (2)

19-22: 메뉴 클릭 콜백 파라미터 추가가 올바르게 구현되었습니다.

새로운 onMenuClick 파라미터가 적절히 추가되었고, 이는 그룹 채팅에서 메뉴 기능을 지원하기 위한 변경사항입니다.


46-56: 프리뷰 함수가 새로운 파라미터에 맞게 정확히 업데이트되었습니다.

onMenuClick 빈 람다와 isMine = false 속성이 올바르게 추가되어 프리뷰가 정상적으로 작동할 것입니다.

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

24-33: Modifier 파라미터 추가가 Compose 베스트 프랙티스를 따릅니다.

선택적 modifier 파라미터를 추가하여 부모 컴포저블에서 레이아웃을 유연하게 제어할 수 있도록 했습니다. 기본값으로 인해 이전 버전과의 호환성도 유지됩니다.

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

64-86: 빈 데이터 상태 UI가 PR 목적에 맞게 잘 구현되었습니다.

채팅이 없을 때의 UI가 사용자 친화적으로 구현되었습니다. 중앙 정렬과 적절한 메시지로 빈 상태를 명확히 표현하고 있습니다.


87-125: 채팅 메시지 목록 구현이 효과적입니다.

날짜별 그룹핑과 구분선을 통해 메시지를 체계적으로 표시하고 있습니다. reverseLayout을 사용하여 최신 메시지가 하단에 표시되도록 한 것도 적절합니다.


149-150: TODO 주석의 하드코딩된 문자열을 StringResource로 추출해야 합니다.

사용자 선호사항에 따라 하드코딩된 문자열들을 strings.xml로 추출하는 것이 좋겠습니다.

예를 들어:

-// TODO: 수정 처리
+// TODO: ${stringResource(R.string.todo_modify_process)}

Also applies to: 157-158, 168-169

⛔ Skipped due to learnings
Learnt from: rbqks529
PR: THIP-TextHip/THIP-Android#30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.
app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt (1)

23-34: Modifier 파라미터 추가가 컴포넌트의 재사용성을 향상시킵니다.

선택적 modifier 파라미터를 추가하여 외부에서 레이아웃을 커스터마이징할 수 있도록 한 것은 Compose의 모범 사례입니다.

app/src/main/java/com/texthip/thip/ui/common/forms/CommentTextField.kt (3)

104-111: 다중 라인 텍스트 입력 구현이 잘 되었습니다.

maxLines = 5로 제한하고 defaultMinSizewrapContentHeight()를 사용하여 동적 높이 조절이 효과적으로 구현되었습니다.


113-123: 플레이스홀더 구현이 개선되었습니다.

Box로 감싸서 플레이스홀더와 실제 텍스트 필드를 오버레이하는 방식이 올바르게 구현되었습니다.


130-132: 전송 버튼의 하단 정렬이 다중 라인 입력에 적합합니다.

Alignment.Bottom을 사용하여 텍스트 필드가 확장될 때 전송 버튼이 하단에 고정되도록 한 것이 UX 관점에서 좋은 개선입니다.

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

1-1: 패키지 선언 변경이 적절합니다.

myroom.screen에서 room.screen으로의 패키지 구조 변경이 일관성 있게 적용되었습니다.


35-35: import 개선이 코드 가독성을 향상시킵니다.

kotlinx.coroutines.delay를 직접 import하여 fully qualified name 대신 간단한 delay(1000) 호출을 사용하는 것이 더 깔끔합니다.

Also applies to: 56-56


38-38: 함수명 변경이 일관성 있게 적용되었습니다.

GroupRoomSecretScreen에서 GroupRoomUnlockScreen으로의 함수명 변경이 정의부와 프리뷰 함수 모두에 일관성 있게 적용되었습니다.

Also applies to: 157-159

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

31-32: 새로운 콜백 매개변수가 적절히 추가되었습니다.

onLongPress 콜백 매개변수 추가로 길게 누르기 제스처 지원이 가능해졌습니다.


35-35: 상태 추출로 코드 가독성이 향상되었습니다.

data.isLocked를 지역 변수로 추출하여 반복 사용 시 가독성과 성능이 개선되었습니다.


39-45: 제스처 감지 구현이 적절합니다.

잠금 상태가 아닐 때만 길게 누르기 제스처를 감지하도록 조건부 처리가 올바르게 구현되었습니다.


69-73: 상호작용 제어 로직이 일관성 있게 적용되었습니다.

좋아요 토글과 댓글 클릭 모두에서 isLocked 상태를 확인하여 잠긴 상태에서는 상호작용을 방지하는 로직이 적절합니다.

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

33-34: 콜백 매개변수 추가가 일관성 있게 적용되었습니다.

TextCommentCard와 동일한 방식으로 onLongPress 콜백이 추가되어 컴포넌트 간 일관성이 유지됩니다.


41-41: 상태 관리가 효율적으로 개선되었습니다.

isLocked 상태를 지역 변수로 추출하여 중복 접근을 방지하고 가독성을 향상시켰습니다.


75-86: 투표 로직에서 잠금 상태 처리가 적절합니다.

투표 선택과 취소 로직 모두에서 isLocked 상태를 확인하여 잠긴 상태에서는 투표 상태 변경을 방지하는 것이 올바른 구현입니다.


63-63: 레이아웃 구조 개선이 적절합니다.

ColumnverticalArrangement = Arrangement.spacedBy(8.dp) 추가로 텍스트와 투표 버튼 간의 일관된 간격이 적용되었습니다.

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

40-44: 레이아웃 구조 개선이 적절합니다.

고정 높이 600dp와 전체 너비를 사용하는 외부 Column 구조로 바텀시트의 일관된 크기가 보장됩니다.


57-76: 빈 상태 처리가 사용자 경험을 향상시킵니다.

댓글이 없을 때 중앙 정렬된 메시지를 표시하는 빈 상태 처리가 적절히 구현되었습니다.


91-107: 댓글 입력 필드 배치가 개선되었습니다.

CommentTextField를 내부 스크롤 영역 밖에 배치하여 항상 접근 가능하도록 한 것이 좋은 UX 개선입니다.

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

1-1: 패키지 구조 통일이 적절합니다.

myroom.screen에서 room.screen으로의 패키지 변경이 다른 파일들과 일관성을 유지합니다.


54-54: 함수명 변경이 명확성을 향상시킵니다.

GroupRoomScreen에서 GroupRoomRecruitScreen으로의 변경이 모집 화면의 목적을 더 명확하게 나타냅니다.


435-435: 프리뷰 함수명 변경이 일관성 있게 적용되었습니다.

모든 프리뷰 함수명이 새로운 컴포저블 함수명에 맞춰 일관성 있게 변경되었습니다.

Also applies to: 516-516, 581-581


502-502: 프리뷰 내부 함수 호출도 정확히 업데이트되었습니다.

프리뷰 함수 내에서 GroupRoomRecruitScreen 호출이 올바르게 변경되어 빌드 오류를 방지합니다.

Also applies to: 567-567, 632-632

app/src/main/res/values/strings.xml (1)

53-54: 문자열 리소스 추가 확인

데이터가 없는 상태를 위한 문자열 리소스가 적절히 추가되었습니다. 네이밍 규칙도 일관성 있게 잘 적용되었습니다.

Also applies to: 152-162, 200-205

Comment on lines +30 to 57
Column(modifier = Modifier.padding(20.dp)) {
items.forEachIndexed { index, item ->
if (index > 0) {
Spacer(modifier = Modifier.height(8.dp))
HorizontalDivider(modifier = Modifier.height(1.dp), color = colors.Grey03)
Spacer(modifier = Modifier.height(8.dp))
}

Column(
modifier = Modifier
.height(50.dp)
.padding(horizontal = 12.dp, vertical = 8.dp),
verticalArrangement = Arrangement.Center
) {
Text(
text = item.text,
style = typography.menu_m500_s16_h24,
color = item.color,
Column(
modifier = Modifier
.fillMaxWidth()
.clickable {
item.onClick()
onDismiss()
}
)
.height(50.dp)
.padding(horizontal = 12.dp, vertical = 8.dp),
verticalArrangement = Arrangement.Center
) {
Text(
text = item.text,
style = typography.menu_m500_s16_h24,
color = item.color,
modifier = Modifier
.fillMaxWidth()
.clickable {
item.onClick()
onDismiss()
}
)
}
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

레이아웃 구조 개선되었으나 접근성 고려 필요

레이아웃 구조가 개선되고 적절한 패딩이 추가되었습니다. 하지만 클릭 가능한 영역이 전체 아이템에서 텍스트로만 제한된 점이 우려됩니다.

접근성을 위해 클릭 영역을 전체 아이템으로 확장하는 것을 권장합니다:

                Column(
                    modifier = Modifier
                        .height(50.dp)
-                        .padding(horizontal = 12.dp, vertical = 8.dp),
+                        .padding(horizontal = 12.dp, vertical = 8.dp)
+                        .clickable {
+                            item.onClick()
+                            onDismiss()
+                        },
                    verticalArrangement = Arrangement.Center
                ) {
                    Text(
                        text = item.text,
                        style = typography.menu_m500_s16_h24,
                        color = item.color,
-                        modifier = Modifier
-                            .fillMaxWidth()
-                            .clickable {
-                                item.onClick()
-                                onDismiss()
-                            }
+                        modifier = Modifier.fillMaxWidth()
                    )
                }
📝 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
Column(modifier = Modifier.padding(20.dp)) {
items.forEachIndexed { index, item ->
if (index > 0) {
Spacer(modifier = Modifier.height(8.dp))
HorizontalDivider(modifier = Modifier.height(1.dp), color = colors.Grey03)
Spacer(modifier = Modifier.height(8.dp))
}
Column(
modifier = Modifier
.height(50.dp)
.padding(horizontal = 12.dp, vertical = 8.dp),
verticalArrangement = Arrangement.Center
) {
Text(
text = item.text,
style = typography.menu_m500_s16_h24,
color = item.color,
Column(
modifier = Modifier
.fillMaxWidth()
.clickable {
item.onClick()
onDismiss()
}
)
.height(50.dp)
.padding(horizontal = 12.dp, vertical = 8.dp),
verticalArrangement = Arrangement.Center
) {
Text(
text = item.text,
style = typography.menu_m500_s16_h24,
color = item.color,
modifier = Modifier
.fillMaxWidth()
.clickable {
item.onClick()
onDismiss()
}
)
}
}
}
Column(
modifier = Modifier
.height(50.dp)
.padding(horizontal = 12.dp, vertical = 8.dp)
.clickable {
item.onClick()
onDismiss()
},
verticalArrangement = Arrangement.Center
) {
Text(
text = item.text,
style = typography.menu_m500_s16_h24,
color = item.color,
modifier = Modifier.fillMaxWidth()
)
}
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/common/bottomsheet/MenuBottomSheet.kt
between lines 30 and 57, the clickable area is currently limited to the Text
component inside each item, which reduces accessibility. To fix this, move the
clickable modifier from the Text to the parent Column that wraps the item
content, so the entire item area is clickable. This will expand the clickable
region to the full item height and width, improving accessibility and user
experience.

Comment on lines +97 to 112
Row(
Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
repeat(pageCount) { iteration ->
val color =
if (pagerState.currentPage == iteration) colors.White else colors.Grey02
Box(
modifier = Modifier
.padding(horizontal = 12.dp)
.background(color, CircleShape)
.size(4.dp)
)
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

빈 데이터 상태에서도 페이지 인디케이터 표시됨

데이터가 비어있을 때도 페이지 인디케이터 점들이 표시되는데, 이는 사용자에게 혼란을 줄 수 있습니다. 빈 상태에서는 인디케이터를 숨기는 것이 좋겠습니다.

-            Row(
-                Modifier
-                    .fillMaxWidth(),
-                horizontalArrangement = Arrangement.Center
-            ) {
-                repeat(pageCount) { iteration ->
-                    val color =
-                        if (pagerState.currentPage == iteration) colors.White else colors.Grey02
-                    Box(
-                        modifier = Modifier
-                            .padding(horizontal = 12.dp)
-                            .background(color, CircleShape)
-                            .size(4.dp)
-                    )
+            if (pageCount > 1) {
+                Row(
+                    Modifier.fillMaxWidth(),
+                    horizontalArrangement = Arrangement.Center
+                ) {
+                    repeat(pageCount) { iteration ->
+                        val color =
+                            if (pagerState.currentPage == iteration) colors.White else colors.Grey02
+                        Box(
+                            modifier = Modifier
+                                .padding(horizontal = 12.dp)
+                                .background(color, CircleShape)
+                                .size(4.dp)
+                        )
+                    }
                 }
             }
📝 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
Row(
Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
repeat(pageCount) { iteration ->
val color =
if (pagerState.currentPage == iteration) colors.White else colors.Grey02
Box(
modifier = Modifier
.padding(horizontal = 12.dp)
.background(color, CircleShape)
.size(4.dp)
)
}
}
if (pageCount > 1) {
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
repeat(pageCount) { iteration ->
val color =
if (pagerState.currentPage == iteration) colors.White else colors.Grey02
Box(
modifier = Modifier
.padding(horizontal = 12.dp)
.background(color, CircleShape)
.size(4.dp)
)
}
}
}
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt around lines
97 to 112, the page indicator dots are shown even when the data is empty, which
can confuse users. Add a condition to check if pageCount is greater than zero
before rendering the Row with the indicators, and skip rendering the indicators
entirely when pageCount is zero or less.

Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 210.dp), // TODO: 유동적으로 수정 가능할수도
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

하드코딩된 패딩 값에 대한 개선이 필요합니다.

padding(top = 210.dp)에 대한 TODO 주석이 있지만, 이런 고정값은 다양한 화면 크기에서 문제가 될 수 있습니다.

다음과 같이 유동적인 레이아웃을 고려해보세요:

-                        .padding(top = 210.dp), // TODO: 유동적으로 수정 가능할수도
+                        .weight(1f),
+                    verticalArrangement = Arrangement.Center

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/ui/group/note/component/CommentBottomSheet.kt
at line 61, the padding is hardcoded as top = 210.dp which can cause layout
issues on different screen sizes. Replace this fixed padding value with a
dynamic calculation based on screen dimensions or use a responsive layout
approach such as using Modifier.weight, Spacer, or ConstraintLayout to adjust
padding proportionally. This will ensure the UI adapts smoothly across various
devices.

var isLeaveDialogVisible by remember { mutableStateOf(false) }
var isDeleteDialogVisible by remember { mutableStateOf(false) }

val isOwner = false // 서버에서 받아오기
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

하드코딩된 isOwner 값을 서버에서 받아오도록 구현 필요

현재 isOwner가 false로 하드코딩되어 있습니다. TODO 주석대로 서버에서 실제 소유자 정보를 받아와야 합니다.

서버 API 호출을 통해 소유자 정보를 가져오는 코드를 생성해드릴까요?

🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt at
line 49, the isOwner variable is currently hardcoded to false. Replace this
hardcoded value by implementing a server API call to fetch the actual ownership
status. Use the appropriate network client or repository method to retrieve the
owner information asynchronously and update the isOwner variable accordingly.

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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9f7223 and 29c3ed7.

📒 Files selected for processing (8)
  • app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/TextCommentCard.kt (4 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt (6 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/note/screen/GroupNoteScreen.kt (6 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupEmptyResult.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupFilteredSearchResult.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt (2 hunks)
  • app/src/main/res/values/strings.xml (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupFilteredSearchResult.kt
  • app/src/main/java/com/texthip/thip/ui/group/search/component/GroupEmptyResult.kt
  • app/src/main/java/com/texthip/thip/ui/group/search/screen/GroupSearchScreen.kt
  • app/src/main/java/com/texthip/thip/ui/group/note/component/TextCommentCard.kt
  • app/src/main/res/values/strings.xml
🧰 Additional context used
🧠 Learnings (2)
app/src/main/java/com/texthip/thip/ui/group/note/component/VoteCommentCard.kt (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.981Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.

🧬 Code Graph Analysis (1)
app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (1)
app/src/main/java/com/texthip/thip/ui/common/buttons/ActionMediumButton.kt (1)
  • ActionMediumButton (31-80)
🔇 Additional comments (24)
app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (3)

9-9: 필요한 import 추가가 적절합니다.

size modifier 사용을 위한 import가 올바르게 추가되었습니다.


40-49: 텍스트 컴포넌트가 올바르게 구현되었습니다.

제목과 설명 텍스트의 스타일링과 색상이 다크 테마 다이얼로그에 적합하게 설정되었습니다.


51-69: 버튼 구현이 잘 되어 있습니다.

동일한 가중치, 적절한 색상 구분(취소는 회색, 확인은 퍼플), 그리고 문자열 리소스 사용이 모두 좋은 구현입니다. 버튼 순서(아니오, 예)가 앱의 전체 디자인 가이드라인과 일치하는지 확인해보세요.

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

3-3: 새로운 제스처 기능을 위한 적절한 import 추가

Long press 제스처 처리를 위해 필요한 import들이 올바르게 추가되었습니다.

Also applies to: 15-15


33-35: 콜백 파라미터 구조가 잘 설계됨

새로운 상호작용 콜백들이 기본값과 함께 적절히 추가되어 기존 코드와의 호환성을 유지합니다.


42-44: 상태 파생이 깔끔하게 구현됨

데이터로부터 UI 상태를 명확하게 파생시켜 단일 진실 공급원 원칙을 잘 따릅니다.


47-53: 블러 효과와 제스처 처리가 적절히 구현됨

잠금 상태에 따른 시각적 피드백과 제스처 제어가 잘 구현되었습니다. 조건부 pointer input 사용도 효율적입니다.


77-88: 투표 로직에 잠금 상태 체크가 올바르게 추가됨

잠금 상태일 때 투표를 방지하면서 기존 투표 로직을 잘 보존했습니다.


96-106: 액션 버튼 상호작용이 적절히 제어됨

잠금 상태와 작성자 여부에 따른 버튼 표시 및 상호작용 제어가 올바르게 구현되었습니다.

app/src/main/java/com/texthip/thip/ui/group/note/screen/GroupNoteScreen.kt (15)

3-7: 새로운 기능을 위한 필수 import들이 적절히 추가됨

토스트 애니메이션, 메뉴 바텀시트, 다이얼로그 등 새로운 UI 기능들을 위한 import들이 올바르게 추가되었습니다.

Also applies to: 16-16, 20-20, 34-34, 36-36, 41-42, 52-52, 56-56


72-74: 필터링 로직이 요구사항에 맞게 개선됨

탭 0에서 전체 기록을 표시하도록 변경되어 PR 목표와 일치합니다.


77-86: UI 상태 분리가 아키텍처를 개선함

바텀시트와 다이얼로그 상태를 분리하여 코드 유지보수성과 독립적인 상태 관리가 가능해졌습니다.


88-94: 토스트 자동 숨김 로직이 올바르게 구현됨

LaunchedEffect를 사용한 토스트 타이밍 제어가 적절합니다. 주석의 타이밍 분석(2초 등장 + 4초 노출)과 실제 6초 지연이 일치하는지 확인해주세요.


97-97: 블러 조건이 모든 다이얼로그 상태를 포함하도록 올바르게 업데이트됨

댓글, 메뉴, 핀 다이얼로그 모든 상태에 대해 배경 블러가 적용되도록 로직이 정확합니다.


105-125: 토스트 애니메이션이 잘 구현됨

슬라이드 애니메이션과 적절한 위치 지정, 레이어링이 올바르게 구현되었습니다. 애니메이션 시간도 LaunchedEffect와 일치합니다.


126-139: 상단 영역 구조가 표준 패턴을 잘 따름

탑 앱바와 탭 바 구현이 깔끔하고 적절한 레이아웃을 가집니다.


141-167: 빈 상태 처리가 잘 설계됨

탭에 따른 맥락적 메시지와 적절한 중앙 정렬, FAB을 고려한 패딩이 올바르게 구현되었습니다.


168-235: LazyColumn 구현이 개선됨

itemsIndexed 사용과 조건부 정보 행, 마지막 아이템 패딩 처리가 적절하며, 모든 콜백 처리가 올바르게 구현되었습니다.


239-267: 필터 섹션이 적절히 구현됨

탭 0에서만 표시되는 조건부 로직과 비활성화 상태에서의 토스트 표시가 좋은 UX 개선입니다.


269-282: FAB 구현이 표준을 잘 따름

확장 가능한 플로팅 버튼과 메뉴 아이템 구현이 적절하며, 플레이스홀더 콜백은 현 개발 단계에서 적절합니다.


286-299: 댓글 바텀시트 구현이 올바름

상태 관리와 정리, 모크 데이터 사용이 적절하며 개발 단계에 맞는 구현입니다.


301-341: 메뉴 바텀시트가 역할 기반으로 잘 구현됨

작성자 여부에 따른 동적 메뉴와 타입 체크, 상태 관리가 올바르게 구현되었습니다. TODO 플레이스홀더도 현 단계에서 적절합니다.


343-361: 핀 다이얼로그가 표준 패턴을 잘 따름

중앙 정렬과 상태 관리, 문자열 리소스 사용이 적절하며 표준 다이얼로그 패턴을 올바르게 구현했습니다.


58-362: 전체적으로 잘 구조화된 Compose 화면 구현

다음과 같은 강점들이 있습니다:

  • 상태 관리의 적절한 분리
  • 문자열 리소스 활용 (학습된 선호사항 반영)
  • 조건부 UI 렌더링의 올바른 사용
  • 애니메이션과 제스처 처리의 적절한 구현
  • Compose 베스트 프랙티스 준수

코드가 유지보수 가능하고 확장 가능한 구조를 가지고 있습니다.

Comment on lines +30 to 39
Column(
modifier = modifier
.width(320.dp)
.height(182.dp)
.size(width = 320.dp, height = 182.dp)
.background(
color = colors.DarkGrey,
shape = RoundedCornerShape(12.dp)
)
.padding(20.dp)
.padding(20.dp),
verticalArrangement = Arrangement.SpaceBetween,
) {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

고정 크기 대신 최소 크기 사용을 고려해보세요.

Column으로의 변경과 SpaceBetween 정렬은 다이얼로그 레이아웃에 적합합니다. 하지만 고정 높이(182.dp)는 다음과 같은 문제를 야기할 수 있습니다:

  • 접근성: 큰 글꼴 크기에서 텍스트 잘림 현상
  • 다국어 지원: 언어별 텍스트 길이 차이
  • 유연성: 다양한 컨텐츠 길이 대응 어려움

더 유연한 접근 방식을 고려해보세요:

-            .size(width = 320.dp, height = 182.dp)
+            .width(320.dp)
+            .wrapContentHeight(min = 182.dp)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt around
lines 30 to 39, the Column uses a fixed height of 182.dp which can cause text
clipping with large fonts, issues with varying text lengths in different
languages, and reduces layout flexibility. Replace the fixed height with a
minimum height constraint using .heightIn(min = ...) or remove the fixed height
entirely to allow the Column to expand based on content size, ensuring better
accessibility and adaptability for diverse content.

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.

에러 처리랑 기본 파일명 변경, 위치 변경한거 모두 확인했습니다!

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
Member Author

Choose a reason for hiding this comment

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

이거 제 화면에서 "총평보기"가 disabled상태임에도 클릭이 돼서 toast message가 떠야해서 onDisabledClick을 추가했습니다!

}

if (isBottomSheetVisible && selectedMessage != null) {
val menuItems = if (selectedMessage!!.isMine) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

이런 문은 null safe 하지 않을거 같은데 괜찮나요?

Copy link
Member Author

Choose a reason for hiding this comment

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

해당 코드 바로 위에 이미 if (isBottomSheetVisible && selectedMessage != null)로 null 체크가 있기 때문에 실제로 이 줄이 실행될 때는 selectedMessage가 null일 가능성이 없긴 한데 수정하면 좋긴 할거같아서 ..! 수정하겠습니닷 ~

.blur(if (isLocked) 5.dp else 0.dp)
.pointerInput(Unit) {
if (!isLocked) {
detectTapGestures(onLongPress = { onLongPress() })
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
Member Author

Choose a reason for hiding this comment

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

해당 요소를 꾹 눌렀는지를 감지하는 함수입니닷

.height(600.dp)
) {
Column(
modifier = Modifier
Copy link
Collaborator

Choose a reason for hiding this comment

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

wight를 넣고 fillMaxHeight를 이렇게 넣으면 높이가 어떻게 정해지나요?

Copy link
Member Author

Choose a reason for hiding this comment

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

column의 내용이 column을 꽉 채우는데, column의 높이 자체는 화면의 80%를 채우게 됩니닷 !

Copy link
Member

@JJUYAAA JJUYAAA left a comment

Choose a reason for hiding this comment

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

전체적으로 온클릭 함수, 세세한 부분들 수정하시고 데이터 없는 페이지들 구현 확인했습니다! 수고하셨습니당 ~

HorizontalDivider(modifier = Modifier.height(1.dp), color = colors.Grey03)
Spacer(modifier = Modifier.height(8.dp))
}
Column(modifier = Modifier.padding(20.dp)) {
Copy link
Member

Choose a reason for hiding this comment

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

요기는 Column으로 감싸고 패딩 추가하신 이유가 무엇인가용? 디자인상으로 기존 컴포넌트가 문제될 것이 없어보이는데 어떤 이유로 수정하시게 된건지 궁금합니닷

Copy link
Member Author

Choose a reason for hiding this comment

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

이거 개인적인 QA 진행하면서 피그마랑 디자인이 다르길래 수정한건데
아마 규빈이가 이 bottomsheet도 같이 써야해서 공통으로 분리하면서 padding이 사라져서 추가한걸거입니둣 ~

Comment on lines +30 to +32
Column(
modifier = modifier
.width(320.dp)
.height(182.dp)
.size(width = 320.dp, height = 182.dp)
Copy link
Member

Choose a reason for hiding this comment

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

여기는 column으로 수정된 이유가 어떤걸까요?
제가 생성한 컴포넌트이고 저도 요걸 사용하는 화면이 있었는데, 공통으로 사용되는 팝업창 레이아웃에 맞게끔 Box로 구성해두었다고 생각해서요!

Copy link
Member Author

Choose a reason for hiding this comment

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

아 이거 dialog 안내 내용이 한줄일때 가운데 정렬이 안되길래 수정하게 됐는데
안에 column이 많이 쓰였는데 수정하다보니 box로 안하고 안에쓰인 column만 남겨도 될거같아서 column으로 수정하게 됐습니닷 !

@rbqks529 rbqks529 merged commit 089c5e3 into THIP-TextHip:develop Jul 27, 2025
1 check passed
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.

[UI] 데이터 없는 페이지 [(THIP2025-140)]

3 participants