Skip to content

Design/#116 면접 UI 구현 - #129

Open
i-meant-to-be wants to merge 13 commits into
developfrom
design/#116
Open

Design/#116 면접 UI 구현#129
i-meant-to-be wants to merge 13 commits into
developfrom
design/#116

Conversation

@i-meant-to-be

@i-meant-to-be i-meant-to-be commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

🚩 연관 이슈

closed #116

📝 작업 내용

면접 진행/오류 화면 UI 구현. UI 완성도에 집중하기 위해 로직은 최소한으로만 연결함 (아래 "신경 써야 할 부분" 참고).

feature:interview 모듈 신설

  • :feature:interview:api, :feature:interview:impl 모듈 추가
  • InterviewRoute, InterviewErrorRoute(MIC/NETWORK) 정의, Navigation3 EntryProvider 연결
  • CameraX(camera-core/camera2/lifecycle/view) 의존성 추가

⚠️ 신경 써야 할 부분

  • InterviewNavigationModuleonNavigateHome, onResumeInterview 콜백이 빈 람다로 스텁 처리되어 있음. 실제 상위 네비게이션 연결은 후속 작업 필요.

면접 진행 화면 (InterviewScreen)

  • InterviewScreenBaseLayer(카메라 프리뷰 + 그라데이션 오버레이 + 얼굴 가이드 프레임), InterviewScreenPrepareLayer(준비 상태 안내/시작 버튼), InterviewScreenOngoingLayer(타이머/발언자 인디케이터/조기 종료 버튼) 3개 레이어로 구성
  • InterviewCameraPreview: 전면 카메라 CameraX 프리뷰, @Preview/권한 미허용 시 Mock Placeholder로 대체
  • InterviewReadinessIndicator, InterviewTimer, InterviewSpeakerIndicator, InterviewCompletableBubble, InterviewStartButton, InterviewAbortModal, InterviewFinishModal 등 하위 Composable 신설

⚠️ 신경 써야 할 부분

  • InterviewAbortModal/InterviewFinishModal의 버튼 클릭 콜백, InterviewScreenOngoingLayer의 종료 버튼 onClick이 아직 상위로 연결되지 않은 부분 있음(로직 연결 최소화 스코프).

면접 오류 화면 (InterviewErrorScreen)

  • 마이크 상태 불량 / 네트워크 상태 불량 2종 오류 화면 구현 (Figma Node 609:9269, 609:9259)
  • InterviewErrorViewModel MVI 연결, 오류 유형별 문구·버튼 구성 분기

디자인 시스템 변경

  • HilitMiniButton: enabled 파라미터 추가, 비활성 스타일 분기 추가
  • HilitFixedBottomButton: when 분기를 Kotlin guard 문법(if)으로 정리
  • HilitTextHighlight: Black 하이라이트 색상 추가
  • HilitModalPreviewHostinternalpublic으로 변경 (feature 모듈 Preview에서 재사용 목적)
  • 신규 벡터 에셋 추가: alert_red, finish, mic, network

권한 추가

매니페스트에 음성 녹음 및 카메라 권한 추가

기타

  • InterviewRemoteDataSourceTest: deprecated된 ResponseBody.createtoResponseBody 확장 함수로 교체 (CI 오류 대응)

🏞️ 스크린샷 (선택)

면접 화면 InterviewScreen

image

면접 오류 화면

image

기타 세부 UI

Base Layer

image

카메라 화면과 프레임이 출력되는 기본 레이어

Prepare Layer

image

면접 준비 중 출력되는 레이어

Ongoing Layer

image

면접 진행 중 출력되는 레이어

실제 실행 화면

image

스윙스

🗣️ 리뷰 요구사항 (선택)

별도 없음

Summary by CodeRabbit

  • 새로운 기능

    • 면접 진행 화면과 시작 전 준비 화면을 추가했습니다.
    • 전면 카메라 미리보기, 얼굴 위치 안내, 발화자 상태 표시를 제공합니다.
    • 남은 시간 타이머와 면접 조기 종료 기능을 추가했습니다.
    • 마이크 및 네트워크 오류 화면에서 홈 이동 또는 면접 재개를 선택할 수 있습니다.
    • 면접 중단·종료 확인 모달을 추가했습니다.
    • 마이크, 네트워크, 경고, 완료 상태를 위한 아이콘을 추가했습니다.
  • 개선 사항

    • 버튼의 활성화·비활성화 상태와 스타일 표시를 개선했습니다.
    • 강조 텍스트에 검은색 스타일을 추가했습니다.

@i-meant-to-be
i-meant-to-be requested a review from lyh5427 August 6, 2026 16:18
@i-meant-to-be i-meant-to-be self-assigned this Aug 6, 2026
@i-meant-to-be i-meant-to-be added the feat 새 기능 추가 label Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@i-meant-to-be, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 54 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7a006609-a82b-4c85-89b0-0ee7788dd936

📥 Commits

Reviewing files that changed from the base of the PR and between 9a17117 and 2650af7.

📒 Files selected for processing (3)
  • app/build.gradle.kts
  • app/src/main/AndroidManifest.xml
  • app/src/main/res/values/strings.xml
📝 Walkthrough

Walkthrough

인터뷰 API·구현 모듈과 Navigation 3 엔트리를 추가했습니다. CameraX 기반 프리뷰와 Compose 인터뷰 화면을 구현했습니다. 인터뷰 상태, 오류 처리, 디자인 시스템 아이콘과 버튼 스타일을 확장했습니다.

Changes

인터뷰 기능 기반 및 네비게이션

Layer / File(s) Summary
모듈·계약·네비게이션 기반
settings.gradle.kts, feature/interview/api/..., feature/interview/impl/..., gradle/libs.versions.toml
인터뷰 API·구현 모듈, 라우트, MVI 계약, ViewModel, Navigation 3 엔트리와 Hilt 멀티바인딩을 추가했습니다.
디자인 시스템 및 아이콘 자산
core/resources/.../drawable/*, designsystem/.../button/*, designsystem/.../icon/*, designsystem/.../modal/*, designsystem/.../text/*
인터뷰용 아이콘 리소스를 등록하고, 버튼 비활성화 스타일과 검정 하이라이트 색상을 추가했습니다.
카메라 및 인터뷰 UI 컴포넌트
feature/interview/impl/.../component/*
CameraX 전면 카메라 프리뷰, 카메라 프레임, 비디오 오버레이, 준비도·발언자·타이머 표시기, 시작·종료 모달을 추가했습니다.
인터뷰 상태 및 화면 흐름
feature/interview/impl/.../interview/*, feature/interview/impl/.../layer/*
준비·진행 상태를 ViewModel과 화면 레이어에 연결했습니다. 시작 시 진행 상태로 전환하고 발언자를 변경합니다.
인터뷰 오류 처리 흐름
feature/interview/impl/.../error/*
마이크·네트워크 오류별 콘텐츠, 버튼 동작, 상태 수집, 홈 이동 및 인터뷰 재개 effect를 추가했습니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: design

Suggested reviewers: lyh5427

Sequence Diagram(s)

sequenceDiagram
  participant Navigation
  participant InterviewScreen
  participant InterviewViewModel
  participant InterviewContent
  participant CameraX
  participant InterviewScreenOngoingLayer

  Navigation->>InterviewScreen: InterviewRoute 진입
  InterviewScreen->>InterviewViewModel: 상태 수집
  InterviewViewModel-->>InterviewScreen: InterviewState 반환
  InterviewScreen->>InterviewContent: 상태와 Intent 전달
  InterviewContent->>CameraX: 전면 카메라 프리뷰 바인딩
  InterviewContent->>InterviewScreenOngoingLayer: 진행 상태 렌더링
  InterviewScreenOngoingLayer->>InterviewViewModel: ChangeSpeaker Intent
  InterviewViewModel-->>InterviewContent: 변경된 InterviewState 반환
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 면접 UI 구현이라는 변경의 핵심을 명확하고 간결하게 설명합니다.
Linked Issues check ✅ Passed 인터뷰 UI와 기초 ViewModel·Intent 구현 요구사항을 화면, 컴포넌트, 모듈, 상태 코드로 충족합니다. [#116]
Out of Scope Changes check ✅ Passed 변경 사항이 인터뷰 UI 구현, CameraX 연동, 디자인 시스템 보완, 신규 리소스 및 CI 수정 범위에 포함됩니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch design/#116

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.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Catalog Preview

상태: ❌ 최신 Preview 배포 실패

마지막으로 성공한 Preview가 없습니다.

실패 Commit: 2650af75ae2d

실행: GitHub Actions

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 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
`@feature/interview/api/src/main/kotlin/com/dminus14/app/feature/interview/api/InterviewRoute.kt`:
- Around line 4-15: Update InterviewRoute and InterviewErrorRoute to implement
the Navigation 3 NavKey contract and annotate both types with `@Serializable` so
they can be used with entry<T> and persisted by rememberNavBackStack; add the
required imports without changing their existing route data or error-type
fields.

In
`@feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewCameraPreview.kt`:
- Around line 83-85: Update the camera-binding flow in CameraPreviewReal so
failures from cameraProvider.bindToLifecycle() are exposed through UI state
instead of being swallowed. Use that failure state to render CameraPreviewMock
or an explicit error UI, ensuring the empty AndroidView is not shown after
binding fails.
- Around line 76-82: Update the camera setup and cleanup flow around the visible
cameraProvider binding block: remove both unbindAll() calls, obtain the
ProcessCameraProvider inside the existing future listener rather than waiting on
the UI executor, and clean up only the created preview use case via
cameraProvider.unbind(preview) before rebinding it. Preserve the lifecycleOwner,
cameraSelector, and preview binding behavior.

In
`@feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewTimer.kt`:
- Around line 39-47: Update the timer formatting logic around remainingSeconds
so negative values are clamped to zero before calculating minutes and seconds,
then always render the result with the existing String.format(Locale.US,
"%d:%02d", minutes, seconds) MM:SS format; remove the special sub-minute
"${remainingSeconds...}초" branch.

In
`@feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/di/InterviewNavigationModule.kt`:
- Around line 16-21: InterviewNavigationModule의 provideInterviewEntryInstaller에서
비어 있는 onNavigateHome 및 onResumeInterview 람다를 실제 상위 Navigator 호출로 연결하십시오.
InterviewErrorScreen의 NavigateToHome과 ResumeInterview 효과가 각각 홈 화면 이동과 면접 재개 동작으로
전달되도록 기존 Navigation API와 대상 라우트를 재사용하십시오.

In
`@feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/interview/InterviewContract.kt`:
- Around line 47-48: Update the canFinishedEarly getter in InterviewContract so
early completion is allowed when elapsedSeconds is exactly equal to or greater
than InterviewConstants.CAN_FINISH_INTERVIEW_SECONDS, including the 480-second
boundary.

In
`@feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/interview/InterviewScreen.kt`:
- Line 39: InterviewScreen의 권한 흐름에서 권한 상태를 하드코딩하거나 기본값에 의존하지 말고,
InterviewViewModel 또는 기존 권한 처리 계층의 isCameraPermissionGranted를 실제 상태로 공급하세요. 이 값을
InterviewScreenBaseLayer와 InterviewScreenPrepareLayer에서 InterviewCameraPreview까지
전달해 거부 시 CameraPreviewReal() bind를 시도하지 않도록 하고, 거부 상태의 뒤로가기 아이콘에는 홈 이동 effect
경계까지 연결되는 클릭 콜백을 전달하세요.

In
`@feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/layer/InterviewScreenOngoingLayer.kt`:
- Around line 51-62: InterviewScreenOngoingLayer의 `면접 종료하기` 버튼이 실제 종료 동작을 수행하도록
연결하십시오. 레이어에 `onFinishRequest` 콜백을 추가하고, `InterviewScreen`에서 종료 모달 또는 종료 Intent를
실행하는 핸들러를 전달하십시오. 버튼의 `onClick`에서 빈 람다 대신 해당 콜백을 호출하고 기존 `isInterviewOngoing`
활성화 조건은 유지하십시오.
🪄 Autofix

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 Plus

Run ID: a2fdf10f-d61a-43f1-b81d-e3aee880b65a

📥 Commits

Reviewing files that changed from the base of the PR and between f5f7451 and 9a17117.

📒 Files selected for processing (40)
  • .gitignore
  • CLAUDE.md
  • core/resources/src/commonMain/composeResources/drawable/alert_red.xml
  • core/resources/src/commonMain/composeResources/drawable/finish.xml
  • core/resources/src/commonMain/composeResources/drawable/mic.xml
  • core/resources/src/commonMain/composeResources/drawable/network.xml
  • data/src/test/kotlin/com/dminus14/app/data/remote/datasource/InterviewRemoteDataSourceTest.kt
  • designsystem/src/commonMain/kotlin/com/dminus14/designsystem/component/button/HilitFixedBottomButton.kt
  • designsystem/src/commonMain/kotlin/com/dminus14/designsystem/component/button/HilitMiniButton.kt
  • designsystem/src/commonMain/kotlin/com/dminus14/designsystem/component/icon/HilitIcon.kt
  • designsystem/src/commonMain/kotlin/com/dminus14/designsystem/component/modal/HilitModal.kt
  • designsystem/src/commonMain/kotlin/com/dminus14/designsystem/component/text/HilitTextHighlight.kt
  • feature/interview/api/build.gradle.kts
  • feature/interview/api/src/main/kotlin/com/dminus14/app/feature/interview/api/InterviewRoute.kt
  • feature/interview/impl/build.gradle.kts
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/InterviewConstants.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewAbortModal.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewCameraFrame.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewCameraPreview.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewCompletableBubble.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewFinishModal.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewReadinessIndicator.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewSpeakerIndicator.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewStartButton.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/InterviewTimer.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/TrapezoidShape.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/component/VideoOverlay.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/di/InterviewNavigationModule.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/error/InterviewErrorContract.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/error/InterviewErrorScreen.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/error/InterviewErrorViewModel.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/interview/InterviewContract.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/interview/InterviewScreen.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/interview/InterviewViewModel.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/layer/InterviewScreenBaseLayer.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/layer/InterviewScreenOngoingLayer.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/layer/InterviewScreenPrepareLayer.kt
  • feature/interview/impl/src/main/kotlin/com/dminus14/app/feature/interview/navigation/InterviewEntryBuilder.kt
  • gradle/libs.versions.toml
  • settings.gradle.kts

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

질문

  • 흐르는 애니메이션이 요구사항이었던걸로 기억하는데, 변경되었거나 혹은 후속작업 예정이신가요?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

아! 그럼 그렇게 반영해서 병합해 둘게용

@lyh5427 lyh5427 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

승인합니다!

질문 1건, coflict, ci 확인 부탁드립니다!

@lyh5427

lyh5427 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

/noti
승인합니다. 코멘트 확인 부탁드립니다!

@lyh5427

lyh5427 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

스윙스 ㅋㅋㅋㅋㅋㅋㅋㅋ

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.

[DESIGN] 인터뷰 UI 구현

2 participants