docs(chat): 다중행 입력 요구사항과 검증을 기록한다
@@ -0,0 +1,78 @@
|
|||||||
|
# 채팅 다중행 입력 구현 계획
|
||||||
|
|
||||||
|
| 항목 | 내용 |
|
||||||
|
|---|---|
|
||||||
|
| 상태 | 구현·하네스 검증 완료 / 실제 DM 통합 QA 대기 |
|
||||||
|
| 기준 | [prd.md](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는 회귀로 실행한다.
|
||||||
|
|
||||||
|
- [x] **RED:** 변경 전 실제 inputBarView를 사용하는 임시 native 하네스에서 긴 입력이 한 줄로 표시되는 기준을 캡처했다.
|
||||||
|
- [x] **RED 확인:** 기준 UI에서 1→3줄 자동 확장이 없음을 확인했다. 이를 UI 수용 실패 재현으로 기록하며 Foundation unit-test 실패라고 표기하지 않는다.
|
||||||
|
- [x] **GREEN:** `axis: .vertical`, `.lineLimit(1...3)`, `.onSubmit` 자동 전송 제거, 전송 버튼 하단 정렬을 적용했다. 모서리는 기존 고정 반경20 패턴을 사용했다.
|
||||||
|
- [x] **GREEN 확인:** 같은 source-derived native 하네스에서 1/2/3/4+줄 높이·내부 스크롤·본문 보존·삭제 후 축소·Return을 확인했다. 실제로 조작한 범위와 합성 전송 sink를 명시했다.
|
||||||
|
- [x] **REFACTOR:** 추가 추상화 없이 수정 범위가 inputBarView에 한정되는지 확인하고 기존 검사·컴파일을 실행했다.
|
||||||
|
|
||||||
|
### Phase 1 Gate
|
||||||
|
|
||||||
|
**Goal P1-GATE:** 코드·빌드·native 시나리오 증거를 대조한다.
|
||||||
|
**TDD 예외 사유:** Gate는 검증·문서 기록 작업이며 새 기능 로직을 작성하지 않는다.
|
||||||
|
**대체 검증:** native 입력 control 조작 로그·캡처, 기존 standalone 검사, 두 타깃 컴파일.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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 수행을 대신 주장하지 않는다.
|
||||||
|
|
||||||
|
- [x] 입력 1/2/3줄의 높이 증가와 4줄 이상 동일 높이·내용 overflow를 native 측정값으로 확인했다.
|
||||||
|
- [x] native contentOffset 조작으로 입력창 내부 위/아래 내용을 확인하고 전체 텍스트 보존을 확인했다. 실제 터치 제스처 검증은 아니다.
|
||||||
|
- [x] native Return 줄바꿈, 긴 텍스트/한글, 삭제 후 축소, 빈 입력·비연결 전송 가드·전송 action 초기화를 확인했다. 비연결 GUI 편집 차단은 기존 disabled modifier 보존만 확인했다.
|
||||||
|
- [x] 375pt 폭과 light/dark 표본에서 입력·전송 버튼이 잘리거나 겹치지 않음을 독립 시각 검토자가 확인했다.
|
||||||
|
- [x] 코드/시각 리뷰 결과를 `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도구도 제공되지 않아 컴파일/빌드와 구분해 미실행을 기록했다. [증거](reviews/evidence/README.md)를 보존하고 작업 소유 임시자원만 정리한다.
|
||||||
|
- 정리 완료: native검증자의 simulator 삭제·프로세스 종료 영수증을 부모가 빈 device목록/프로세스 부재로 재확인했다. 캡처44장·matrix·provenance·검증JSON·대표픽셀비교를 보존하고 작업 임시루트·메모를 제거했다. 현재main을 유지하며 공유빌드캐시는 삭제하지 않았다.
|
||||||
|
|
||||||
|
## Decision Log
|
||||||
|
|
||||||
|
- 조사된 native control 설정을 그대로 사용하며 새 dependency·UIKit wrapper·공용 컴포넌트를 만들지 않는다.
|
||||||
|
- 실제 입력 UI의 기존 테스트 타깃이 없으므로 native 전후 동작 확인으로 UI RED/GREEN을 기록한다. 서버 통합은 별도 판정한다.
|
||||||
|
- 리뷰에서 확정한 수정 항목은 코드 수정 전에 이 Phase에 신규 Task로 등록한다.
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# 유저-크리에이터 채팅 다중행 입력 PRD
|
||||||
|
|
||||||
|
## 문서 정보
|
||||||
|
|
||||||
|
| 항목 | 내용 |
|
||||||
|
|---|---|
|
||||||
|
| 상태 | 구현·네이티브 하네스 검증 완료 / 실제 DM 통합 QA 미실행 |
|
||||||
|
| 작성일 | 2026-10-16 |
|
||||||
|
| 대상 | iOS 유저-크리에이터 DM 입력창 |
|
||||||
|
| 결정권자 | 사용자, 조사 결과에 대한 `진행하자` 승인 |
|
||||||
|
| 계획 | [plan-task.md](plan-task.md) |
|
||||||
|
| 리뷰 | [phase1-multiline-input.md](reviews/phase1-multiline-input.md) |
|
||||||
|
| API 계약 | 기존 SEND_TEXT/textMessage 문자열 유지, 별도 변경 없음 |
|
||||||
|
|
||||||
|
## 1. 개요와 문제
|
||||||
|
|
||||||
|
현재 DM 입력창은 단일 행 TextField라 긴 메시지를 작성하며 앞뒤 문맥을 확인하기 어렵다. 입력창은 한 줄에서 시작해 최대 세 줄까지 확장되고, 그 이상은 입력창 안에서 스크롤해 확인할 수 있어야 한다.
|
||||||
|
|
||||||
|
## 2. 목표와 제외 범위
|
||||||
|
|
||||||
|
- 목표: 내용 손실 없이 최대 세 줄 표시, 초과 내용 스크롤, Return 줄바꿈, 기존 전송 버튼 사용.
|
||||||
|
- 제외: AI 채팅·커뮤니티 입력 변경, 글자 수 제한 추가, ViewModel/서버/DTO 변경, 새로운 공용 컴포넌트나 UIKit 래퍼, 날짜 구분선 변경.
|
||||||
|
- 현재 브랜치 `main`을 유지한다. 별도 브랜치·worktree·원격 push는 만들지 않는다.
|
||||||
|
|
||||||
|
## 3. 사용자 흐름과 요구사항
|
||||||
|
|
||||||
|
| ID | 상태 | 요구사항 | 수용 기준 | 연결 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| INPUT-001 | 확정 | 입력 내용에 따라 1~3줄 높이로 자동 확장 | 1/2/3줄에서 높이가 증가하고 4줄 이상은 더 커지지 않음 | P1-T1 |
|
||||||
|
| INPUT-002 | 확정 | 세 줄 초과 내용은 내부 세로 스크롤 | 긴 내용이 잘리거나 전송 데이터에서 제거되지 않고 앞뒤 확인 가능 | P1-T1 |
|
||||||
|
| INPUT-003 | 확정 | Return은 줄바꿈, 전송은 기존 버튼 | Return으로 자동 전송하지 않으며 버튼 전송 후 입력이 비워짐 | P1-T1 |
|
||||||
|
| INPUT-004 | 확정 | 기존 전송 가드와 문자열 처리를 유지 | 미연결 상태 입력 금지, 공백·줄바꿈만 있는 메시지 전송 금지, 본문 중간 줄바꿈 보존 | P1-T1 |
|
||||||
|
| INPUT-005 | 확정 | 다중행에 맞춘 전송 버튼 하단 정렬 | 1~3줄 변화 시 버튼이 입력 영역 하단에 정렬되고 모서리가 글자를 가리지 않음 | P1-T1, P1-GATE |
|
||||||
|
|
||||||
|
## 4. 기술·UX 제약
|
||||||
|
|
||||||
|
- 대상: `SodaLive/Sources/V2/Main/Chat/UserCreatorChat/UserCreatorChatRoomView.swift`의 inputBarView.
|
||||||
|
- 기존 커뮤니티 입력 패턴처럼 `TextField(..., axis: .vertical).lineLimit(1...3)` 사용. 최소 iOS16.6에서 지원되는 iOS16 API다.
|
||||||
|
- 별도 ScrollView, 문자 수 기준 높이 계산 또는 TextEditor로 교체하지 않는다. 스크롤 인디케이터는 시스템 동작을 사용하며 항상 표시되는 커스텀 바는 추가하지 않는다.
|
||||||
|
- 전송 전 양끝 공백·줄바꿈 제거, 전송 시 키보드 닫기와 입력 비우기는 변경하지 않는다.
|
||||||
|
- 기존 색상·14pt 글꼴·간격을 유지한다. 모서리는 다중행 글자 보호를 위해 필요하면 기존 커뮤니티의 고정 rounded-rectangle 반경20 패턴을 적용한다(구현 판단).
|
||||||
|
- 입력 높이 증가에 따른 대화 영역 축소는 기존 VStack 배치를 따르며, 메시지 목록 스크롤 정책을 새로 설계하지 않는다.
|
||||||
|
|
||||||
|
## 5. 성공 기준
|
||||||
|
|
||||||
|
- [x] 한 줄에서 세 줄까지 확장, 초과 내용 내부 스크롤을 네이티브 UI로 확인했다. 내부 스크롤은 native contentOffset 조작으로 검증했다.
|
||||||
|
- [ ] 실제 키보드/IME·클립보드 붙여넣기 및 터치 기반 전송·스크롤을 실제 DM에서 확인한다. native Return·삭제·비우기와 긴 문자열 상태 주입은 하네스에서 통과했다.
|
||||||
|
- [x] 기존 전송 버튼의 action과 입력 가능 조건을 보존하고 빌드·회귀 검사가 통과했다. 실제 전송 버튼 탭 검증과 구별한다.
|
||||||
|
- [x] 네이티브 하네스 검증과 실제 로그인 DM 검증의 범위를 구분해 기록했다.
|
||||||
|
|
||||||
|
## 6. 열린 질문과 외부 조건
|
||||||
|
|
||||||
|
제품 결정의 열린 질문은 없다. 서버의 줄바꿈 저장·재조회 보존 및 실제 채팅방에서의 키보드/목록 상호작용은 승인된 테스트 계정·roomId가 필요한 외부 검증이다. 클라이언트 JSON 인코딩만으로 서버 통과를 주장하지 않는다.
|
||||||
|
|
||||||
|
## 7. Decision Log
|
||||||
|
|
||||||
|
| ID | 결정 | 근거 |
|
||||||
|
|---|---|---|
|
||||||
|
| DEC-001 | 조사 단계는 읽기 전용, 후속 `진행하자`부터 구현 | 사용자 승인 전 구현 금지 및 후속 승인 |
|
||||||
|
| DEC-002 | 1~3줄·내부 스크롤·Return 줄바꿈·버튼 전송·하단 정렬 | 직전 조사 제안에 대한 사용자 승인 |
|
||||||
|
| DEC-003 | 현재 main 유지, 제품 소스 한 파일의 최소 변경 | 사용자 현재 브랜치 작업 지시 및 기존 native 패턴 |
|
||||||
|
|
||||||
|
## 8. 구현·검증 기록
|
||||||
|
|
||||||
|
- 제품 변경: inputBarView4줄 추가/4줄 삭제, commit `14b415e`. 서버·ViewModel·날짜 목록·전송 handler는 변경하지 않았다.
|
||||||
|
- 입력 높이1/2/3/4/8줄:17/34/50/50/50pt. 8줄 content134pt, 내부 offset0→84pt에서 전체 문자열 보존. Return은 줄바꿈만 넣고 삭제·초기화 후17pt로 축소됐다.
|
||||||
|
- 최종 두 타깃 빌드와 기존12개 검사 스크립트/19회 실행 통과. 별도 신규 비즈니스 로직 테스트를 만들지 않았으며 native 동작·소스22검사 + PNG44검사로 증거를 검증했다.
|
||||||
|
- 독립 코드 APPROVE, 최종 입력 캡처22장 시각 PASS. 실제 DM·서버·IME·터치·키보드/목록 연동 검증으로 확대하지 않는다.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# 다중행 입력 native 증거
|
||||||
|
|
||||||
|
기준 소스 commit은 `b0cabf9`다. before/after의 입력창·입력/전송 가드·sendText 블록은 실제 `UserCreatorChatRoomView.swift`에서 그대로 추출했다. provenance.json의 SHA-256 및 추출본으로 확인한다. 주변 VStack, 연결 상태, 전송 sink, 일부 컴파일용 문자열은 임시 하네스이며 제품 코드에 추가하지 않았다.
|
||||||
|
|
||||||
|
- 환경: iPhone SE3, iOS18.3.1, 375pt 폭 / 750×1334px PNG.
|
||||||
|
- before/after 각각22장, 총44장. 시스템 권한 팝업이나 실제 사용자 데이터 없이 `simctl io screenshot`으로 촬영했다.
|
||||||
|
- after/matrix.json: 실제 native 편집기 bounds/contentSize/contentOffset, binding/native 문자열, 전송 sink 상태. before/matrix.json은 기존 단일행 기준이다.
|
||||||
|
- verification.json: 동작·소스22개 검사와 PNG형식·크기44개 검사, 합계66개다. 비즈니스 테스트66개라는 뜻이 아니다.
|
||||||
|
- cleanup.json: 작업 소유 시뮬레이터 삭제와 하네스 프로세스 종료 영수증.
|
||||||
|
|
||||||
|
| 입력 줄 | before 높이 | after 높이 | after 내용 높이 |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| 1 | 18.5 | 17 | 17 |
|
||||||
|
| 2 | 18.5 | 34 | 34 |
|
||||||
|
| 3 | 18.5 | 50 | 51 |
|
||||||
|
| 4 | 18.5 | 50 | 67 |
|
||||||
|
| 8 | 18.5 | 50 | 134 |
|
||||||
|
|
||||||
|
8줄 입력의 내부 offset은0→84pt로 이동하며 전체 문자열은 보존된다. Return은 native UIKeyInput으로 삽입했고, 전송 확인은 원본 sendText를 합성 sink에 직접 호출했다. 삭제·비우기·전송 후17pt로 축소된다.
|
||||||
|
|
||||||
|
**미검증:** 실제 터치 스크롤, 소프트웨어 키보드·한글 IME, 클립보드 붙여넣기, 전송 버튼 탭, 비활성 상태의 GUI 입력 차단, 서버 저장·재조회, 전체 채팅방의 키보드/목록 연동. 상태 주입을 실제 붙여넣기라고 주장하지 않으며 native isEditable 값만으로 GUI 차단을 판정하지 않는다.
|
||||||
|
|
||||||
|
독립 코드 검토 APPROVE, 최종22장 시각 검토 PASS. 캡처는 입력창 하네스 범위만 증명한다. 자세한 결과는 [리뷰 리포트](../phase1-multiline-input.md)를 따른다.
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
private var inputBarView: some View {
|
||||||
|
HStack(alignment: .bottom, spacing: SodaSpacing.s8) {
|
||||||
|
ZStack(alignment: .leading) {
|
||||||
|
if messageText.isEmpty {
|
||||||
|
Text(I18n.UserCreatorChat.messagePlaceholder)
|
||||||
|
.appFont(size: 14, weight: .regular)
|
||||||
|
.foregroundColor(Color.gray500)
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField("", text: $messageText, axis: .vertical)
|
||||||
|
.appFont(size: 14, weight: .regular)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.accentColor(Color.soda400)
|
||||||
|
.lineLimit(1...3)
|
||||||
|
.disabled(isInputEnabled == false)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s16)
|
||||||
|
.padding(.vertical, SodaSpacing.s12)
|
||||||
|
.background(Color.gray900)
|
||||||
|
.cornerRadius(20)
|
||||||
|
|
||||||
|
Button(action: sendText) {
|
||||||
|
Image("ic_message_send")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 24, height: 24)
|
||||||
|
.opacity(isSendEnabled ? 1 : 0.4)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
.disabled(isSendEnabled == false)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s12)
|
||||||
|
.padding(.vertical, SodaSpacing.s12)
|
||||||
|
.frame(width: screenSize().width)
|
||||||
|
.background(Color.black)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isInputEnabled: Bool {
|
||||||
|
viewModel.socketState == .joined
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isSendEnabled: Bool {
|
||||||
|
isInputEnabled && messageText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func sendText() {
|
||||||
|
let trimmedText = messageText.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard isInputEnabled, trimmedText.isEmpty == false else { return }
|
||||||
|
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
|
||||||
|
viewModel.sendText(trimmedText)
|
||||||
|
messageText = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# 변경 후
|
||||||
|
|
||||||
|
원본 inputBarView에 승인된 최소 수정이 적용된 캡처·측정값이다. 각 프레임의 상태는 matrix.json의 id와 대응한다. overflow-top/bottom은 동일 문자열의 native 편집기 내부 스크롤 전후다.
|
||||||
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 61 KiB |
@@ -0,0 +1,852 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-empty",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-1-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 609
|
||||||
|
},
|
||||||
|
"id": "after-2-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 51,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-3-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 67,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-4-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 134,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-8-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "top",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 134,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-overflow-top",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "bottom",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 84
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 134,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-overflow-bottom",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. ",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 34
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 301,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. ",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-wrapping",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-clear",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "첫째 줄",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-return-seed",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "insert",
|
||||||
|
"bounds": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄\n",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "첫째 줄\n",
|
||||||
|
"firstResponder": true,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 609
|
||||||
|
},
|
||||||
|
"id": "after-return",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "insert",
|
||||||
|
"bounds": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄\n둘째 줄",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "첫째 줄\n둘째 줄",
|
||||||
|
"firstResponder": true,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 34,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 609
|
||||||
|
},
|
||||||
|
"id": "after-return-followup",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "deleteAll",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": true,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-delete-all",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": " 첫째 줄\n둘째 줄\n셋째 줄 ",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 51,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": " 첫째 줄\n둘째 줄\n셋째 줄 ",
|
||||||
|
"firstResponder": true,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-send-seed",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-send",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": " \n \n ",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 51,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": " \n \n ",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-whitespace",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": " \n \n ",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 51,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": " \n \n ",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-whitespace-send",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "연결 전 입력",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "연결 전 입력",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-disabled",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"bounds": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "연결 전 입력",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "연결 전 입력",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 17,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 626
|
||||||
|
},
|
||||||
|
"id": "after-disabled-send",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄 끝글자\n둘째 줄 끝글자\n셋째 줄 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 51,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "첫째 줄 끝글자\n둘째 줄 끝글자\n셋째 줄 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-light-3-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄 끝글자\n둘째 줄 끝글자\n셋째 줄 끝글자",
|
||||||
|
"contentOffset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"contentSize": {
|
||||||
|
"height": 51,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"editorClass": "VerticalTextView",
|
||||||
|
"editorText": "첫째 줄 끝글자\n둘째 줄 끝글자\n셋째 줄 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 50,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 593
|
||||||
|
},
|
||||||
|
"id": "after-dark-3-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 65240,
|
||||||
|
"scrollEnabled": true,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
],
|
||||||
|
"textContainerInset": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"source": "/Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/UserCreatorChatRoomView.swift",
|
||||||
|
"sha256": "ff5e753384a56969cf7137d73f9a6b2ddb8909e5ef94106009849a1414d64dcd",
|
||||||
|
"extractedSha256": "4dc54374643fb83bc71cb3a4b6033af717a476851fdf9f7b083b237c4ae1c79b",
|
||||||
|
"verbatimBlocks": [
|
||||||
|
"inputBarView",
|
||||||
|
"isInputEnabled",
|
||||||
|
"isSendEnabled",
|
||||||
|
"sendText"
|
||||||
|
],
|
||||||
|
"synthetic": [
|
||||||
|
"Sink viewModel/socketState",
|
||||||
|
"I18n Korean placeholder constant from source",
|
||||||
|
"LanguageOption enum shim",
|
||||||
|
"screenSize method copied from source",
|
||||||
|
"outer harness VStack/control bridge"
|
||||||
|
],
|
||||||
|
"unchangedHelpers": [
|
||||||
|
"FontModifier.swift",
|
||||||
|
"Font.swift",
|
||||||
|
"Color.swift",
|
||||||
|
"ColorExtension.swift",
|
||||||
|
"Spacing.swift"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
private var inputBarView: some View {
|
||||||
|
HStack(spacing: SodaSpacing.s8) {
|
||||||
|
ZStack(alignment: .leading) {
|
||||||
|
if messageText.isEmpty {
|
||||||
|
Text(I18n.UserCreatorChat.messagePlaceholder)
|
||||||
|
.appFont(size: 14, weight: .regular)
|
||||||
|
.foregroundColor(Color.gray500)
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField("", text: $messageText)
|
||||||
|
.appFont(size: 14, weight: .regular)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.accentColor(Color.soda400)
|
||||||
|
.disabled(isInputEnabled == false)
|
||||||
|
.onSubmit { sendText() }
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s16)
|
||||||
|
.padding(.vertical, SodaSpacing.s12)
|
||||||
|
.background(Color.gray900)
|
||||||
|
.cornerRadius(999)
|
||||||
|
|
||||||
|
Button(action: sendText) {
|
||||||
|
Image("ic_message_send")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 24, height: 24)
|
||||||
|
.opacity(isSendEnabled ? 1 : 0.4)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
.disabled(isSendEnabled == false)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s12)
|
||||||
|
.padding(.vertical, SodaSpacing.s12)
|
||||||
|
.frame(width: screenSize().width)
|
||||||
|
.background(Color.black)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isInputEnabled: Bool {
|
||||||
|
viewModel.socketState == .joined
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isSendEnabled: Bool {
|
||||||
|
isInputEnabled && messageText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func sendText() {
|
||||||
|
let trimmedText = messageText.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard isInputEnabled, trimmedText.isEmpty == false else { return }
|
||||||
|
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
|
||||||
|
viewModel.sendText(trimmedText)
|
||||||
|
messageText = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# 변경 전
|
||||||
|
|
||||||
|
원본 단일 행 inputBarView의 기준 캡처·측정값이다. Return이 전송으로 연결되고 여러 줄 내용도 한 줄 높이에 표시되는 상태를 기록한다.
|
||||||
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 50 KiB |
@@ -0,0 +1,581 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-empty",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-1-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자 2번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-2-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자 2번째 메시지 내용 끝글자 3번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-3-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자 2번째 메시지 내용 끝글자 3번째 메시지 내용 끝글자 4번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-4-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자 2번째 메시지 내용 끝글자 3번째 메시지 내용 끝글자 4번째 메시지 내용 끝글자 5번째 메시지 내용 끝글자 6번째 메시지 내용 끝글자 7번째 메시지 내용 끝글자 8번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-8-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "top",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자 2번째 메시지 내용 끝글자 3번째 메시지 내용 끝글자 4번째 메시지 내용 끝글자 5번째 메시지 내용 끝글자 6번째 메시지 내용 끝글자 7번째 메시지 내용 끝글자 8번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-overflow-top",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "bottom",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "1번째 메시지 내용 끝글자\n2번째 메시지 내용 끝글자\n3번째 메시지 내용 끝글자\n4번째 메시지 내용 끝글자\n5번째 메시지 내용 끝글자\n6번째 메시지 내용 끝글자\n7번째 메시지 내용 끝글자\n8번째 메시지 내용 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "1번째 메시지 내용 끝글자 2번째 메시지 내용 끝글자 3번째 메시지 내용 끝글자 4번째 메시지 내용 끝글자 5번째 메시지 내용 끝글자 6번째 메시지 내용 끝글자 7번째 메시지 내용 끝글자 8번째 메시지 내용 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-overflow-bottom",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. ",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. 안녕하세요 긴 메시지를 작성하면서 앞뒤 내용을 확인합니다. 마지막 글자까지 모두 보존되어야 합니다. ",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-wrapping",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-clear",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "첫째 줄",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-return-seed",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "insert",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-return",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "insert",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "둘째 줄",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "둘째 줄",
|
||||||
|
"firstResponder": true,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-return-followup",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "deleteAll",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": true,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-delete-all",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": " 첫째 줄\n둘째 줄\n셋째 줄 ",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": " 첫째 줄 둘째 줄 셋째 줄 ",
|
||||||
|
"firstResponder": true,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-send-seed",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-send",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄",
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": " \n \n ",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": " ",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-whitespace",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄",
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": " \n \n ",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": " ",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-whitespace-send",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄",
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "연결 전 입력",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "연결 전 입력",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-disabled",
|
||||||
|
"inputEnabled": false,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄",
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "send",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "연결 전 입력",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "연결 전 입력",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-disabled-send",
|
||||||
|
"inputEnabled": false,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": false,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄",
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄 끝글자\n둘째 줄 끝글자\n셋째 줄 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "첫째 줄 끝글자 둘째 줄 끝글자 셋째 줄 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-light-3-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄",
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "set",
|
||||||
|
"bounds": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287
|
||||||
|
},
|
||||||
|
"boundText": "첫째 줄 끝글자\n둘째 줄 끝글자\n셋째 줄 끝글자",
|
||||||
|
"editorClass": "UITextField",
|
||||||
|
"editorText": "첫째 줄 끝글자 둘째 줄 끝글자 셋째 줄 끝글자",
|
||||||
|
"firstResponder": false,
|
||||||
|
"font": "Pretendard-Regular",
|
||||||
|
"fontLineHeight": 16.70703125,
|
||||||
|
"frame": {
|
||||||
|
"height": 18.5,
|
||||||
|
"width": 287,
|
||||||
|
"x": 28,
|
||||||
|
"y": 624.5
|
||||||
|
},
|
||||||
|
"id": "before-dark-3-lines",
|
||||||
|
"inputEnabled": true,
|
||||||
|
"pid": 64504,
|
||||||
|
"sendAssetLoaded": true,
|
||||||
|
"sendEnabled": true,
|
||||||
|
"sent": [
|
||||||
|
"첫째 줄",
|
||||||
|
"첫째 줄\n둘째 줄\n셋째 줄"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"source": "/Users/klaus/Develop/sodalive/iOS/SodaLive/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/UserCreatorChatRoomView.swift",
|
||||||
|
"sha256": "6f2f84963cc18fe3afeedf5100f5d9838630f3ce95109f1bb6c9f33613d7bb16",
|
||||||
|
"extractedSha256": "a668c26729345cbd78cd702f71cfaa1c43dc3c27757f6215c034dfa605236e36",
|
||||||
|
"verbatimBlocks": [
|
||||||
|
"inputBarView",
|
||||||
|
"isInputEnabled",
|
||||||
|
"isSendEnabled",
|
||||||
|
"sendText"
|
||||||
|
],
|
||||||
|
"synthetic": [
|
||||||
|
"Sink viewModel/socketState",
|
||||||
|
"I18n Korean placeholder constant from source",
|
||||||
|
"LanguageOption enum shim",
|
||||||
|
"screenSize method copied from source",
|
||||||
|
"outer harness VStack/control bridge"
|
||||||
|
],
|
||||||
|
"unchangedHelpers": [
|
||||||
|
"FontModifier.swift",
|
||||||
|
"Font.swift",
|
||||||
|
"Color.swift",
|
||||||
|
"ColorExtension.swift",
|
||||||
|
"Spacing.swift"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"deviceUDID": "7A3A7C1D-CA68-4E0F-AFD6-73EFD891A17E",
|
||||||
|
"ownedDeviceSet": "/private/var/folders/yh/8xsbvpsj5wg2qnxzxdp11_gm0000gn/T/opencode/dm-input.MBW85o/native.vyi84m/devices",
|
||||||
|
"deleted": true,
|
||||||
|
"appTerminatedAfterEachMatrix": true,
|
||||||
|
"harnessPIDs": [
|
||||||
|
64504,
|
||||||
|
65240
|
||||||
|
],
|
||||||
|
"livePIDs": [],
|
||||||
|
"parentRetained": true,
|
||||||
|
"evidenceRetained": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
{
|
||||||
|
"command": "image-diff",
|
||||||
|
"dimensionsMatch": true,
|
||||||
|
"reference": {
|
||||||
|
"width": 750,
|
||||||
|
"height": 1334
|
||||||
|
},
|
||||||
|
"actual": {
|
||||||
|
"width": 750,
|
||||||
|
"height": 1334
|
||||||
|
},
|
||||||
|
"totalPixels": 1000500,
|
||||||
|
"diffPixels": 54474,
|
||||||
|
"diffRatio": 0.0544,
|
||||||
|
"similarityScore": 95,
|
||||||
|
"alphaChannelIntact": true,
|
||||||
|
"hotspots": [
|
||||||
|
{
|
||||||
|
"gridX": 1,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 93,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4813
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 2,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 187,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4715
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 3,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 281,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4358
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 4,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 375,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4012
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 5,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 468,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4006
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 6,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 562,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.3889
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 0,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 0,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.3408
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 4,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 375,
|
||||||
|
"y": 0,
|
||||||
|
"width": 93,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.1187
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 3,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 281,
|
||||||
|
"y": 0,
|
||||||
|
"width": 94,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.1144
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 7,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 656,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0926
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 1,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 93,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 2,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 187,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 3,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 281,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 4,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 375,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 5,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 468,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 6,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 562,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0282
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 0,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 0,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0171
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 2,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 187,
|
||||||
|
"y": 0,
|
||||||
|
"width": 94,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.0136
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 5,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 468,
|
||||||
|
"y": 0,
|
||||||
|
"width": 94,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.0109
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summary": "95/100 similarity; 54474/1000500 pixels differ; 19 hotspot region(s)."
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
{
|
||||||
|
"command": "image-diff",
|
||||||
|
"dimensionsMatch": true,
|
||||||
|
"reference": {
|
||||||
|
"width": 750,
|
||||||
|
"height": 1334
|
||||||
|
},
|
||||||
|
"actual": {
|
||||||
|
"width": 750,
|
||||||
|
"height": 1334
|
||||||
|
},
|
||||||
|
"totalPixels": 1000500,
|
||||||
|
"diffPixels": 55051,
|
||||||
|
"diffRatio": 0.055,
|
||||||
|
"similarityScore": 94,
|
||||||
|
"alphaChannelIntact": true,
|
||||||
|
"hotspots": [
|
||||||
|
{
|
||||||
|
"gridX": 2,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 187,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4905
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 1,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 93,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4821
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 3,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 281,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4521
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 4,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 375,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4012
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 5,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 468,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.4006
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 6,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 562,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.3889
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 0,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 0,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.3459
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 4,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 375,
|
||||||
|
"y": 0,
|
||||||
|
"width": 93,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.1162
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 3,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 281,
|
||||||
|
"y": 0,
|
||||||
|
"width": 94,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.1128
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 7,
|
||||||
|
"gridY": 7,
|
||||||
|
"x": 656,
|
||||||
|
"y": 1167,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0926
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 1,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 93,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 2,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 187,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 3,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 281,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 4,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 375,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 5,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 468,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0359
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 6,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 562,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 94,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0282
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 0,
|
||||||
|
"gridY": 6,
|
||||||
|
"x": 0,
|
||||||
|
"y": 1000,
|
||||||
|
"width": 93,
|
||||||
|
"height": 167,
|
||||||
|
"diffRatio": 0.0171
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 2,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 187,
|
||||||
|
"y": 0,
|
||||||
|
"width": 94,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.0136
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gridX": 5,
|
||||||
|
"gridY": 0,
|
||||||
|
"x": 468,
|
||||||
|
"y": 0,
|
||||||
|
"width": 94,
|
||||||
|
"height": 166,
|
||||||
|
"diffRatio": 0.0109
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summary": "94/100 similarity; 55051/1000500 pixels differ; 19 hotspot region(s)."
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"checksPassed": 66,
|
||||||
|
"checks": [
|
||||||
|
"baseline 1/2/3/4/8 lines stay single-height",
|
||||||
|
"baseline Return submits",
|
||||||
|
"native 1/2/3-line growth and 4/8 cap",
|
||||||
|
"1 lines preserved in native control and binding",
|
||||||
|
"2 lines preserved in native control and binding",
|
||||||
|
"3 lines preserved in native control and binding",
|
||||||
|
"4 lines preserved in native control and binding",
|
||||||
|
"8 lines preserved in native control and binding",
|
||||||
|
"overflow scrolls internally",
|
||||||
|
"overflow scroll preserves all text",
|
||||||
|
"long wrapping text retained",
|
||||||
|
"native Return inserts newline without submitting",
|
||||||
|
"native continued typing preserves newline",
|
||||||
|
"clear shrinks to one line",
|
||||||
|
"delete-all shrinks to one line",
|
||||||
|
"send shrinks to one line",
|
||||||
|
"existing send action trims edges and preserves internal newlines",
|
||||||
|
"whitespace send guard unchanged",
|
||||||
|
"disconnected send guard unchanged",
|
||||||
|
"original registered font and send asset loaded",
|
||||||
|
"final native evidence is from current product source",
|
||||||
|
"send guards and action byte-for-byte unchanged",
|
||||||
|
"before-overflow-top.png is correctly sized native PNG",
|
||||||
|
"before-delete-all.png is correctly sized native PNG",
|
||||||
|
"before-return-seed.png is correctly sized native PNG",
|
||||||
|
"before-return.png is correctly sized native PNG",
|
||||||
|
"before-whitespace-send.png is correctly sized native PNG",
|
||||||
|
"before-1-lines.png is correctly sized native PNG",
|
||||||
|
"before-dark-3-lines.png is correctly sized native PNG",
|
||||||
|
"before-send-seed.png is correctly sized native PNG",
|
||||||
|
"before-whitespace.png is correctly sized native PNG",
|
||||||
|
"before-2-lines.png is correctly sized native PNG",
|
||||||
|
"before-return-followup.png is correctly sized native PNG",
|
||||||
|
"before-overflow-bottom.png is correctly sized native PNG",
|
||||||
|
"before-4-lines.png is correctly sized native PNG",
|
||||||
|
"before-empty.png is correctly sized native PNG",
|
||||||
|
"before-clear.png is correctly sized native PNG",
|
||||||
|
"before-3-lines.png is correctly sized native PNG",
|
||||||
|
"before-light-3-lines.png is correctly sized native PNG",
|
||||||
|
"before-send.png is correctly sized native PNG",
|
||||||
|
"before-disabled.png is correctly sized native PNG",
|
||||||
|
"before-disabled-send.png is correctly sized native PNG",
|
||||||
|
"before-wrapping.png is correctly sized native PNG",
|
||||||
|
"before-8-lines.png is correctly sized native PNG",
|
||||||
|
"after-empty.png is correctly sized native PNG",
|
||||||
|
"after-clear.png is correctly sized native PNG",
|
||||||
|
"after-4-lines.png is correctly sized native PNG",
|
||||||
|
"after-send-seed.png is correctly sized native PNG",
|
||||||
|
"after-delete-all.png is correctly sized native PNG",
|
||||||
|
"after-return.png is correctly sized native PNG",
|
||||||
|
"after-2-lines.png is correctly sized native PNG",
|
||||||
|
"after-8-lines.png is correctly sized native PNG",
|
||||||
|
"after-overflow-bottom.png is correctly sized native PNG",
|
||||||
|
"after-return-followup.png is correctly sized native PNG",
|
||||||
|
"after-send.png is correctly sized native PNG",
|
||||||
|
"after-3-lines.png is correctly sized native PNG",
|
||||||
|
"after-whitespace.png is correctly sized native PNG",
|
||||||
|
"after-dark-3-lines.png is correctly sized native PNG",
|
||||||
|
"after-whitespace-send.png is correctly sized native PNG",
|
||||||
|
"after-disabled-send.png is correctly sized native PNG",
|
||||||
|
"after-return-seed.png is correctly sized native PNG",
|
||||||
|
"after-1-lines.png is correctly sized native PNG",
|
||||||
|
"after-wrapping.png is correctly sized native PNG",
|
||||||
|
"after-overflow-top.png is correctly sized native PNG",
|
||||||
|
"after-disabled.png is correctly sized native PNG",
|
||||||
|
"after-light-3-lines.png is correctly sized native PNG"
|
||||||
|
],
|
||||||
|
"screenshots": 44,
|
||||||
|
"limitations": [
|
||||||
|
"Programmatic native interaction, not human touch/IME",
|
||||||
|
"Send closure directly invokes unchanged sendText action with synthetic sink; no network or button tap",
|
||||||
|
"State seeding stands in for multiline paste",
|
||||||
|
"SwiftUI disabled UITextView still reports isEditable=true; this does not prove GUI hit-testing. Disabled modifier unchanged; actual disabled user interaction not exercised.",
|
||||||
|
"System software keyboard not displayed; no keyboard/message-list integration tested",
|
||||||
|
"375pt SE3 width only, light/dark style samples; no full-device matrix",
|
||||||
|
"No LSP tool exposed; no full app xcodebuild; parent handles full build and independent review"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Phase 1 다중행 입력 검증·리뷰
|
||||||
|
|
||||||
|
## 1. 리뷰 정보
|
||||||
|
|
||||||
|
| 항목 | 내용 |
|
||||||
|
|---|---|
|
||||||
|
| 기준 | main, 시작 b0cabf9 / 구현 14b415e |
|
||||||
|
| 요구사항 | [PRD](../prd.md), INPUT-001~005 |
|
||||||
|
| 계획 | [plan-task.md](../plan-task.md), P1-T1/P1-GATE |
|
||||||
|
| 상태 | 코드·하네스 시각 검토 승인 / 실제 DM 통합 QA 미실행 |
|
||||||
|
|
||||||
|
## 2. 범위와 판정 기준
|
||||||
|
|
||||||
|
유저-크리에이터 DM의 inputBarView만 검토한다. 단일→최대3줄 확장, 초과 내용 내부 스크롤, Return 줄바꿈, 기존 버튼 전송·빈 입력 가드·비연결 입력 가드 보존이 기준이다. 네트워크·서버·날짜 목록·다른 입력창은 변경 범위 밖이다.
|
||||||
|
|
||||||
|
## 3. 검증 근거
|
||||||
|
|
||||||
|
- 기존 커뮤니티 입력창이 vertical TextField + lineLimit1...3을 사용한다.
|
||||||
|
- 메시지 입력 UI의 기존 XCTest seam은 없다. 새 source-string 검사를 만들어 UI 기능 테스트처럼 주장하지 않고 native 전후 동작을 확인한다.
|
||||||
|
- 현재 노출 도구에 LSP diagnostics가 없어 native compiler/build로 검증하고, LSP 실행 여부와 구분한다.
|
||||||
|
|
||||||
|
| 검사 | 결과 |
|
||||||
|
|---|---|
|
||||||
|
| 운영/개발 타깃 최종 빌드 | 모두 exit0, 전후 RoomView SHA-256 일치 |
|
||||||
|
| 기존 검사12개 스크립트/지원 모드19회 | 모두 exit0, 날짜113 assertions 포함 |
|
||||||
|
| 네이티브 입력 UI 전후 비교 | 동작·소스22검사 + PNG44검사 통과, 부모 재실행 exit0 |
|
||||||
|
| 독립 코드·시각 리뷰 | 코드 APPROVE, 최종22장 시각 PASS, 필수 수정 없음 |
|
||||||
|
|
||||||
|
## 4. 발견 사항과 외부 조건
|
||||||
|
|
||||||
|
확정 발견 사항 없음. 실제 로그인 DM 및 서버의 줄바꿈 저장·재조회는 승인된 계정·roomId 부재로 검증하지 않았다. 하네스의 합성 전송 sink는 실제 서버 전송을 증명하지 않는다.
|
||||||
|
|
||||||
|
## 5. 종료 판정과 후속 기록
|
||||||
|
|
||||||
|
최종 코드·실행 증거·리뷰 결과를 이 문서에 누적하며, 확정 수정이 필요하면 계획에 신규 Task를 등록한 뒤 수정한다. 임시 native 앱·시뮬레이터·컴파일 캐시는 작업 소유 자원만 제거한다.
|
||||||
|
|
||||||
|
### 확인한 동작과 증거
|
||||||
|
|
||||||
|
| 입력 줄 수 | 기준 높이 | 변경 후 높이 | 변경 후 contentSize |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| 1 | 18.5pt | 17pt | 17pt |
|
||||||
|
| 2 | 18.5pt | 34pt | 34pt |
|
||||||
|
| 3 | 18.5pt | 50pt | 51pt |
|
||||||
|
| 4 | 18.5pt | 50pt | 67pt |
|
||||||
|
| 8 | 18.5pt | 50pt | 134pt |
|
||||||
|
|
||||||
|
- 8줄 입력의 native offset0→84pt 이동으로 첫1~3줄과 마지막6~8줄을 확인했고 전체 binding/native 문자열은 같았다. 긴 한글 wrapping은 content301pt,표시50pt로 유지됐다.
|
||||||
|
- native UIKeyInput의 Return 삽입: 기준은 자동 전송·초기화, 변경 후는 `첫째 줄\n`이며 전송 없음. 후속 삽입 결과는 `첫째 줄\n둘째 줄`로 보존됐다.
|
||||||
|
- native 전체 삭제와 상태 비우기, 원본 sendText 직접 호출 뒤 한 줄17pt로 축소됐다. 원본 전송 handler는 앞뒤 공백 제거·중간 줄바꿈 보존·합성sink 수신·입력 초기화·포커스 해제를 유지했다.
|
||||||
|
- 입력창·isInputEnabled·isSendEnabled·sendText를 제품 소스에서 그대로 추출했다. 기존 폰트·색상·간격·send asset을 사용했다. 주변화면·연결상태·일부 문자열·전송sink는 임시 하네스다. [provenance와 캡처](evidence/README.md)를 따른다.
|
||||||
|
- `verification.json`의66 checks는 동작·소스22개와44 PNG형식/크기 확인의 합계다. 비즈니스 테스트66개 또는 실제 서버66시나리오로 해석하지 않는다.
|
||||||
|
|
||||||
|
### 실행 명령과 결과
|
||||||
|
|
||||||
|
- `sh work/tests/check-user-creator-chat-date-presentation.sh`:113 assertions, exit0.
|
||||||
|
- work/tests/check-*.sh 12개 기본 실행 + received-gift-detail의 foundation/recipient-form/received-states + gift-phase11의 profile/policy/button + gift-address-search의 baseline, 총19회 모두 exit0.
|
||||||
|
- `xcodebuild -quiet -workspace SodaLive.xcworkspace -scheme SodaLive -configuration Debug -destination 'generic/platform=iOS' CODE_SIGNING_ALLOWED=NO build`:최종 exit0. SodaLive-dev 동일 명령도 exit0. 기존 프로젝트 관리 DerivedData를 재사용했으며 삭제하지 않는다.
|
||||||
|
- `plutil -lint SodaLive.xcodeproj/project.pbxproj`:OK. 제품 파일 Swift parse 및 `git diff --check`도 exit0. LSP 도구는 없어 미실행이다.
|
||||||
|
- 임시 native하네스의 swiftc·actool·설치·실행·simctl screenshot은 모두 exit0. 전후22장씩44개 PNG가750×1334px이며, 최종 소스와 after스냅샷의 일치를 확인했다. 부모도 verify.py를 실행해 native측정·본문·provenance·이미지형식 검사를 재확인했다.
|
||||||
|
|
||||||
|
### 독립 리뷰 판정
|
||||||
|
|
||||||
|
- Oracle 코드/기능 검토: APPROVE. 사용자 요구범위의4줄 추가·4줄 삭제이며 차단 결함 없음. 원본 코드 추출과 native측정 경로를 검토했다.
|
||||||
|
- 시각 검토: 최종after22장과 기준3장을 직접 열어 PASS. 3줄의 끝글자·첫/마지막줄 잘림 없음, 내부 스크롤 전후 표시 일치, 둥근 모서리와 전송버튼 겹침 없음, 팝업 가림 없음. 50pt높이/51ptcontent 차이만으로 결함을 주장하지 않고 실제 글리프를 확인했다.
|
||||||
|
- 실제 터치·IME·클립보드·전송버튼탭·비연결 GUI입력차단·소프트웨어키보드·전체대화목록·서버·VoiceOver·다른기기/OS는 미검증이다. 이번 승인을 해당 범위로 확대하지 않는다. 추가 제품 코드 수정 요구는 없다.
|
||||||
|
|
||||||
|
### 정리 기록
|
||||||
|
|
||||||
|
- native검증자가 소유 simulator `7A3A7C1D-CA68-4E0F-AFD6-73EFD891A17E`를 shutdown/delete하고 하네스 PID64504/65240 종료를 확인했다. [cleanup.json](evidence/cleanup.json)에 영수증이 있다.
|
||||||
|
- 부모도 custom device set의 빈 기기 목록과 DMInputHarness 프로세스 부재를 확인했다. 증거를 보존한 뒤 작업 소유 `dm-input.MBW85o` 루트(하네스·스크립트·캐시·로그)를 제거하고 경로 부재를 확인했다. 작업 메모도 삭제했다. 공유 simulator·프로젝트 관리 DerivedData는 제거하지 않았다.
|
||||||
|
|
||||||
|
### 픽셀 비교 보조 증거
|
||||||
|
|
||||||
|
- visual-qa의 `image-diff`를 같은 단계의 before/after22쌍에 실행해 모두 exit0으로 JSON을 생성했다. 내용/높이를 의도적으로 바꾸는 작업이므로 픽셀 동일성을 통과 조건으로 사용하지 않는다.
|
||||||
|
- [3줄 비교](evidence/image-diff-three-lines.json): 크기 일치, alpha 유지, diffRatio0.055 / similarity94. 주요 변화는 하단 입력창이 세 줄로 확장된 영역이다.
|
||||||
|
- [overflow 하단 비교](evidence/image-diff-overflow.json): 크기 일치, alpha 유지, diffRatio0.0544 / similarity95. 기존 한 줄 표시 대신 마지막6~8줄이 보이는 하단 입력 영역이 변경됐다. 하네스 제목·상태바 차이도 포함된 참고 수치이며 기능 판정은 native측정과 독립 시각 검토를 따른다.
|
||||||