홈 화면 API 연동 및 네비게이션 연결#141
Hidden character warning
Conversation
* **feat: 메인 데이터 및 연습 기록 관련 도메인 모델 및 UseCase 추가**
* 메인 화면의 대시보드 데이터를 위한 `MainData`와 프레젠테이션 연습 일정을 위한 `PracticeRecords` 모델을 추가했습니다.
* `FetchMainDataUseCase` 및 `FetchPracticeRecordsUseCase`를 구현하여 관련 비즈니스 로직을 제공합니다.
* **feat: 네트워크 레이어 API 연동 및 DTO 정의**
* `PresentationService`에 메인 데이터 조회(`GET /main`) 및 연습 기록 조회(`GET /recording/{presentationId}/practice-records`) API를 추가했습니다.
* 서버 응답 처리를 위한 `GetMainDataResponse`와 `GetPracticeRecordsResponse` DTO를 정의했습니다.
* **refactor: PresentationRepository 및 Data 레이어 구현**
* `PresentationRepository` 인터페이스에 새로운 기능들을 추가하고, `PresentationRepositoryImpl`에서 이를 구현했습니다.
* `PresentationMapper`를 확장하여 네트워크 응답 DTO를 도메인 모델인 `MainData` 및 `PracticeRecords`로 변환하는 매핑 로직을 추가했습니다.
* `PresentationRemoteDataSource`를 통해 실제 네트워크 통신을 수행하도록 연동했습니다.
* **feat: `AppDimmerState` 및 `LocalAppDimmerState` 추가**
* 앱 전체 화면을 어둡게(Dim) 처리하거나 상태를 관리하기 위한 `AppDimmerState` 클래스를 정의했습니다.
* `show`, `hide` 메서드와 함께 Dim 영역 클릭 시 호출될 `onDismissRequest` 콜백 로직을 구현했습니다.
* `LocalAppDimmerState` CompositionLocal을 제공하여 하위 컴포넌트에서 전역 Dimmer 상태에 접근할 수 있도록 했습니다.
* **feat: `PrezelApp` 내 전역 Dimmer 레이아웃 적용**
* `PrezelApp` 최상위 레이아웃에 Dimmer를 위한 `Box` 오버레이를 추가했습니다.
* `appDimmerState.isVisible` 상태에 따라 `scrimContainer` 색상의 배경이 나타나도록 설정했습니다.
* `noRippleClickable`을 사용하여 Dimmer 영역 클릭 시 설정된 `dismiss` 동작이 수행되도록 구현했습니다.
* **fix: `PracticeCard` 트래커 아이템의 종료일 포함 로직 수정**
* `toTrackerItems` 함수 호출 시 `dDay`에 1일을 더하도록 변경하여, 트래커 아이템 범위에 D-Day 당일이 올바르게 포함되도록 수정했습니다.
* **refactor: `PracticeCardPreview` 샘플 데이터 및 날짜 계산 로직 변경**
* 프리뷰 확인을 위한 `baseDate`와 `dDay` 날짜를 업데이트했습니다.
* 샘플 아이템 리스트 생성 시에도 `dDay`에 1일을 추가하여 실제 컴포넌트의 날짜 계산 방식과 일치시켰습니다.
* **refactor: `FetchMainDataUseCase` 내 연습 기록 병렬 조회 및 결합 로직 추가**
* 각 발표 데이터(`MainData`)에 해당하는 연습 기록을 `async`/`awaitAll`을 이용해 병렬로 조회하도록 개선했습니다.
* 유즈케이스의 반환 타입을 `Result<List<MainDataWithPracticeRecords>>`로 변경했습니다.
* **refactor: 도메인 및 네트워크 모델 구조 수정**
* 발표 정보와 연습 기록을 함께 담는 `MainDataWithPracticeRecords` 모델을 새롭게 정의했습니다.
* `MainData` 모델에서 `accuracyScoreChange`, `scriptMatchRateChange` 필드를 제거했습니다.
* `GetMainDataResponse` 네트워크 응답 모델의 필드들을 nullable로 변경하고, `PresentationMapper`에서 이에 따른 null 처리 로직을 반영했습니다.
* **build: 의존성 추가 및 기타 변경 사항**
* `core:domain` 모듈에 `kotlinx-datetime` 라이브러리 의존성을 추가했습니다.
* `AnalyzePresentationUseCase` 실행 시 성공 로그를 출력하도록 수정했습니다.
* **feat: 홈 화면 데이터 연동 및 상태 관리 로직 구현**
* `FetchMainDataUseCase`를 연동하여 실제 데이터를 조회하도록 `HomeViewModel`을 수정했습니다.
* 성장 그래프의 아이템 선택 상태를 토글하는 `ClickCardGraphItem` Intent 및 처리 로직을 추가했습니다.
* `HomeUiState`에서 도메인 모델(`MainDataWithPracticeRecords`)을 UI 모델로 변환하는 매핑 로직을 구현했습니다.
* **refactor: UI 데이터 모델 구조 개선**
* `PresentationUiModel`을 `Past`와 `Upcoming` 타입을 가진 `sealed interface`로 개편하여 발표 상태별 데이터 구조를 명확히 했습니다.
* 연습 기록 데이터를 관리하는 `PracticeRecordsUiModel`과 성장 그래프 데이터를 위한 `GrowthGraphData` 모델을 추가했습니다.
* **feat: 홈 화면 UI 구성 요소 고도화**
* **Floating Action Button(FAB) 및 배경 딤(Dim) 처리:** `LocalAppDimmerState`를 연동하여 FAB 확장 시 배경을 어둡게 처리하고, `Popup` 및 `PopupPositionProvider`를 통해 FAB 메뉴의 위치를 동적으로 계산하도록 개선했습니다.
* **발표 상세 시트(PresentationSheet):** 기존의 단순 버튼 구조에서 `PracticeCard`(연습 기록) 및 `CardGraph`(성장 그래프)를 포함한 상세한 정보를 보여주도록 업데이트했습니다.
* **발표 상태별 대응:** 과거 발표와 예정된 발표에 따라 시트 내 타이틀과 하단 콘텐츠(그래프 또는 키워드 섹션)가 다르게 노출되도록 구현했습니다.
* **style: 디자인 시스템 컴포넌트 및 리소스 추가**
* `PrezelFloatingButton` 및 `PrezelFloatingMenu`에 `enabled` 속성을 추가하여 상태 제어가 가능하도록 수정했습니다.
* 홈 화면 하단 시트에서 사용하는 새로운 문자열 리소스를 추가했습니다.
* `feature:home:impl` 모듈에 `core:domain` 의존성을 추가했습니다.
* **refactor: `HomeScreen` 컴포저블 분리 및 구조화**
* `HomeScreen.kt`의 거대한 UI 로직을 `HomeScreenContent`와 `HomeAnalysisFabOverlay`로 분리하여 가독성과 유지보수성을 높였습니다.
* 홈 화면의 상태(Loading, Empty, Content)에 따른 레이아웃 처리 로직을 `HomeScreenContent`로 통합했습니다.
* `HomeScreen` 프리뷰 코드에서 `CompositionLocalProvider`를 통해 필요한 상태를 주입하도록 개선했습니다.
* **feat: `HomeAnalysisFabOverlay` 컴포넌트 추가**
* 음성 녹음 분석 및 파일 업로드 분석 기능을 제공하는 확장형 플로팅 메뉴를 구현했습니다.
* `PopupPositionProvider`를 사용하여 메뉴의 확장/축소 상태에 따른 동적 팝업 위치 계산 로직을 적용했습니다.
* `LocalAppDimmerState`와 연동하여 메뉴 확장 시 배경 딤 처리가 적용되도록 구현했습니다.
* **refactor: `PrezelApp` 레이아웃 및 네비게이션 로직 정리**
* `PrezelApp`의 UI 구조를 `AppNavigationContent`와 `AppDimmerOverlay` 컴포저블로 분리하여 역할을 명확히 했습니다.
* 반복되는 네비게이션 애니메이션 설정을 `defaultPrezelNavTransition` 함수로 공통화했습니다.
* **refactor: 데이터 소스 및 UI 모델 정리**
* `PresentationRemoteDataSourceImpl`에서 파일 처리를 위한 헬퍼 함수들을 파일 수준의 프라이빗 함수로 이동하여 클래스 내부 로직을 단순화했습니다.
* `GrowthGraphData` 모델에서 사용되지 않는 `selectedItem` 프로퍼티를 제거했습니다.
* **fix: UI 텍스트 및 프리뷰 데이터 수정**
* `PresentationSheet`의 D-Day 표기 형식을 `-3`에서 `D-3`으로 수정했습니다.
* `HomeScreen` 프리뷰에서 그래프 데이터가 올바르게 표시되도록 샘플 데이터를 보강했습니다.
* **refactor: 네트워크 및 데이터 레이어 내 발표 ID 파라미터 추가**
* `PracticeService`의 연습 녹음 분석 API(`analyzePracticeRecording`)에 `presentationId` 쿼리 파라미터를 추가했습니다.
* `PracticeRemoteDataSource` 및 `PracticeRepository` 인터페이스와 관련 구현체에 `presentationId` 전달 로직을 반영했습니다.
* **refactor: 네비게이션 키 구조 변경 및 파라미터 전달 로직 개선**
* `PracticeNavKey`를 `data object`에서 `presentationId`를 포함하는 `data class`로 변경했습니다.
* `PracticeAnalysisNavKey`에 분석 대상 발표를 식별하기 위한 `presentationId` 필드를 추가했습니다.
* `HomeEntryBuilder` 및 `PracticeEntryBuilder`에서 변경된 네비게이션 키를 통해 ID가 전달되도록 수정했습니다.
* **refactor: UI 컴포넌트 및 네비게이션 의존성 정리**
* `HomeScreen`에서 `LocalNavigator` 직접 참조를 제거하고, `navigateToPracticeRecording` 콜백을 통해 네비게이션을 처리하도록 개선했습니다.
* `HomeScreenContent` 및 하위 컴포넌트에서 연습 녹음 시작 시 해당 발표의 ID를 전달하도록 변경했습니다.
* `EmptyPresentationSheet`의 불필요한 클릭 리스너 전달 로직을 정리했습니다.
* **refactor: 도메인 및 ViewModel 내 발표 ID 활용**
* `AnalyzePracticeRecordingUseCase`가 `presentationId`를 요구하도록 수정했습니다.
* `PracticeAnalysisViewModel` 및 Assisted Factory에 `presentationId`를 추가하여 분석 요청 시 사용하도록 구현했습니다.
* **refactor: ButtonType.FILLED의 배경색 테마 컬러 변경**
* `ButtonType.FILLED`에 적용되던 배경색 색상 값을 `PrezelTheme.colors.bgLarge`에서 `PrezelTheme.colors.bgDisabled`로 변경했습니다.
* **refactor: 메인 데이터 처리를 위한 `MainDataBundle` 도입 및 UseCase 개편**
* 닉네임과 발표 데이터 목록을 포함하는 `MainDataBundle` 클래스를 추가했습니다.
* `FetchMainDataUseCase`에서 `UserRepository`를 통해 사용자의 닉네임을 비동기로 함께 조회하도록 수정했습니다.
* `HomeUiState`의 매핑 로직을 `MainDataBundle` 기반으로 변경하여 하드코딩된 임시 닉네임을 실제 데이터로 대체했습니다.
* **feat: `UserRepository` 내 닉네임 캐싱 로직 추가**
* `UserRepository` 인터페이스에 `getUserNickname` 메서드를 추가했습니다.
* `UserRepositoryImpl`에서 `@Volatile` 변수를 사용하여 닉네임을 메모리에 캐싱하고, 정보 조회나 수정 시 캐시를 갱신하도록 구현했습니다.
* **refactor: 홈 화면 UI 구성 요소 리팩터링 및 기능 연결**
* 홈 화면의 빈 상태를 표시하는 로직을 별도의 `EmptySheet` 컴포넌트로 분리하여 가독성을 높였습니다.
* `EmptySheet`에 사용될 문자열 리소스를 추가하고 디자인 시스템의 버튼 및 테마를 적용했습니다.
* 홈 화면의 '발표 추가' 버튼 클릭 시 음성 녹음 분석 화면으로 이동하도록 네비게이션 로직을 연결했습니다.
* **refactor: UI 모델 클래스 이름 변경**
* `PracticeUiModel`을 보다 구체적인 명칭인 `PracticeRecordsUiModel`로 변경했습니다.
* **refactor: `ProfileViewModel` 초기화 시 데이터 로드 수행**
* 기존 UI 레이어에서 `FetchData` Intent를 통해 데이터를 요청하던 방식에서, ViewModel의 `init` 블록 내에서 `fetchUserInfo()`를 직접 호출하도록 변경했습니다.
* **cleanup: `ProfileUiIntent.FetchData` 및 관련 코드 제거**
* 더 이상 사용되지 않는 `ProfileUiIntent.FetchData` 정의를 삭제했습니다.
* `ProfileScreen`의 `LaunchedEffect`에서 `FetchData` Intent를 전달하던 로직을 제거하고, ViewModel의 `onIntent` 내 해당 처리 케이스를 삭제했습니다.
|
Warning Review limit reached
More reviews will be available in 40 minutes and 14 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthrough네트워크 응답 모델부터 도메인 인터페이스, 저장소 구현을 거쳐 홈 화면의 데이터 주도 렌더링까지 통합되는 홈 화면 API 연동 변경입니다. 연습 기록과 성장 그래프를 조회하는 새로운 엔드포인트를 추가하고, 복합 데이터를 병렬 로드하는 유스케이스를 도입하며, 홈 화면 UI를 상태 기반으로 재구성합니다. Changes홈 화면 API 연동 및 렌더링
Possibly related PRs
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
Prezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/FetchMainDataUseCase.kt (1)
18-44: 💤 Low value병렬 조회 구조는 정상이나, 발표 수에 비례하는 N+1 요청 패턴에 유의하세요.
각 발표마다
getPracticeRecords를 개별 호출하므로 발표 목록이 커지면 동시 네트워크 요청 수가 비례해 증가합니다. 구조적 동시성(coroutineScope+async/awaitAll)과 예외 전파/runCatching캡처는 올바르게 구성되어 있어 동작상 문제는 없습니다. 향후 목록 규모가 커질 가능성이 있다면 서버에서 메인 데이터에 연습 기록을 포함해 단일 응답으로 내려주는 방식을 검토해 보세요.🤖 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 `@Prezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/FetchMainDataUseCase.kt` around lines 18 - 44, The current invoke() in FetchMainDataUseCase builds presentations by calling repository.getPracticeRecords(...) inside a per-presentation async, causing an N+1 request pattern as presentation count grows; change this to a batched fetch: after repository.getMainData(), collect presentationIds and call a new or existing repository method (e.g., repository.getPracticeRecordsForPresentations(presentationIds) or extend repository.getMainData() to include practiceRecords) to retrieve all practice records in one request, then map those records back to each presentation when constructing MainDataBundle (keeping coroutineScope + async/awaitAll only for non-network parallelism if needed); update repository interfaces and toMainDataWithPracticeRecords usage accordingly to use the batched result.Prezel/core/ui/src/main/java/com/team/prezel/core/ui/state/LocalAppDimmerState.kt (1)
18-30: ⚡ Quick win
dismiss()에서hide()까지 보장하도록 보완 필요(현재는 우회 중)
LocalAppDimmerState.dismiss()는onDismissRequest?.invoke()만 실행하고isVisible = false처리는 하지 않습니다. 따라서show()를 콜백 없이(기본{}사용) 호출하는 케이스가 생기면 스크림 탭 시 디머가 닫히지 않는 “잠재적” 문제가 있습니다.다만 현재
LocalAppDimmerState.current사용처는HomeAnalysisFabOverlay뿐이며, 여기서는show { isFabExpanded = false }로 콜백을 넘기고(Prezel/feature/home/.../HomeAnalysisFabOverlay.kt),LaunchedEffect(isFabExpanded)에서isFabExpanded가 false가 되면hide()를 호출해 오늘 경로는 정상 동작합니다.
LocalAppDimmerState.dismiss()에서hide()를 함께 수행하도록(예:hide()후 콜백 invoke) 해서 기본 콜백{}를 쓰더라도 항상 닫히게 만드는 쪽을 권장합니다.🤖 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 `@Prezel/core/ui/src/main/java/com/team/prezel/core/ui/state/LocalAppDimmerState.kt` around lines 18 - 30, LocalAppDimmerState.dismiss() currently only invokes onDismissRequest and doesn't change isVisible, so update dismiss() to call hide() first and then invoke the callback (e.g., call hide() and then onDismissRequest?.invoke()) so the dimmer is always hidden even when the default empty callback is used; reference LocalAppDimmerState.dismiss(), hide(), show(), onDismissRequest and isVisible when making the change.Prezel/feature/home/impl/src/main/res/values/strings.xml (1)
27-29: 💤 Low value중복 문자열 값 정리 (선택).
feature_home_impl_empty_sheet_practice_card_title(라인 29, "지금부터 연습해보세요")은 라인 4feature_home_impl_bottom_sheet_empty_title과,feature_home_impl_empty_sheet_practice_card_button_text(라인 28, "연습하기")은 라인 25feature_home_impl_practice_recording_action과 동일한 값입니다. 동일 의미라면 기존 키 재사용을 검토해 중복을 줄일 수 있습니다.🤖 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 `@Prezel/feature/home/impl/src/main/res/values/strings.xml` around lines 27 - 29, The three string entries duplicate existing values: replace feature_home_impl_empty_sheet_practice_card_title ("지금부터 연습해보세요") with the existing feature_home_impl_bottom_sheet_empty_title, and replace feature_home_impl_empty_sheet_practice_card_button_text ("연습하기") with feature_home_impl_practice_recording_action, then remove the duplicate keys from strings.xml and update any UI/layout/code references that used feature_home_impl_empty_sheet_practice_card_title or feature_home_impl_empty_sheet_practice_card_button_text to use the reused keys (leave feature_home_impl_empty_sheet_practice_card_message as-is if unique).Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt (1)
41-69: 💤 Low value
enabled가 토글 버튼에만 적용됨 (선택 검토).
enabled = false여도isExpanded가 true이면 메뉴 항목(라인 48-59)은 그대로 노출/클릭 가능합니다. 비활성화 시 메뉴 펼침까지 막을 의도라면isExpanded && enabled조건을 고려하세요. 호출부에서isExpanded를 함께 통제한다면 현재 동작으로 충분합니다.🤖 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 `@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt` around lines 41 - 69, In PrezelFloatingMenu, the menu UI is still shown when isExpanded is true even if enabled is false; update the render guard so the menu only displays when both isExpanded and enabled (e.g., change the if condition around PrezelMenu from "if (isExpanded)" to "if (isExpanded && enabled)"), ensuring PrezelMenu (and its items) are not interactable when the floating control is disabled while leaving PrezelFloatingButton usage/props (isExpanded, onChangeExpanded, enabled) unchanged.
🤖 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
`@Prezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/AnalyzePresentationUseCase.kt`:
- Line 35: Remove the leftover debug print in AnalyzePresentationUseCase: delete
the onSuccess { println(date) } call in the chain inside
AnalyzePresentationUseCase (the debug lambda attached via .onSuccess) so no
standard-output debug remains; if you need runtime visibility, replace it with a
structured logger call (e.g., processLogger.info/trace) that includes the date
instead of println.
In
`@Prezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/body/EmptyPresentationSheet.kt`:
- Around line 25-28: EmptyPresentationSheet currently renders PrezelButton with
onClick = {} (no-op) causing a UX gap; update EmptyPresentationSheet to accept a
callback parameter (e.g., onPracticeClick: () -> Unit) and pass it to
PrezelButton's onClick, update EmptyPresentationContentPreview to supply a no-op
or sample lambda, and ensure any real callers of EmptyPresentationSheet wire a
proper handler; if you cannot guarantee callers will provide a handler,
alternatively render the PrezelButton as enabled = false or hide it until a real
callback is available—make the change in the EmptyPresentationSheet function and
its usages (EmptyPresentationContentPreview) so the button is either actionable
via onPracticeClick or explicitly disabled/hidden.
In
`@Prezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/body/PresentationSheet.kt`:
- Around line 42-50: PresentationSheet's PresentationUiModel.Past branch always
renders CardGraph with presentation.growthGraphData.graphItems which can be
empty (mapped via GetMainDataResponse.toDomain()), causing CardGraph's internal
require to throw; change the Past branch to check
presentation.growthGraphData.graphItems.isNotEmpty() before rendering CardGraph
(or render a safe placeholder/empty state) so CardGraph is only called with
non-empty items; update the branch around CardGraph and keep the existing
onClickCardGraphItemIndex handling for the non-empty path.
In
`@Prezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/contract/HomeUiState.kt`:
- Line 40: The hardcoded fallback "unknown" in HomeUiState (val fallbackNickname
= nickname.ifBlank { "unknown" }) should be moved to a string resource (e.g.,
add <string name="unknown_nickname">Unknown</string> in strings.xml) and the
code should obtain that resource instead of the literal; either compute
fallbackNickname outside the pure UI state (in the ViewModel or Composable)
using context.getString(R.string.unknown_nickname) / stringResource(...) and
pass it into HomeUiState or change HomeUiState to accept a fallback parameter so
the resource can be injected where Android context is available—replace the
literal with the resource-backed value and update callers accordingly.
---
Nitpick comments:
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt`:
- Around line 41-69: In PrezelFloatingMenu, the menu UI is still shown when
isExpanded is true even if enabled is false; update the render guard so the menu
only displays when both isExpanded and enabled (e.g., change the if condition
around PrezelMenu from "if (isExpanded)" to "if (isExpanded && enabled)"),
ensuring PrezelMenu (and its items) are not interactable when the floating
control is disabled while leaving PrezelFloatingButton usage/props (isExpanded,
onChangeExpanded, enabled) unchanged.
In
`@Prezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/FetchMainDataUseCase.kt`:
- Around line 18-44: The current invoke() in FetchMainDataUseCase builds
presentations by calling repository.getPracticeRecords(...) inside a
per-presentation async, causing an N+1 request pattern as presentation count
grows; change this to a batched fetch: after repository.getMainData(), collect
presentationIds and call a new or existing repository method (e.g.,
repository.getPracticeRecordsForPresentations(presentationIds) or extend
repository.getMainData() to include practiceRecords) to retrieve all practice
records in one request, then map those records back to each presentation when
constructing MainDataBundle (keeping coroutineScope + async/awaitAll only for
non-network parallelism if needed); update repository interfaces and
toMainDataWithPracticeRecords usage accordingly to use the batched result.
In
`@Prezel/core/ui/src/main/java/com/team/prezel/core/ui/state/LocalAppDimmerState.kt`:
- Around line 18-30: LocalAppDimmerState.dismiss() currently only invokes
onDismissRequest and doesn't change isVisible, so update dismiss() to call
hide() first and then invoke the callback (e.g., call hide() and then
onDismissRequest?.invoke()) so the dimmer is always hidden even when the default
empty callback is used; reference LocalAppDimmerState.dismiss(), hide(), show(),
onDismissRequest and isVisible when making the change.
In `@Prezel/feature/home/impl/src/main/res/values/strings.xml`:
- Around line 27-29: The three string entries duplicate existing values: replace
feature_home_impl_empty_sheet_practice_card_title ("지금부터 연습해보세요") with the
existing feature_home_impl_bottom_sheet_empty_title, and replace
feature_home_impl_empty_sheet_practice_card_button_text ("연습하기") with
feature_home_impl_practice_recording_action, then remove the duplicate keys from
strings.xml and update any UI/layout/code references that used
feature_home_impl_empty_sheet_practice_card_title or
feature_home_impl_empty_sheet_practice_card_button_text to use the reused keys
(leave feature_home_impl_empty_sheet_practice_card_message as-is if unique).
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e767f434-3ec1-4a7b-a7f5-e4c66347de13
📒 Files selected for processing (65)
Prezel/app/src/main/java/com/team/prezel/ui/PrezelApp.ktPrezel/core/data/src/main/java/com/team/prezel/core/data/mapper/PresentationMapper.ktPrezel/core/data/src/main/java/com/team/prezel/core/data/repository/PracticeRepositoryImpl.ktPrezel/core/data/src/main/java/com/team/prezel/core/data/repository/PresentationRepositoryImpl.ktPrezel/core/data/src/main/java/com/team/prezel/core/data/repository/UserRepositoryImpl.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.ktPrezel/core/domain/build.gradle.ktsPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/repository/practice/PracticeRepository.ktPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/repository/presentation/PresentationRepository.ktPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/repository/profile/UserRepository.ktPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/practice/AnalyzePracticeRecordingUseCase.ktPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/AnalyzePresentationUseCase.ktPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/FetchMainDataUseCase.ktPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/FetchPracticeRecordsUseCase.ktPrezel/core/domain/src/main/kotlin/com/team/prezel/core/domain/usecase/presentation/FetchPresentationDetailUseCase.ktPrezel/core/model/src/main/java/com/team/prezel/core/model/presentation/MainData.ktPrezel/core/model/src/main/java/com/team/prezel/core/model/presentation/MainDataBundle.ktPrezel/core/model/src/main/java/com/team/prezel/core/model/presentation/MainDataWithPracticeRecords.ktPrezel/core/model/src/main/java/com/team/prezel/core/model/presentation/PracticeRecords.ktPrezel/core/model/src/main/java/com/team/prezel/core/model/presentation/PresentationDetailWithPracticeRecords.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/datasource/PracticeRemoteDataSource.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/datasource/PracticeRemoteDataSourceImpl.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/datasource/PresentationRemoteDataSource.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/datasource/PresentationRemoteDataSourceImpl.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/model/presentation/GetMainDataResponse.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/model/presentation/GetPracticeRecordsResponse.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/service/PracticeService.ktPrezel/core/network/src/main/java/com/team/prezel/core/network/service/PresentationService.ktPrezel/core/ui/src/main/java/com/team/prezel/core/ui/component/PracticeCard.ktPrezel/core/ui/src/main/java/com/team/prezel/core/ui/state/LocalAppDimmerState.ktPrezel/feature/home/impl/build.gradle.ktsPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/HomeScreen.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/HomeViewModel.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/HomeAnalysisFabOverlay.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/HomeScreenContent.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/body/EmptyPresentationSheet.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/body/EmptySheet.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/body/HomeBottomSheetTitle.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/body/PresentationSheet.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/head/HomeHeadSection.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/component/title/PresentationHero.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/contract/HomeUiIntent.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/contract/HomeUiState.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/model/GrowthGraphItemUiModel.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/model/PracticeRecordsUiModel.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/main/model/PresentationUiModel.ktPrezel/feature/home/impl/src/main/java/com/team/prezel/feature/home/impl/navigation/HomeEntryBuilder.ktPrezel/feature/home/impl/src/main/res/values/strings.xmlPrezel/feature/practice/api/src/main/java/com/team/prezel/feature/practice/api/PracticeNavKey.ktPrezel/feature/practice/impl/src/main/java/com/team/prezel/feature/practice/impl/analysis/PracticeAnalysisViewModel.ktPrezel/feature/practice/impl/src/main/java/com/team/prezel/feature/practice/impl/navigation/PracticeAnalysisNavKey.ktPrezel/feature/practice/impl/src/main/java/com/team/prezel/feature/practice/impl/navigation/PracticeEntryBuilder.ktPrezel/feature/profile/impl/src/main/java/com/team/prezel/feature/profile/impl/ProfileScreen.ktPrezel/feature/profile/impl/src/main/java/com/team/prezel/feature/profile/impl/ProfileViewModel.ktPrezel/feature/profile/impl/src/main/java/com/team/prezel/feature/profile/impl/contract/ProfileUiIntent.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/AnalysisReportViewModel.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/component/ReportBodyContent.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/component/body/PracticeHistorySection.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/contract/AnalysisReportUiState.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/contract/AnalysisReportUiStateMapper.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/model/PracticeRecordsUiModel.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/model/PracticeUiModel.ktPrezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/preview/ReportPreviewUiState.kt
💤 Files with no reviewable changes (3)
- Prezel/feature/profile/impl/src/main/java/com/team/prezel/feature/profile/impl/contract/ProfileUiIntent.kt
- Prezel/feature/report/impl/src/main/java/com/team/prezel/feature/report/impl/model/PracticeUiModel.kt
- Prezel/feature/profile/impl/src/main/java/com/team/prezel/feature/profile/impl/ProfileScreen.kt
* **refactor: 발표 데이터 표시 로직 개선 및 미사용 컴포넌트 제거**
* `PresentationSheet`에서 과거 발표(`PresentationUiModel.Past`)의 그래프 데이터가 비어있는 경우, 하단 시트 콘텐츠를 렌더링하지 않도록 가드 로직을 추가했습니다.
* 더 이상 사용되지 않는 `EmptyPresentationSheet.kt` 컴포넌트 파일을 삭제했습니다.
* **cleanup: 불필요한 디버그 코드 제거**
* `AnalyzePresentationUseCase` 내 성공 콜백에 남아있던 디버그용 `println` 호출을 삭제했습니다.
📌 작업 내용
FetchMainDataUseCase에서 발표 목록과 연습 기록을 결합하도록 개선하고, 홈 화면 UI 상태를 실제 서버 데이터 기반으로 매핑하도록 변경했습니다.HomeScreenContent,HomeAnalysisFabOverlay등으로 분리해 구조를 정리했습니다.presentationId를 전달하도록 수정했습니다.PracticeCard의 D-Day 포함 범위를 수정하고 일부 디자인 시스템 버튼 색상 설정을 보정했습니다.🧩 관련 이슈
📸 스크린샷
📢 논의하고 싶은 내용
Summary by CodeRabbit
릴리스 노트
New Features
Improvements