[Feature/#227] 리포트 화면 구현 - #229
Conversation
: 당일 감정구슬 조회 바텀시트, 이전/이후 월로 이동
…구슬 목록을 서버로부터 받아오도록 수정
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Walkthrough활동 로그 조회와 월별 캐시를 추가했습니다. 배지와 감정 구슬을 표시하는 리포트 화면을 구현했습니다. 리포트 탭과 홈 내비게이션을 연결했습니다. 감정 등록 성공 시 현재 월의 감정 구슬 캐시를 무효화합니다. Changes활동 로그 리포트
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant 사용자
participant SummaryScreen
participant SummaryViewModel
participant GetBadgesUseCase
participant ActivityLogRepositoryImpl
participant ActivityLogService
사용자->>SummaryScreen: 리포트 탭 선택
SummaryScreen->>SummaryViewModel: 월 변경 전달
SummaryViewModel->>GetBadgesUseCase: 인접 월 조회
GetBadgesUseCase->>ActivityLogRepositoryImpl: YearMonth 전달
ActivityLogRepositoryImpl->>ActivityLogService: 배지 API 호출
ActivityLogService-->>ActivityLogRepositoryImpl: 배지 응답 반환
ActivityLogRepositoryImpl-->>SummaryViewModel: MonthlyBadge 결과 반환
SummaryViewModel-->>SummaryScreen: 상태 갱신
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (1)
presentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/SummaryScreen.kt (1)
64-84: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win
currentPage대신settledPage를 사용하십시오.
LaunchedEffect(pagerState.currentPage)는 페이지가 스냅 위치에 가까워지는 즉시 갱신되는currentPage를 감지합니다. 공식 문서에 따르면currentPage는 스크롤 중에도 즉시 갱신되지만,settledPage는 애니메이션이 완전히 끝날 때까지 값이 유지됩니다.사용자가 여러 달을 빠르게 스와이프하면, 최종적으로 머무르지 않는 중간 달에 대해서도
onMonthChanged가 호출됩니다. 이는 불필요한 뱃지/감정 구슬 프리페치 호출과 월 라벨 텍스트의 깜빡임을 유발합니다.
pagerState.settledPage로 바꾸면 스크롤이 완전히 멈춘 뒤에만 상태를 갱신합니다.♻️ 제안하는 수정
- LaunchedEffect(pagerState.currentPage) { - val monthOffset = pagerState.currentPage - INITIAL_PAGE + LaunchedEffect(pagerState.settledPage) { + val monthOffset = pagerState.settledPage - INITIAL_PAGE val targetMonth = YearMonth.now().plusMonths(monthOffset.toLong()) if (state.currentMonth != targetMonth) { onMonthChanged(targetMonth) } }Based learnings from Android Developers 공식 문서: "currentPage immediately updates if the page is close enough to the snap position, but settledPage remains the same until all the animations are finished running."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@presentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/SummaryScreen.kt` around lines 64 - 84, SummaryScreen의 페이지 변경 감지에서 LaunchedEffect와 월 오프셋 계산에 사용하는 pagerState.currentPage를 pagerState.settledPage로 변경하십시오. 애니메이션이 완전히 종료된 최종 페이지만 기준으로 onMonthChanged가 호출되도록 하고, 나머지 월 계산 및 상태 비교 로직은 유지하십시오.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@data/src/main/java/com/threegap/bitnagil/data/activitylog/model/response/BadgeResponse.kt`:
- Around line 44-45: Update String.toBadgeType in BadgeResponse to stop falling
back to BadgeType.UNKNOWN and instead propagate a
serializationException/SerializationException when BadgeType.valueOf receives an
unsupported server value; remove the BadgeType.UNKNOWN fallback comment. In
BadgeType.kt, make no direct change unless required to support this
exception-based mapping.
In
`@data/src/main/java/com/threegap/bitnagil/data/activitylog/repositoryImpl/ActivityLogRepositoryImpl.kt`:
- Around line 61-62: Synchronize invalidateEmotionMarbleCache with in-flight
emotion-marble reads using emotionMarbleFetchMutex, ensuring cache removal
cannot race with a fetch that later stores stale data. Alternatively, track
per-month generations and prevent reads started before invalidation from writing
their results.
- Around line 40-58: Update getEmotionMarbles so the cache key includes both
startDate and endDate, preventing results for one date range from being reused
for another; alternatively, change the repository contract to accept YearMonth
and consistently calculate the month boundaries internally if only monthly
queries are supported. Update the corresponding emotionMarblesByMonth cache
lookups and saveEmotionMarbles calls to use the selected range key or normalized
monthly range.
In
`@presentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/component/template/summarybadge/SummaryBadgeView.kt`:
- Line 1: SummaryBadgeView와 SummaryScreen의 높이 설정을 일치시키십시오. StarImage의 offset 계산이
260.dp 기준이라면 SummaryScreen에서 전달하는 .height(360.dp)를 260.dp로 변경하고, 360.dp가 의도된
값이라면 Background 내부 높이와 모든 star/offset 배치를 360.dp 기준으로 갱신하십시오.
- Around line 86-97: Align the height configuration between SummaryBadgeView()
and its SummaryScreen.kt caller: use one consistent rendering height instead of
combining the caller’s 360.dp with the internal 260.dp constraint in the
Background/BoxWithConstraints block. Preserve the StarImage offset and alignment
design by either matching the caller to 260.dp or removing the internal fixed
height and related statusBarsPadding so the component uses the caller-provided
size.
In
`@presentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/component/template/summarycalendar/SummaryCalendarView.kt`:
- Around line 139-146: Update the SummaryCalendarView preview data to use
prevMonth.atEndOfMonth() instead of prevMonth.atDay(30), ensuring the previous
month’s final valid date is used for every month, including February.
In
`@presentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/SummaryViewModel.kt`:
- Around line 66-110: SummaryViewModel에서 배지 및 감정 구슬 요청 실패가 로그에만 남지 않고 UI에 전달되도록
수정하세요. SummaryState에 오류 상태 필드를 추가해 실패 정보를 반영하거나, container의 Unit 타입을 실제 오류 사이드
이펙트 타입으로 변경하고 fetchBadges와 fetchEmotionMarbles의 onFailure에서 postSideEffect를
호출하세요. 기존 loadingCount 감소 처리는 유지하고 두 요청 경로가 동일한 실패 전달 방식을 사용하도록 하세요.
---
Nitpick comments:
In
`@presentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/SummaryScreen.kt`:
- Around line 64-84: SummaryScreen의 페이지 변경 감지에서 LaunchedEffect와 월 오프셋 계산에 사용하는
pagerState.currentPage를 pagerState.settledPage로 변경하십시오. 애니메이션이 완전히 종료된 최종 페이지만
기준으로 onMonthChanged가 호출되도록 하고, 나머지 월 계산 및 상태 비교 로직은 유지하십시오.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 47667ab0-1f34-4ba1-8e55-b139221621ed
📒 Files selected for processing (39)
app/src/main/java/com/threegap/bitnagil/di/data/DataSourceModule.ktapp/src/main/java/com/threegap/bitnagil/di/data/RepositoryModule.ktapp/src/main/java/com/threegap/bitnagil/di/data/ServiceModule.ktapp/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.ktapp/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.ktapp/src/main/java/com/threegap/bitnagil/navigation/home/HomeRoute.ktapp/src/main/res/drawable/ic_report.xmlcore/designsystem/src/main/res/drawable/ic_badge_question.xmldata/src/main/java/com/threegap/bitnagil/data/activitylog/datasource/ActivityLogLocalDataSource.ktdata/src/main/java/com/threegap/bitnagil/data/activitylog/datasource/ActivityLogRemoteDataSource.ktdata/src/main/java/com/threegap/bitnagil/data/activitylog/datasourceImpl/ActivityLogLocalDataSourceImpl.ktdata/src/main/java/com/threegap/bitnagil/data/activitylog/datasourceImpl/ActivityLogRemoteDataSourceImpl.ktdata/src/main/java/com/threegap/bitnagil/data/activitylog/model/response/BadgeResponse.ktdata/src/main/java/com/threegap/bitnagil/data/activitylog/model/response/EmotionMarbleResponse.ktdata/src/main/java/com/threegap/bitnagil/data/activitylog/repositoryImpl/ActivityLogRepositoryImpl.ktdata/src/main/java/com/threegap/bitnagil/data/activitylog/service/ActivityLogService.ktdata/src/main/java/com/threegap/bitnagil/data/emotion/repositoryImpl/EmotionRepositoryImpl.ktdomain/src/main/java/com/threegap/bitnagil/domain/activitylog/model/Badge.ktdomain/src/main/java/com/threegap/bitnagil/domain/activitylog/model/BadgeType.ktdomain/src/main/java/com/threegap/bitnagil/domain/activitylog/model/EmotionMarble.ktdomain/src/main/java/com/threegap/bitnagil/domain/activitylog/model/MonthlyBadge.ktdomain/src/main/java/com/threegap/bitnagil/domain/activitylog/repository/ActivityLogRepository.ktdomain/src/main/java/com/threegap/bitnagil/domain/activitylog/usecase/GetBadgesUseCase.ktdomain/src/main/java/com/threegap/bitnagil/domain/activitylog/usecase/GetEmotionMarblesUseCase.ktdomain/src/main/java/com/threegap/bitnagil/domain/emotion/usecase/RegisterEmotionUseCase.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/emotion/EmotionScreen.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/emotion/component/template/SwipeEmotionSelectionScreen.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/SummaryScreen.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/SummaryViewModel.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/component/template/emotiondaybottomsheet/EmotionDayBottomSheet.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/component/template/summarybadge/SummaryBadgeView.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/component/template/summarycalendar/SummaryCalendarView.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/contract/SummaryState.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/model/BadgeImage.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/model/SummaryBadgeTypeUiModel.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/model/SummaryBadgeUiModel.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/model/SummaryEmotionCellUiModel.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/model/SummaryEmotionDayUiModel.ktpresentation/src/main/java/com/threegap/bitnagil/presentation/screen/summary/model/SummaryEmotionType.kt
[ PR Content ]
리포트 화면을 구현합니다.
Related issue
Screenshot 📸
KakaoTalk_Video_2026-07-31-20-19-06.mp4
감정 구슬 선택 화면 전/후 비교
Work Description
To Reviewers 📢
Summary by CodeRabbit
새로운 기능
개선