Conversation
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In
`@app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt`:
- Around line 90-98: The Challenge composable can crash when gauges is empty
because safeStep = currentStep.coerceIn(1, gauges.size) yields 1 and then
gauges[safeStep - 1] is out of bounds; update Challenge to early-return or
render an empty/placeholder UI when gauges.isEmpty(), or compute safeStep only
if gauges.isNotEmpty() (e.g., guard before using gauges[safeStep - 1]), and
reference the currentStep, gauges, safeStep and currentPercent variables so you
avoid accessing gauges[...] when size == 0.
In
`@app/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.kt`:
- Around line 116-128: The key used inside the second loop of PlanBoxSection
(the key(...) wrapping PlanBox in the plans.drop(previewCount).forEachIndexed
block) is missing the loop index and can collide when
procedureName/daysSince/downtimePhase repeat; include the extraIndex in the key
(e.g., append or incorporate extraIndex) so each item gets a unique key; update
the key construction that builds from plan.procedureName, plan.daysSince and
plan.downtimePhase to also include extraIndex while leaving PlanBox and
PlanBoxState.Filled unchanged.
In `@app/src/main/java/com/cherrish/android/presentation/home/HomeUiState.kt`:
- Around line 23-49: HomeUiState.fake uses a hardcoded todayDate but builds
upcomingPlans with LocalDate.now(), causing inconsistent preview data; create a
LocalDate fakeBaseDate = LocalDate.of(2026, 1, 1) inside the companion object
and replace LocalDate.now().plusDays(...) uses for
UpcomingPlanUiModel.upcomingPlanDate with fakeBaseDate.plusDays(...) so all
dates (todayDate and upcomingPlanDate) and dDay calculations are consistently
based on the same reference date in the HomeUiState.fake initializer.
♻️ Duplicate comments (1)
app/src/main/java/com/cherrish/android/presentation/home/HomeScreen.kt (1)
98-106:selectedIndex가 유효 범위를 벗어날 경우 크래시 가능성
uiState.gauges[uiState.selectedIndex]에서selectedIndex가gauges리스트의 범위를 벗어나면IndexOutOfBoundsException이 발생합니다.🐛 안전한 인덱스 접근으로 수정
item { ChallengeSection( - imageRes = uiState.gauges[uiState.selectedIndex].image, + imageRes = uiState.gauges.getOrNull(uiState.selectedIndex)?.image + ?: R.drawable.img_lv1, currentStep = uiState.currentStep, gauges = uiState.gauges, onChallengeStartClick = onChallengeStartClick, challengeName = uiState.challengeName ) }
🧹 Nitpick comments (2)
app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt (1)
166-172: 불필요한currentStep파라미터
NoChallenge는currentStep == 0일 때만 호출되므로,currentStep파라미터를 전달받을 필요가 없습니다.CherrishGaugeBar에 직접 0을 전달하면 됩니다.♻️ 파라미터 제거 제안
`@Composable` private fun NoChallenge( - currentStep: Int, gauges: ImmutableList<CherrishGaugeType>, onChallengeStartClick: () -> Unit, modifier: Modifier = Modifier ) { // ... CherrishGaugeBar( - currentStep = currentStep, + currentStep = 0, gauges = gauges )호출부도 수정:
NoChallenge( - currentStep = currentStep, gauges = gauges, onChallengeStartClick = onChallengeStartClick )app/src/main/java/com/cherrish/android/presentation/home/HomeScreen.kt (1)
37-55: Loading/Failure 상태에 대한 UI 처리 부재
UiState.Loading과UiState.Failure상태에서 아무것도 렌더링하지 않습니다. 사용자 경험을 위해 로딩 인디케이터나 에러 메시지 표시를 고려해 보세요.향후 구현 예정인지 확인 부탁드립니다. 필요하시면 로딩/에러 UI 구현을 도와드릴 수 있습니다.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (5)
app/src/main/res/drawable/img_lv0.pngis excluded by!**/*.png,!**/*.pngapp/src/main/res/drawable/img_lv1.pngis excluded by!**/*.png,!**/*.pngapp/src/main/res/drawable/img_lv2.pngis excluded by!**/*.png,!**/*.pngapp/src/main/res/drawable/img_lv3.pngis excluded by!**/*.png,!**/*.pngapp/src/main/res/drawable/img_lv4.pngis excluded by!**/*.png,!**/*.png
📒 Files selected for processing (8)
app/src/main/java/com/cherrish/android/core/designsystem/component/type/CherrishGaugeType.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeScreen.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeUiState.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeViewModel.ktapp/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.ktapp/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.ktapp/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.ktapp/src/main/res/drawable/ic_app_logo.xml
🧰 Additional context used
📓 Path-based instructions (1)
**/*.kt
⚙️ CodeRabbit configuration file
**/*.kt: - Jetpack Compose 구조, 상태 관리, recomposition 최적화에 집중
- ViewModel, UiState, 단방향 데이터 흐름 패턴 검토
- 불필요한 recomposition 가능성, remember/derivedStateOf 적절한 사용 확인
- 네이밍 컨벤션, 가독성, Google 권장 Android 아키텍처 준수 여부
Files:
app/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.ktapp/src/main/java/com/cherrish/android/core/designsystem/component/type/CherrishGaugeType.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeScreen.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeUiState.ktapp/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeViewModel.ktapp/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt
🧠 Learnings (1)
📚 Learning: 2026-01-12T19:49:27.085Z
Learnt from: nhyeonii
Repo: TEAM-Cherrish/Cherrish-Android PR: 41
File: app/src/main/java/com/cherrish/android/presentation/challenge/ChallengeScreen.kt:30-39
Timestamp: 2026-01-12T19:49:27.085Z
Learning: When a Jetpack Compose screen composable receives a Scaffold paddingValues: PaddingValues parameter (commonly from Scaffold), apply it to the root container's modifier first (e.g., .padding(paddingValues)) before applying any additional padding. This ensures content respects system bars (status/navigation) and avoids layout overlap. This pattern should be followed across presentation screens under app/src/main/java/com/cherrish/android/presentation/ to maintain consistent insets handling.
Applied to files:
app/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeScreen.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeUiState.ktapp/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.ktapp/src/main/java/com/cherrish/android/presentation/home/HomeViewModel.ktapp/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt
🧬 Code graph analysis (3)
app/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.kt (2)
app/src/main/java/com/cherrish/android/presentation/home/component/PlanBox.kt (1)
PlanBox(22-63)app/src/main/java/com/cherrish/android/core/designsystem/theme/Theme.kt (1)
CherrishTheme(38-61)
app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt (3)
app/src/main/java/com/cherrish/android/presentation/home/HomeViewModel.kt (1)
onUpcomingPlanClick(20-21)app/src/main/java/com/cherrish/android/core/designsystem/component/button/CherrishButton.kt (1)
CherrishButton(27-79)app/src/main/java/com/cherrish/android/core/designsystem/theme/Theme.kt (1)
CherrishTheme(38-61)
app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt (3)
app/src/main/java/com/cherrish/android/core/designsystem/component/gaugebar/CherrishGaugeBar.kt (1)
CherrishGaugeBar(28-107)app/src/main/java/com/cherrish/android/core/designsystem/component/button/CherrishButton.kt (1)
CherrishButton(27-79)app/src/main/java/com/cherrish/android/core/designsystem/theme/Theme.kt (1)
CherrishTheme(38-61)
⏰ 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). (2)
- GitHub Check: PR Lint Check
- GitHub Check: PR Build Check
🔇 Additional comments (18)
app/src/main/res/drawable/ic_app_logo.xml (1)
1-33: 로고 벡터 자산 구성 OK입니다.벡터 리소스 구조와 경로 정의가 정상적으로 보입니다.
app/src/main/java/com/cherrish/android/core/designsystem/component/type/CherrishGaugeType.kt (1)
6-14: 퍼센트/이미지 매핑 추가가 명확합니다.레벨별 수치와 리소스가 한눈에 들어와 유지보수에 도움이 됩니다.
app/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.kt (1)
150-184: 프리뷰 구성 좋습니다.샘플 데이터로 동작 확인하기에 충분합니다.
app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt (9)
56-105: 섹션 구성과 분기가 깔끔합니다.헤더/구분선/빈 상태/리스트 분기가 명확합니다.
107-130: 리스트 렌더링 구조가 명확합니다.아이템별 key 적용도 적절합니다.
132-168: 콘텐츠 구성 및 클릭 처리 흐름이 자연스럽습니다.타임라인과 콘텐츠 연계가 잘 되어 있습니다.
170-214: 타임라인 드로잉 로직이 명료합니다.스타일 계산과 그리기 흐름이 읽기 쉽습니다.
288-305: DDay 칩 구성 간결하고 좋습니다.스타일/컬러 적용이 일관됩니다.
307-341: 빈 상태 UI가 명확합니다.이미지/문구/CTA 흐름이 자연스럽습니다.
343-353: 빈 상태 프리뷰 적절합니다.
355-384: 채워진 상태 프리뷰도 충분합니다.
234-249: 로케일 기반 날짜 포맷 적용 필요 여부를 수동으로 확인해 주세요.Line 239의
upcomingDate.toString()이 ISO 포맷을 사용하는지, 그리고 사용자 표시용으로 로케일 포맷이 필요한지 확인이 필요합니다. 또한 제안된remember()사용이 현재 Composable의 상태 관리 구조에 적합한지도 함께 검토해 주세요.app/src/main/java/com/cherrish/android/presentation/home/HomeViewModel.kt (1)
20-27: 클릭 핸들러 메서드들이 구현되어 있지 않아 사용자 상호작용이 동작하지 않습니다.
onUpcomingPlanClick,onAddChallengeClick,onAddPlanClick메서드들이 비어있습니다. ViewModel의 단방향 데이터 흐름 패턴에 맞게 적절한 이벤트 또는 상태 변경 로직을 구현해 주세요.app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt (2)
38-48: LGTM! 외부 modifier 처리 패턴이 적절합니다.외부
modifier를 Box에만 적용하고, 내부 Column에서는 새로운Modifier.fillMaxWidth()를 사용하는 구조가 올바르게 구현되었습니다.
207-233: 프리뷰 구현이 적절합니다.
CherrishTheme으로 래핑하고,currentStep = 0(NoChallenge)과currentStep = 2(InProgress) 두 가지 상태를 모두 커버하는 프리뷰가 잘 구성되어 있습니다.app/src/main/java/com/cherrish/android/presentation/home/HomeScreen.kt (3)
86-89: LGTM! paddingValues 적용 패턴이 올바릅니다.
paddingValues를 LazyColumn의 modifier에 먼저 적용하여 시스템 바(상태바/네비게이션 바)와의 오버랩을 방지하고 있습니다. Based on learnings, 이 패턴이 프레젠테이션 스크린에서 권장됩니다.
76-83: Gradient 색상에persistentListOf사용 - 좋습니다.
Brush.verticalGradient의 colors 파라미터에persistentListOf를 사용하여 불필요한 recomposition을 방지하고 있습니다.
126-138: 프리뷰 구현이 적절합니다.
CherrishTheme으로 래핑하고HomeUiState.fake를 사용하여 프리뷰를 구성했습니다. 모든 콜백에 빈 람다를 전달하여 프리뷰가 정상 동작합니다.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| @Composable | ||
| private fun Challenge( | ||
| currentStep: Int, | ||
| gauges: ImmutableList<CherrishGaugeType>, | ||
| challengeName: String, | ||
| modifier: Modifier = Modifier | ||
| ) { | ||
| val safeStep = currentStep.coerceIn(1, gauges.size) | ||
| val currentPercent = gauges[safeStep - 1].percent |
There was a problem hiding this comment.
gauges가 빈 리스트일 때 IndexOutOfBoundsException 발생 가능
gauges.size가 0이면 coerceIn(1, 0)은 1을 반환하고, gauges[0] 접근 시 크래시가 발생합니다.
🐛 빈 리스트 방어 코드 추가
`@Composable`
private fun Challenge(
currentStep: Int,
gauges: ImmutableList<CherrishGaugeType>,
challengeName: String,
modifier: Modifier = Modifier
) {
+ if (gauges.isEmpty()) return
+
val safeStep = currentStep.coerceIn(1, gauges.size)
val currentPercent = gauges[safeStep - 1].percent📝 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.
| @Composable | |
| private fun Challenge( | |
| currentStep: Int, | |
| gauges: ImmutableList<CherrishGaugeType>, | |
| challengeName: String, | |
| modifier: Modifier = Modifier | |
| ) { | |
| val safeStep = currentStep.coerceIn(1, gauges.size) | |
| val currentPercent = gauges[safeStep - 1].percent | |
| `@Composable` | |
| private fun Challenge( | |
| currentStep: Int, | |
| gauges: ImmutableList<CherrishGaugeType>, | |
| challengeName: String, | |
| modifier: Modifier = Modifier | |
| ) { | |
| if (gauges.isEmpty()) return | |
| val safeStep = currentStep.coerceIn(1, gauges.size) | |
| val currentPercent = gauges[safeStep - 1].percent |
🤖 Prompt for AI Agents
In
`@app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt`
around lines 90 - 98, The Challenge composable can crash when gauges is empty
because safeStep = currentStep.coerceIn(1, gauges.size) yields 1 and then
gauges[safeStep - 1] is out of bounds; update Challenge to early-return or
render an empty/placeholder UI when gauges.isEmpty(), or compute safeStep only
if gauges.isNotEmpty() (e.g., guard before using gauges[safeStep - 1]), and
reference the currentStep, gauges, safeStep and currentPercent variables so you
avoid accessing gauges[...] when size == 0.
| plans.drop(previewCount).forEachIndexed { extraIndex, plan -> | ||
| key( | ||
| "${plan.procedureName}-${plan.daysSince}-${plan.downtimePhase}" | ||
| ) { | ||
| PlanBox( | ||
| state = PlanBoxState.Filled( | ||
| medicalProcedureName = plan.procedureName, | ||
| medicalProcedureNameDate = plan.daysSince, | ||
| downtimePhase = plan.downtimePhase | ||
| ) | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n app/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.kt | head -200Repository: TEAM-Cherrish/Cherrish-Android
Length of output: 8431
🏁 Script executed:
find . -type f -name "*.kt" | xargs grep -l "class PlanUiModel\|data class PlanUiModel" | head -5Repository: TEAM-Cherrish/Cherrish-Android
Length of output: 153
🏁 Script executed:
cat -n ./app/src/main/java/com/cherrish/android/presentation/home/model/PlanUiModel.ktRepository: TEAM-Cherrish/Cherrish-Android
Length of output: 441
동일 일정 key 충돌 가능성
Line 117의 key에 인덱스가 빠져 있습니다. 첫 번째 루프(84줄)에서는 인덱스를 포함하고 있으나, 이 부분에서는 누락되어 있습니다. procedureName, daysSince, downtimePhase 조합이 반복될 경우 동일한 key를 가진 항목들의 상태가 섞일 수 있습니다. extraIndex를 포함하여 수정해 주세요.
🔧 수정 제안
- key(
- "${plan.procedureName}-${plan.daysSince}-${plan.downtimePhase}"
- ) {
+ key(
+ "${plan.procedureName}-${plan.daysSince}-${plan.downtimePhase}-$extraIndex"
+ ) {📝 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.
| plans.drop(previewCount).forEachIndexed { extraIndex, plan -> | |
| key( | |
| "${plan.procedureName}-${plan.daysSince}-${plan.downtimePhase}" | |
| ) { | |
| PlanBox( | |
| state = PlanBoxState.Filled( | |
| medicalProcedureName = plan.procedureName, | |
| medicalProcedureNameDate = plan.daysSince, | |
| downtimePhase = plan.downtimePhase | |
| ) | |
| ) | |
| } | |
| } | |
| plans.drop(previewCount).forEachIndexed { extraIndex, plan -> | |
| key( | |
| "${plan.procedureName}-${plan.daysSince}-${plan.downtimePhase}-$extraIndex" | |
| ) { | |
| PlanBox( | |
| state = PlanBoxState.Filled( | |
| medicalProcedureName = plan.procedureName, | |
| medicalProcedureNameDate = plan.daysSince, | |
| downtimePhase = plan.downtimePhase | |
| ) | |
| ) | |
| } | |
| } |
🤖 Prompt for AI Agents
In
`@app/src/main/java/com/cherrish/android/presentation/home/component/PlanBoxSection.kt`
around lines 116 - 128, The key used inside the second loop of PlanBoxSection
(the key(...) wrapping PlanBox in the plans.drop(previewCount).forEachIndexed
block) is missing the loop index and can collide when
procedureName/daysSince/downtimePhase repeat; include the extraIndex in the key
(e.g., append or incorporate extraIndex) so each item gets a unique key; update
the key construction that builds from plan.procedureName, plan.daysSince and
plan.downtimePhase to also include extraIndex while leaving PlanBox and
PlanBoxState.Filled unchanged.
| companion object { | ||
| val fake = HomeUiState( | ||
| currentStep = 1, | ||
| gauges = CherrishGaugeType.entries.toImmutableList(), | ||
| challengeName = "웰니스 • 마음챙김", | ||
| todayDate = "2026년 1월 1일 (목)", | ||
| plans = List(10) { | ||
| PlanUiModel( | ||
| procedureName = "슈링크", | ||
| daysSince = 2, | ||
| downtimePhase = DowntimePhase.SENSITIVE | ||
| ) | ||
| }.toImmutableList(), | ||
| upcomingPlans = persistentListOf( | ||
| UpcomingPlanUiModel( | ||
| upcomingPlanDate = LocalDate.now().plusDays(3), | ||
| procedureName = "써마지", | ||
| procedureCount = 2, | ||
| dDay = 3 | ||
| ), | ||
| UpcomingPlanUiModel( | ||
| upcomingPlanDate = LocalDate.now().plusDays(3), | ||
| procedureName = "써마지", | ||
| procedureCount = 2, | ||
| dDay = 3 | ||
| ) | ||
| ), |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cd "$(git rev-parse --show-toplevel)" && \
wc -l app/src/main/java/com/cherrish/android/presentation/home/HomeUiState.ktRepository: TEAM-Cherrish/Cherrish-Android
Length of output: 148
🏁 Script executed:
cat -n app/src/main/java/com/cherrish/android/presentation/home/HomeUiState.ktRepository: TEAM-Cherrish/Cherrish-Android
Length of output: 2366
🏁 Script executed:
# Search for other usages of todayDate and upcomingPlanDate in the codebase
rg -A 3 -B 3 "todayDate|upcomingPlanDate" app/src/main/java/com/cherrish/android/presentation/home/ --type ktRepository: TEAM-Cherrish/Cherrish-Android
Length of output: 100
🏁 Script executed:
# Check if there are date comparisons or calculations in HomeScreen or related composables
rg -l "HomeUiState" app/src/main --type kt | head -10Repository: TEAM-Cherrish/Cherrish-Android
Length of output: 100
🏁 Script executed:
rg "HomeUiState.fake" app/src/main --type kotlinRepository: TEAM-Cherrish/Cherrish-Android
Length of output: 300
🏁 Script executed:
rg -A 5 -B 5 "todayDate" app/src/main/java/com/cherrish/android/presentation/home/ --type kotlinRepository: TEAM-Cherrish/Cherrish-Android
Length of output: 7259
🏁 Script executed:
# Search for date-based calculations or comparisons in home-related files
rg "LocalDate|dDay|daysSince" app/src/main/java/com/cherrish/android/presentation/home/ --type kotlin -A 2Repository: TEAM-Cherrish/Cherrish-Android
Length of output: 14005
fake 데이터의 기준일 불일치를 수정하세요.
todayDate는 "2026년 1월 1일 (목)"로 고정되어 있으나, upcomingPlanDate는 LocalDate.now()를 기준으로 하므로 매일 달라집니다. 이로 인해 preview의 일관성이 깨지고 신뢰할 수 없는 테스트 데이터가 됩니다. 예를 들어, dDay = 3은 고정값이지만 upcomingPlanDate는 실행 시점에 따라 변하므로 불일치가 발생합니다.
fakeBaseDate = LocalDate.of(2026, 1, 1)을 생성한 후 upcomingPlanDate에서 사용하여 모든 날짜를 이 기준일 기반으로 통일하세요.
🔧 수정 제안
companion object {
+ private val fakeBaseDate = LocalDate.of(2026, 1, 1)
val fake = HomeUiState(
currentStep = 1,
gauges = CherrishGaugeType.entries.toImmutableList(),
challengeName = "웰니스 • 마음챙김",
todayDate = "2026년 1월 1일 (목)",
plans = List(10) {
PlanUiModel(
procedureName = "슈링크",
daysSince = 2,
downtimePhase = DowntimePhase.SENSITIVE
)
}.toImmutableList(),
upcomingPlans = persistentListOf(
UpcomingPlanUiModel(
- upcomingPlanDate = LocalDate.now().plusDays(3),
+ upcomingPlanDate = fakeBaseDate.plusDays(3),
procedureName = "써마지",
procedureCount = 2,
dDay = 3
),
UpcomingPlanUiModel(
- upcomingPlanDate = LocalDate.now().plusDays(3),
+ upcomingPlanDate = fakeBaseDate.plusDays(3),
procedureName = "써마지",
procedureCount = 2,
dDay = 3
)
),
selectedIndex = 0
)🤖 Prompt for AI Agents
In `@app/src/main/java/com/cherrish/android/presentation/home/HomeUiState.kt`
around lines 23 - 49, HomeUiState.fake uses a hardcoded todayDate but builds
upcomingPlans with LocalDate.now(), causing inconsistent preview data; create a
LocalDate fakeBaseDate = LocalDate.of(2026, 1, 1) inside the companion object
and replace LocalDate.now().plusDays(...) uses for
UpcomingPlanUiModel.upcomingPlanDate with fakeBaseDate.plusDays(...) so all
dates (todayDate and upcomingPlanDate) and dDay calculations are consistently
based on the same reference date in the HomeUiState.fake initializer.
| modifier: Modifier = Modifier, | ||
| @DrawableRes imageRes: Int = R.drawable.img_lv1, | ||
| onChallengeStartClick: () -> Unit = {}, | ||
| challengeName: String = "웰니스 • 마음챙김" |
There was a problem hiding this comment.
P2 : 얘랑 위에잇는 imageRes 이거능 기본값이 필요하까여 ??
|
|
||
| @Composable | ||
| private fun NoChallenge( | ||
| currentStep: Int, |
There was a problem hiding this comment.
P3 : 챌린지가 없을 경우는 currentStep이 0이 고정이니까 고정 기본값 = 0으로 줘도 괜찮지 않을가여 ???!
| .clip(shape = RoundedCornerShape(14.dp)) | ||
| .background(color = CherrishTheme.colors.gray0) | ||
| .padding(horizontal = 15.dp, vertical = 16.dp), | ||
| verticalArrangement = Arrangement.spacedBy(16.dp) |
| Column( | ||
| modifier = modifier | ||
| .fillMaxWidth() | ||
| .padding(horizontal = 9.dp), |
There was a problem hiding this comment.
P1 : 요거 패딩 9.dp 어디에잇는지....?! ㅜㅜ
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt`:
- Around line 238-249: The Text is using upcomingDate.toString() which outputs
an ISO date; change it to format the LocalDate with a localized
DateTimeFormatter (e.g., DateTimeFormatter.ofPattern("M월 d일", Locale.KOREA) or
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.KOREA))
and call formatter.format(upcomingDate) inside the Text; update the imports to
include java.time.format.DateTimeFormatter and java.util.Locale and keep the
existing modifier logic (previousDateTextTopY / onDateTextTopPositioned)
unchanged.
♻️ Duplicate comments (2)
app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt (1)
97-98: 빈 gauges에서 크래시 가능 (guard 필요)
gauges.size가 0이면coerceIn(1, 0)가 1로 반환되어gauges[0]접근 시 크래시가 발생합니다. 빈 리스트일 때는 조기 반환하거나 placeholder를 렌더링하세요.🐛 제안 수정
private fun Challenge( currentStep: Int, gauges: ImmutableList<CherrishGaugeType>, challengeName: String, modifier: Modifier = Modifier ) { + if (gauges.isEmpty()) return + val safeStep = currentStep.coerceIn(1, gauges.size) val currentPercent = gauges[safeStep - 1].percentapp/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt (1)
63-88: 디바이더가 카드 패딩만큼 인셋됨 — 풀폭 필요 여부 확인상위 Column에 수평 패딩(15.dp)이 있어 디바이더도 함께 인셋됩니다. 디자인이 카드 풀폭 디바이더를 요구한다면 패딩을 디바이더 밖으로 분리하는 구조가 필요합니다. citeturn0search0
🔧 예시 수정안
- Column( - modifier = modifier - .fillMaxWidth() - .dropShadow(...) - .clip(shape = RoundedCornerShape(14.dp)) - .background(color = CherrishTheme.colors.gray0) - .padding(horizontal = 15.dp, vertical = 16.dp) - ) { - Text(...) - HorizontalDivider(...) - ... - } + Column( + modifier = modifier + .fillMaxWidth() + .dropShadow(...) + .clip(shape = RoundedCornerShape(14.dp)) + .background(color = CherrishTheme.colors.gray0) + ) { + Column(modifier = Modifier.padding(horizontal = 15.dp, vertical = 16.dp)) { + Text(...) + } + HorizontalDivider( + thickness = 1.dp, + color = CherrishTheme.colors.gray300 + ) + Column(modifier = Modifier.padding(horizontal = 15.dp, vertical = 16.dp)) { + ... + } + }
🧹 Nitpick comments (1)
app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt (1)
113-129: 리스트가 길어질 수 있다면 LazyColumn 전환 권장현재 Column + forEachIndexed는 전체 측정/조합이 발생합니다. 계획 개수가 늘어날 가능성이 있으면 LazyColumn으로 전환해 성능과 메모리 사용을 안정화하는 편이 Compose 관례에 맞습니다. citeturn0search0
♻️ LazyColumn 예시
- Column( - modifier = modifier - .fillMaxWidth() - .padding(start = 26.dp, end = 16.dp) - ) { - plans.forEachIndexed { index, plan -> - key("${plan.upcomingPlanDate}-$index") { - UpcomingPlanContent(...) - } - } - } + LazyColumn( + modifier = modifier + .fillMaxWidth() + .padding(start = 26.dp, end = 16.dp) + ) { + itemsIndexed( + items = plans, + key = { index, plan -> "${plan.upcomingPlanDate}-$index" } + ) { index, plan -> + UpcomingPlanContent(...) + } + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.ktapp/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt
🧰 Additional context used
📓 Path-based instructions (1)
**/*.kt
⚙️ CodeRabbit configuration file
**/*.kt: - Jetpack Compose 구조, 상태 관리, recomposition 최적화에 집중
- ViewModel, UiState, 단방향 데이터 흐름 패턴 검토
- 불필요한 recomposition 가능성, remember/derivedStateOf 적절한 사용 확인
- 네이밍 컨벤션, 가독성, Google 권장 Android 아키텍처 준수 여부
Files:
app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.ktapp/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt
🧠 Learnings (1)
📚 Learning: 2026-01-12T19:49:27.085Z
Learnt from: nhyeonii
Repo: TEAM-Cherrish/Cherrish-Android PR: 41
File: app/src/main/java/com/cherrish/android/presentation/challenge/ChallengeScreen.kt:30-39
Timestamp: 2026-01-12T19:49:27.085Z
Learning: When a Jetpack Compose screen composable receives a Scaffold paddingValues: PaddingValues parameter (commonly from Scaffold), apply it to the root container's modifier first (e.g., .padding(paddingValues)) before applying any additional padding. This ensures content respects system bars (status/navigation) and avoids layout overlap. This pattern should be followed across presentation screens under app/src/main/java/com/cherrish/android/presentation/ to maintain consistent insets handling.
Applied to files:
app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.ktapp/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt
🧬 Code graph analysis (1)
app/src/main/java/com/cherrish/android/presentation/home/component/ChallengeSection.kt (3)
app/src/main/java/com/cherrish/android/core/designsystem/component/gaugebar/CherrishGaugeBar.kt (1)
CherrishGaugeBar(28-107)app/src/main/java/com/cherrish/android/core/designsystem/component/button/CherrishButton.kt (1)
CherrishButton(27-79)app/src/main/java/com/cherrish/android/core/designsystem/theme/Theme.kt (1)
CherrishTheme(38-61)
⏰ 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). (2)
- GitHub Check: PR Lint Check
- GitHub Check: PR Build Check
🔇 Additional comments (5)
app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt (5)
132-168: 구성/상태 흐름 문제 없음타임라인/박스 상태 분리와 클릭 처리 흐름이 명확합니다.
170-214: 타임라인 캔버스 로직 OK라인/도트 렌더링과 크기 계산 흐름이 자연스럽습니다.
288-305: DDayChip 구성 OK간결하고 목적에 맞는 컴포저블입니다.
307-343: 빈 상태 UI 구성 OK요소 배치와 버튼 액션 연결이 명확합니다.
345-386: 프리뷰 구성 OK빈/채움 상태를 모두 커버해 확인에 유용합니다.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| Text( | ||
| text = upcomingDate.toString(), | ||
| style = CherrishTheme.typography.body1M14, | ||
| color = CherrishTheme.colors.gray700, | ||
| modifier = Modifier.onGloballyPositioned { coordinates -> | ||
| val y = coordinates.positionInParent().y | ||
| if (previousDateTextTopY.isNaN() || abs(y - previousDateTextTopY) > 0.5f) { | ||
| previousDateTextTopY = y | ||
| onDateTextTopPositioned(y) | ||
| } | ||
| } | ||
| ) |
There was a problem hiding this comment.
날짜 표시 형식 로컬라이즈 필요
LocalDate.toString()은 ISO(예: 2026-01-20)로 노출됩니다. 홈 화면이 한국어 UX라면 M월 d일 등 로컬 형식으로 포맷하는 편이 자연스럽습니다.
💡 포맷 적용 예시
- Text(
- text = upcomingDate.toString(),
+ val formatter = remember { java.time.format.DateTimeFormatter.ofPattern("M월 d일") }
+ Text(
+ text = upcomingDate.format(formatter),필요 시 상단 import 추가:
import java.time.format.DateTimeFormatter🤖 Prompt for AI Agents
In
`@app/src/main/java/com/cherrish/android/presentation/home/component/UpcomingPlanSection.kt`
around lines 238 - 249, The Text is using upcomingDate.toString() which outputs
an ISO date; change it to format the LocalDate with a localized
DateTimeFormatter (e.g., DateTimeFormatter.ofPattern("M월 d일", Locale.KOREA) or
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.KOREA))
and call formatter.format(upcomingDate) inside the Text; update the imports to
include java.time.format.DateTimeFormatter and java.util.Locale and keep the
existing modifier logic (previousDateTextTopY / onDateTextTopPositioned)
unchanged.
@nhyeonii |












Related issue 🛠
Work Description ✏️
Screenshot 📸
Screen_recording_20260116_033813.mp4
Uncompleted Tasks 😅
To Reviewers 📢
홈 화면 섹션별로 #21 에서 작업을 하고 그 브랜치에서 새 브랜치를 파서 뷰 조립 작업을 진행했는데요..!
그 과정에서 뷰 수정이 일어나 리드님과 의논하에 그 이슈 버리고 이 피알에서 다 보기로 했습니다ㅎㅎ
(많은 양의 변경 미리 죄송합니다ㅜㅜㅜ)
최종 바뀐 부분까지 반영했습니다~
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선사항
✏️ Tip: You can customize this high-level summary in your review settings.