28 KiB
FanTalk 글 입력 구현 계획/TASK
For agentic workers: 각 단계는 체크박스(
- [ ])로 추적하고, 완료 즉시- [x]로 갱신한다. 구현 범위 변경이 생기면 이 문서를 먼저 수정한 뒤 코드에 반영한다.
Goal: 크리에이터 채널 FanTalk 탭에서 고정형 plus button 또는 empty 응원 남기기 버튼으로 글 입력 화면에 진입하고, 기존 FanTalk 등록 API로 응원글을 등록한다.
Architecture: 기존 CreatorChannelFanTalkFragment의 빈 글쓰기 click callback을 Host로 올리고, CreatorChannelActivity에서 신규 CreatorChannelFanTalkWriteActivity를 ActivityResult로 실행한다. 기존 Fragment 내부 floating button은 Activity overlay fixed button으로 대체해 스크롤과 분리하고, 등록 API는 CreatorChannelRepository.writeFanTalk() wrapper가 레거시 ExplorerRepository.writeCheers()를 호출한다.
Tech Stack: Kotlin, Android XML Views, ViewBinding, Activity Result API, RxJava3, Koin, JUnit4/Robolectric.
전제와 성공 기준
- PRD:
docs/20260708_FanTalk_글_입력/prd.md - 기존 FanTalk 탭 문서:
docs/20260622_FanTalk_탭/prd.mddocs/20260622_FanTalk_탭/plan-task.md
- 기존 FanTalk 탭 구현:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.ktapp/src/main/res/layout/fragment_creator_channel_fantalk.xmlapp/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt
- 기존 FanTalk 등록 API:
app/src/main/java/kr/co/vividnext/sodalive/explorer/ExplorerRepository.ktapp/src/main/java/kr/co/vividnext/sodalive/explorer/ExplorerApi.ktapp/src/main/java/kr/co/vividnext/sodalive/explorer/profile/cheers/PostWriteCheersRequest.kt
- 기존 v2 repository:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelRepository.kt
- fixed plus button은
CreatorChannelActivitylayout overlay에 배치한다. - fixed plus button icon은
ic_plus_no_bg를 사용하고 white tint를 적용한다. - empty 상태의
응원 남기기버튼은 Fragment 내부에 유지하고 글 입력 화면으로 연결한다. - 글 등록 성공 후
refreshCreatorChannelFanTalk()와homeActionDelegate?.refreshHome()를 호출한다. - 구현 완료 판단 시 Gradle 검증뿐 아니라 Figma
290:9235,290:9282,290:9290,308:19046의 주요 layout 구조, 버튼 상태, popup 문구가 실제 구현 화면에 반영되었는지 확인한다. - 자동 검증에서도 Figma에서 확정된 UI 계약을 확인한다.
- 입력값 없음: 보내기 버튼 disabled
- 입력값 있음: 보내기 버튼 enabled
- 입력 종료 popup: title/desc/cancel/confirm 문구 일치
- fixed plus button:
ic_plus_no_bg, white tint, Activity overlay 고정 배치
- Figma 대조 결과는 문서 최하단
Verification Log에 한국어로 누적 기록한다. - 구현 완료 후 최소 다음 명령을 실행한다.
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.*"./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.*"./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*FanTalk*"./gradlew :app:mergeDebugResources./gradlew :app:compileDebugKotlin./gradlew :app:ktlintCheckgit diff --check
Figma 참조
- 입력 값 없음 + keyboard 있음:
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=290-9235&m=dev - 입력 값 있음 + keyboard 있음:
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=290-9282&m=dev - 입력 값 있음 + keyboard 없음:
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=290-9290&m=dev - 입력 종료 modal:
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=308-19046&m=dev - 입력 종료 modal 문구:
- title:
입력 종료 - desc:
입력을 종료할까요?\n지금 나가면 입력한 내용이 저장되지 않아요. - cancel button:
계속 작성 - confirm button:
종료
- title:
파일 구조
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelRepository.ktwriteFanTalk(creatorId, content, token)wrapper를 추가한다.
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.kt- 기존 빈 글쓰기 click listener를 Host callback으로 교체한다.
- content 상태에서 Activity fixed plus button 표시 여부를 Host에 알린다.
- Fragment 내부
btn_creator_channel_fantalk_write는 더 이상 floating 진입점으로 사용하지 않는다.
- 수정:
app/src/main/res/layout/fragment_creator_channel_fantalk.xml- Fragment 내부
btn_creator_channel_fantalk_write를 제거하거나 항상gone처리한다. - empty
응원 남기기버튼은 유지한다.
- Fragment 내부
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.ktCreatorChannelFanTalkWriteActivityActivityResult launcher를 추가한다.- FanTalk fixed plus button 표시/숨김과 click 처리를 담당한다.
- 등록 성공 시 FanTalk 목록과 홈 요약을 refresh한다.
- 수정:
app/src/main/res/layout/activity_creator_channel.xml- FanTalk fixed plus button을 root overlay 우측 하단에 추가한다.
- icon은
@drawable/ic_plus_no_bg, tint는@color/white를 사용한다.
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteActivity.kt- Figma 기반 입력 화면, keyboard show/hide, 취소 popup, 등록 성공 result를 담당한다.
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteViewModel.kt- 입력값 상태, 보내기 버튼 enabled 상태, 등록 loading/result/error 상태를 관리한다.
- 생성:
app/src/main/res/layout/activity_creator_channel_fantalk_write.xml- 입력 화면 layout을 구현한다.
- 생성 가능:
app/src/main/res/drawable/bg_creator_channel_fantalk_write_send_enabled.xml- 기존 drawable로 대응되지 않을 때만 enabled 보내기 버튼 배경을 추가한다.
- 생성 가능:
app/src/main/res/drawable/bg_creator_channel_fantalk_write_send_disabled.xml- 기존 drawable로 대응되지 않을 때만 disabled 보내기 버튼 배경을 추가한다.
- 수정:
app/src/main/res/values/strings.xml- FanTalk 글 입력 title/hint/send/cancel/popup/오류 문구를 추가하거나 기존 문자열을 재사용한다.
- 수정:
app/src/main/res/values-en/strings.xml,app/src/main/res/values-ja/strings.xml- 신규 문자열의 다국어 값을 추가한다.
- 수정:
app/src/main/AndroidManifest.xml- 신규
CreatorChannelFanTalkWriteActivity를 등록한다.
- 신규
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.ktCreatorChannelFanTalkWriteViewModelbinding을 추가한다.
- 테스트 생성:
app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteViewModelTest.ktapp/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteSourceTest.kt
- 테스트 수정:
app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.ktapp/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragmentLayoutTest.kt
Phase 1: 기존 구조 확인과 fixed button 경계 고정
-
Task 1.1: 기존 FanTalk 글쓰기 진입점 상태 확인
- 확인:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.ktapp/src/main/res/layout/fragment_creator_channel_fantalk.xml
- 작업:
btnCreatorChannelFantalkWrite.setOnClickListener { }와layoutCreatorChannelFantalkEmptyWriteButton.setOnClickListener { }가 빈 동작임을 확인한다.- Fragment 내부
btn_creator_channel_fantalk_write가 Fragment root bottom에 묶여 있어 긴 콘텐츠에서 화면 우측 하단 고정 요구사항을 만족하지 못하는지 확인한다.
- 검증:
rg -n "btnCreatorChannelFantalkWrite|layoutCreatorChannelFantalkEmptyWriteButton|btn_creator_channel_fantalk_write" app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk app/src/main/res/layout/fragment_creator_channel_fantalk.xml- 기대 결과: 빈 click listener와 Fragment 내부 floating view 위치가 확인된다.
- 확인:
-
Task 1.2: Activity overlay fixed button 배치 지점 확인
- 확인:
app/src/main/res/layout/activity_creator_channel.xmlapp/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt
- 작업:
- donation floating button, owner FAB와 겹치지 않는 FanTalk fixed plus button 배치 지점을 정한다.
- current tab이
CreatorChannelTab.FanTalk이고 FanTalk content 상태일 때만 표시되도록 Activity 상태 변수를 둔다.
- 검증:
rg -n "btnCreatorChannelDonationWrite|owner_fab_button|updateDonationFloatingButtonVisibility|CreatorChannelTab.FanTalk" app/src/main/res/layout/activity_creator_channel.xml app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt- 기대 결과: Activity overlay에 fixed button을 추가할 위치와 visibility 갱신 지점이 확인된다.
- 확인:
Phase 2: FanTalk 등록 API wrapper와 ViewModel 계약
-
Task 2.1: Repository wrapper 추가
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelRepository.kt
- 작업:
writeFanTalk(creatorId: Long, content: String, token: String)method를 추가한다.- 내부에서는
explorerRepository.writeCheers(parentCheersId = null, creatorId = creatorId, content = content, token = token)를 호출한다.
- 검증 명령:
./gradlew :app:compileDebugKotlin
- 기대 결과:
- 기존 레거시 파일 수정 없이 v2 repository에서 FanTalk 등록 API를 호출할 수 있다.
- 수정:
-
Task 2.2: FanTalk 글 입력 ViewModel RED 테스트 작성
- 생성:
app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteViewModelTest.kt
- 테스트 케이스:
- 초기 입력값은 빈 값이고 보내기 버튼은 disabled다.
- 공백과 줄바꿈만 입력하면 보내기 버튼은 disabled다.
- trim 결과가 비어 있지 않으면 보내기 버튼은 enabled다.
- disabled 상태에서 submit하면 repository를 호출하지 않는다.
- enabled 상태에서 submit하면
CreatorChannelRepository.writeFanTalk(creatorId, trimmedContent, "Bearer $token")을 호출한다. - 등록 중에는 중복 submit을 무시한다.
- 등록 성공 시 완료 event를 emit한다.
- 등록 실패 시 입력값을 유지하고 toast message를 emit한다.
- 검증 명령:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.CreatorChannelFanTalkWriteViewModelTest"
- 기대 결과:
- ViewModel 구현 전 실패한다.
- 생성:
-
Task 2.3: FanTalk 글 입력 ViewModel 구현
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteViewModel.kt
- 작업:
contentLiveData,isSendEnabledLiveData,isLoadingLiveData, 완료 event, toast event를 제공한다.onContentChanged(content)에서content.trim().isNotEmpty()기준으로 보내기 enabled 상태를 갱신한다.submit(creatorId)에서 disabled/loading/invalid creatorId 상태를 방어한다.- 성공 시 완료 event를 emit하고, 실패 시 toast event를 emit한다.
- 검증 명령:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.CreatorChannelFanTalkWriteViewModelTest"
- 기대 결과:
- 신규 ViewModel 테스트가 PASS한다.
- 생성:
Phase 3: 글 입력 Activity와 Figma UI 구현
-
Task 3.1: 글 입력 Activity layout 추가
- 생성:
app/src/main/res/layout/activity_creator_channel_fantalk_write.xml
- 작업:
- Figma
290:9235,290:9282,290:9290기준으로 title/cancel/input/send 영역을 구성한다. - 입력값 없음 상태의 보내기 버튼 disabled style과 입력값 있음 상태의 enabled style을 분리한다.
- keyboard가 내려간 상태에서도 입력 영역과 하단 action이 겹치지 않게 구성한다.
- Figma
- 검증 명령:
./gradlew :app:mergeDebugResources
- 기대 결과:
- 신규 layout과 drawable/string resource가 resource merge를 통과한다.
- 생성:
-
Task 3.2: 글 입력 Activity 구현
- 생성:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteActivity.kt
- 수정:
app/src/main/AndroidManifest.xmlapp/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt
- 작업:
newIntent(context, creatorId)를 제공한다.- 진입 시
creatorId가 없으면finish()한다. EditText에 focus를 주고 keyboard를 표시한다.- text change를 ViewModel에 전달한다.
- 보내기 버튼 enabled/loading 상태를 ViewModel state로 반영한다.
- 등록 성공 event 수신 시
setResult(RESULT_OK)후finish()한다.
- 검증 명령:
./gradlew :app:compileDebugKotlin
- 기대 결과:
- 신규 Activity, manifest, DI 구성이 컴파일된다.
- 생성:
-
Task 3.3: 취소 popup과 back 동작 구현
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteActivity.ktapp/src/main/res/values/strings.xmlapp/src/main/res/values-en/strings.xmlapp/src/main/res/values-ja/strings.xml
- 작업:
- 입력값이 없으면 좌측 상단
취소버튼 터치 시 즉시 종료한다. - 입력값이 있으면 좌측 상단
취소버튼 터치 시 Figma308:19046기준SodaDialog를 표시한다. - popup title은
입력 종료로 추가한다. - popup desc는
입력을 종료할까요?\n지금 나가면 입력한 내용이 저장되지 않아요.로 추가한다. - popup cancel button label은
계속 작성으로 추가한다. - popup confirm button label은
종료로 추가한다. - popup 종료 확정 시
RESULT_OK를 설정하지 않고finish()한다. - popup 유지 선택 시 dialog만 닫는다.
- Android back 동작도 좌측 상단
취소버튼과 동일한 입력값 기준을 따른다. - 입력값이 있으면 Android back 실행 시 입력 종료 popup을 표시한다.
- 입력값이 없으면 Android back 실행 시 popup 없이 현재 화면을 종료한다.
- 입력값이 없으면 좌측 상단
- 검증 명령:
./gradlew :app:mergeDebugResources./gradlew :app:compileDebugKotlin
- 기대 결과:
- 취소 popup 문자열, 좌측 상단
취소버튼 조건, Android back popup 조건이 resource merge 및 Kotlin compile을 통과한다.
- 취소 popup 문자열, 좌측 상단
- 수정:
Phase 4: FanTalk 탭 진입점 연결과 fixed plus button 수정
-
Task 4.1: Fragment Host callback 추가
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragment.ktapp/src/main/res/layout/fragment_creator_channel_fantalk.xml
- 작업:
- Host에
onCreatorChannelFanTalkWriteClicked()를 추가한다. - Host에
onCreatorChannelFanTalkFloatingButtonVisibilityChanged(isVisible: Boolean)를 추가한다. - empty
응원 남기기버튼 click은onCreatorChannelFanTalkWriteClicked()를 호출한다. - content 상태에서는 Activity fixed plus button이 보이도록
true를 전달한다. - loading/empty/error 상태와
onDestroyView()에서는false를 전달한다. - Fragment 내부
btn_creator_channel_fantalk_write는 제거하거나gone으로 고정한다.
- Host에
- 검증 명령:
./gradlew :app:compileDebugKotlin
- 기대 결과:
- Fragment가 직접 floating button을 소유하지 않고 Host에 표시 상태와 진입 action을 위임한다.
- 수정:
-
Task 4.2: Activity fixed plus button 추가
- 수정:
app/src/main/res/layout/activity_creator_channel.xmlapp/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt
- 작업:
- root overlay 우측 하단에 FanTalk fixed plus button을 추가한다.
- button icon은
@drawable/ic_plus_no_bg를 사용한다. - icon tint는
@color/white로 지정한다. - current tab이 FanTalk이고 Fragment가 content 상태 표시를 요청한 경우에만 visible 처리한다.
- bottom inset 또는 기존 bottom margin 정책을 적용해 navigation bar와 겹치지 않게 한다.
- 검증 명령:
./gradlew :app:mergeDebugResources./gradlew :app:compileDebugKotlin
- 기대 결과:
- plus button이 목록 스크롤과 분리된 Activity overlay에 존재하고, icon이 white로 표시되도록 resource가 구성된다.
- 수정:
-
Task 4.3: ActivityResult 기반 글 입력 화면 연결
- 수정:
app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt
- 작업:
CreatorChannelFanTalkWriteActivitylauncher를 추가한다.- FanTalk fixed plus button click과 empty
응원 남기기Host callback에서 동일한openFanTalkWrite()를 호출한다. - 로그인 토큰이 비어 있으면 기존
showLoginActivity()를 호출하고 글 입력 화면을 열지 않는다. - 등록 성공 result 수신 시
refreshCreatorChannelFanTalk()와homeActionDelegate?.refreshHome()를 호출한다.
- 검증 명령:
./gradlew :app:compileDebugKotlin
- 기대 결과:
- 두 진입점 모두 동일한 글 입력 화면으로 이동하고 성공 후 목록/홈 요약 refresh가 연결된다.
- 수정:
Phase 5: Source/단위 테스트와 회귀 검증
-
Task 5.1: fixed plus button/진입점 source test 추가
- 수정:
app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.ktapp/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/CreatorChannelFanTalkFragmentLayoutTest.kt
- 작업:
activity_creator_channel.xml에 FanTalk fixed plus button과@drawable/ic_plus_no_bg,@color/whitetint가 있는지 확인한다.- FanTalk fixed plus button이
activity_creator_channel.xmlroot overlay에 있고fragment_creator_channel_fantalk.xml의 RecyclerView/content height에 묶이지 않는지 확인한다. fragment_creator_channel_fantalk.xml의 empty응원 남기기버튼은 유지되고 Fragment 내부 floating button은 사용되지 않는지 확인한다.CreatorChannelActivity에 ActivityResult launcher와 등록 성공 refresh 호출이 있는지 확인한다.CreatorChannelFanTalkFragment.Host에 글쓰기 click/visibility callback이 있는지 확인한다.
- 검증 명령:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*FanTalk*"
- 기대 결과:
- Activity overlay fixed plus button과 글 입력 진입점 연결 source test가 PASS한다.
- 수정:
-
Task 5.2: 글 입력 Activity source test 추가
- 생성:
app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteSourceTest.kt
- 작업:
CreatorChannelFanTalkWriteActivity가newIntent(context, creatorId)를 제공하는지 확인한다.- 좌측 상단
취소버튼은 입력값이 있을 때 popup을 표시하고, 입력값이 없을 때 즉시 종료하는 경로가 있는지 확인한다. - Android back 동작도 입력값이 있을 때 popup을 표시하고, 입력값이 없을 때 즉시 종료하는 경로가 있는지 확인한다.
- 입력 종료 popup 문자열 resource가 title
입력 종료, desc입력을 종료할까요?\n지금 나가면 입력한 내용이 저장되지 않아요., cancel계속 작성, confirm종료값을 갖는지 확인한다. - 글 입력 layout에 입력 영역, 좌측 상단
취소, 보내기 버튼이 있고 ViewModel의 enabled/disabled 상태를 반영하는 binding 경로가 있는지 확인한다. - 등록 성공 시
setResult(RESULT_OK)후 종료하는지 확인한다. AndroidManifest.xml에 신규 Activity가 등록되어 있는지 확인한다.
- 검증 명령:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.*"
- 기대 결과:
- 글 입력 Activity의 핵심 연결 계약 source test가 PASS한다.
- 생성:
-
Task 5.3: 전체 검증 실행
- 실행:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.*"./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.*"./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*FanTalk*"./gradlew :app:mergeDebugResources./gradlew :app:compileDebugKotlin./gradlew :app:ktlintCheckgit diff --check
- Figma 기반 자동 확인:
CreatorChannelFanTalkWriteViewModelTest에서 입력값 없음/공백 입력은 보내기 disabled, 입력값 있음은 보내기 enabled임을 확인한다.CreatorChannelFanTalkWriteSourceTest에서 입력 종료 popup 문구가 Figma308:19046확정 문구와 일치하는지 확인한다.CreatorChannelActivitySourceTest에서 fixed plus button이 Activity overlay에 있고ic_plus_no_bg와 white tint를 사용하는지 확인한다.CreatorChannelFanTalkFragmentLayoutTest에서 Fragment 내부 floating button이 스크롤 콘텐츠에 묶인 진입점으로 남아 있지 않은지 확인한다.
- Figma 수동 확인:
- 입력값 없음 + keyboard 있음 화면이 Figma
290:9235의 주요 layout 구조와 버튼 disabled 상태를 반영하는지 확인한다. - 입력값 있음 + keyboard 있음 화면이 Figma
290:9282의 주요 layout 구조와 버튼 enabled 상태를 반영하는지 확인한다. - 입력값 있음 + keyboard 없음 화면이 Figma
290:9290의 주요 layout 구조와 버튼 enabled 상태를 반영하는지 확인한다. - 입력 종료 popup이 Figma
308:19046의 문구와 버튼 구성을 반영하는지 확인한다. - FanTalk 탭 fixed plus button이 스크롤과 관계없이 viewport 우측 하단에 고정되고,
ic_plus_no_bgicon이 white로 보이는지 확인한다.
- 입력값 없음 + keyboard 있음 화면이 Figma
- 기대 결과:
- 모든 명령이 PASS하고, Figma 기반 자동 확인과 Figma 4개 상태 화면 및 fixed plus button 수동 대조 결과가 PASS한다.
- 검증 기록:
- Figma 기반 자동 확인 결과와 수동 대조를 수행한 화면 상태, 기기/해상도, PASS/FAIL 결과를
Verification Log에 누적한다.
- Figma 기반 자동 확인 결과와 수동 대조를 수행한 화면 상태, 기기/해상도, PASS/FAIL 결과를
- 실행:
Phase 6: Figma 290:9290 글 입력 UI 보정
- Task 6.1: title 제거와 하단 글자수 UI 추가
- 수정:
app/src/main/res/layout/activity_creator_channel_fantalk_write.xmlapp/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteActivity.ktapp/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/fantalk/write/CreatorChannelFanTalkWriteViewModel.kt
- 작업:
- Figma
290:9290기준으로tv_creator_channel_fantalk_write_title을 제거한다. - 보내기 버튼 enabled 상태는
soda_400배경과 white 글자색을 사용한다. - 하단 fixed info bar에 현재 글자수와
/500자를 표시한다. - keyboard가 올라오면 info bar가 함께 올라오도록 Activity layout bottom에 고정한다.
- 입력값은 500자를 넘을 수 없게 제한한다.
- Figma
- 검증 명령:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.*"./gradlew :app:mergeDebugResources./gradlew :app:compileDebugKotlin
- 기대 결과:
- title 없는 Figma 구조, 글자수 UI, 500자 제한 계약이 테스트/리소스/컴파일을 통과한다.
- 수정:
Verification Log
-
구현 전 문서 작성 단계에서는 Gradle 검증을 실행하지 않았다.
-
2026-07-08 구현 중 TDD 기록:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.CreatorChannelFanTalkWriteViewModelTest"를 RED 테스트 추가 직후 실행했으나 첫 실행은 120초 제한, 두 번째 실행은 300초 제한에서compileDebugKotlin단계 중 시간 초과되어 실패 출력을 끝까지 확보하지 못했다. 이후 구현 후 동일 계약을 포함한 write 테스트 묶음에서 GREEN을 확인했다. -
2026-07-08 구현 검증:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.*"최초 실행은 테스트 문자열 escape와ApiResponse제네릭 불일치로 실패했고, 수정 후 재실행 결과 PASS했다. 이 테스트에서 입력값 없음/공백 disabled, 입력값 있음 enabled, trim submit, 중복 submit 무시, 성공 finish, 실패 시 입력 유지 및 서버 message toast, popup 문구, 신규 Activity/Manifest 계약을 확인했다. -
2026-07-08 구현 검증:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.*"PASS. FanTalk Fragment layout/source 계약과 기존 FanTalk 단위 테스트 회귀를 확인했다. -
2026-07-08 구현 검증:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*FanTalk*"PASS. Activity overlay fixed plus,ic_plus_no_bg, white tint, ActivityResult refresh, Fragment Host callback source 계약을 확인했다. -
2026-07-08 구현 검증:
./gradlew :app:mergeDebugResourcesPASS. 신규 write layout/drawable/string/manifest resource 병합을 확인했다. -
2026-07-08 구현 검증:
./gradlew :app:compileDebugKotlinPASS. 기존 deprecation/unchecked warning만 출력되었고 신규 컴파일 오류는 없었다. -
2026-07-08 구현 검증:
./gradlew :app:ktlintCheckPASS. 기존.editorconfig의disabled_rulesdeprecation 경고만 출력되었다. -
2026-07-08 구현 검증:
git diff --checkPASS. trailing whitespace 및 patch whitespace 오류가 없음을 확인했다. -
2026-07-08 Figma 계약 대조: 자동 테스트와 소스 확인으로 fixed plus가 Activity root overlay에 있고
ic_plus_no_bg+@color/whitetint를 사용함을 확인했다. write 화면은 입력값 없음/있음에 따른 send disabled/enabled와 입력 종료 popup의 PRD 확정 문구를 테스트로 확인했다. 실제 기기/에뮬레이터 수동 실행은 이번 환경에서 수행하지 못했다. -
2026-07-08 후속 수정: Figma
290:9290대조 결과 상단 title이 없어야 하고 하단현재/500자info bar가 필요함을 확인했다. 실제 기기/에뮬레이터 수동 실행은 환경 제약으로 별도 수행이 필요하다. -
2026-07-08 후속 수정 검증: write 테스트 첫 실행은 source test 문자열 escape 오류로
compileDebugUnitTestKotlin단계에서 실패했다. escape와 enabled 색상 계약을 수정 후 재검증한다. -
2026-07-08 후속 수정 검증:
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.fantalk.write.*"PASS. title 제거, 하단 글자수 UI, 500자 제한, enabled 버튼soda_400배경/white 글자색 계약을 테스트로 확인했다. -
2026-07-08 후속 수정 검증:
./gradlew :app:mergeDebugResourcesPASS,./gradlew :app:compileDebugKotlinPASS,git diff --checkPASS.