11 KiB
11 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 계약을 확인한다.
cancelButtonTitleblank: 확인 버튼 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:ktlintCheckgit 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.ktAlertDialog기반 공통 모달 클래스. 생성자 파라미터로 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.xmlgray_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.xmlapp/src/main/res/layout/dialog_v2_modal.xml
- 작업:
bg_v2_modal.xml은gray_900solid, 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이 실행된다. cancelButtonClick이null이어도 취소 버튼 클릭 시 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.Builder로dialog_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:ktlintCheckgit 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 비율, 색상을 반영하는지 확인한다.
- 버튼 1개 모달이 Figma
- 기대 결과:
- 모든 명령이 PASS하고, Figma 두 변형 대조 결과가 PASS한다.
- 검증 기록:
- 자동 확인 결과와 수동 대조 결과를
Verification Log에 누적한다.
- 자동 확인 결과와 수동 대조 결과를
- 실행:
Verification Log
- 2026-07-08 문서 작성 단계: 구현 전이므로 Gradle 검증을 실행하지 않았다. Figma
567:17662,567:17666디자인 컨텍스트와 스크린샷으로 layout 구조/색상 값을 확정했고,v2/components/modal빈 패키지와gray_900/soda_400색상 리소스 존재를 확인했다. - 2026-07-08 구현 단계:
./gradlew :app:mergeDebugResourcesPASS.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 --checkPASS../gradlew :app:ktlintCheck는 기존 레거시/타 영역 파일의 package-name, trailing comma, indentation 등 사전 존재 위반으로 FAIL했으며, ktlint 보고서에 이번 변경 파일(V2ModalDialog.kt,V2ModalDialogTest.kt,dialog_v2_modal.xml,bg_v2_modal.xml)은 포함되지 않았다. Figma567: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 MCP567:17662,567:17666기준으로 재대조했으며 차단 이슈는 발견하지 않았다../gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.components.modal.*",./gradlew :app:mergeDebugResources,./gradlew :app:compileDebugKotlin,git diff --checkPASS. 신규 untracked 파일은git diff --no-index --check /dev/null <file>로 별도 확인했고 whitespace 오류 출력이 없었다../gradlew :app:ktlintCheck는 기존 레거시/타 영역 위반으로 FAIL했으며 ktlint 보고서에서 이번 변경 파일명 검색 결과는 없었다.