refactor: ViewModel 일관성 개선 및 MiniPlayer 상태 생성 로직 중복 제거#80
Merged
Conversation
selectPlaylist/removeTrackFromPlaylist/playPlaylist를 private으로 변경하고 onAction()을 통해서만 접근하도록 통일. PlaylistDetailAction에 SelectPlaylist 액션 추가, NavGraph와 테스트 코드도 onAction() 방식으로 업데이트.
PlaylistDetailViewModel과 AudioPermissionHandler는 외부 Flow 구독 없이 직접 값을 push하거나 ViewModel 생명주기 내내 상태를 유지해야 하므로 MutableStateFlow.asStateFlow()가 적합함을 주석으로 명시.
ZenPlayerServiceBinder 확장 함수(miniPlayerUiState, miniPlayerProgress)로 공통 로직을 core/service에 추출. MiniPlayerViewModel과 ZenMusicSelectViewModel의 중복 구현을 제거하고 공통 함수를 재사용.
TimerEngine.UPDATE_INTERVAL_MS와 ZenAudioController.POSITION_UPDATE_INTERVAL_MS는 값(100L)이 같지만 각각 타이머 UI 갱신, 재생 위치 추적이라는 독립적인 용도를 가지므로 공통 상수로 통합하지 않고 의도를 주석으로 명시.
- PlaylistDetailAction에서 MiniPlayer 케이스 제거 → Screen에 onMiniPlayerAction 파라미터 분리, NavGraph에서 exhaustive when으로 컴파일러 안전망 복원 - MiniPlayerViewModel, ZenMusicSelectViewModel의 _binder 필드 제거 → serviceBinder.binderFlow에 직접 접근하여 불필요한 중간 필드 삭제
Coverage Report
|
There was a problem hiding this comment.
Pull request overview
ViewModel 퍼블릭 API를 onAction() 단일 진입점 패턴으로 통일하고, 여러 ViewModel에 중복되어 있던 MiniPlayer UI/progress Flow 생성 로직을 ZenPlayerServiceBinder 확장 함수로 공통화하는 리팩터링입니다.
Changes:
PlaylistDetailViewModel의 공개 메서드를onAction(PlaylistDetailAction)로 통합하고 액션 모델을 정리 (SelectPlaylist추가, MiniPlayer 래퍼 제거)- MiniPlayer 상태/진행률 Flow 생성 로직을
ZenPlayerServiceBinderExtensions.kt로 추출하여MiniPlayerViewModel,ZenMusicSelectViewModel에서 재사용 PlaylistDetailScreen의 MiniPlayer 액션 전달 경로를 별도 콜백(onMiniPlayerAction)으로 분리하고, 호출부/테스트를 새 API에 맞게 수정
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| app/src/test/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailViewModelTest.kt | selectPlaylist/playPlaylist/removeTrackFromPlaylist 직접 호출 대신 onAction() 기반으로 테스트 갱신 |
| app/src/main/java/com/happyseal/zenplayer/zen/musicselect/ZenMusicSelectViewModel.kt | MiniPlayer/progress Flow 생성 중복 제거, binder 접근을 serviceBinder로 일원화 |
| app/src/main/java/com/happyseal/zenplayer/zen/miniplayer/MiniPlayerViewModel.kt | MiniPlayer/progress Flow 생성 로직을 공통 확장 함수로 치환 |
| app/src/main/java/com/happyseal/zenplayer/features/timer/domain/TimerEngine.kt | 타이머 UI 갱신 주기 상수의 “의도”를 설명하는 주석 추가 |
| app/src/main/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailViewModel.kt | onAction() 단일 진입점 도입 및 기존 공개 메서드 private 전환 |
| app/src/main/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailScreen.kt | MiniPlayer 액션 콜백을 onAction에서 분리해 onMiniPlayerAction으로 전달 |
| app/src/main/java/com/happyseal/zenplayer/features/playlist/ui/PlaylistDetailAction.kt | MiniPlayer 래퍼 제거, SelectPlaylist 액션 추가 |
| app/src/main/java/com/happyseal/zenplayer/features/player/data/ZenAudioController.kt | 재생 위치 갱신 주기 상수의 “의도”를 설명하는 주석 추가 |
| app/src/main/java/com/happyseal/zenplayer/features/music/ui/AudioPermissionHandler.kt | 권한 상태 Flow 유지 전략(항상 활성) 의도 주석 추가 |
| app/src/main/java/com/happyseal/zenplayer/core/service/ZenPlayerServiceBinderExtensions.kt | binderFlow 기반 MiniPlayer UI/progress StateFlow 생성 확장 함수 신규 추가 |
| app/src/main/java/com/happyseal/zenplayer/core/navigation/NavGraph.kt | PlaylistDetailViewModel 초기화/액션 전달을 onAction() 기반으로 변경, MiniPlayer 액션은 별도 콜백으로 위임 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
onAction()단일 진입점 패턴으로 통일하고, 여러 ViewModel에 중복된 MiniPlayer 상태 생성 로직을 공통 확장 함수로 추출함Key Changes
PlaylistDetailViewModel: 퍼블릭 메서드(selectPlaylist,playPlaylist,removeTrackFromPlaylist)를 private으로 전환하고onAction(PlaylistDetailAction)단일 진입점 추가PlaylistDetailAction:MiniPlayer래퍼 액션 제거,SelectPlaylist액션 추가ZenPlayerServiceBinderExtensions.kt신규 추가:miniPlayerUiState(),miniPlayerProgress()공통 확장 함수MiniPlayerViewModel,ZenMusicSelectViewModel: 중복된 MiniPlayer/progress Flow 생성 코드를 공통 확장 함수로 대체PlaylistDetailScreen:onMiniPlayerAction콜백을 별도 파라미터로 분리 (onAction내부 래핑 제거)WhileSubscribed5s미사용 이유, 상수 분리 의도Technical Details
ZenPlayerServiceBinder에miniPlayerUiState(scope),miniPlayerProgress(scope)확장 함수를 정의하여binderFlow.whenNonNull + combine + stateIn패턴을 단일 구현으로 집약NavGraph에서PlaylistDetailAction.MiniPlayer래핑 대신miniPlayerViewModel.onAction()직접 호출로 변경onAction()호출 방식으로 업데이트Rationale
onAction()단일 진입점으로 통일하면 호출부의 ViewModel 내부 구조 의존도가 낮아짐PlaylistDetailAction.MiniPlayer래퍼는 관심사가 다른 액션을 억지로 묶은 형태로, 분리가 더 명확한 구조