Skip to content

[UI] view appbar header modal 컴포넌트 구현#21

Merged
JJUYAAA merged 27 commits intoTHIP-TextHip:developfrom
JJUYAAA:ui/#19_common_components_view_appbar_header_modal
Jun 23, 2025
Merged

[UI] view appbar header modal 컴포넌트 구현#21
JJUYAAA merged 27 commits intoTHIP-TextHip:developfrom
JJUYAAA:ui/#19_common_components_view_appbar_header_modal

Conversation

@JJUYAAA
Copy link
Member

@JJUYAAA JJUYAAA commented May 31, 2025

➕ 이슈 링크


🔎 작업 내용

  • view/countingbar
  • header/profilebar_feed -> ProfileBar, AuthorHeader, ProfileBarWithDate 세개로 나누어 구현
  • modal/tooltip -> 화살표 방향 세가지 중 선택 가능하도록
  • modal/snackbar
  • modal/popup -> InfoPopup, DialogPopup 두개로 나누어 구현 / InfoPopup에 사용되는 ScrollbarUtil 구현
  • Appbar/bottomnavi -> navigator 패키지 안에 BarItem, BottomNavigationBar, MainNavHost, NavBarItems, Routes 를 생성하였으며, 필요한 screen들 생성 (추후 논의 후 대공사가 필요한 부분이라 지난 회의 이후 수정하지 않은 파일들입니다)

📸 스크린샷

view/countingbar -> CountingBar
image
header/profilebar_feed -> AuthorHeader, ProfileBar, ProfileBarWithDate
AuthorHeader
image
ProfileBar
image
ProfileBarWithDate
image

modal/tooltip -> ToolTip
image
modal/snackbar -> SnackBar
image

modal/popup -> InfoPopup, DialogPopup
InfoPopup
Screen_recording_20250531_201914

DialogPopup
image

Appbar/bottomnavi
Screen_recording_20250531_200409


😢 해결하지 못한 과제

  • 바텀네비게이션은 지난 회의 날 요즘 방식(?)으로 구현하기로 의논했기에 더 건들이지 않고 4개의 메인 화면에만 연결해놓은 상태입니다. 나중에 같이 논의해보면 좋을 것 같습니당


📢 리뷰어들에게

  • 컴포즈는 처음이라 아직도 익숙하지가 않아서 실수가 많을 것 같습니다ㅜㅜ😢 마구마구 지적해주시면 금방 수정하도록 하겠습니당

Summary by CodeRabbit

  • 신규 기능
    • 메인 화면에 하단 내비게이션 바 및 네비게이션 구조 추가
    • 피드, 모임, 도서 검색, 내 정보 등 주요 화면 및 네비게이션 경로 추가
    • 저자 헤더, 프로필 바, 날짜 포함 프로필 바, 카운팅 바, 다이얼로그 팝업, 정보 팝업, 스낵바, 툴팁 등 다양한 공통 UI 컴포넌트 추가
  • 라이브러리 및 리소스
    • Jetpack Navigation Compose 라이브러리 도입
    • 하단 내비게이션 아이콘(선택 상태) 벡터 드로어블 4종 추가
    • 문자열 리소스 11종 추가 및 기존 컬러 리소스 일부 제거
  • 기타
    • 프로젝트 설정 및 IDE 관련 파일 일부 수정 및 추가

Nico1eKim and others added 21 commits May 15, 2025 02:20
[INIT]: 메인 브랜치에 합치기
Copy link
Member

@Nico1eKim Nico1eKim left a comment

Choose a reason for hiding this comment

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

수고하셨습니둥 ~~ 전반적으로 컴포넌트 분리 잘 한거같아요 !!

참고사항으로 패키지에 대문자가 들어가는게 일반적이지 않은걸로 알고있는데 아마 깃허브에서 대소문자 인식을 못할거라서 리팩할거면 패키지를 삭제해서 pr올리고 다시 패키지 만들어서 pr 올려야될거에용 .. 지금 있는 패키지들은 냅둬도 될거같은데 추후 만드는 패키지에는 대문자 자제해주세용 ~ (사실 저도 몰랐던 사실)

Comment on lines 63 to 95
Row(
horizontalArrangement = Arrangement.spacedBy(20.dp),
modifier = Modifier.fillMaxWidth()
) {
Button(
onClick = onCancel,
colors = ButtonDefaults.buttonColors(
containerColor = colors.Grey02
),
shape = RoundedCornerShape(12.dp),
modifier = Modifier.weight(1f)
) {
Text(
stringResource(R.string.no),
color = colors.White,
style = typography.smalltitle_sb600_s16_h24
)
}

Button(
onClick = onConfirm,
colors = ButtonDefaults.buttonColors(
containerColor = colors.Purple
),
shape = RoundedCornerShape(12.dp),
modifier = Modifier.weight(1f)
) {
Text(
stringResource(R.string.yes),
color = colors.White,
style = typography.smalltitle_sb600_s16_h24
)
}
Copy link
Member

Choose a reason for hiding this comment

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

이부분 제 pr 머지되면 제가 만들어둔 공통 컴포넌트로 리팩부탁해욧 ..! 잘만들었느데 통일성있게 공통 컴포넌트 쓰면 좋을것같아서링 ..ㅎ.ㅎ.ㅎ.

Copy link
Member Author

Choose a reason for hiding this comment

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

알게쓤다잇 ㅎㅅㅎ

Comment on lines +13 to +42
fun Modifier.drawVerticalScrollbar(
scrollState: ScrollState,
trackThickness: Dp = 1.dp,
thumbThickness: Dp = 3.dp,
trackColor: Color = Color.White.copy(alpha = 0.2f),
thumbColor: Color = Color.White.copy(alpha = 0.8f),
): Modifier = this.then(
Modifier.drawBehind {
if (scrollState.maxValue == 0) return@drawBehind

val scrollbarHeight = size.height / 8f
val scrollProgress = scrollState.value.toFloat() / scrollState.maxValue
val scrollbarOffsetY = (size.height - scrollbarHeight) * scrollProgress

//전체 고정 바
drawRoundRect(
color = trackColor,
topLeft = Offset(x = size.width - trackThickness.toPx(), y = 0f),
size = Size(trackThickness.toPx(), size.height),
cornerRadius = CornerRadius(trackThickness.toPx() / 2)
)
//핸들 바
drawRoundRect(
color = thumbColor,
topLeft = Offset(x = size.width - thumbThickness.toPx(), y = scrollbarOffsetY),
size = Size(thumbThickness.toPx(), scrollbarHeight),
cornerRadius = CornerRadius(thumbThickness.toPx() / 2)
)
}
) No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

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

우왕 싱기하다 ~~ 저도 스크롤 커스텀은 한번도 안해봤는데 싱기하네요

Comment on lines +69 to +84
val arrowModifier = when (arrowPosition) {
ArrowPosition.LEFT -> Modifier
.align(Alignment.TopStart)
.padding(start = 24.dp)

ArrowPosition.CENTER -> Modifier
.align(Alignment.TopCenter)

ArrowPosition.RIGHT -> Modifier
.align(Alignment.TopEnd)
.padding(end = 24.dp)
}
TriangleArrow(
color = colors.DarkGrey,
modifier = arrowModifier
)
Copy link
Member

Choose a reason for hiding this comment

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

👍

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.

확인했습니다!

}
} else {
Text(
text = stringResource(R.string.hours_ago,10),
Copy link
Collaborator

Choose a reason for hiding this comment

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

몇 시간 전인지 함수 파라미터 변수에 추가 되면 좋을 거 같아요

@coderabbitai
Copy link

coderabbitai bot commented Jun 23, 2025

"""

Walkthrough

이 변경사항은 Jetpack Compose 기반의 Android 앱에 공통 헤더, 모달, 뷰 컴포넌트와 네비게이션 구조를 도입합니다. 여러 UI 컴포넌트(헤더, 프로필 바, 다이얼로그, 스낵바 등)와 네비게이션 관련 파일, string 및 drawable 리소스가 추가되었으며, Gradle 및 IDE 설정도 일부 갱신되었습니다.

Changes

파일/경로 그룹 변경 요약
.idea/... IDE 설정 파일 추가 및 수정: 프로젝트 명, 컴파일러, 배포 타겟, JDK 설정 등 업데이트
app/build.gradle.kts, gradle/libs.versions.toml Navigation Compose 라이브러리 의존성 추가 및 버전 명시
app/src/main/java/com/texthip/thip/MainActivity.kt MainScreen 컴포저블로 메인 UI 진입점 변경, 불필요 import 및 Scaffold 주석 처리
app/src/main/java/com/texthip/thip/MainScreen.kt 네비게이션 컨트롤러와 바텀 네비게이션 바가 포함된 메인 화면 컴포저블 신설
app/src/main/java/com/texthip/thip/ui/bookSearch/screen/BookSearchScreen.kt
app/src/main/java/com/texthip/thip/ui/feed/screen/FeedScreen.kt
app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt
app/src/main/java/com/texthip/thip/ui/myPage/screen/MyPageScreen.kt
각 섹션별 기본 화면 컴포저블 추가(중앙 정렬 텍스트)
app/src/main/java/com/texthip/thip/ui/common/header/AuthorHeader.kt
app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt
app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarWithDate.kt
공통 헤더/프로필 UI 컴포저블 추가 및 프리뷰 포함
app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt
app/src/main/java/com/texthip/thip/ui/common/modal/InfoPopup.kt
app/src/main/java/com/texthip/thip/ui/common/modal/SnackBar.kt
app/src/main/java/com/texthip/thip/ui/common/modal/ToolTip.kt
app/src/main/java/com/texthip/thip/ui/common/modal/ScrollbarUtil.kt
다양한 모달/스낵바/툴팁/스크롤바 등 공통 모달 컴포저블 및 유틸 추가
app/src/main/java/com/texthip/thip/ui/common/view/CountingBar.kt 카운팅 뷰 컴포저블 추가 및 프리뷰 포함
app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt
app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt
app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt
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/res/drawable/ic_booksearch_selected.xml
app/src/main/res/drawable/ic_feed_selected.xml
app/src/main/res/drawable/ic_group_selected.xml
app/src/main/res/drawable/ic_mypage_selected.xml
바텀 네비게이션 바용 선택 상태 아이콘 벡터 드로어블 추가
app/src/main/res/values/colors.xml "black" 컬러 리소스 삭제
app/src/main/res/values/strings.xml UI 관련 신규 string 리소스 11종 추가

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MainActivity
    participant MainScreen
    participant NavController
    participant MainNavHost
    participant FeedScreen/GroupScreen/BookSearchScreen/MyPageScreen

    User->>MainActivity: 앱 실행
    MainActivity->>MainScreen: setContent { MainScreen() }
    MainScreen->>NavController: rememberNavController()
    MainScreen->>MainNavHost: MainNavHost(navController)
    MainNavHost->>FeedScreen: Feed route 진입 시 FeedScreen(navController)
    MainNavHost->>GroupScreen: Group route 진입 시 GroupScreen(navController)
    MainNavHost->>BookSearchScreen: BookSearch route 진입 시 BookSearchScreen(navController)
    MainNavHost->>MyPageScreen: MyPage route 진입 시 MyPageScreen(navController)
    MainScreen->>BottomNavigationBar: route에 따라 바텀바 표시
    User->>BottomNavigationBar: 네비게이션 아이템 클릭
    BottomNavigationBar->>NavController: navigate(route)
    NavController->>MainNavHost: 목적지 화면 전환
Loading

Assessment against linked issues

Objective Addressed Explanation
공통 View 컴포넌트 제작 (#19)
공통 Header 컴포넌트 제작 (#19)
공통 Modal 컴포넌트 제작 (#19)
공통 Appbar 컴포넌트 제작 (#19) Appbar(앱바) 관련 컴포저블은 추가되지 않았음.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
IDE 설정 파일 추가/수정 (.idea/.name, .idea/compiler.xml, .idea/deploymentTargetSelector.xml, .idea/misc.xml) 이 변경은 코드 기능과 무관하며, 이슈 요구사항(공통 UI 컴포넌트)에 포함되지 않음.
"black" 컬러 리소스 삭제 (app/src/main/res/values/colors.xml) UI 컴포넌트 추가와 직접 관련이 없는 리소스 삭제로, 이슈 범위에서 벗어남.

Suggested labels

🐻 규빈

Suggested reviewers

  • Nico1eKim

Poem

🐇
새로 만든 헤더, 바와 모달,
토끼는 신나서 깡총깡총 달~
네비게이션도 척척,
뷰 컴포넌트도 번쩍!
앱 화면이 풍성해진 오늘,
코드 속에 봄바람이 솔솔 불어오네.
🥕✨
"""


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 53061b2 and c653ce7.

📒 Files selected for processing (1)
  • app/src/main/java/com/texthip/thip/ui/common/header/AuthorHeader.kt (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • app/src/main/java/com/texthip/thip/ui/common/header/AuthorHeader.kt
✨ Finishing Touches
  • 📝 Generate Docstrings

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

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

♻️ Duplicate comments (1)
app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (1)

63-96: TODO 주석 해결 및 버튼 코드 중복 개선

이전 리뷰에서 언급된 공통 버튼 컴포넌트 사용을 고려해주세요. 현재 버튼 스타일링이 중복되고 있습니다.

버튼 공통화가 어렵다면 최소한 스타일링 로직을 함수로 분리하는 것을 고려해보세요:

@Composable
private fun DialogButton(
    text: String,
    onClick: () -> Unit,
    backgroundColor: Color,
    modifier: Modifier = Modifier
) {
    Button(
        onClick = onClick,
        colors = ButtonDefaults.buttonColors(containerColor = backgroundColor),
        shape = RoundedCornerShape(12.dp),
        modifier = modifier
    ) {
        Text(
            text = text,
            color = colors.White,
            style = typography.smalltitle_sb600_s16_h24
        )
    }
}
🧹 Nitpick comments (31)
app/src/main/java/com/texthip/thip/ui/feed/screen/FeedScreen.kt (3)

12-12: navController 파라미터 미사용
현재 navController가 사용되지 않으므로, 향후 네비게이션 기능 추가 시 활용하거나 불필요할 경우 제거를 고려해주세요.


17-17: 하드코딩된 텍스트 리소스화 필요
"Feed Screen" 문자열을 다국어 지원을 위해 stringResource로 관리해주세요.


11-19: @Preview 애노테이션 추가 제안
Compose 미리보기를 위해 @Preview 함수를 추가하면 UI 개발 및 검증이 편리합니다.

app/src/main/java/com/texthip/thip/ui/myPage/screen/MyPageScreen.kt (3)

12-12: navController 파라미터 미사용
현재 navController가 활용되지 않으므로, 이후 네비게이션 로직 추가 시 참조하거나 필요 없으면 제거해 함수 시그니처를 단순화해주세요.


17-17: 하드코딩된 텍스트 리소스화 필요
"MyPage Screen" 문자열을 다국어 지원을 위해 stringResource로 관리해주세요.


11-19: @Preview 애노테이션 추가 제안
Compose 미리보기를 위해 @Preview 함수를 추가하면 UI 개발 및 검증이 수월해집니다.

app/src/main/res/drawable/ic_booksearch_selected.xml (1)

7-8: 색상 하드코딩 개선 제안
android:fillColor="#6868FF" 대신 컬러 리소스나 테마 속성(e.g. @color/nav_selected)으로 처리하여 재사용성과 다크 모드 호환성을 높이길 권장합니다.

app/src/main/res/drawable/ic_feed_selected.xml (1)

7-11: 색상 하드코딩 개선 제안
android:fillColor="#6868FF"을 컬러 리소스(@color/nav_selected) 또는 테마 속성으로 대체해 유지보수성과 테마 적응성을 강화해주세요.

app/src/main/java/com/texthip/thip/ui/bookSearch/screen/BookSearchScreen.kt (2)

12-12: 사용하지 않는 NavController 매개변수에 대한 경고 처리가 필요합니다.

현재 navController 매개변수가 사용되지 않아 컴파일러 경고가 발생할 수 있습니다. 플레이스홀더 구현이라면 다음 중 하나를 적용해주세요:

@Composable
-fun BookSearchScreen(navController: NavController) {
+fun BookSearchScreen(@Suppress("UNUSED_PARAMETER") navController: NavController) {

또는 향후 사용 예정임을 명시:

@Composable
-fun BookSearchScreen(navController: NavController) {
+fun BookSearchScreen(navController: NavController) {
+    // TODO: 향후 네비게이션 기능 구현 시 navController 사용 예정

3-9: import 순서를 표준 컨벤션에 맞게 정리해주세요.

Android 개발 컨벤션에 따라 import를 그룹별로 정리하는 것을 권장합니다:

+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.navigation.NavController

일반적으로 androidx → 서드파티 → 프로젝트 내부 순으로 정리합니다.

app/src/main/res/drawable/ic_mypage_selected.xml (1)

8-8: 하드코딩된 색상을 리소스로 관리하는 것을 권장합니다.

현재 색상값 #6868FF가 하드코딩되어 있습니다. 일관성과 유지보수성을 위해 colors.xml에 정의하여 사용하는 것을 권장합니다:

<!-- colors.xml -->
<color name="primary_blue">#6868FF</color>
-android:fillColor="#6868FF"
+android:fillColor="@color/primary_blue"

이는 다크 테마 지원이나 브랜드 색상 변경 시 유용합니다.

Also applies to: 11-11

app/src/main/res/drawable/ic_group_selected.xml (1)

8-8: 하드코딩된 색상을 리소스로 관리하는 것을 권장합니다.

MyPage 아이콘과 동일하게 색상값 #6868FF가 하드코딩되어 있습니다. 일관성을 위해 colors.xml에 정의하여 사용해주세요:

-android:fillColor="#6868FF"
+android:fillColor="@color/primary_blue"

모든 내비게이션 아이콘에서 동일한 색상 리소스를 사용하면 일관성 있는 UI를 유지할 수 있습니다.

Also applies to: 12-12, 15-15, 18-18

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

12-12: 사용하지 않는 NavController 매개변수 처리가 필요합니다.

BookSearchScreen과 동일한 이슈입니다. 사용하지 않는 navController 매개변수에 대한 경고를 처리해주세요:

@Composable
-fun GroupScreen(navController: NavController) {
+fun GroupScreen(@Suppress("UNUSED_PARAMETER") navController: NavController) {

3-9: import 순서 정리를 권장합니다.

BookSearchScreen과 동일하게 import 순서를 표준 컨벤션에 맞게 정리해주세요.

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

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

각 화면에 NavController를 전달하는 패턴이 일관성 있게 적용되었습니다. 향후 고려사항:

  • 네비게이션 인자가 필요한 경우 argument 블록 추가
  • 딥링크 지원이 필요한 경우 deepLinks 추가
  • 화면 간 데이터 전달이 필요한 경우 SavedStateHandle 활용

현재 구현은 기본 네비게이션 구조로서 적절합니다.

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

6-6: 리스트 프로퍼티 명명 규칙 개선 권장

BarItems 프로퍼티명이 복수형이므로 barItems로 명명하는 것이 Kotlin 코딩 규칙에 더 적합합니다.

-    val BarItems = listOf(
+    val barItems = listOf(

8-11: 프로퍼티 명명 규칙 일관성 개선

IconResSelectedIconRes 프로퍼티가 대문자로 시작하고 있습니다. Kotlin 관례에 따라 프로퍼티명은 소문자로 시작해야 합니다.

-            IconRes = R.drawable.ic_feed,
-            SelectedIconRes = R.drawable.ic_feed_selected
+            iconRes = R.drawable.ic_feed,
+            selectedIconRes = R.drawable.ic_feed_selected
app/src/main/java/com/texthip/thip/ui/navigator/BarItem.kt (1)

8-9: 프로퍼티 명명 규칙 준수 필요

Kotlin 명명 규칙에 따라 프로퍼티명은 소문자로 시작해야 합니다.

-    @DrawableRes val IconRes: Int,
-    @DrawableRes val SelectedIconRes: Int
+    @DrawableRes val iconRes: Int,
+    @DrawableRes val selectedIconRes: Int
app/src/main/java/com/texthip/thip/MainActivity.kt (2)

22-27: 주석 처리된 코드 제거 권장

주석 처리된 이전 Scaffold 코드를 제거하여 코드베이스를 깔끔하게 유지하는 것이 좋습니다.

-                /*Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
-                    Greeting(
-                        name = "Android",
-                        modifier = Modifier.padding(innerPadding)
-                    )
-                }*/

34-73: 미사용 Greeting 컴포저블 정리 고려

Greeting 컴포저블이 더 이상 사용되지 않는다면 제거를 고려해보세요. 테스트 목적으로 유지하려면 별도 파일로 분리하는 것을 권장합니다.

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

20-20: 라우트 비교 로직 최적화 가능

현재 매번 map을 호출하여 라우트 리스트를 생성하고 있습니다. 성능 향상을 위해 미리 계산된 Set을 사용하는 것을 고려해보세요.

+    val bottomBarRoutes = remember { NavBarItems.barItems.map { it.route }.toSet() }
-    val showBottomBar = currentRoute in NavBarItems.BarItems.map { it.route }
+    val showBottomBar = currentRoute in bottomBarRoutes
app/src/main/java/com/texthip/thip/ui/common/modal/SnackBar.kt (1)

3-3: 사용하지 않는 import를 제거하세요.

android.R.id.message import가 코드에서 사용되지 않으므로 제거해야 합니다.

-import android.R.id.message
app/src/main/java/com/texthip/thip/ui/common/modal/InfoPopup.kt (1)

30-30: onDismiss 매개변수 설계를 재검토하세요.

onDismiss 매개변수가 있지만 실제로 이를 호출하는 UI 요소(닫기 버튼 등)가 없습니다. 사용자가 팝업을 닫을 수 있는 방법을 제공하거나, 매개변수가 불필요하다면 제거하는 것을 고려해보세요.

app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarWithDate.kt (2)

15-16: 사용하지 않는 import를 제거하세요.

Material Icons 관련 import들이 코드에서 사용되지 않으므로 제거해야 합니다.

-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.MoreVert

49-49: contentDescription에 문자열 리소스를 사용하세요.

접근성을 위한 contentDescription이 하드코딩되어 있습니다. 다국어 지원과 일관성을 위해 문자열 리소스를 사용하는 것을 고려해보세요.

-                contentDescription = "프로필 이미지",
+                contentDescription = stringResource(R.string.profile_image),
-            contentDescription = "메뉴",
+            contentDescription = stringResource(R.string.menu),

Also applies to: 77-77

app/src/main/java/com/texthip/thip/ui/common/modal/ScrollbarUtil.kt (1)

23-23: 스크롤바 높이 비율을 상수로 추출 고려

현재 하드코딩된 1/8f 비율을 상수로 추출하면 유지보수성이 향상됩니다.

+private const val SCROLLBAR_HEIGHT_RATIO = 1/8f
+
 fun Modifier.drawVerticalScrollbar(
     // ...
 ): Modifier = this.then(
     Modifier.drawBehind {
         if (scrollState.maxValue == 0) return@drawBehind
 
-        val scrollbarHeight = size.height / 8f
+        val scrollbarHeight = size.height * SCROLLBAR_HEIGHT_RATIO
app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (1)

35-43: 고정 크기 대신 유연한 크기 고려

320x182dp 고정 크기는 다양한 화면 크기에서 문제가 될 수 있습니다. 최소/최대 크기 제한을 두면서 내용에 따라 조절되도록 하는 것을 고려해보세요.

app/src/main/java/com/texthip/thip/ui/common/modal/ToolTip.kt (1)

115-141: 프리뷰에서 하드코딩된 값 개선 제안

프리뷰에서 80 값이 하드코딩되어 있습니다. 의미 있는 상수로 정의하거나 샘플 데이터를 더 명확하게 표현하는 것이 좋겠습니다.

+private const val SAMPLE_PROGRESS = 80
+
 @Preview(showBackground = true)
 @Composable
 private fun PopupPrev() {
     Column {
         PopupModal(
-            text = stringResource(R.string.condition_of_general_review,80),
+            text = stringResource(R.string.condition_of_general_review, SAMPLE_PROGRESS),
app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (3)

83-83: 문자열 리소스 사용 시 공백 추가 필요

쉼표 뒤에 공백이 없어 코드 가독성이 떨어집니다.

-                    text = stringResource(R.string.subscriber_num,subscriberCount),
+                    text = stringResource(R.string.subscriber_num, subscriberCount),
-                text = stringResource(R.string.hours_ago,hoursAgo),
+                text = stringResource(R.string.hours_ago, hoursAgo),

Also applies to: 97-97


52-52: 접근성을 위한 콘텐츠 설명 영어 사용 권장

콘텐츠 설명에 한국어를 사용하고 있습니다. 접근성 도구와의 호환성을 위해 영어 사용을 권장합니다.

-                contentDescription = "프로필 이미지",
+                contentDescription = "Profile image",
-                    contentDescription = "화살표",
+                    contentDescription = "Arrow",

Also applies to: 90-90


88-93: 아이콘 틴트 테마 일관성

Color.Unspecified를 사용하여 아이콘 색상을 지정하지 않고 있습니다. 테마 일관성을 위해 적절한 테마 색상을 사용하는 것이 좋습니다.

                Icon(
                    painter = painterResource(id = R.drawable.ic_chevron_right),
-                    contentDescription = "화살표",
+                    contentDescription = "Arrow",
                    modifier = Modifier.size(16.dp),
-                    tint = Color.Unspecified
+                    tint = colors.Grey01
                )
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1f7c62f and ab596f4.

📒 Files selected for processing (32)
  • .idea/.name (1 hunks)
  • .idea/compiler.xml (1 hunks)
  • .idea/deploymentTargetSelector.xml (1 hunks)
  • .idea/misc.xml (1 hunks)
  • app/build.gradle.kts (1 hunks)
  • app/src/main/java/com/texthip/thip/MainActivity.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/MainScreen.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/bookSearch/screen/BookSearchScreen.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/header/AuthorHeader.kt (1 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/ProfileBarWithDate.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/modal/DialogPopup.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/modal/InfoPopup.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/modal/ScrollbarUtil.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/modal/SnackBar.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/modal/ToolTip.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/common/view/CountingBar.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/feed/screen/FeedScreen.kt (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.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 (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt (1 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 (1 hunks)
  • app/src/main/java/com/texthip/thip/ui/navigator/Routes.kt (1 hunks)
  • app/src/main/res/drawable/ic_booksearch_selected.xml (1 hunks)
  • app/src/main/res/drawable/ic_feed_selected.xml (1 hunks)
  • app/src/main/res/drawable/ic_group_selected.xml (1 hunks)
  • app/src/main/res/drawable/ic_mypage_selected.xml (1 hunks)
  • app/src/main/res/values/colors.xml (0 hunks)
  • app/src/main/res/values/strings.xml (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
💤 Files with no reviewable changes (1)
  • app/src/main/res/values/colors.xml
🔇 Additional comments (34)
.idea/.name (1)

1-1: IDE 설정 파일: 검토 불필요
.idea 디렉토리 내 설정 파일은 개인 개발 환경별로 달라질 수 있으므로 버전 관리에서 제외하거나 리뷰에서 생략하는 것이 좋습니다.

gradle/libs.versions.toml (2)

11-11: 새 버전 정의 추가 확인
navigationCompose = "2.9.0" 항목이 [versions] 섹션에 올바르게 추가되었습니다.


28-28: 라이브러리 별칭 추가 적절
androidx-navigation-compose alias가 [libraries] 섹션에 정상적으로 정의되었습니다.

.idea/deploymentTargetSelector.xml (1)

7-14: IDE 배포 타겟 설정: 검토 불필요
런 구성 환경에 따른 IDE 설정은 로컬 환경별로 상이하므로 리뷰에서 제외하는 것을 권장합니다.

Also applies to: 17-25, 27-29

.idea/compiler.xml (1)

4-4: 컴파일러 타겟 레벨 설정 검토 불필요
IDE 설정파일 변경은 로컬 개발 환경에 종속적이므로 리뷰 대상에서 제외하세요.

app/build.gradle.kts (1)

52-52: Jetpack Navigation Compose 의존성 추가 적절
implementation(libs.androidx.navigation.compose)가 의존성 블록에 정상적으로 포함되어 있으며, PR 목적에 부합합니다.

.idea/misc.xml (1)

5-5: JDK 21 지원 여부 검증 필요
Android Gradle Plugin 및 빌드 툴이 languageLevel="JDK_21"project-jdk-name="jbr-21" 설정을 공식적으로 지원하는지 확인해주세요.

app/src/main/res/drawable/ic_booksearch_selected.xml (1)

2-5: 아이콘 크기 및 뷰포트 일관성 확인
다른 네비게이션 아이콘(ic_feed_selected, ic_group_selected, ic_mypage_selected)과 동일한 width/heightviewportWidth/viewportHeight를 사용하는지 검증해주세요.

app/src/main/res/drawable/ic_feed_selected.xml (1)

2-5: 아이콘 크기 및 뷰포트 일관성 확인
다른 네비게이션 아이콘과 동일한 width/heightviewportWidth/viewportHeight를 사용하는지 검증해주세요.

app/src/main/java/com/texthip/thip/ui/bookSearch/screen/BookSearchScreen.kt (1)

11-19: 플레이스홀더 구현으로서는 적절합니다.

현재 구현은 기본적인 Jetpack Compose 화면 구조를 잘 따르고 있습니다. 향후 실제 책 검색 기능을 구현할 때 고려사항:

  • 검색 입력 필드 추가
  • 검색 결과 리스트 표시
  • 로딩 상태 관리
  • 에러 처리
app/src/main/res/drawable/ic_mypage_selected.xml (1)

1-12: 벡터 드로어블 구조가 적절합니다.

아이콘의 구조와 크기가 내비게이션 바에 적합하게 구현되었습니다. 사용자 프로필을 나타내는 두 개의 패스(머리와 몸)가 명확하게 표현되어 있습니다.

app/src/main/res/drawable/ic_group_selected.xml (1)

1-20: 그룹 아이콘 구현이 적절합니다.

복수의 사용자를 나타내는 아이콘으로 4개의 패스를 사용하여 그룹을 잘 표현했습니다. fillType="evenOdd" 속성도 복잡한 경로에 적절히 사용되었습니다.

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

11-19: 일관성 있는 플레이스홀더 구현입니다.

다른 화면들과 동일한 패턴으로 구현되어 일관성이 좋습니다. 향후 그룹 기능 구현 시 고려사항:

  • 그룹 목록 표시
  • 그룹 생성/참여 기능
  • 그룹 멤버 관리
  • 상태 관리 (로딩, 에러 등)
app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt (2)

14-14: 시작 경로 설정이 적절합니다.

Feed를 시작 화면으로 설정한 것이 일반적인 앱 구조에 적합합니다. Routes 객체를 사용하여 타입 안전성을 확보한 것도 좋은 접근입니다.


3-6: import 구조가 적절합니다.

Navigation Compose 관련 import들이 올바르게 구성되어 있고, 필요한 의존성들이 적절히 import되었습니다.

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

6-31: 네비게이션 설정 구조 검증

네비게이션 아이템 설정이 적절하게 구성되어 있습니다. 4개의 주요 화면에 대한 라우팅과 아이콘 리소스가 올바르게 매핑되어 있습니다.

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

4-9: 타입 안전 네비게이션 라우트 구현 우수

Sealed class를 사용한 라우트 정의가 매우 적절합니다. 타입 안전성을 보장하면서 컴파일 타임에 라우트 오류를 방지할 수 있습니다.

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

5-10: 데이터 클래스 구조 적절함

네비게이션 바 아이템을 위한 데이터 클래스 구조가 잘 설계되었습니다. @DrawableRes 어노테이션 사용으로 타입 안전성도 확보했습니다.

app/src/main/java/com/texthip/thip/MainActivity.kt (1)

28-28: 네비게이션 기반 아키텍처로의 전환 승인

MainScreen()으로의 전환이 적절합니다. 네비게이션 기반 아키텍처로 깔끔하게 변경되었습니다.

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

17-19: 네비게이션 상태 관리 적절함

네비게이션 컨트롤러와 백스택 상태 관찰이 올바르게 구현되었습니다. Jetpack Compose Navigation의 모범 사례를 따르고 있습니다.


22-30: Scaffold 구조와 조건부 네비게이션 바 구현 우수

Scaffold를 사용한 레이아웃 구조와 조건부 바텀 네비게이션 바 표시 로직이 적절하게 구현되었습니다. 패딩 처리도 올바르게 되어 있습니다.


20-20: NavBarItems 프로퍼티명 일관성 확인 필요

NavBarItems.BarItems 참조가 있는데, 앞서 권장한 명명 규칙 개선사항과 일관성을 유지해야 합니다.

다음 스크립트를 실행하여 NavBarItems 사용처를 확인하세요:

#!/bin/bash
# NavBarItems.BarItems 사용처 확인
rg -A 2 -B 2 "NavBarItems\.BarItems"
app/src/main/java/com/texthip/thip/ui/common/view/CountingBar.kt (1)

21-43: 깔끔한 구현입니다!

컴포넌트가 잘 구조화되어 있고 테마 시스템을 올바르게 사용하고 있습니다. 재사용 가능한 디자인과 적절한 매개변수 구조를 갖추고 있습니다.

app/src/main/java/com/texthip/thip/ui/common/modal/SnackBar.kt (1)

23-53: 잘 구현된 SnackBar 컴포넌트입니다.

컴포넌트 구조가 명확하고 테마 시스템을 적절히 활용하고 있습니다. 클릭 가능한 액션과 적절한 레이아웃을 제공합니다.

app/src/main/java/com/texthip/thip/ui/common/modal/InfoPopup.kt (1)

57-57: ```shell
#!/bin/bash

InfoPopup.kt 파일의 import 구문과 drawVerticalScrollbar 사용 위치 확인

fd "InfoPopup.kt" --exec sed -n '1,50p' {}
fd "InfoPopup.kt" --exec rg -n "drawVerticalScrollbar" {}


</details>
<details>
<summary>app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarWithDate.kt (1)</summary>

`33-84`: **잘 구현된 ProfileBar 컴포넌트입니다.**

null 처리, 테마 적용, 레이아웃 구조가 모두 적절하게 구현되어 있습니다. 재사용 가능한 좋은 컴포넌트입니다.

</details>
<details>
<summary>app/src/main/java/com/texthip/thip/ui/navigator/BottomNavigationBar.kt (1)</summary>

`28-93`: **네비게이션 구현이 우수합니다.**

NavController의 상태 관리와 네비게이션 옵션들이 모두 적절하게 구현되어 있습니다. `saveState`, `restoreState`, `launchSingleTop` 등의 옵션을 통해 올바른 네비게이션 동작을 보장하고 있습니다.

</details>
<details>
<summary>app/src/main/java/com/texthip/thip/ui/common/header/AuthorHeader.kt (1)</summary>

`34-40`: **매개변수 순서가 올바르게 적용됨**

이전 리뷰 코멘트에서 제안된 매개변수 순서 규칙(modifier → 일반 변수 → 콜백 함수)이 잘 적용되었습니다.

</details>
<details>
<summary>app/src/main/res/values/strings.xml (1)</summary>

`3-13`: **문자열 리소스 추가가 적절함**

새로 추가된 한국어 문자열 리소스들이 UI 컴포넌트들과 잘 매칭되며, 포맷 문자열 사용법도 올바릅니다.

</details>
<details>
<summary>app/src/main/java/com/texthip/thip/ui/common/modal/ScrollbarUtil.kt (1)</summary>

`13-42`: **스크롤바 구현이 잘 되어 있음**

커스텀 스크롤바 구현이 깔끔하고 성능을 고려한 좋은 코드입니다. 스크롤 상태 확인과 계산 로직이 적절합니다.

</details>
<details>
<summary>app/src/main/java/com/texthip/thip/ui/common/modal/ToolTip.kt (2)</summary>

`36-53`: **Canvas를 이용한 화살표 구현이 깔끔함**

삼각형 화살표를 Canvas로 그리는 방식이 적절하고, LocalDensity 사용도 올바릅니다.

---

`70-85`: **화살표 위치 처리 로직이 잘 구현됨**

when 표현식을 사용한 화살표 위치 처리가 깔끔하고 직관적입니다.

</details>
<details>
<summary>app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt (2)</summary>

`33-103`: **전반적으로 잘 구현된 컴포넌트**

ProfileBar 컴포넌트가 잘 구현되었습니다. 이전 리뷰 피드백들이 적절히 반영되었고(boolean 파라미터, 시간 파라미터 추가), Jetpack Compose 모범 사례를 잘 따르고 있습니다.

- 적절한 기본값 제공
- 조건부 UI 렌더링 올바르게 구현
- 테마 타이포그래피와 색상 사용
- 접근성 고려 (콘텐츠 설명 제공)

---

`105-126`: **유용한 프리뷰 구현**

두 가지 다른 상태(구독자 정보 표시/시간 표시)를 보여주는 프리뷰가 잘 구현되어 있어 컴포넌트의 다양한 사용 케이스를 확인할 수 있습니다.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

modifier = Modifier
.size(36.dp)
.clip(CircleShape)
.background(Grey)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

테마 색상 일관성 유지

플레이스홀더 배경색으로 Grey를 사용하고 있지만, 다른 부분에서는 colors.Grey01을 사용하고 있습니다. 테마 일관성을 위해 theme colors를 사용하는 것이 좋습니다.

-                    .background(Grey)
+                    .background(colors.Grey01)
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt at line 62,
the background color is set to Grey directly, but elsewhere theme colors like
colors.Grey01 are used for consistency. Replace the hardcoded Grey with the
appropriate theme color reference, such as colors.Grey01, to maintain consistent
theming across the app.

@JJUYAAA JJUYAAA merged commit eedc71a into THIP-TextHip:develop Jun 23, 2025
1 check passed
@JJUYAAA JJUYAAA changed the title UI/#19 view appbar header modal [UI] view appbar header modal 컴포넌트 구현 Jun 30, 2025
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] view, appbar, header, modal 컴포넌트 [(THIP2025-28)]

3 participants