Skip to content

[FEAT] 네비게이션 연결 기초 세팅 완료#57

Merged
rbqks529 merged 20 commits intoTHIP-TextHip:developfrom
rbqks529:ui/#55_typesafe_navigation
Jul 26, 2025
Merged

[FEAT] 네비게이션 연결 기초 세팅 완료#57
rbqks529 merged 20 commits intoTHIP-TextHip:developfrom
rbqks529:ui/#55_typesafe_navigation

Conversation

@rbqks529
Copy link
Collaborator

@rbqks529 rbqks529 commented Jul 24, 2025

➕ 이슈 링크


🔎 작업 내용

  • 기존 네비게이션 변경 완료
  • 네비게이션 파일 분리 완료
  • 네비게이션 함수 분리 완료

📸 스크린샷


😢 해결하지 못한 과제

  • [] 구글링 + 지피티로 구현해보긴 했는데 한번씩 구조 확인해보시면 좋을거 같습니다


📢 리뷰어들에게

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

Summary by CodeRabbit

  • 새로운 기능

    • 네비게이션 구조가 개선되어 각 주요 화면(피드, 모임, 검색, 마이페이지)에 대한 모듈화된 네비게이션이 추가되었습니다.
    • 하단 네비게이션 바의 아이템 및 라우트가 타입 세이프하게 재정의되어, 아이콘 리소스와 경로 관리가 쉬워졌습니다.
    • Kotlin 직렬화 및 관련 라이브러리 지원이 추가되었습니다.
    • 네비게이션 확장 함수가 도입되어 화면 이동이 간결해졌습니다.
  • 버그 수정 및 개선

    • 하단 네비게이션 바의 표시 로직이 개선되어, 현재 경로에 따라 더 정확하게 표시됩니다.
    • 하단 네비게이션 바의 디자인이 개선되어 상단 모서리에 곡선 테두리가 추가되었습니다.
    • 일부 아이콘 리소스가 변경되었습니다.
    • 알림 화면의 빈 상태 UI에서 아이콘 및 간격이 제거되고 텍스트 스타일이 개선되었습니다.
  • 리팩터 및 구조 개선

    • 네비게이션 관련 데이터와 확장 함수, 라우트 정의가 파일별로 분리되어 유지보수성이 향상되었습니다.
    • ViewModel 및 미리보기 관련 코드가 간소화되었습니다.
    • 그룹 화면의 네비게이션 콜백 구조가 변경되어 직접적인 네비게이션 의존성이 제거되었습니다.
  • 기타

    • 여러 라이브러리와 플러그인의 버전이 최신으로 업데이트되었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Jul 24, 2025

"""

Walkthrough

이 변경사항은 앱의 네비게이션 시스템을 전면적으로 리팩토링하여, 기존의 문자열 기반 라우트와 BarItem 정의를 타입 세이프하고 직렬화 가능한 Routes 계층 구조로 대체합니다. 네비게이션 구성은 각 기능별로 모듈화된 함수로 분리되었고, 관련된 데이터 클래스와 확장 함수가 새롭게 도입되었습니다. 또한, Gradle 및 라이브러리 버전이 최신화되고, Kotlin 직렬화가 추가되었습니다.

Changes

파일/그룹 변경 요약
app/build.gradle.kts, gradle/libs.versions.toml Kotlin 직렬화 플러그인 및 라이브러리 추가, 주요 라이브러리 및 플러그인 버전 업데이트
app/src/main/java/com/texthip/thip/MainScreen.kt 바텀 네비게이션 노출 조건 로직을 Routes 기반으로 변경, UI 및 변수명 정리
app/src/main/java/com/texthip/thip/ui/group/makeroom/screen/GroupMakeRoomScreen.kt, app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt Preview ViewModel 목 구현 방식 변경, MockGroupRepository 추가 및 기본값 지정
app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt, app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt 네비게이션 의존성 제거 및 FAB 클릭 방식 변경, 불필요 메서드 제거
app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt 알림 설정 아이콘 리소스 변경
app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt, app/src/main/java/com/texthip/thip/ui/navigator/NavBarItems.kt, app/src/main/java/com/texthip/thip/ui/navigator/Routes.kt 기존 BarItem, NavBarItems, Routes 파일 및 클래스 삭제
app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt NavHostController 기반으로 리팩토링, 아이콘 및 선택 로직 개선, 커스텀 테두리 추가, 색상 일관화
app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt 네비게이션 그래프 구성을 각 기능별 모듈화 함수로 분리
app/src/main/java/com/texthip/thip/ui/navigator/data/BarItem.kt, app/src/main/java/com/texthip/thip/ui/navigator/data/NavBarItems.kt 타입 세이프 BarItem 및 NavBarItems 클래스 신규 생성
app/src/main/java/com/texthip/thip/ui/navigator/extensions/*.kt 네비게이션 관련 확장 함수 신규 추가 (탭 이동, 뒤로가기 등)
app/src/main/java/com/texthip/thip/ui/navigator/navigations/*.kt Feed, Group, Search, MyPage 네비게이션 그래프 빌더 함수 신규 추가
app/src/main/java/com/texthip/thip/ui/navigator/routes/*.kt Routes, FeedRoutes, GroupRoutes, MyPageRoutes, SearchRoutes 등 타입 세이프 sealed class 계층 신규 도입
app/src/main/res/values/strings.xml 네비게이션 라벨용 문자열 리소스 추가
app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt 빈 상태 UI에서 아이콘 및 Spacer 제거, 텍스트 스타일 및 색상 변경

Sequence Diagram(s)

sequenceDiagram
    participant MainScreen
    participant NavHostController
    participant MainNavHost
    participant feedNavigation
    participant groupNavigation
    participant searchNavigation
    participant myPageNavigation

    MainScreen->>NavHostController: 현재 목적지 확인
    MainScreen->>MainNavHost: 네비게이션 그래프 호출(navController)
    MainNavHost->>feedNavigation: Feed 네비게이션 등록
    MainNavHost->>groupNavigation: Group 네비게이션 등록
    MainNavHost->>searchNavigation: Search 네비게이션 등록
    MainNavHost->>myPageNavigation: MyPage 네비게이션 등록
    Note over MainNavHost: 각 navigation 함수가<br>해당 화면의 Composable 등록
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40분

Possibly related PRs

  • THIP-TextHip/THIP-Android#21: 기존 네비게이터 패키지 및 BarItem, NavBarItems, Routes 등 네비게이션 구성요소의 초기 도입과 관련. 본 PR은 이 구조를 타입 세이프 방식으로 대체 및 리팩토링함.

Suggested reviewers

  • Nico1eKim

Poem

토끼가 깡총깡총 뛰며 외치네,
"이제 네비게이션, 타입 세이프하게!"
문자열 대신 sealed class,
화면 이동도 한결 쉽지!
🐰✨
코드가 깔끔해진 오늘,
우리 앱도 한 단계 점프!

"""

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.

This comment was marked as outdated.

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

🔭 Outside diff range comments (2)
app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt (1)

19-76: 하드코딩된 문자열을 strings.xml로 추출하는 것을 권장합니다

init 블록에 많은 한국어 문자열이 하드코딩되어 있습니다. 유지보수와 국제화를 위해 이러한 문자열들을 strings.xml로 추출하는 것이 좋겠습니다.

예시:

- GroupCardData("호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1")
+ GroupCardData(context.getString(R.string.group_hormone_change), 22, R.drawable.bookcover_sample, 40, "uibowl1")
app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt (1)

80-82: 에러 핸들링 로직을 활성화하는 것을 고려해보세요.

현재 에러 메시지 표시 부분이 주석 처리되어 있습니다. 사용자 경험 개선을 위해 적절한 에러 피드백을 제공하는 것이 좋겠습니다.

학습된 정보에 따르면 현재 프로토타입 단계이므로 추후 구현 예정인 것으로 이해하지만, 기본적인 에러 처리는 현재 단계에서도 유용할 것 같습니다.

Also applies to: 94-95, 97-98

🧹 Nitpick comments (6)
app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt (1)

110-113: 아이콘 리소스 교체 시 접근성 설명도 함께 고려
R.drawable.ic_notice로 변경되었지만 contentDescription이 없으면 TalkBack 사용자가 버튼 의미를 알 수 없습니다. MenuItemButton 내부에 description을 전달할 API가 있다면 문자열 자원(@string/notification_settings)을 함께 넣어 주세요.

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

9-14: 일관된 네비게이션 패턴이 잘 적용되었습니다

다른 네비게이션 함수들과 일관된 구조를 가지고 있어 좋습니다. 다만 9번 라인의 주석을 좀 더 구체적으로 작성하면 어떨까요?

- // Feed
+ // Feed 화면 네비게이션 설정
app/src/main/java/com/texthip/thip/ui/navigator/data/Routes.kt (1)

19-22: 라우트 구조 개선을 고려해보세요.

GroupMakeRoom이 "Group 관련 하위 화면"이라고 주석 처리되어 있지만, 구조적으로는 다른 메인 라우트들과 같은 레벨에 위치하고 있습니다. 더 명확한 계층 구조를 위해 중첩 sealed class를 고려해보세요:

 @Serializable
 sealed class Routes {
     @Serializable
     data object Feed : Routes()
     
     @Serializable
-    data object Group : Routes()
+    sealed class Group : Routes() {
+        @Serializable
+        data object Main : Group()
+        
+        @Serializable
+        data object MakeRoom : Group()
+    }
     
     @Serializable
     data object Search : Routes()
     
     @Serializable
     data object MyPage : Routes()
-    
-    // Group 관련 하위 화면들
-    @Serializable
-    data object GroupMakeRoom : Routes()
 }

이렇게 하면 Group 관련 화면들의 계층 관계가 더 명확해집니다.

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

80-82: 하드코딩된 문자열을 StringResource로 추출 고려

이전 학습 내용에 따르면 하드코딩된 UI 문자열을 strings.xml로 추출하는 것을 선호하시는데, 주석 내의 "에러는 uiState.errorMessage로 처리"와 같은 문자열도 추출을 고려해보시기 바랍니다.

유지보수성과 다국어 지원을 위해 모든 사용자 대면 텍스트는 StringResource 사용을 권장합니다.

app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt (1)

127-139: MockGroupRepository 구현에 추가 시나리오 고려를 권장합니다.

현재 구현은 항상 성공 응답만 반환합니다. 실제 개발과 테스트에서는 다음과 같은 시나리오도 필요할 수 있습니다:

 class MockGroupRepository : GroupRepository {
     override suspend fun createGroup(request: GroupMakeRoomRequest): ApiResult<GroupCreateResponse> {
+        // 테스트를 위한 실패 시나리오 추가 (예: 빈 제목일 때)
+        if (request.roomTitle.isBlank()) {
+            return ApiResult(
+                isSuccess = false,
+                message = "방 제목을 입력해주세요"
+            )
+        }
+        
+        // 네트워크 지연 시뮬레이션
+        kotlinx.coroutines.delay(500)
+        
         // 임시로 성공 응답 반환
         return ApiResult(
             isSuccess = true,
             data = GroupCreateResponse(
                 groupId = "mock_group_${System.currentTimeMillis()}",
                 groupName = request.roomTitle
             )
         )
     }
 }
app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt (1)

50-88: 커스텀 테두리 구현이 정교합니다.

Path를 사용한 둥근 모서리 테두리 구현이 잘 되어 있습니다. 다만 복잡한 그리기 로직이므로 성능을 고려해보세요.

만약 성능 이슈가 발생한다면, Compose의 내장 Border modifier나 더 간단한 방식을 고려할 수 있습니다:

// 대안 1: 간단한 테두리
.border(
    width = 2.dp,
    color = greyColor,
    shape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)
)

// 대안 2: remember로 Path 캐싱
val borderPath = remember { Path() }
📜 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 53b0e58.

📒 Files selected for processing (25)
  • app/build.gradle.kts (2 hunks)
  • app/src/main/java/com/texthip/thip/MainScreen.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/makeroom/screen/GroupMakeRoomScreen.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt (2 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/mypage/screen/MypageScreen.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt (0 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt (4 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/NavBarItems.kt (0 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/Routes.kt (0 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/data/BarItem.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/data/NavBarItems.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/data/Routes.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/extensions/CommonNavigationExtensions.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/extensions/FeedNavigationExtensions.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/extensions/GroupNavigationExtensions.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/extensions/MyPageNavigationExtensions.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/extensions/SearchNavigationExtensions.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/navigations/MyPageNavigation.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/navigations/SearchNavigation.kt (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
💤 Files with no reviewable changes (3)
  • app/src/main/java/com/texthip/thip/ui/navigator/NavBarItems.kt
  • app/src/main/java/com/texthip/thip/ui/navigator/Routes.kt
  • app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt
🧰 Additional context used
🧠 Learnings (8)
📓 Common 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/mypage/screen/MypageScreen.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/viewmodel/GroupViewModel.kt (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.239Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.

app/src/main/java/com/texthip/thip/ui/navigator/extensions/MyPageNavigationExtensions.kt (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.239Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.

app/src/main/java/com/texthip/thip/ui/navigator/navigations/MyPageNavigation.kt (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.239Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.

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

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.

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.239Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.

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

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.239Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.

app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt (1)

Learnt from: rbqks529
PR: #30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.239Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.

🧬 Code Graph Analysis (4)
app/src/main/java/com/texthip/thip/ui/navigator/navigations/SearchNavigation.kt (1)
app/src/main/java/com/texthip/thip/ui/search/screen/SearchBookScreen.kt (1)
  • SearchBookScreen (36-160)
app/src/main/java/com/texthip/thip/MainScreen.kt (2)
app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt (1)
  • BottomNavigationBar (33-131)
app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt (1)
  • MainNavHost (13-21)
app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt (4)
app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt (1)
  • feedNavigation (10-14)
app/src/main/java/com/texthip/thip/ui/navigator/navigations/GroupNavigation.kt (1)
  • groupNavigation (15-38)
app/src/main/java/com/texthip/thip/ui/navigator/navigations/SearchNavigation.kt (1)
  • searchNavigation (9-13)
app/src/main/java/com/texthip/thip/ui/navigator/navigations/MyPageNavigation.kt (1)
  • myPageNavigation (10-19)
app/src/main/java/com/texthip/thip/ui/navigator/navigations/FeedNavigation.kt (1)
app/src/main/java/com/texthip/thip/ui/feed/screen/FeedScreen.kt (1)
  • FeedScreen (21-42)
🔇 Additional comments (31)
gradle/libs.versions.toml (3)

2-3: 의존성 대폭 업그레이드 시 호환성 재확인 필요
AGP 8.9.3 ↗, Kotlin 2.2.0 ↗ 업그레이드는 컴파일러/플러그인, 특히 KSP·Compose Compiler 버전과의 상호 호환성에 직결됩니다. 루트 build.gradle 및 CI 이미지가 동일 버전을 사용하도록 맞춰져 있는지 한 번 더 검증해 주세요.


11-14: Navigation 2.9.2 전체 업그레이드 👍
버전 불일치가 없어 가독성이 좋아졌습니다.


17-18: kotlinx-serialization-json 1.9.0 존재 확인됨
Maven Central에서 버전 1.9.0이 정상적으로 배포된 것이 확인되었습니다. 추가 조치 없이 그대로 머지하셔도 됩니다.

app/build.gradle.kts (2)

7-8: Serialization 플러그인 추가 👍 → compileTasks 확인
kotlin-serialization 플러그인은 kapt/ksp와 충돌 사례가 가끔 있습니다. 해당 모듈에서 다른 플러그인과 함께 사용 중이라면 빌드 타스크 캐시가 깨지지 않는지 확인해 주세요.


59-59: 직렬화 라이브러리 모듈 의존성 OK
implementation(libs.kotlinx.serialization.json) 추가로 Routes sealed class의 @Serializable 사용이 가능해졌습니다. 별다른 문제 없어 보입니다.

app/src/main/java/com/texthip/thip/ui/group/viewmodel/GroupViewModel.kt (2)

1-1: 패키지 구조 개선이 잘 되었습니다

ViewModel을 mock 패키지에서 적절한 viewmodel 패키지로 이동시킨 것이 좋습니다. 이는 더 명확한 코드 구조를 제공합니다.


5-7: Mock 데이터 import가 적절히 추가되었습니다

패키지 변경에 따라 필요한 mock 데이터 클래스들을 정확히 import했습니다.

app/src/main/java/com/texthip/thip/ui/navigator/extensions/MyPageNavigationExtensions.kt (1)

9-11: 타입 안전한 네비게이션 확장 함수가 잘 구현되었습니다

Routes.MyPage를 사용한 타입 안전한 네비게이션 구조가 기존 문자열 기반 방식보다 훨씬 개선되었습니다. 코드가 간결하고 명확합니다.

app/src/main/java/com/texthip/thip/ui/navigator/navigations/SearchNavigation.kt (1)

9-13: 모듈화된 네비게이션 구조가 훌륭합니다

NavGraphBuilder 확장 함수를 통한 모듈화된 네비게이션 구조가 코드의 가독성과 유지보수성을 크게 향상시켰습니다. 타입 안전한 Routes.Search 사용도 좋습니다.

app/src/main/java/com/texthip/thip/ui/navigator/data/Routes.kt (1)

5-23: 타입 세이프 네비게이션 구조가 잘 설계되었습니다.

문자열 기반 라우팅에서 sealed class 기반으로의 전환이 훌륭합니다. @Serializable 어노테이션을 통한 직렬화 지원도 적절합니다.

app/src/main/java/com/texthip/thip/ui/navigator/navigations/MyPageNavigation.kt (1)

10-18: 모듈화된 네비게이션 구조가 훌륭합니다.

NavGraphBuilder 확장 함수를 통한 모듈화된 접근 방식이 좋습니다. 기존의 단일 파일에서 각 섹션별로 분리한 것이 유지보수성을 크게 향상시킵니다.

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

35-37: 네비게이션 의존성 분리가 잘 되었습니다.

NavController 직접 의존성을 제거하고 콜백 패턴으로 변경한 것이 좋습니다. 이렇게 하면 컴포넌트 테스트가 용이해지고 관심사 분리가 더 명확해집니다.


30-30: import 경로 수정이 적절합니다.

GroupViewModel의 import 경로가 새로운 패키지 구조에 맞게 올바르게 업데이트되었습니다.


98-101: FAB 콜백 패턴이 깔끔합니다.

FloatingButton의 클릭 핸들러가 콜백 패턴으로 변경된 것이 좋습니다. 이전의 viewModel.onFabClick() 방식보다 더 명확하고 테스트하기 용이합니다.

app/src/main/java/com/texthip/thip/MainScreen.kt (3)

9-14: 타입 세이프 네비게이션으로의 전환이 좋습니다.

문자열 기반 라우트 체크에서 Routes sealed class를 사용하는 방식으로 변경한 것이 훌륭합니다. 컴파일 타임 안전성이 크게 향상됩니다.


28-30: 기본 동작 검토가 필요합니다.

currentDestination?.route가 null일 때 기본적으로 하단 네비게이션 바를 표시하도록 설정되어 있습니다(?: true). 이것이 의도된 동작인지 확인이 필요합니다. 일반적으로는 메인 탭이 아닌 화면에서는 하단 바를 숨기는 것이 더 일반적입니다.


36-36: 투명한 컨테이너 색상 설정이 적절합니다.

ScaffoldcontainerColor를 투명으로 설정한 것이 좋습니다. 이렇게 하면 각 화면에서 자체적으로 배경색을 관리할 수 있어 더 유연합니다.

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

15-38: 네비게이션 구조가 잘 설계되었습니다!

  • 타입 세이프한 Routes 클래스 사용으로 컴파일 타임 안전성 확보
  • 화면별 콜백 패턴 적용으로 관심사 분리가 잘 되어 있음
  • 확장 함수를 통한 네비게이션 로직 캡슐화가 적절함
  • ViewModel 인스턴스화도 표준 방식을 따름

모듈화된 네비게이션 구조로 유지보수성이 크게 개선되었습니다.

app/src/main/java/com/texthip/thip/ui/navigator/extensions/CommonNavigationExtensions.kt (2)

10-12: 단순하고 명확한 뒤로가기 구현

popBackStack()을 사용한 간단하고 직관적인 구현입니다.


15-23: 하단 네비게이션에 적합한 옵션 설정

탭 네비게이션에 최적화된 네비게이션 옵션들이 올바르게 설정되어 있습니다:

  • popUpTosaveState로 스택 중복 방지 및 상태 저장
  • launchSingleTop으로 동일 화면 중복 생성 방지
  • restoreState로 이전 상태 복원

Android 네비게이션 베스트 프랙티스를 잘 따르고 있습니다.

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

5-10: 모듈화된 네비게이션 임포트가 잘 구성되었습니다

각 기능별로 분리된 네비게이션 모듈들을 깔끔하게 임포트하고 있습니다. 코드 구조가 명확해졌습니다.


15-20: 네비게이션 그래프 구성이 크게 개선되었습니다

  • 타입 세이프한 Routes.Feed 시작 목적지 설정
  • 각 기능별 네비게이션 함수 호출로 모듈화 완성
  • 인라인 composable 정의를 함수 호출로 대체하여 가독성 향상

이전 구조 대비 유지보수성과 확장성이 크게 개선되었습니다.

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

27-27: ViewModel Compose 라이브러리 임포트 추가

프리뷰에서 표준 ViewModel 인스턴스화를 위한 적절한 임포트입니다.


238-238: 프리뷰 ViewModel 인스턴스화 개선

수동 목 ViewModel 생성을 표준 viewModel() 함수로 대체한 것이 좋습니다. UI 파일에서 목 로직을 제거하여 관심사 분리가 개선되었습니다.

app/src/main/java/com/texthip/thip/ui/navigator/extensions/GroupNavigationExtensions.kt (1)

9-15: 간결하고 명확한 그룹 네비게이션 확장 함수들

타입 세이프한 Routes 객체를 사용한 깔끔한 네비게이션 확장 함수 구현입니다. 각 함수가 단일 책임을 가지며 명확한 목적을 제공합니다.

전체 네비게이션 아키텍처와 일관성 있게 설계되었습니다.

app/src/main/java/com/texthip/thip/ui/group/makeroom/viewmodel/GroupMakeRoomViewModel.kt (1)

15-17: 의존성 주입 구조가 개선되었습니다.

Mock repository를 기본값으로 제공하여 테스트와 개발 단계에서 편의성을 높였습니다. 추후 실제 repository 구현 시에도 쉽게 교체할 수 있는 구조입니다.

app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt (5)

26-26: NavHostController 타입 변경이 적절합니다.

새로운 네비게이션 아키텍처와의 일관성을 위한 올바른 변경입니다. 타입 안전성도 향상됩니다.

Also applies to: 34-34


35-35: 새로운 Routes sealed class와 잘 통합된 선택 로직입니다.

simpleName을 사용한 route 비교 방식이 타입 안전한 네비게이션 시스템과 잘 어울립니다. 기존 문자열 기반 비교보다 안전합니다.

Also applies to: 100-100


104-104: camelCase 속성명 사용이 코틀린 컨벤션에 적합합니다.

selectedIconResiconRes 네이밍이 일관되고 읽기 쉽습니다.


29-29: 네비게이션 확장 함수 사용으로 코드가 더 깔끔해졌습니다.

navigateToTab 확장 함수를 사용하여 네비게이션 로직을 중앙화한 것이 좋습니다. 코드 재사용성과 유지보수성이 향상됩니다.

Also applies to: 117-117


36-36: 테마 색상 사용으로 일관성이 개선되었습니다.

Color.Unspecified 대신 colors.Grey02를 사용하여 앱 전체의 디자인 일관성을 높였습니다.

Also applies to: 123-123, 125-125

Comment on lines 6 to 9
// Feed 확장 함수
fun NavHostController.navigateToFeed() {
navigate(Routes.Feed)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

navigate(Routes.Feed) 컴파일 여부 확인
NavHostController.navigate() 기본값은 String. 별도 확장 함수 navigate(route: Routes)를 정의하지 않았다면 이 코드는 컴파일 오류가 납니다. 존재 여부를 다시 한번 확인하거나 아래와 같이 route 프로퍼티(또는 name)로 넘겨주세요.

-fun NavHostController.navigateToFeed() {
-    navigate(Routes.Feed)
-}
+fun NavHostController.navigateToFeed() {
+    navigate(Routes.Feed.route) // 또는 Routes.Feed.name 등
+}
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/ui/navigator/extensions/FeedNavigationExtensions.kt
lines 6 to 9, the call navigate(Routes.Feed) may cause a compile error because
NavHostController.navigate() expects a String parameter and there is no
navigate(route: Routes) extension defined. To fix this, confirm if such an
extension exists; if not, change the argument to navigate(Routes.Feed.route) or
navigate(Routes.Feed.name) to pass a String route instead.

Comment on lines 7 to 10
// Search 관련 네비게이션 확장 함수들
fun NavHostController.navigateToSearch() {
navigate(Routes.Search)
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Search 확장 함수도 동일 이슈
위 Feed와 동일하게 Routes.Search 객체를 직접 넘기면 타입 미스매치가 발생할 수 있습니다. 공통 확장 NavHostController.navigate(Routes)가 존재하는지 확인 후 필요 시 프로퍼티로 전달해 주세요.

🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/ui/navigator/extensions/SearchNavigationExtensions.kt
around lines 7 to 10, the function navigateToSearch passes Routes.Search
directly to navigate, causing a type mismatch. Check if there is a common
extension function NavHostController.navigate(Routes) that accepts a property
instead of the object. If so, modify navigateToSearch to pass the appropriate
property from Routes.Search rather than the object itself to fix the type
mismatch.

@rbqks529 rbqks529 requested review from JJUYAAA and Copilot July 25, 2025 04:50
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

네비게이션 구조를 개선하여 타입 세이프한 네비게이션 시스템을 도입한 PR입니다. Kotlin 직렬화를 활용한 라우트 정의와 모듈화된 네비게이션 구조로 변경되었습니다.

  • 기존 String 기반 라우트를 Kotlin 직렬화 기반 타입 세이프 라우트로 변경
  • 네비게이션 관련 코드를 기능별로 모듈화하여 분리
  • 확장 함수를 통한 네비게이션 로직 간소화 및 재사용성 향상

Reviewed Changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
gradle/libs.versions.toml Kotlin 직렬화 및 관련 라이브러리 의존성 추가
app/build.gradle.kts Kotlin 직렬화 플러그인 적용
app/src/main/res/values/strings.xml 네비게이션 탭 이름을 위한 문자열 리소스 추가
Routes 관련 파일들 기존 String 기반 라우트를 Kotlin 직렬화 기반으로 재정의
Navigation 관련 파일들 기능별로 네비게이션 로직을 분리하고 확장 함수 추가
MainNavHost.kt 새로운 네비게이션 구조에 맞게 메인 네비게이션 호스트 업데이트
BottomNavigationBar.kt 타입 세이프 라우트와 확장 함수를 사용하도록 개선
GroupScreen.kt 네비게이션 콜백 구조로 변경하여 직접적인 네비게이션 의존성 제거

open class GroupMakeRoomViewModel(
private val groupRepository: GroupRepository // 의존성 주입
class GroupMakeRoomViewModel(
private val groupRepository: GroupRepository = MockGroupRepository() // 기본값으로 Mock Repository 사용
Copy link

Copilot AI Jul 25, 2025

Choose a reason for hiding this comment

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

Production code should not have Mock implementations as default parameters. Consider using dependency injection or factory patterns to provide the appropriate repository implementation based on the environment.

Suggested change
private val groupRepository: GroupRepository = MockGroupRepository() // 기본값으로 Mock Repository 사용
private val groupRepository: GroupRepository // Dependency must be explicitly provided

Copilot uses AI. Check for mistakes.
// Bottom Navigation용 Tab 이동 (메인 탭에만 사용)
fun NavHostController.navigateToTab(route: MainTabRoutes) {
navigate(route) {
popUpTo(graph.startDestinationId) {
Copy link

Copilot AI Jul 25, 2025

Choose a reason for hiding this comment

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

Using graph.startDestinationId may not work correctly with type-safe navigation. Consider using the actual start destination route instead.

Suggested change
popUpTo(graph.startDestinationId) {
popUpTo(MainTabRoutes.Feed::class.qualifiedName ?: "") {

Copilot uses AI. Check for mistakes.
val cornerRadius = 12.dp.toPx()
val strokeWidth = 2.dp.toPx()

val path = Path().apply {
Copy link

Copilot AI Jul 25, 2025

Choose a reason for hiding this comment

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

Creating a Path object in the drawBehind block will be executed on every recomposition. Consider moving this path creation outside the drawBehind or caching it.

Copilot uses AI. Check for mistakes.
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: 0

🧹 Nitpick comments (1)
app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt (1)

113-117: 프리뷰의 하드코딩된 문자열을 string resource로 추출하는 것을 고려해 보세요.

프리뷰 함수에서 사용된 하드코딩된 한국어 문자열들("피드", "내 글을 좋아합니다." 등)을 strings.xml로 추출하면 일관성과 유지보수성이 향상됩니다. 이는 이전에 선호했던 방식과도 일치합니다.

예시:

-AlarmItem(1, "피드", "내 글을 좋아합니다.", "user123님이 내 글에 좋아요를 눌렀어요.", "2", false),
+AlarmItem(1, stringResource(R.string.alarm_feed), stringResource(R.string.preview_like_title), stringResource(R.string.preview_like_message), "2", false),
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between dd15818 and 14d5b7b.

📒 Files selected for processing (1)
  • app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common 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/alarmpage/screen/AlarmScreen.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.

🔇 Additional comments (2)
app/src/main/java/com/texthip/thip/ui/common/alarmpage/screen/AlarmScreen.kt (2)

77-78: 빈 상태 텍스트 스타일링 개선이 적용되었습니다.

텍스트 크기가 증가하고 색상이 흰색으로 변경되어 가독성이 향상되었습니다. 다만 배경색과의 대비를 확인하여 접근성 가이드라인을 준수하는지 검토해 주세요.


35-104: 전체적으로 잘 구현된 AlarmScreen 컴포저블입니다.

  • 상태 관리가 적절히 구현되어 있습니다
  • 필터링 로직이 명확하고 올바릅니다
  • 빈 상태와 리스트 상태 모두 적절히 처리되어 있습니다
  • string resource 사용이 일관되게 적용되어 있습니다
  • 프리뷰 컴포저블도 빈 상태와 데이터가 있는 상태 모두 제공되어 있어 좋습니다

@rbqks529 rbqks529 merged commit e95b216 into THIP-TextHip:develop Jul 26, 2025
1 check passed
@coderabbitai coderabbitai bot mentioned this pull request Aug 19, 2025
1 task
@coderabbitai coderabbitai bot mentioned this pull request Sep 25, 2025
4 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.

[FEAT] 네비게이션 연결 [(THIP2025-149)]

2 participants