7.8 KiB
채팅 다중행 입력 구현 계획
| 항목 | 내용 |
|---|---|
| 상태 | 구현·하네스 검증 완료 / 실제 DM 통합 QA 대기 |
| 기준 | prd.md, INPUT-001~005 |
| 현재 Phase / Goal | Phase 1 / 실행 중 Goal 없음, P1-GATE 실제 DM 확인 대기 |
| 완료 Task | 1/1 |
목표와 범위
기존 DM 입력창에서 1~3줄을 표시하고 초과 내용은 내부 스크롤로 확인한다. 현재 main에서 작업한다. 네트워크·ViewModel·날짜 목록·AI 채팅·공용 입력창은 변경하지 않는다.
Phase 1
결과: 다중행 입력과 기존 전송 동작을 함께 사용할 수 있다. 선행조건: 사용자 구현 승인 완료.
Task 1.1 입력창의 native 다중행 설정
Goal P1-T1: native TextField의 줄 수·Return 동작과 주변 정렬만 변경한다.
-
Files Modify:
SodaLive/Sources/V2/Main/Chat/UserCreatorChat/UserCreatorChatRoomView.swift. -
Files Reference:
SodaLive/Sources/V2/CreatorChannel/Community/Detail/Components/CreatorChannelCommunityPostDetailInputBar.swift. -
Interfaces: 기존
messageText: String,isInputEnabled,isSendEnabled,sendText()유지. 신규 public 타입·함수 없음. -
완료 증거: 이전 단일 행 기준과 이후 native UI 동작 비교, 빌드 및 날짜 회귀, 범위 한정 코드·시각 리뷰.
-
테스트 방침: 변경은 native UI 설정으로 신규 비즈니스 로직이 없다. 소스 문자열을 검사하는 가짜 테스트나 새 테스트 타깃을 추가하지 않는다. 기존 날짜 checker는 회귀로 실행한다.
-
RED: 변경 전 실제 inputBarView를 사용하는 임시 native 하네스에서 긴 입력이 한 줄로 표시되는 기준을 캡처했다.
-
RED 확인: 기준 UI에서 1→3줄 자동 확장이 없음을 확인했다. 이를 UI 수용 실패 재현으로 기록하며 Foundation unit-test 실패라고 표기하지 않는다.
-
GREEN:
axis: .vertical,.lineLimit(1...3),.onSubmit자동 전송 제거, 전송 버튼 하단 정렬을 적용했다. 모서리는 기존 고정 반경20 패턴을 사용했다. -
GREEN 확인: 같은 source-derived native 하네스에서 1/2/3/4+줄 높이·내부 스크롤·본문 보존·삭제 후 축소·Return을 확인했다. 실제로 조작한 범위와 합성 전송 sink를 명시했다.
-
REFACTOR: 추가 추상화 없이 수정 범위가 inputBarView에 한정되는지 확인하고 기존 검사·컴파일을 실행했다.
Phase 1 Gate
Goal P1-GATE: 코드·빌드·native 시나리오 증거를 대조한다. TDD 예외 사유: Gate는 검증·문서 기록 작업이며 새 기능 로직을 작성하지 않는다. 대체 검증: native 입력 control 조작 로그·캡처, 기존 standalone 검사, 두 타깃 컴파일.
sh work/tests/check-user-creator-chat-date-presentation.sh
plutil -lint SodaLive.xcodeproj/project.pbxproj
xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug CODE_SIGNING_ALLOWED=NO build
xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug CODE_SIGNING_ALLOWED=NO build
Expected: 검사·빌드 exit0, 날짜113 assertions 유지. 기존 경고는 분리하고 새 오류만 수정한다. 현재 환경에서 LSP 도구가 없으면 그 사실을 남기며 빌드 통과로 LSP 수행을 대신 주장하지 않는다.
- 입력 1/2/3줄의 높이 증가와 4줄 이상 동일 높이·내용 overflow를 native 측정값으로 확인했다.
- native contentOffset 조작으로 입력창 내부 위/아래 내용을 확인하고 전체 텍스트 보존을 확인했다. 실제 터치 제스처 검증은 아니다.
- native Return 줄바꿈, 긴 텍스트/한글, 삭제 후 축소, 빈 입력·비연결 전송 가드·전송 action 초기화를 확인했다. 비연결 GUI 편집 차단은 기존 disabled modifier 보존만 확인했다.
- 375pt 폭과 light/dark 표본에서 입력·전송 버튼이 잘리거나 겹치지 않음을 독립 시각 검토자가 확인했다.
- 코드/시각 리뷰 결과를
reviews/phase1-multiline-input.md에 기록했다. - 실제 DM에서 터치 스크롤·전송 버튼 탭, 소프트웨어 키보드·IME·클립보드·대화 목록 연동 및 서버 줄바꿈 저장·재조회를 확인한다. 테스트 계정·roomId가 없는 환경에서는 미완료로 유지한다.
실제 서버 전송/저장 검증이 불가능하면 계정·roomId를 필요한 조건으로 기록한다. native 하네스에는 실제 source의 입력 UI를 사용하며 제품 코드에 테스트 전용 route/mock/상태를 추가하지 않는다. 하네스·컴파일 캐시·시뮬레이터는 작업 소유 자원만 정리한다.
실행 순서
P1-T1 → P1-GATE. source/인터페이스가 하나여서 구현 병렬 분할은 하지 않는다. 검증과 읽기 전용 검토만 독립적으로 병행할 수 있다.
Progress
- 사용자 승인 및 현재 main clean 확인. 기존 입력은 단일 행, Return 전송 연결임을 읽어 확인했다. PRD·계획 샘플 확인 후 본 문서를 작성했다. 아직 제품 코드 변경·실행 검증 전이다.
- 후속 구현: inputBarView에 세로 TextField, 1...3줄 제한, Return 자동 전송 제거, HStack 하단 정렬 및 고정 모서리20을 적용했다. 변경은 해당 입력 UI 안의 기존 코드에 한정한다.
- 최종 두 타깃 컴파일:
xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination 'generic/platform=iOS' CODE_SIGNING_ALLOWED=NO build와 SodaLive-dev 동일 명령이 모두 exit0. 전후 RoomView SHA-256 일치로 빌드 중 소스 변경이 없음을 확인했다. 기존 프로젝트 관리 DerivedData를 재사용했으며 공유 캐시는 제거하지 않는다. - 기존 회귀: work/tests의12개 스크립트, 지원 모드 포함19회 모두 exit0, 날짜113 assertions 포함. 새 비즈니스 로직이나 제품 테스트 타깃은 추가하지 않았다. native 입력 동작 검증과 독립 리뷰는 수집 중이다.
- native 후속 결과: 기준1~8줄 높이18.5pt, 변경 후17/34/50/50/50pt. 8줄 내부 offset0→84pt,content134pt,전체본문 유지. 실제 source블록을 추출한 하네스의 UIKeyInput Return·삭제, 원본 sendText+합성sink의 trim/초기화/가드 확인. 부모가 verify.py를 재실행해66 checks(동작·소스22,PNG44) exit0을 확인했다.
- 독립 리뷰: 코드·기능 APPROVE, 최종after22장과 기준3장 직접 확인한 시각 PASS. 필수 수정 없음. source4줄추가4줄삭제를 현재main에서
14b415e로 커밋하고 사전 subject검사 및 커밋 후 저장소 검사스크립트 통과. 이 스크립트에는 --message 지원이 없어 한글conventional형식·길이 사전검사는 별도로 수행했다. - 한계: 실제 터치·IME·클립보드·버튼탭·서버·전체채팅방흐름은 미검증. LSP도구도 제공되지 않아 컴파일/빌드와 구분해 미실행을 기록했다. 증거를 보존하고 작업 소유 임시자원만 정리한다.
- 정리 완료: native검증자의 simulator 삭제·프로세스 종료 영수증을 부모가 빈 device목록/프로세스 부재로 재확인했다. 캡처44장·matrix·provenance·검증JSON·대표픽셀비교를 보존하고 작업 임시루트·메모를 제거했다. 현재main을 유지하며 공유빌드캐시는 삭제하지 않았다.
Decision Log
- 조사된 native control 설정을 그대로 사용하며 새 dependency·UIKit wrapper·공용 컴포넌트를 만들지 않는다.
- 실제 입력 UI의 기존 테스트 타깃이 없으므로 native 전후 동작 확인으로 UI RED/GREEN을 기록한다. 서버 통합은 별도 판정한다.
- 리뷰에서 확정한 수정 항목은 코드 수정 전에 이 Phase에 신규 Task로 등록한다.