Files

22 KiB

V2 공통 모달창 구현 계획/TASK

For agentic workers: 각 단계는 체크박스(- [ ])로 추적하고, 완료 즉시 - [x]로 갱신한다. 구현 범위 변경이 생기면 이 문서를 먼저 수정한 뒤 코드에 반영한다.

Goal: Figma 567:17662(버튼 1개), 567:17666(버튼 2개) 디자인 기반의 V2 공통 모달창 V2ModalDialog를 만들어, 기존 SodaDialog처럼 어디서든 title/desc/버튼 title/버튼 action을 조정해 사용할 수 있게 한다.

Architecture: 레거시 SodaDialog를 수정하지 않고, kr.co.vividnext.sodalive.v2.components.modal 하위에 AlertDialog + ViewBinding 기반의 신규 클래스와 신규 layout(dialog_v2_modal.xml)을 추가한다. cancelButtonTitle이 blank이면 버튼 1개, 아니면 취소+확인 버튼 2개(1:1 비율)로 표시한다.

Tech Stack: Kotlin, Android XML Views, ViewBinding, AlertDialog, JUnit4/Robolectric.


전제와 성공 기준

  • PRD: docs/20260708_V2_공통_모달창/prd.md
  • 기존 참조 구현: app/src/main/java/kr/co/vividnext/sodalive/base/SodaDialog.kt (수정 금지, 사용 방식 참조만)
  • 신규 코드 위치: app/src/main/java/kr/co/vividnext/sodalive/v2/components/modal/ (빈 패키지 존재 확인 완료)
  • 색상 리소스: gray_900(#202020), soda_400(#00BDF7), white 기존 정의 재사용 (colors.xml 확인 완료)
  • 구현 완료 판단 시 Gradle 검증뿐 아니라 Figma 567:17662, 567:17666의 layout 구조(컨테이너/타이틀/본문/버튼 영역), 색상, 버튼 구성이 실제 구현에 반영되었는지 확인한다.
  • 자동 검증에서도 Figma에서 확정된 UI 계약을 확인한다.
    • cancelButtonTitle blank: 확인 버튼 1개만 표시
    • cancelButtonTitle 있음: 취소+확인 버튼 2개 표시
    • 버튼 클릭: dismiss 후 전달받은 action 실행
    • 색상: 컨테이너 gray_900, 확인 버튼 텍스트 soda_400, 취소 버튼 텍스트 white
  • Figma 대조 결과는 문서 최하단 Verification Log에 한국어로 누적 기록한다.
  • 구현 완료 후 최소 다음 명령을 실행한다.
    • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.*"
    • ./gradlew :app:mergeDebugResources
    • ./gradlew :app:compileDebugKotlin
    • ./gradlew :app:ktlintCheck
    • git diff --check

Figma 참조

  • 버튼 1개: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=567-17662&m=dev
  • 버튼 2개: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=567-17666&m=dev
  • 확정 디자인 값:
    • 컨테이너: 배경 gray_900(#202020), radius 14dp
    • title: 높이 64dp, 20sp Bold, white, 가운데 정렬
    • desc: 패딩 20dp, 16sp Regular, white, 가운데 정렬, line spacing 1.45
    • 버튼 영역: 좌우 패딩 20dp, 상하 패딩 14dp, 버튼 간 간격 8dp
    • 버튼: 내부 패딩 14dp, radius 100dp capsule, 18sp Medium
    • 확인 버튼 텍스트: soda_400(#00BDF7), 취소 버튼 텍스트: white

파일 구조

  • 생성: app/src/main/java/kr/co/vividnext/sodalive/v2/components/modal/V2ModalDialog.kt
    • AlertDialog 기반 공통 모달 클래스. 생성자 파라미터로 title/desc/confirm title/confirm action/cancel title/cancel action을 받는다.
  • 생성: app/src/main/res/layout/dialog_v2_modal.xml
    • Figma 기준 모달 layout(title/desc/버튼 영역).
  • 생성: app/src/main/res/drawable/bg_v2_modal.xml
    • gray_900 배경 + radius 14dp 컨테이너 배경.
  • 테스트 생성:
    • app/src/test/java/kr/co/vividnext/sodalive/v2/components/modal/V2ModalDialogTest.kt

Phase 1: 모달 layout과 리소스 구현

  • Task 1.1: 모달 배경 drawable과 layout 추가
    • 생성:
      • app/src/main/res/drawable/bg_v2_modal.xml
      • app/src/main/res/layout/dialog_v2_modal.xml
    • 작업:
      • bg_v2_modal.xmlgray_900 solid, corner radius 14dp로 구성한다.
      • dialog_v2_modal.xml은 Figma 확정 값 기준으로 title(높이 64dp, 20sp Bold, white, 가운데 정렬), desc(패딩 20dp, 16sp Regular, white, 가운데 정렬, line spacing 1.45), 버튼 영역(좌우 20dp/상하 14dp 패딩, 버튼 간격 8dp)을 구성한다.
      • 취소/확인 버튼은 내부 패딩 14dp, 18sp Medium으로 구성하고, 2개일 때 1:1 비율이 되도록 동일 weight를 준다.
      • 확인 버튼 텍스트 색상은 soda_400, 취소 버튼 텍스트 색상은 white로 지정한다.
    • 검증 명령:
      • ./gradlew :app:mergeDebugResources
    • 기대 결과:
      • 신규 drawable/layout resource가 resource merge를 통과한다.

Phase 2: V2ModalDialog 클래스 구현

  • Task 2.1: V2ModalDialog RED 테스트 작성

    • 생성:
      • app/src/test/java/kr/co/vividnext/sodalive/v2/components/modal/V2ModalDialogTest.kt
    • 테스트 케이스:
      • cancelButtonTitle이 blank(빈 문자열/공백)이면 취소 버튼이 GONE이고 확인 버튼만 VISIBLE이다.
      • cancelButtonTitle이 있으면 취소/확인 버튼이 모두 VISIBLE이고 각 버튼 title이 반영된다.
      • title/desc 텍스트가 파라미터 값으로 표시된다.
      • 확인 버튼 클릭 시 dialog가 dismiss되고 confirmButtonClick이 실행된다.
      • 취소 버튼 클릭 시 dialog가 dismiss되고 cancelButtonClick이 실행된다.
      • cancelButtonClicknull이어도 취소 버튼 클릭 시 dismiss되고 예외가 발생하지 않는다.
      • layout이 bg_v2_modal 배경, soda_400 확인 텍스트, white 취소 텍스트를 사용한다(source/resource 계약 확인).
    • 검증 명령:
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.V2ModalDialogTest"
    • 기대 결과:
      • 클래스 구현 전 실패한다.
  • Task 2.2: V2ModalDialog 구현

    • 생성:
      • app/src/main/java/kr/co/vividnext/sodalive/v2/components/modal/V2ModalDialog.kt
    • 작업:
      • 생성자 파라미터: activity: Activity, layoutInflater: LayoutInflater, title: String, desc: String, confirmButtonTitle: String, confirmButtonClick: () -> Unit, cancelButtonTitle: String = "", cancelButtonClick: (() -> Unit)? = null.
      • AlertDialog.Builderdialog_v2_modal.xml을 표시하고 setCancelable(false), window 배경 투명 처리를 적용한다.
      • cancelButtonTitle.isNotBlank()일 때만 취소 버튼을 VISIBLE 처리한다.
      • 각 버튼 클릭 시 dismiss() 후 전달받은 action을 실행한다.
      • show(width)는 기존 SodaDialog와 동일하게 width - 26.7dp로 dialog 폭을 지정한다.
      • 레거시 SodaDialog.kt, dialog_soda.xml은 수정하지 않는다.
    • 검증 명령:
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.V2ModalDialogTest"
      • ./gradlew :app:compileDebugKotlin
    • 기대 결과:
      • 신규 테스트가 PASS하고 컴파일 오류가 없다.

Phase 3: 회귀 검증과 Figma 대조

  • Task 3.1: 전체 검증 실행
    • 실행:
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.*"
      • ./gradlew :app:mergeDebugResources
      • ./gradlew :app:compileDebugKotlin
      • ./gradlew :app:ktlintCheck
      • git diff --check
    • Figma 기반 자동 확인:
      • V2ModalDialogTest에서 버튼 1개/2개 구성, dismiss 후 action 실행, title/desc/버튼 title 반영 계약을 확인한다.
      • layout/drawable에 gray_900 배경, radius 14dp, soda_400 확인 텍스트, white 취소 텍스트가 있는지 확인한다.
    • Figma 수동 확인:
      • 버튼 1개 모달이 Figma 567:17662의 layout 구조와 색상을 반영하는지 확인한다.
      • 버튼 2개 모달이 Figma 567:17666의 layout 구조, 버튼 1:1 비율, 색상을 반영하는지 확인한다.
    • 기대 결과:
      • 모든 명령이 PASS하고, Figma 두 변형 대조 결과가 PASS한다.
    • 검증 기록:
      • 자동 확인 결과와 수동 대조 결과를 Verification Log에 누적한다.

Phase 4: V2 사용처 dialog_v2_modal 적용 대상 조사

  • Task 4.1: kr.co.vividnext.sodalive.v2 하위 dialog/modal 사용처 검색

    • 확인:
      • app/src/main/java/kr/co/vividnext/sodalive/v2
      • app/src/test/java/kr/co/vividnext/sodalive/v2
    • 검색 키워드:
      • SodaDialog
      • AlertDialog.Builder
      • V2ModalDialog
      • DialogFragment
      • BottomSheetDialogFragment
      • PopupWindow
      • LivePaymentDialog
      • LiveRoomPasswordDialog
      • LiveCancelDialog
      • LiveRoomDonationDialog
      • UserReportDialog
      • ProfileReportDialog
      • CheersReportDialog
      • NotificationSettingsDialog
      • EventPopupDialogFragment
    • 검증 명령:
      • rg -n "SodaDialog|V2ModalDialog|AlertDialog\\.Builder|AlertDialog" app/src/main/java/kr/co/vividnext/sodalive/v2 app/src/test/java/kr/co/vividnext/sodalive/v2
      • rg -n "SodaDialog\\(|AlertDialog\\.Builder\\(|UserReportDialog\\(|ProfileReportDialog\\(|CheersReportDialog\\(|LivePaymentDialog\\(|LiveRoomPasswordDialog\\(|LiveCancelDialog\\(|LiveRoomDonationDialog\\(|NotificationSettingsDialog\\(|EventPopupDialogFragment\\(|BottomSheetDialogFragment|PopupWindow" app/src/main/java/kr/co/vividnext/sodalive/v2
    • 기대 결과:
      • V2ModalDialog로 직접 바꿀 수 있는 확인형 모달과 별도 설계가 필요한 커스텀 다이얼로그를 구분한다.
    • 검증 기록:
      • 2026-07-08 실행 결과, 직접 교체 후보는 SodaDialog 6곳, AlertDialog.Builder 1곳, ProfileReportDialog 1곳으로 분류했다.
      • 입력/라디오/이미지/토글/BottomSheet/PopupWindow 기반 사용처는 현 V2ModalDialog API로 직접 표현하기 어려워 별도 설계 후보로 분류했다.
  • Task 4.2: 교체 후보와 테스트 영향 문서화

    • 수정:
      • docs/20260708_V2_공통_모달창/prd.md
      • docs/20260708_V2_공통_모달창/plan-task.md
    • 바로 교체 가능한 후보:
      • app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuard.kt:49
      • app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt:186
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt:386
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt:403
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt:607
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt:643
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt:980
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteActivity.kt:124
    • 테스트 영향:
      • app/src/test/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuardSourceTest.kt:20
      • app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt:602
      • app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt:1374
    • 검증 명령:
      • rg -n "SodaDialog\\(|AlertDialog\\.Builder\\(|ProfileReportDialog\\(" app/src/main/java/kr/co/vividnext/sodalive/v2 app/src/test/java/kr/co/vividnext/sodalive/v2
    • 기대 결과:
      • 후속 구현자가 교체 파일, 테스트 파일, 제외/보류 대상을 문서만으로 파악할 수 있다.
    • 검증 기록:
      • 2026-07-08 문서 작성 단계에서는 구현 변경이 없으므로 Gradle 검증을 실행하지 않았다.

Phase 5: 확인형 모달 V2ModalDialog 교체 구현

  • Task 5.1: SodaDialog, AlertDialog.Builder, ProfileReportDialog 직접 교체 후보를 V2ModalDialog로 변경

    • 수정:
      • app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuard.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteActivity.kt
    • 작업:
      • kr.co.vividnext.sodalive.v2.components.modal.V2ModalDialog를 import한다.
      • 확인/취소형 모달의 title, desc, confirm/cancel title, confirm/cancel action을 기존 동작과 동일하게 매핑한다.
      • descGravity = Gravity.CENTER는 현 dialog_v2_modal desc가 중앙 정렬이므로 제거한다.
      • 교체 후 미사용 SodaDialog, AlertDialog, Gravity, ProfileReportDialog import를 제거한다.
      • 레거시 다이얼로그 클래스와 레거시 layout은 수정하지 않는다.
    • 검증 명령:
      • ./gradlew :app:compileDebugKotlin
      • git diff --check
    • 기대 결과:
      • 직접 교체 후보가 dialog_v2_modal 기반으로 표시되고 컴파일 오류가 없다.
    • 검증 기록:
      • 2026-07-08 MainV2LoginGuard.kt, HomeOnAirLiveActivity.kt, CreatorChannelActivity.kt, CreatorChannelFanTalkWriteActivity.kt의 직접 교체 후보를 V2ModalDialog로 변경했다. descGravity = Gravity.CENTERdialog_v2_modal의 desc 중앙 정렬 계약으로 대체되어 제거했고, 기존 title/desc/button string과 confirm/cancel callback은 유지했다.
      • 2026-07-08 rg -n "SodaDialog\(|AlertDialog\.Builder\(|ProfileReportDialog\(|descGravity|import android.view.Gravity|import kr.co.vividnext.sodalive.base.SodaDialog|import androidx.appcompat.app.AlertDialog|import kr.co.vividnext.sodalive.report.ProfileReportDialog" ... 확인 결과, 생산 코드의 직접 교체 대상 레거시 생성자/import는 남지 않았다. 검색에 남은 showProfileReportDialog는 V2 모달을 여는 메서드명이다.
  • Task 5.2: source 테스트 기대값 갱신

    • 수정:
      • app/src/test/java/kr/co/vividnext/sodalive/v2/main/MainV2LoginGuardSourceTest.kt
      • app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt
    • 작업:
      • SodaDialog( 문자열 기대를 V2ModalDialog( 또는 더 구체적인 V2 모달 import/호출 계약으로 바꾼다.
      • CreatorChannelActivity의 사용자 차단/프로필 신고/삭제/성인 인증 확인 흐름이 기존 callback을 유지하는지 source 계약으로 확인한다.
    • 검증 명령:
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.MainV2LoginGuardSourceTest"
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"
    • 기대 결과:
      • 갱신된 source 테스트가 PASS한다.
    • 검증 기록:
      • 2026-07-08 MainV2LoginGuardSourceTest, CreatorChannelActivitySourceTest, CreatorChannelFanTalkWriteSourceTest의 source 계약을 V2ModalDialog( 기대와 레거시 SodaDialog(/AlertDialog.Builder(/ProfileReportDialog(this, layoutInflater) 금지 조건으로 갱신했다.
      • 2026-07-08 테스트 변경 직후 병렬 Gradle 실행은 Kotlin incremental cache 경합으로 test assertion 전에 실패했다. 이후 --no-parallel --no-daemon -Pkotlin.incremental=false로 직렬 실행해 MainV2LoginGuardSourceTest, CreatorChannelActivitySourceTest, CreatorChannelFanTalkWriteSourceTest가 PASS함을 확인했다.
  • Task 5.3: 직접 교체 범위 회귀 검증

    • 실행:
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.*"
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.MainV2LoginGuardSourceTest"
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"
      • ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.CreatorChannelFanTalkWriteSourceTest"
      • ./gradlew :app:compileDebugKotlin
      • git diff --check
    • 기대 결과:
      • 직접 교체 범위 테스트와 컴파일이 PASS한다.
    • 검증 기록:
      • 2026-07-08 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.*" --no-parallel --no-daemon -Pkotlin.incremental=false PASS.
      • 2026-07-08 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.MainV2LoginGuardSourceTest" --no-parallel --no-daemon -Pkotlin.incremental=false PASS.
      • 2026-07-08 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest" --no-parallel --no-daemon -Pkotlin.incremental=false PASS.
      • 2026-07-08 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.CreatorChannelFanTalkWriteSourceTest" --no-parallel --no-daemon -Pkotlin.incremental=false PASS.
      • 2026-07-08 ./gradlew :app:compileDebugKotlin --no-parallel --no-daemon -Pkotlin.incremental=false PASS.
      • 2026-07-08 git diff --check PASS.

Phase 6: 커스텀 콘텐츠 다이얼로그 후속 설계

  • Task 6.1: 현 V2ModalDialog로 직접 표현할 수 없는 사용처 처리 방침 결정
    • 확인 대상:
      • app/src/main/java/kr/co/vividnext/sodalive/v2/main/MainV2Activity.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelLiveCoordinator.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelMoreBottomSheet.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelSortPopup.kt
      • app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/ui/CreatorChannelFanTalkMorePopup.kt
    • 결정 필요:
      • report 라디오 목록, password/reason 입력, payment 시간 안내, donation BottomSheet, notification toggle, event image popup을 dialog_v2_modal 기반으로 새로 설계할지 여부
      • BottomSheet/PopupWindow 메뉴를 모달 교체 범위에서 제외할지 여부
    • 검증 기준:
      • 결정 결과를 이 문서의 Phase 6 아래에 추가하고, 구현 전 PRD를 먼저 갱신한다.

Verification Log

  • 2026-07-08 문서 작성 단계: 구현 전이므로 Gradle 검증을 실행하지 않았다. Figma 567:17662, 567:17666 디자인 컨텍스트와 스크린샷으로 layout 구조/색상 값을 확정했고, v2/components/modal 빈 패키지와 gray_900/soda_400 색상 리소스 존재를 확인했다.
  • 2026-07-08 구현 단계: ./gradlew :app:mergeDebugResources PASS. dialog_v2_modal.xml, bg_v2_modal.xml 리소스 merge를 확인했다.
  • 2026-07-08 RED 확인: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.V2ModalDialogTest" 실행 시 V2ModalDialog 구현 전 Unresolved reference 'V2ModalDialog'로 실패해 RED 상태를 확인했다.
  • 2026-07-08 GREEN 확인: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.V2ModalDialogTest" PASS. 버튼 1개/2개 구성, title/desc/버튼 title 반영, dismiss 후 action 실행, cancelButtonClick = null 취소 동작, Figma 리소스 계약을 확인했다.
  • 2026-07-08 최종 검증: ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.*", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, git diff --check PASS. ./gradlew :app:ktlintCheck는 기존 레거시/타 영역 파일의 package-name, trailing comma, indentation 등 사전 존재 위반으로 FAIL했으며, ktlint 보고서에 이번 변경 파일(V2ModalDialog.kt, V2ModalDialogTest.kt, dialog_v2_modal.xml, bg_v2_modal.xml)은 포함되지 않았다. Figma 567:17662, 567:17666 스크린샷 기준으로 컨테이너/타이틀/본문/버튼 영역, 버튼 1:1 구성, gray_900/white/soda_400 색상을 대조했다.
  • 2026-07-08 리뷰 반영: 투명 bg_v2_modal_button.xml은 실제 시각 효과가 없어 제거했다. 버튼 중복 클릭 시 action이 여러 번 실행될 수 있는 위험을 막기 위해 최초 클릭 1회만 dismiss/action을 수행하도록 보완했고, 긴 title 줄바꿈 시 잘림을 줄이기 위해 title 높이를 wrap_content + minHeight=64dp로 조정했다.
  • 2026-07-08 코드 리뷰/검증: V2ModalDialog.kt, dialog_v2_modal.xml, bg_v2_modal.xml, V2ModalDialogTest.kt를 PRD와 Figma MCP 567:17662, 567:17666 기준으로 재대조했으며 차단 이슈는 발견하지 않았다. ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.*", ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, git diff --check PASS. 신규 untracked 파일은 git diff --no-index --check /dev/null <file>로 별도 확인했고 whitespace 오류 출력이 없었다. ./gradlew :app:ktlintCheck는 기존 레거시/타 영역 위반으로 FAIL했으며 ktlint 보고서에서 이번 변경 파일명 검색 결과는 없었다.
  • 2026-07-08 Phase 5 구현: MainV2LoginGuard.kt, HomeOnAirLiveActivity.kt, CreatorChannelActivity.kt, CreatorChannelFanTalkWriteActivity.kt의 직접 교체 후보를 V2ModalDialog로 변경하고 source test 계약을 갱신했다. 병렬 RED 실행은 Kotlin incremental cache 경합으로 assertion 전 실패했으나, 이후 비증분/직렬 실행으로 MainV2LoginGuardSourceTest, CreatorChannelActivitySourceTest, CreatorChannelFanTalkWriteSourceTest, v2.components.modal.* 테스트가 PASS했다. ./gradlew :app:compileDebugKotlin --no-parallel --no-daemon -Pkotlin.incremental=falsegit diff --check도 PASS했다.