Skip to content

PrezelPlayer 디자인 시스템 구현#129

Open
HamBeomJoon wants to merge 13 commits intodevelopfrom
feat/#125-ds-player
Open

PrezelPlayer 디자인 시스템 구현#129
HamBeomJoon wants to merge 13 commits intodevelopfrom
feat/#125-ds-player

Conversation

@HamBeomJoon
Copy link
Copy Markdown
Contributor

@HamBeomJoon HamBeomJoon commented May 7, 2026

📌 작업 내용

  • 디자인시스템에 PrezelPlayer 컴포넌트 추가
  • 재생/일시정지, 이전/다음 이동, 탭/드래그 seek 지원
  • 외부에서 재생 상태, 현재 위치, 전체 길이, seek 이벤트를 제어하는 controlled state 구조 적용
  • 드래그 중 외부 currentMillis 업데이트로 핸들이 스냅백되지 않도록 상태 동기화 보정

타임라인/리소스 트랙

  • 현재 시간/전체 시간 라벨 표시
  • idle 상태 및 드래그 핸들 노출 상태 지원
  • PrezelPlayerItem을 Segment/Marker sealed 모델로 구성
  • 모든 item은 이전/다음 이동 대상이며, Marker만 타임라인 마커로 표시

마커/리소스

  • GOOD, WARNING, NEUTRAL 마커 타입 및 표시 UI 추가
  • 뒤로/앞으로 이동 아이콘 drawable 추가
  • PrezelIcons에 SkipBackward, SkipForward 등록

🧩 관련 이슈


📸 스크린샷

스크린샷 2026-05-07 15 55 09 스크린샷 2026-05-07 15 56 18 스크린샷 2026-05-07 15 56 09
  • 영상
2026-05-07.22.25.20.mov

Summary by CodeRabbit

새로운 기능

  • New Features
    • 재생, 일시정지, 이전, 다음 버튼을 포함한 새로운 플레이어 컴포넌트 추가
    • 드래그 가능한 타임라인과 진행률 표시 기능 제공
    • 타임라인에 마커 및 세그먼트 시각화
    • 플레이어 상태 관리 및 접근성 지원 추가
    • 이전/다음 이동 아이콘 및 접근성 문자열 리소스 추가

Review Change Stack

* **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` 확장 함수를 추가했습니다.
-ds-player

# Conflicts:
#	Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.kt
#	Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.kt
*   **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) 방지 로직을 적용했습니다.
@HamBeomJoon HamBeomJoon self-assigned this May 7, 2026
@HamBeomJoon HamBeomJoon requested a review from moondev03 as a code owner May 7, 2026 06:57
@HamBeomJoon HamBeomJoon added the ✨ feat 새로운 기능 추가 또는 기존 기능 확장 label May 7, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Warning

Rate limit exceeded

@HamBeomJoon has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 43 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1a2a70ac-ade7-4666-ac32-21b9c75caf3b

📥 Commits

Reviewing files that changed from the base of the PR and between 215e9cf and b968f12.

📒 Files selected for processing (2)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.kt
  • Prezel/core/designsystem/src/main/res/values/strings.xml
📝 Walkthrough

Walkthrough

플레이어 디자인 시스템을 구현합니다. 데이터 모델(Segment, Marker), 마커 렌더링 컴포넌트, 타임라인 시크 로직과 미리보기, 트랙 UI, Compose 기반 상태 홀더(PrezelPlayerState), 공개 플레이어 컴포저블, 백워드/포워드 아이콘 및 접근성 문자열을 추가합니다.

Changes

플레이어 디자인 시스템

Layer / File(s) Summary
데이터 모델 및 열거형
PrezelPlayerModels.kt
PrezelPlayerMarkerType 열거형(GOOD, WARNING, NEUTRAL)과 sealed interface PrezelPlayerItem, Segment, Marker 데이터 클래스를 정의합니다.
마커 시각화 컴포넌트
PrezelPlayerResourceMarker.kt
마커 타입별 색상 매핑 및 8dp 크기의 clipped Box를 렌더링하는 내부 Compose 컴포넌트를 구현합니다.
타임라인 핵심 로직
PrezelPlayerTimeline.kt
너비 측정, 정규화된 시크, 마커 위치 계산, 진행도 오버레이, 드래그 핸들 렌더링 및 접근성 시맨틱을 구현합니다.
타임라인 미리보기 및 샘플 데이터
PrezelPlayerTimeline.kt
타임라인의 진행도 바 모드, 드래그 핸들 모드, 겹치는 마커 시나리오를 보여주는 미리보기 UI와 샘플 데이터를 제공합니다.
트랙 리소스 컴포넌트
PrezelPlayerResourceTrack.kt
40dp 높이의 타임라인, mm:ss 시간 레이블, idle 처리, 드래그 콜백을 포함한 트랙 컴포넌트를 구현합니다.
플레이어 상태 홀더
PrezelPlayerState.kt
mutable Compose 상태, 파생 UI 플래그(idle, showHandle, previousEnabled, nextEnabled), 시크/네비게이션/드래그 제어 메서드를 가진 상태 클래스와 rememberPrezelPlayerState 함수를 제공합니다.
플레이어 UI 컴포저블
PrezelPlayer.kt
Public PrezelPlayer 컴포저블, 내부 Content/Controls/Buttons 구성을 구현하며, 모든 값과 콜백을 PrezelPlayerState에서 전달받고 자동 재생 미리보기를 포함합니다.
아이콘 및 리소스
PrezelIcons.kt, drawable/core_designsystem_ic_backward.xml, drawable/core_designsystem_ic_forward.xml, strings.xml
SkipBackward/SkipForward 아이콘 매핑, 벡터 드로어블 2개, 플레이어 접근성 문자열 6개(이전/다음 네비게이션, 재생/일시중지, 트랙 타입 설명)를 추가합니다.

Possibly related PRs

  • Team-Prezel/Prezel-Android#19: PrezelIcons 객체 초기 추가 및 다양한 아이콘 리소스 정의 — 본 PR이 SkipBackward/SkipForward 아이콘을 추가하는 것과 동일한 코드 레벨에서 관련.
  • Team-Prezel/Prezel-Android#55: PrezelIcons.kt에 여러 아이콘 상수 추가 — 본 PR과 동일한 기호 모음에서 아이콘을 추가하므로 관련.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 PR의 주요 변경 사항인 PrezelPlayer 디자인 시스템 구현을 명확하고 간결하게 설명하고 있습니다.
Description check ✅ Passed PR 설명이 작업 내용, 관련 이슈, 스크린샷, 동영상을 포함하여 템플릿의 필수 섹션을 충실히 작성했습니다.
Linked Issues check ✅ Passed PR의 모든 변경 사항이 #125의 목표(PrezelPlayer 구현, 재생/일시정지, 탭/드래그 seek, 상태 제어, 마커 표시, 접근성)를 충족합니다.
Out of Scope Changes check ✅ Passed 모든 변경 사항이 PrezelPlayer 컴포넌트와 관련 리소스 구현으로 제한되어 있으며 #125의 범위 내에 있습니다.

✏️ 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.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@HamBeomJoon HamBeomJoon changed the title Feat/#125 ds player PrezelPlayer 디자인 시스템 구현 May 7, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5f473d7 and c4713e0.

📒 Files selected for processing (9)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.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/PrezelPlayerResourceMarker.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerTimeline.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/icon/PrezelIcons.kt
  • Prezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_backward.xml
  • Prezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_forward.xml
  • Prezel/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`: 회원 탈퇴 요청 처리 로직 제거
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between c4713e0 and a4e030d.

📒 Files selected for processing (12)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.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/PrezelPlayerResourceMarker.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerTimeline.kt
  • Prezel/core/designsystem/src/main/res/values/strings.xml
  • Prezel/core/domain/src/main/java/com/team/prezel/core/domain/repository/auth/AuthRepository.kt
  • Prezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/CheckLoginStatusUseCase.kt
  • Prezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/LoginUseCase.kt
  • Prezel/core/domain/src/main/java/com/team/prezel/core/domain/usecase/auth/LogoutUseCase.kt
  • Prezel/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

@Team-Prezel Team-Prezel deleted a comment from coderabbitai Bot May 7, 2026
@Team-Prezel Team-Prezel deleted a comment from coderabbitai Bot May 7, 2026
@Team-Prezel Team-Prezel deleted a comment from coderabbitai Bot May 7, 2026
@Team-Prezel Team-Prezel deleted a comment from coderabbitai Bot May 7, 2026
@Team-Prezel Team-Prezel deleted a comment from coderabbitai Bot May 7, 2026
* **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`)을 제거하고 원본 값을 사용하도록 단순화했습니다.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ 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

📥 Commits

Reviewing files that changed from the base of the PR and between a4e030d and 215e9cf.

📒 Files selected for processing (6)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayer.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/PrezelPlayerResourceMarker.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerResourceTrack.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/player/PrezelPlayerState.kt
  • Prezel/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`를 통해 관리하도록 개선했습니다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat 새로운 기능 추가 또는 기존 기능 확장

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Player, PlayerResourceTrack 구현

2 participants