-
Notifications
You must be signed in to change notification settings - Fork 0
[Feature/#30] 추천 루틴 화면 구현 #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthrough추천 루틴 화면 기능이 새롭게 추가되었습니다. 추천 루틴 화면 UI, 상태 관리 ViewModel, MVI 인텐트/상태/사이드이펙트, 카테고리/난이도 타입, 루틴 데이터 모델, 각종 컴포저블 UI(카테고리 칩, 루틴 아이템, 감정 추천 버튼, 난이도 바텀시트) 등이 구현되었고, 디자인 시스템에 두 가지 색상(coolGray7, coolGray5)이 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant RecommendRoutineScreenContainer
participant RecommendRoutineViewModel
User->>RecommendRoutineScreenContainer: 화면 진입
RecommendRoutineScreenContainer->>RecommendRoutineViewModel: 초기화/루틴 로드
RecommendRoutineViewModel->>RecommendRoutineScreenContainer: UI 상태 emit
User->>RecommendRoutineScreenContainer: 카테고리 선택/난이도 선택/바텀시트 열기
RecommendRoutineScreenContainer->>RecommendRoutineViewModel: 인텐트 전달
RecommendRoutineViewModel->>RecommendRoutineScreenContainer: 상태 업데이트 emit
User->>RecommendRoutineScreenContainer: 루틴 추가/감정 추천 버튼 클릭
RecommendRoutineScreenContainer->>RecommendRoutineViewModel: (추후) 인텐트 전달
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
🧹 Nitpick comments (16)
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/type/RecommendRoutineCategory.kt (1)
6-12
:displayName
하드코딩 → string 리소스로 분리 권장
UI 컴포넌트에서 직접 enum의displayName
을 사용하게 되면 다국어 대응이 어렵습니다.@StringRes
ID를 보관하도록 변경하거나,stringResource()
로 매핑할 수 있는 방식으로 리팩터링을 고려해주세요.presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/type/RecommendRoutineDifficulty.kt (1)
6-10
: 문자열 리소스 분리 필요
난이도 표시 문자열도 enum 내부에 하드코딩되어 있어 i18n 및 디자인시스템 통일에 불리합니다. 리소스 분리를 권장합니다.presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/block/EmotionRecommendRoutineButton.kt (4)
32-41
: 모서리 둥글기(clip) 누락
border
와background
에 동일한RoundedCornerShape
를 사용하셨지만Modifier.clip()
이 없어 내부 콘텐츠가 모서리를 넘어서 그려질 수 있습니다. 다음과 같이 추가를 제안드립니다..background( color = BitnagilTheme.colors.white, shape = RoundedCornerShape(12.dp), ) + .clip(RoundedCornerShape(12.dp))
49-56
: 아이콘 접근성 설명 및 TODO
contentDescription = null
로 두면 스크린리더가 버튼 의미를 알 수 없습니다. 교체 전 임시 아이콘이라도"추천 루틴 추가 아이콘"
등 설명을 넣어 주세요.
58-62
: 텍스트 하드코딩 → 리소스 분리
문자열이 고정되면 다국어 지원 및 A/B 테스트가 어렵습니다.stringResource(R.string.emotion_recommend_button)
형태로 분리하십시오.
66-72
: 프리뷰에서 테마 래핑 누락
프리뷰 렌더링 시BitnagilTheme
로 감싸지 않으면 색상·타이포그래피가 제대로 적용되지 않습니다.@Composable private fun EmotionRecommendRoutineButtonPreview() { - EmotionRecommendRoutineButton( - onClick = {}, - ) + BitnagilTheme { + EmotionRecommendRoutineButton( + onClick = {}, + ) + } }presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/atom/RecommendCategoryChip.kt (2)
32-32
: 리플 효과 제거 TODO 해결 제안리플 효과를 제거하려면
clickable
대신Modifier.pointerInput
을 사용하거나clickable
의indication
파라미터를null
로 설정하세요.- // todo: 리플효과 제거하기 - .clickable { onCategorySelected() } + .clickable( + indication = null, + interactionSource = remember { MutableInteractionSource() } + ) { onCategorySelected() }또는
NoRippleTheme
을 사용하는 방법도 있습니다.
30-30
: 하드코딩된 값들을 디자인 토큰으로 추출하는 것을 고려해보세요
RoundedCornerShape(20.dp)
와 패딩 값들(9.dp
,14.dp
)을 디자인 시스템의 상수로 추출하면 일관성과 유지보수성이 향상됩니다.Also applies to: 35-37
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/template/RecommendRoutineEmptyView.kt (3)
51-51
: 리플 효과 제거 TODO 해결 제안앞서 제안한 것과 동일하게
clickable
의indication
파라미터를null
로 설정하여 리플 효과를 제거할 수 있습니다.
49-49
: 하드코딩된 값들을 디자인 토큰으로 추출 고려
RoundedCornerShape(100.dp)
와 패딩 값들을 디자인 시스템의 상수로 추출하면 일관성이 향상됩니다.Also applies to: 54-55
29-29
: 하드코딩된 문자열을 리소스 파일로 추출하는 것을 고려해보세요"맞춤 추천 루틴이 없어요"와 "루틴을 등록해서 나만의 추천 루틴을 받아보세요!" 같은 문자열을
strings.xml
로 추출하면 다국어 지원과 유지보수성이 향상됩니다.Also applies to: 37-37
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt (1)
61-93
: 더미 데이터 생성 로직 개선 제안현재 더미 데이터에 반복적인 패턴이 있습니다. 코드를 더 간결하고 유지보수하기 쉽게 개선할 수 있습니다.
private fun generateDummyRecommendRoutine(): Map<RecommendRoutineCategory, List<RecommendRoutine>> { + fun createRoutines(baseName: String, baseDescription: String, count: Int): List<RecommendRoutine> { + val difficulties = RecommendRoutineDifficulty.values() + return (1..count).map { index -> + RecommendRoutine( + name = if (index == 1) baseName else "$baseName$index", + description = if (index == 1) baseDescription else "$baseDescription$index", + difficulty = difficulties[index % difficulties.size] + ) + } + } + return mapOf( RecommendRoutineCategory.CUSTOM_RECOMMEND to emptyList(), - RecommendRoutineCategory.GO_OUT to listOf( - RecommendRoutine("나가는 루틴", "밖으로 나가보자고", RecommendRoutineDifficulty.EASY), - // ... 반복적인 코드들 - ), + RecommendRoutineCategory.GO_OUT to createRoutines("나가는 루틴", "밖으로 나가보자고", 8), + RecommendRoutineCategory.CONNECT to createRoutines("연결해요 루틴", "연결하는 루틴임", 3), + RecommendRoutineCategory.TAKE_REST to createRoutines("쉬어가요 루틴", "쉬어가요 루틴임", 4), + RecommendRoutineCategory.GROW to createRoutines("성장해요 루틴", "성장해요 루틴임", 4), ) }presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/block/RecommendRoutineItem.kt (1)
39-42
: TODO 주석 확인리플 효과 제거에 대한 TODO가 있습니다. 디자인 시스템과 일치하도록 적절한 시점에 처리해 주세요.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt (2)
164-228
: 복잡한 조건부 렌더링 로직 개선 검토메인 콘텐츠 영역의 조건부 렌더링 로직이 복잡합니다. 가독성과 유지보수성을 위해 별도의 컴포저블 함수로 분리하는 것을 고려해 보세요.
@Composable private fun MainContent( uiState: RecommendRoutineState, onAddRoutineClick: () -> Unit, onEmotionRecommendClick: () -> Unit, onEmptyViewClick: () -> Unit, ) { when { uiState.isDefaultCategory && uiState.currentRoutines.isEmpty() -> { DefaultCategoryEmptyContent(onEmotionRecommendClick, onEmptyViewClick) } uiState.isDefaultCategory && uiState.currentRoutines.isNotEmpty() -> { DefaultCategoryWithRoutines(uiState, onAddRoutineClick, onEmotionRecommendClick) } !uiState.isDefaultCategory && uiState.currentRoutines.isNotEmpty() -> { CategoryWithRoutines(uiState, onAddRoutineClick) } else -> { OtherCategoryEmptyContent(onEmptyViewClick) } } }
136-139
: TODO 주석 확인리플 효과 제거에 대한 TODO가 있습니다. 디자인 시스템과 일치하도록 처리해 주세요.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/template/RoutineDifficultyBottomSheet.kt (1)
73-75
: TODO 주석 확인리플 효과 제거에 대한 TODO가 있습니다. 다른 컴포넌트들과 일관성을 위해 처리해 주세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/color/BitnagilColors.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/atom/RecommendCategoryChip.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/block/EmotionRecommendRoutineButton.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/block/RecommendRoutineItem.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/template/RecommendRoutineEmptyView.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/template/RoutineDifficultyBottomSheet.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutine.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutineIntent.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutineSideEffect.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutineState.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/type/RecommendRoutineCategory.kt
(1 hunks)presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/type/RecommendRoutineDifficulty.kt
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/common/mviviewmodel/MviViewModel.kt (1)
sendIntent
(30-37)
🔇 Additional comments (12)
core/designsystem/src/main/java/com/threegap/bitnagil/designsystem/color/BitnagilColors.kt (1)
32-33
:CoolGray7
,CoolGray5
상수 정의 여부 확인 필요
두 컬러 프로퍼티를 추가하셨는데, 실제CoolGray7
,CoolGray5
값이 정의돼 있지 않으면 컴파일 에러가 발생합니다. 디자인시스템Color.kt
등에 상수를 이미 추가했는지 다시 한 번 점검 부탁드립니다.presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutineSideEffect.kt (1)
5-5
: MVI 시드 이펙트용 마커 인터페이스 추가 👍
단순 타입 세이프티 목적의 인터페이스로 적절합니다. 추가 구현 사항 없으면 그대로 진행해도 무방합니다.presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutine.kt (1)
7-12
: 데이터 클래스 구현이 깔끔합니다Parcelable 인터페이스와 @parcelize 어노테이션을 사용하여 Android 컴포넌트 간 직렬화를 효율적으로 처리했습니다. 불변성을 보장하는 val 속성들로 함수형 프로그래밍 스타일을 잘 따르고 있습니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutineIntent.kt (1)
7-14
: MVI 패턴의 Intent 구현이 우수합니다sealed class를 사용하여 Intent를 타입 안전하게 정의했고, data object와 data class를 적절히 구분하여 사용했습니다. 각 Intent의 목적이 명확하게 드러나는 네이밍도 좋습니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt (2)
23-25
: 초기화 로직이 깔끔합니다init 블록에서 데이터 로딩을 시작하는 것은 적절한 패턴입니다. 사용자가 화면에 진입하자마자 필요한 데이터를 불러올 수 있습니다.
51-54
: nullable 처리 검토 제안
OnDifficultySelected
Intent에서difficulty
가 nullable이지만, 이 경우ClearDifficultyFilter
Intent와 기능이 중복될 수 있습니다. 설계 의도를 명확히 하는 것이 좋겠습니다.null 값으로 difficulty를 선택하는 경우와 명시적으로 필터를 클리어하는 경우의 차이점이 있는지 확인해보세요. 만약 동일한 동작이라면 Intent를 통합하는 것을 고려해볼 수 있습니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/block/RecommendRoutineItem.kt (1)
23-71
: 컴포넌트 구조 양호전체적인 컴포넌트 구조가 잘 설계되어 있습니다. 레이아웃, 스타일링, 그리고 콜백 처리가 적절히 구현되어 있습니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutineState.kt (2)
19-27
: 계산된 프로퍼티 구현 우수
currentRoutines
계산된 프로퍼티가 카테고리와 난이도 필터링을 효율적으로 처리하고 있습니다. 로직이 명확하고 성능상 문제가 없습니다.
8-28
: MVI 패턴 준수 및 상태 설계 양호상태 클래스가 MVI 패턴을 잘 따르고 있으며, 불변성을 유지하면서 UI 상태를 적절히 관리하고 있습니다.
@Parcelize
애노테이션 사용도 적절합니다.presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt (1)
44-65
: 컨테이너 패턴 적절한 구현뷰모델과 UI 상태 관리가 올바르게 분리되어 있고, 의도(Intent) 전달이 적절히 구현되어 있습니다.
presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/component/template/RoutineDifficultyBottomSheet.kt (2)
46-49
: 선택 토글 로직 우수현재 선택된 난이도를 다시 클릭하면 선택 해제되는 토글 로직이 잘 구현되어 있습니다. 사용자 경험을 향상시키는 좋은 접근입니다.
22-61
: 바텀시트 구현 잘 되어 있음Material3 ModalBottomSheet를 적절히 사용하고 있으며, 레이아웃과 상태 관리가 올바르게 구현되어 있습니다.
...egap/bitnagil/presentation/recommendroutine/component/block/EmotionRecommendRoutineButton.kt
Show resolved
Hide resolved
.../com/threegap/bitnagil/presentation/recommendroutine/component/block/RecommendRoutineItem.kt
Show resolved
Hide resolved
.../src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt
Show resolved
Hide resolved
...ap/bitnagil/presentation/recommendroutine/component/template/RoutineDifficultyBottomSheet.kt
Show resolved
Hide resolved
.../src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt
Outdated
Show resolved
Hide resolved
...main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutineState.kt
Show resolved
Hide resolved
.../com/threegap/bitnagil/presentation/recommendroutine/component/atom/RecommendCategoryChip.kt
Show resolved
Hide resolved
...c/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineViewModel.kt
Outdated
Show resolved
Hide resolved
- 엠티뷰 제거 - 추천 루틴화면 엠티 루틴으로 인한 분기처리 제거 - "맞춤 추천" 추천 카테고리의 경우 "감정버튼" 상단에 상시 노출
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다! 머지 진행하시죠!
[ PR Content ]
추천 루틴 화면을 구현합니다.
Related issue
Screenshot 📸
맞춤 추천 카테고리 선택 시 화면 분기처리
구현 영상
ui.mp4
Work Description
To Reviewers 📢
Summary by CodeRabbit
New Features
Style