PrezelPlayer 디자인 시스템 구현#129
Conversation
* **feat: `PrezelPlayer` 및 관련 컴포넌트 추가**
* 재생/일시정지, 전/후 이동 제어 및 프로그레스 바를 포함한 `PrezelPlayer` 컴포넌트를 구현했습니다.
* `PrezelPlayerResourceTrack`: 재생 진행 상태, 시간 표시, 마커(Marker) 표시 및 탐색(Seek) 기능을 지원하는 트랙 컴포넌트를 추가했습니다.
* `PrezelPlayerResourceMarker`: 트랙 위에 표시될 상태 마커(`GOOD`, `WARNING`, `NEUTRAL`) 컴포넌트를 추가했습니다.
* **feat: 플레이어 제어용 아이콘 및 데이터 모델 추가**
* `PrezelIcons`: `SkipBackward`, `SkipForward` 아이콘 리소스를 추가하고 등록했습니다.
* `PrezelPlayerResourceMarkerItem`: 트랙의 마커 데이터를 정의하기 위한 sealed 구조의 모델과 팩토리 메서드(`speech`, `scriptMatch`)를 추가했습니다.
* `PrezelPlayerResourceTrackType`: 음성(`SPEECH`) 및 대본 일치(`SCRIPT_MATCH`) 트랙 타입을 정의하는 열거형을 추가했습니다.
* **refactor: 플레이어 UI 스타일 및 인터랙션 구현**
* 터치 및 드래그 제스처를 통한 재생 위치 탐색(Seek) 로직을 적용했습니다.
* `playing` 상태에 따라 재생/일시정지 버튼의 색상 및 아이콘이 동적으로 변경되도록 구현했습니다.
* 밀리초(Long) 단위를 `mm:ss` 형식으로 변환하는 `formatPlayerTime` 확장 함수를 추가했습니다.
* **feat: `PrezelPlayer` 및 관련 컴포넌트 추가**
* 재생/일시정지, 전/후 이동 제어 및 프로그레스 바를 포함한 `PrezelPlayer` 컴포넌트를 구현했습니다.
* `PrezelPlayerResourceTrack`: 재생 진행 상태, 시간 표시, 마커(Marker) 표시 및 탐색(Seek) 기능을 지원하는 트랙 컴포넌트를 추가했습니다.
* `PrezelPlayerResourceMarker`: 트랙 위에 표시될 상태 마커(`GOOD`, `WARNING`, `NEUTRAL`) 컴포넌트를 추가했습니다.
* **feat: 플레이어 제어용 아이콘 및 데이터 모델 추가**
* `PrezelIcons`: `SkipBackward`, `SkipForward` 아이콘 리소스를 추가하고 등록했습니다.
* `PrezelPlayerResourceMarkerItem`: 트랙의 마커 데이터를 정의하기 위한 sealed 구조의 모델과 팩토리 메서드(`speech`, `scriptMatch`)를 추가했습니다.
* `PrezelPlayerResourceTrackType`: 음성(`SPEECH`) 및 대본 일치(`SCRIPT_MATCH`) 트랙 타입을 정의하는 열거형을 추가했습니다.
* **refactor: 플레이어 UI 스타일 및 인터랙션 구현**
* 터치 및 드래그 제스처를 통한 재생 위치 탐색(Seek) 로직을 적용했습니다.
* `playing` 상태에 따라 재생/일시정지 버튼의 색상 및 아이콘이 동적으로 변경되도록 구현했습니다.
* 밀리초(Long) 단위를 `mm:ss` 형식으로 변환하는 `formatPlayerTime` 확장 함수를 추가했습니다.
* **feat: 플레이어 데이터 모델 및 마커 인터페이스 정의**
* `PrezelPlayerResourceMarkerItem` sealed interface를 추가하여 `Speech`와 `ScriptMatch` 트랙 마커를 구분하고, `timeSeconds` 기반으로 위치를 계산하도록 개선했습니다.
* 마커 타입(`GOOD`, `WARNING`, `NEUTRAL`) 및 트랙 타입(`SPEECH`, `SCRIPT_MATCH`)을 정의하는 Enum 클래스들을 추가했습니다.
* **refactor: `PrezelPlayer` 및 관련 컴포넌트 구조 개선**
* `PrezelPlayerResourceTrack`: 외부에서 `progress`를 주입받는 대신 `currentMillis`와 `durationMillis`를 통해 내부에서 계산하도록 로직을 변경했습니다.
* `PrezelPlayerTimeline`: 타임라인 로직을 별도 컴포넌트로 분리하고, 드래그/탭 제스처를 통한 탐색(Seek) 및 마커 렌더링 로직을 통합했습니다.
* 컴포넌트 내부에 흩어져 있던 Preview 코드들을 `PrezelPlayerPreview.kt`로 분리하여 관리 효율성을 높였습니다.
* **feat: 접근성(Accessibility) 및 다국어 지원 추가**
* 재생, 일시정지, 앞/뒤로 이동 버튼 및 각 트랙 타임라인에 대한 `contentDescription`을 추가했습니다.
* `strings.xml`에 플레이어 조작 및 트랙 설명 관련 리소스를 정의했습니다.
* **fix: 플레이어 로직 안정화**
* 시간 표시 포맷팅 로직(`formatPlayerTime`) 및 재생 시간 제한(`coercePlayerMillis`) 유틸리티 함수를 추가했습니다.
* `progress` 계산 시 0으로 나누기(Division by zero) 방지 로직을 적용했습니다.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough플레이어 디자인 시스템을 구현합니다. 데이터 모델(Segment, Marker), 마커 렌더링 컴포넌트, 타임라인 시크 로직과 미리보기, 트랙 UI, Compose 기반 상태 홀더(PrezelPlayerState), 공개 플레이어 컴포저블, 백워드/포워드 아이콘 및 접근성 문자열을 추가합니다. Changes플레이어 디자인 시스템
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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: 1
🧹 Nitpick comments (1)
Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerModels.kt (1)
5-21: 💤 Low value
enum class에@Immutable적용은 불필요합니다.Compose 컴파일러는 enum 클래스를 별도 어노테이션 없이 이미 안정적(stable)으로 추론합니다. sealed class/interface 및 그 구현체(
data class)에 대한@Immutable적용은 의미가 있지만, enum에 적용하는 것은 불필요한 noise입니다.♻️ 제안: enum의 불필요한 어노테이션 제거
-@Immutable enum class PrezelPlayerResourceTrackType { SPEECH, SCRIPT_MATCH, } -@Immutable enum class PrezelSpeechMarkerType { GOOD, WARNING, } -@Immutable enum class PrezelScriptMatchMarkerType { GOOD, NEUTRAL, }🤖 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/player/PrezelPlayerModels.kt` around lines 5 - 21, Remove unnecessary `@Immutable` annotations from enum classes: PrezelPlayerResourceTrackType, PrezelSpeechMarkerType, and PrezelScriptMatchMarkerType; the Compose compiler treats enums as stable so simply delete the `@Immutable` annotation usages on those enum class declarations (leave sealed/interface implementations and data classes untouched).
🤖 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/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerTimeline.kt`:
- Around line 51-53: 현재 ::seekTo 로컬 함수 참조와 onDragStarted/onDragStopped 같은 인라인
람다가 재컴포지션마다 새 객체가 되어 pointerInput 키 변경 시 코루틴이 취소되는 문제가 있습니다; 고정된 키(Unit)를 사용하도록
playerTimelineModifier 안의 pointerInput 호출을 변경하고 PrezelPlayerTimeline 내부에서
seekTo, onDragStarted, onDragStopped, onHorizontalDrag 등 외부 콜백들을
rememberUpdatedState로 래핑한 최신 상태 참조로 만든 뒤 그 래핑된 값들을 modifier에 전달해 pointerInput
코루틴이 재시작되지 않도록 수정하세요 (참조 심볼: seekTo, onSeek, onDragStarted, onDragStopped,
onHorizontalDrag, playerTimelineModifier, pointerInput, rememberUpdatedState).
---
Nitpick comments:
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerModels.kt`:
- Around line 5-21: Remove unnecessary `@Immutable` annotations from enum classes:
PrezelPlayerResourceTrackType, PrezelSpeechMarkerType, and
PrezelScriptMatchMarkerType; the Compose compiler treats enums as stable so
simply delete the `@Immutable` annotation usages on those enum class declarations
(leave sealed/interface implementations and data classes untouched).
🪄 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: 39035c60-099f-45c1-bbcc-3082381543dd
📒 Files selected for processing (9)
Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerModels.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceMarker.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerTimeline.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/icon/PrezelIcons.ktPrezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_backward.xmlPrezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_forward.xmlPrezel/core/designsystem/src/main/res/values/strings.xml
* **refactor: 불필요한 `@Immutable` 어노테이션 제거**
* `enum class`는 기본적으로 불변(Immutable)으로 취급되므로, `PrezelPlayerResourceMarkerType`, `PrezelPlayerResourceTrackType`, `PrezelSpeechMarkerType`, `PrezelScriptMatchMarkerType`에 선언된 중복 어노테이션을 삭제했습니다.
* **fix: `PrezelPlayerTimeline` 드래그 및 탭 이벤트 핸들링 개선**
* `pointerInput` 내에서 외부 상태 참조 시 람다 캡처로 인한 부작용을 방지하기 위해 `rememberUpdatedState`를 적용했습니다.
* `pointerInput`의 key를 `Unit`으로 설정하여 불필요한 코루틴 재실행을 방지하고, 최신 콜백(`onSeekTo`, `onDragStarted`, `onDragStopped`)을 안전하게 호출하도록 수정했습니다.
* `playerTimelineModifier` 확장 함수에 `@Composable` 어노테이션을 추가했습니다.
* **feat: PrezelPlayerState 및 Hoisting 로직 추가**
* 재생 상태(`playing`), 재생 시간(`currentMillis`), 전체 길이(`durationMillis`), 아이템 목록(`items`) 등을 통합 관리하는 `PrezelPlayerState` 클래스를 추가했습니다.
* `rememberPrezelPlayerState`를 통해 Compose 생기주기에 맞게 상태를 보존하고, `SideEffect`를 사용하여 외부 상태 변화를 동기화합니다.
* 드래그 상태 관리(`dragging`) 및 이전/다음 아이템 이동 가능 여부(`previousEnabled`, `nextEnabled`) 판단 로직을 포함합니다.
* **refactor: 플레이어 컨트롤러 및 네비게이션 로직 개선**
* 단순히 앞/뒤로 이동하던 로직을 `PrezelPlayerItem` 기반의 '이전/다음 아이템' 이동 로직으로 고도화했습니다.
* `PrezelPlayer` 컴포넌트가 `PrezelPlayerState`를 주입받아 동작하도록 구조를 변경했습니다.
* `PrezelIconButton`에 `enabled` 상태를 적용하여 이동 가능 여부에 따라 버튼 활성화 상태가 시각적으로 표시되도록 개선했습니다.
* **refactor: 데이터 모델 단순화 및 마커 시스템 개편**
* `PrezelPlayerResourceMarkerItem`을 `sealed interface`에서 단일 `data class`로 통합하여 관리 효율성을 높였습니다.
* `PrezelSpeechMarkerType`, `PrezelScriptMatchMarkerType`으로 분리되어 있던 마커 타입을 `PrezelPlayerResourceMarkerType`으로 단일화했습니다.
* **docs: Preview 및 리소스 문자열 업데이트**
* `BasicPreview` 어노테이션을 적용하고, 상태 기반의 플레이어 동작을 확인할 수 있도록 Preview 코드를 보강했습니다.
* 플레이어 컨트롤러 관련 접근성 설명(Content Description)을 '뒤로/앞으로'에서 '이전/다음 아이템'으로 수정했습니다.
인증 관련 도메인 레이어의 구성 요소들을 삭제했습니다. (기존 로직의 위치 이동 또는 구조 재설계로 인한 정리)
* **`AuthRepository` 인터페이스 삭제**
* 로그인 상태 확인(`loginStatus`), 로그인/로그아웃 및 회원 탈퇴 메서드 정의가 포함된 인터페이스를 제거했습니다.
* **인증 관련 UseCase 클래스 삭제**
* `CheckLoginStatusUseCase`: 로그인 상태 구독 로직 제거
* `LoginUseCase`: ID 토큰 기반 서버 로그인 호출 로직 제거
* `LogoutUseCase`: 로그아웃 요청 처리 로직 제거
* `WithdrawUseCase`: 회원 탈퇴 요청 처리 로직 제거
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 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/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.kt`:
- Around line 42-58: The Column is using a fixed height(40.dp) which can
compress PrezelPlayerTimeline when system font scale increases; update the
Column modifier (around where PrezelPlayerTimeline and PlayerTrackTimeLabels are
composed) to either use wrapContentHeight() or heightIn(min = 40.dp) so the
timeline gets a guaranteed tappable height (or alternately make the time label
use a non-scale font size), ensuring PrezelPlayerTimeline and its drag handle
(and PlayerTrackTimeLabels) are not reduced to ~0dp.
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.kt`:
- Around line 123-133: update() unconditionally overwrites this.currentMillis on
every SideEffect call which causes the seek handle to snap back while the user
is dragging; change PrezelPlayerState.update to avoid updating
this.currentMillis when dragging is true (i.e., only set this.currentMillis =
currentMillis.coercePlayerMillis(this.durationMillis) if the instance's dragging
flag is false), while still updating playing, durationMillis (coerced), and
items as before so external updates don't disturb the UI during a drag.
In
`@Prezel/core/domain/src/main/java/com/team/prezel/core/domain/repository/auth/AuthRepository.kt`:
- Around line 7-15: There are two conflicting AuthRepository interfaces (one
defines loginStatus, login, logout, withdraw in AuthRepository.kt and the other
defines hasJwtToken() and clearSession() in the Kotlin version); pick a single
canonical API and eliminate the duplicate: either delete the Java AuthRepository
file and keep the Kotlin interface, or merge the APIs into one AuthRepository
that includes all required members (loginStatus, login(idToken), logout(),
withdraw(reason), hasJwtToken(), clearSession()) and remove the other file;
update all call sites to the unified interface so only one AuthRepository type
remains in the codebase.
In
`@Prezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/CheckLoginStatusUseCase.kt`:
- Around line 17-21: There is a redeclaration conflict for the class
CheckLoginStatusUseCase — locate the existing declaration(s) of
CheckLoginStatusUseCase (and other auth usecases) in the module (the validation
script used in the LogoutUseCase review can help identify duplicate file
locations) and either remove the older/duplicate file or replace it with this
new implementation so only one CheckLoginStatusUseCase class exists; ensure your
fix resolves the Redeclaration error and run the build/validation script to
confirm duplicates are gone.
In
`@Prezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/LoginUseCase.kt`:
- Around line 15-19: LoginUseCase is declared more than once causing a
Redeclaration build error; locate all duplicate declarations (e.g.,
LoginUseCase, similar to previously flagged WithdrawUseCase and LogoutUseCase
duplicates) and remove or consolidate them so only a single LoginUseCase class
remains, ensuring any required logic from duplicates is merged into that one
declaration and imports/DI bindings are updated accordingly.
In
`@Prezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/LogoutUseCase.kt`:
- Around line 14-18: There are duplicate class declarations (LogoutUseCase,
LoginUseCase, CheckLoginStatusUseCase, WithdrawUseCase) present in both the java
and kotlin source trees; remove the redundant copies so each use-case class is
defined only once and keep the implementation in a single source directory
(either the Java file under core/domain/src/main/java or the Kotlin file under
core/domain/src/main/kotlin), then verify no remaining references/imports point
to the deleted path and run a build to ensure the single remaining classes
(e.g., LogoutUseCase, LoginUseCase, CheckLoginStatusUseCase, WithdrawUseCase)
compile cleanly.
In
`@Prezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/WithdrawUseCase.kt`:
- Around line 15-19: There is a redeclaration of WithdrawUseCase causing CI
Redeclaration errors; locate all occurrences of the class named WithdrawUseCase
(same pattern as LogoutUseCase, LoginUseCase, CheckLoginStatusUseCase) and
remove or consolidate duplicates so only a single declaration remains, ensuring
the remaining class keeps the same constructor signature (`@Inject`
constructor(private val authRepository: AuthRepository)) and operator fun
invoke(reason: WithdrawReason): Result<Unit> signature; if the duplicate came
from a copy-paste file, delete the extra file or rename the duplicate class to a
unique name and update any callers accordingly.
🪄 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: b46907e2-cc6a-4947-ae77-30b25d769fd8
📒 Files selected for processing (12)
Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerModels.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceMarker.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerTimeline.ktPrezel/core/designsystem/src/main/res/values/strings.xmlPrezel/core/domain/src/main/java/com/team/prezel/core/domain/repository/auth/AuthRepository.ktPrezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/CheckLoginStatusUseCase.ktPrezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/LoginUseCase.ktPrezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/LogoutUseCase.ktPrezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/WithdrawUseCase.kt
✅ Files skipped from review due to trivial changes (1)
- Prezel/core/designsystem/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (3)
- Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceMarker.kt
- Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerModels.kt
- Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.kt
* **feat: `PrezelPlayerItem` Sealed Interface 도입 및 모델 통합**
* 기존의 `PrezelPlayerItem`과 `PrezelPlayerResourceMarkerItem`으로 분리되어 있던 모델을 `PrezelPlayerItem` 인터페이스 아래 `Segment`와 `Marker`로 통합했습니다.
* 마커 타입을 정의하던 `PrezelPlayerResourceMarkerType`을 `PrezelPlayerMarkerType`으로 변경했습니다.
* 기존 `PrezelPlayerResourceTrackType`에 의존하던 로직을 제거하고, `trackContentDescription`을 외부에서 주입받도록 유연하게 개선했습니다.
* **refactor: 플레이어 상태 관리 및 탐색 로직 개선**
* `PrezelPlayerState`: 드래그 중일 때 `currentMillis` 업데이트 방식을 수정하여 탐색 중 화면 끊김 현상을 개선했습니다.
* `PrezelPlayerState`: `currentItemIndex` 계산 시 `startMillis` 대신 통합된 `timeMillis` 필드를 사용하도록 변경했습니다.
* `PrezelPlayerTimeline`: 마커 표시 로직에서 `PrezelPlayerItem.Marker` 타입만 필터링하여 렌더링하도록 수정했습니다.
* **ui: 디자인 시스템 컴포넌트 레이아웃 조정**
* `PrezelPlayerResourceTrack`: 고정 높이(`height`) 대신 `heightIn(min = 40.dp)`을 사용하여 유연성을 높였습니다.
* `PrezelPlayerTimeline`: 타임라인 내 Played Bar와 Drag Handle의 z-index 및 배치 로직을 최적화했습니다.
* **test: 미리보기(Preview) 데이터 및 컴포넌트 업데이트**
* 변경된 `PrezelPlayerItem` 구조에 맞춰 `previewSpeechItems`, `previewScriptMatchItems` 등 테스트 데이터를 갱신했습니다.
* `PrezelPlayerTimelinePreview`를 추가하여 타임라인 단독 컴포넌트의 시각적 검증을 강화했습니다.
* **refactor: `PrezelPlayerState` 호이스팅 및 업데이트 로직 변경**
* `rememberPrezelPlayerState`에서 외부 콜백(`onPlayPauseClick`, `onSeekToMillis`) 및 `SideEffect`를 통한 자동 업데이트 로직을 제거했습니다.
* 상태 객체 내부에서 직접 상태를 변경할 수 있도록 `updatePlaying`, `updateCurrentMillis`, `togglePlaying` 메서드를 추가했습니다.
* `currentMillis` 및 `durationMillis` 설정 시 사용되던 `coercePlayerMillis` 유틸리티와 불필요한 제약 로직을 제거했습니다.
* **refactor: `PrezelPlayer` 컴포넌트 내부 리팩터링**
* 플레이어 제어 콜백을 `state` 객체의 메서드(`togglePlaying`, `seekToProgress` 등)를 직접 호출하도록 변경했습니다.
* `PrezelPlayer` 레이아웃 구성 시 `Arrangement.spacedBy` 대신 명시적인 `Spacer`를 사용하도록 수정했습니다.
* 프리뷰(Preview) 코드에서 외부 변수로 관리하던 재생 상태를 `playerState` 내부 상태를 사용하도록 업데이트했습니다.
* **refactor: `PrezelPlayerResourceTrack` 최적화**
* 시간 포맷팅 및 진행률 계산 시 불필요하게 호출되던 범위를 제한하는 로직(`coercePlayerMillis`)을 제거하고 원본 값을 사용하도록 단순화했습니다.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.kt (1)
89-103:⚠️ Potential issue | 🟠 Major | ⚡ Quick win드래그 중 외부 시간 업데이트가 시크 위치를 다시 덮어쓸 수 있습니다.
updateCurrentMillis가 드래그 중에도 항상 값을 반영해서, 재생 ticker 업데이트가 들어오면 핸들이 스냅백될 수 있습니다. 또한 내부 시간 보정이 없어 범위를 벗어난 값이 그대로 상태에 들어갑니다. 과거에 같은 성격의 이슈가 있었던 만큼, 여기서도 방어해두는 편이 안전합니다.🐛 제안 수정
fun updateCurrentMillis(currentMillis: Long) { - this.currentMillis = currentMillis + if (!dragging) { + seekToMillis(currentMillis) + } } @@ private fun seekToMillis(targetMillis: Long) { - currentMillis = targetMillis + currentMillis = targetMillis.coerceIn(0L, durationMillis) }🤖 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/player/PrezelPlayerState.kt` around lines 89 - 103, updateCurrentMillis currently overwrites the position even while dragging and allows out-of-range values; change it to ignore external updates when dragging (use the dragging flag set by startDrag/stopDrag) and validate/clamp incoming currentMillis to the valid range before assigning (reuse seekToMillis logic or centralize clamping there), e.g., only assign currentMillis = targetMillis when not dragging and always clamp targetMillis into [0, durationOrMaxMillis] to prevent invalid state.
🤖 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.
Duplicate comments:
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.kt`:
- Around line 89-103: updateCurrentMillis currently overwrites the position even
while dragging and allows out-of-range values; change it to ignore external
updates when dragging (use the dragging flag set by startDrag/stopDrag) and
validate/clamp incoming currentMillis to the valid range before assigning (reuse
seekToMillis logic or centralize clamping there), e.g., only assign
currentMillis = targetMillis when not dragging and always clamp targetMillis
into [0, durationOrMaxMillis] to prevent invalid state.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9cb3a4af-670d-49a4-8740-9b4d7c194704
📒 Files selected for processing (6)
Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerModels.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceMarker.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.ktPrezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerTimeline.kt
# Conflicts: # Prezel/core/designsystem/src/main/res/values/strings.xml
* **feat: PrezelPlayerState 상태 보존 로직 추가**
* 구성 변경(화면 회전 등) 시에도 플레이어의 상태가 유지되도록 `remember`를 `rememberSaveable`로 변경했습니다.
* `PrezelPlayerState`를 저장하고 복원하기 위한 `Saver`를 companion object에 구현했습니다.
* **refactor: PrezelPlayerItem 직렬화 로직 구현**
* `PrezelPlayerItem`의 하위 타입인 `Segment`와 `Marker`를 `List` 형태로 변환하여 저장하고 복구하는 매핑 로직(`toSaveable`, `toPrezelPlayerItem`)을 추가했습니다.
* 플레이어 상태 값(`playing`, `durationMillis`, `currentMillis`)과 아이템 리스트를 모두 `Saver`를 통해 관리하도록 개선했습니다.
📌 작업 내용
타임라인/리소스 트랙
마커/리소스
🧩 관련 이슈
📸 스크린샷
2026-05-07.22.25.20.mov
Summary by CodeRabbit
새로운 기능