diff --git a/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/plan-task.md b/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/plan-task.md index 88e04e57..93189d4d 100644 --- a/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/plan-task.md +++ b/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/plan-task.md @@ -9,7 +9,7 @@ ## 구현 원칙 -- `enterRoom` API와 성공 처리 대신 라이브룸의 렌더링 계층을 수정한다. +- `enterRoom`의 API 요청·응답 처리는 유지하고, 전역 overlay와 충돌하는 navigation side effect만 분리한다. - 전역 라이브룸은 한 곳에서만 생성한다. - 표시 계층 이동으로 가려질 수 있는 기존 외부 이동 확인 다이얼로그도 같은 최상위 계층으로 옮긴다. - 키보드 처리 방식은 새로 만들지 않고, 현재 수동 offset과 충돌하는 safe area 적용 위치만 바로잡는다. @@ -127,6 +127,44 @@ - 라이브룸이 화면 전체를 덮는다. - 키보드 표시 시 입력창이 키보드 바로 위에 위치하고 큰 빈 공간이 없다. +### Phase 6: 라이브 종료 후 입장 전 화면 복원 + +- [x] **Task 6.1: 공용 입장 성공 처리에서 navigation 초기화 제거** + - 대상 파일: + - 수정: `SodaLive/Sources/Live/LiveViewModel.swift` + - 수정: `SodaLive/Sources/Explorer/Profile/UserProfileViewModel.swift` + - 작업 내용: + - 입장 성공 시 `roomId`와 `isShowPlayer`만 갱신한다. + - 공용 `enterRoom` 내부의 `setAppStep(.main)` 호출을 제거한다. + - 검증 기준: + - 앱 내부 진입점이 현재 navigation path를 유지한 채 전역 라이브룸을 표시한다. + +- [x] **Task 6.2: 콜드 스타트 라이브 푸시의 메인 전환 명시** + - 대상 파일: + - 수정: `SodaLive/Sources/Splash/SplashView.swift` + - 작업 내용: + - 스플래시에서 `pushRoomId`를 로컬 값으로 소비한다. + - `.main`을 설정한 뒤 소비한 room ID로 입장을 진행한다. + - 검증 기준: + - 기존 콜드 스타트 푸시가 스플래시에 머물지 않고 메인 위 라이브룸으로 진입한다. + +- [x] **Task 6.3: 정적 검사 및 Debug 빌드** + - 대상 파일: + - 확인: `SodaLive/Sources/Live/LiveViewModel.swift` + - 확인: `SodaLive/Sources/Explorer/Profile/UserProfileViewModel.swift` + - 확인: `SodaLive/Sources/Splash/SplashView.swift` + - 검증 기준: + - `git diff --check`가 성공한다. + - `SodaLive-dev` Debug 빌드가 `** BUILD SUCCEEDED **`로 완료된다. + +- [ ] **Task 6.4: 진입점별 수동 복귀 검증** + - 대상 화면: + - 홈/라이브 탭, 라이브 상세, 크리에이터 채널, 프로필 + - 콜드 스타트 및 포그라운드 라이브 푸시 + - 검증 기준: + - 일반 입장은 종료 후 입장 직전 화면을 표시한다. + - 푸시 입장은 호출부에 정의된 navigation 정책을 유지한다. + ## 검증 기록 - 2026-07-14: 코드 조사 결과 `LiveRoomViewV2`가 `MainView` 내부에 있어 navigation destination보다 아래에 놓이는 표시 계층 문제와, `ScreenCaptureSecureContainer` 바깥의 시스템 키보드 회피 및 내부 수동 offset이 중복될 수 있는 구조를 확인했다. 구현 및 빌드 검증은 아직 수행하지 않았다. @@ -138,3 +176,6 @@ - 2026-07-14: 사용자 재검증에서 라이브룸이 화면 전체를 덮지 않고 키보드 위 빈 공간도 남는 것을 확인했다. 바깥 `ScreenCaptureSecureContainer`와 내부 `UIHostingController`가 별도의 safe area 경계를 가지므로 바깥 modifier 이동만으로는 부족했다. - 2026-07-14: `ScreenCaptureSecureContainer`를 전체 화면 frame으로 확장하고 모든 바깥 safe area를 무시하도록 보정했다. 내부 `UIHostingController.safeAreaRegions`는 `.container`로 제한해 상태 표시줄/홈 인디케이터 safe area는 유지하면서 키보드 자동 회피만 제외했다. - 2026-07-14: 보정 후 `git diff --check`가 성공했고, `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -derivedDataPath /tmp/SodaLiveDerivedData build`에서 `** BUILD SUCCEEDED **`를 확인했다. Task 5.2의 실제 화면 확인은 사용자 수동 재검증이 필요하다. +- 2026-07-14: 사용자 재검증에서 크리에이터 채널로 입장한 라이브 종료 후 메인이 표시되는 문제를 확인했다. 종료 처리가 이동한 것이 아니라 공용 `enterRoom`의 `setAppStep(.main)`이 입장 시 navigation path를 미리 삭제한 것이 원인이었다. +- 2026-07-14: 일반 입장은 현재 화면을 보존하도록 공용 입장 구현 두 곳에서 navigation 초기화를 제거했다. 2025년 콜드 스타트 라이브 푸시 보정의 의도는 `SplashView`에서 `pushRoomId` 소비와 `.main` 전환을 명시하는 방식으로 유지했다. +- 2026-07-14: 변경 후 `git diff --check`가 성공했고, `xcodebuild -workspace SodaLive.xcworkspace -scheme SodaLive-dev -configuration Debug -derivedDataPath /tmp/SodaLiveDerivedData build`에서 `** BUILD SUCCEEDED **`를 확인했다. Task 6.4의 진입점별 종료 복귀와 푸시 진입은 실제 앱 수동 검증이 필요하다. diff --git a/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/prd.md b/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/prd.md index 28b20511..12ef4e72 100644 --- a/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/prd.md +++ b/docs/20260714_라이브룸_전역_표시와_키보드_레이아웃_수정/prd.md @@ -2,7 +2,7 @@ ## 1. Overview -라이브룸 표시 계층을 메인 페이지 내부에서 앱 최상위 계층으로 옮겨 현재 화면과 무관하게 입장 결과가 보이도록 하고, 라이브 채팅 키보드 표시 시 중복 레이아웃 이동을 제거한다. +라이브룸 표시 계층을 메인 페이지 내부에서 앱 최상위 계층으로 옮겨 현재 화면과 무관하게 입장 결과가 보이도록 하고, 종료 후 입장 전 화면을 복원하며, 라이브 채팅 키보드 표시 시 중복 레이아웃 이동을 제거한다. ## 2. Problem @@ -11,6 +11,7 @@ - `LiveRoomViewV2`는 채팅 키보드 높이만큼 콘텐츠를 수동으로 올리지만, 화면 캡처 보호용 `ScreenCaptureSecureContainer`가 SwiftUI와 내부 `UIHostingController` 사이에 경계를 만든다. - 바깥 SwiftUI 계층의 키보드 safe area만 무시해도 내부 `UIHostingController`의 기본 `safeAreaRegions == .all`에 키보드 영역이 남는다. 내부 콘텐츠가 자동으로 줄어든 뒤 수동 offset까지 적용되어 키보드 위에 불필요한 빈 공간이 생긴다. - `ScreenCaptureSecureContainer` 자체가 일반 container safe area 안에 배치되면 내부 배경의 `edgesIgnoringSafeArea`가 UIKit 컨테이너 경계를 넘어갈 수 없어 라이브룸이 화면 전체를 덮지 못한다. +- 공용 `enterRoom` 성공 처리에서 `setAppStep(.main)`을 호출해 모든 일반 입장 경로의 navigation path를 삭제한다. 라이브 종료는 전역 overlay만 숨기므로 홈, 라이브 상세, 크리에이터 채널, 프로필 등 입장 전 화면 대신 메인 페이지가 나타난다. ## 3. Goals @@ -19,11 +20,13 @@ - 크리에이터 채널에서 즉시 시작 라이브를 생성하면 `enterRoom` 성공 직후 라이브룸이 보인다. - 라이브룸 표시 계층 변경 후에도 라이브 중 푸시/딥링크 외부 이동 확인 다이얼로그가 라이브룸 위에 표시된다. - 채팅 키보드가 표시될 때 입력창은 키보드 바로 위에 위치하고, 키보드 높이만큼의 중복 빈 공간이 생기지 않는다. +- 앱 내부의 일반 입장에서는 현재 navigation path를 보존하고, 라이브 종료 후 입장 직전 화면을 다시 표시한다. +- 콜드 스타트 라이브 푸시는 스플래시 처리 지점에서 메인 페이지를 준비한 뒤 정상적으로 입장한다. - 기존 입장 API, Agora 초기화/종료, 채팅 전송, 캡처 보호 동작을 유지한다. ## 4. Non-Goals -- `enterRoom`, `getRoomDetail`, 결제 또는 비밀번호 확인 API 흐름을 변경하지 않는다. +- `enterRoom`, `getRoomDetail`, 결제 또는 비밀번호 확인의 API 요청·응답 처리 흐름을 변경하지 않는다. - 라이브 생성 후 메인/홈/라이브 데이터 갱신 정책을 변경하지 않는다. - 라이브룸 UI 디자인이나 채팅 컴포넌트 모양을 변경하지 않는다. - 키보드 처리 공통 모듈 전체를 리팩터링하지 않는다. @@ -36,7 +39,7 @@ - `LiveRoomViewV2`의 단일 표시 지점을 `MainView` 내부가 아닌 `ContentView`의 `NavigationStack` 최상위 overlay로 이동한다. - 표시 조건은 기존과 동일하게 `AppState.shared.isShowPlayer`를 사용한다. - `LiveRoomViewV2`를 중복 생성하지 않는다. -- `LiveViewModel.enterRoom(roomId:)`의 성공 처리와 `AppState.shared.roomId` 설정은 변경하지 않는다. +- `LiveViewModel.enterRoom(roomId:)`의 API 성공 판정과 `AppState.shared.roomId` 설정은 변경하지 않는다. ### 5.2 외부 이동 확인 보존 @@ -53,9 +56,16 @@ - 시스템 키보드 회피와 수동 offset이 동시에 적용되지 않도록 한다. - 캡처 보호 활성/비활성 상태 모두 같은 키보드 레이아웃 규칙을 사용한다. +### 5.4 입장 전 화면 복원 + +- 공용 `LiveViewModel.enterRoom`과 `UserProfileViewModel.enterRoom`은 라이브 상태만 활성화하고 navigation을 변경하지 않는다. +- 홈, 라이브 탭, 라이브 상세, 크리에이터 채널, 프로필 등 앱 내부 진입점은 각각의 현재 화면을 라이브룸 아래에 유지한다. +- 콜드 스타트 라이브 푸시는 `SplashView`에서 `pushRoomId`를 소비하고 `.main`을 설정한 뒤 입장한다. +- 포그라운드 푸시와 딥링크의 기존 호출부별 navigation 정책은 유지한다. + ## 6. Technical Constraints -- 변경은 기존 파일인 `SodaLive/Sources/ContentView.swift`, `SodaLive/Sources/V2/Main/MainView.swift`, `SodaLive/Sources/App/AppState.swift`, `SodaLive/Sources/Live/Room/V2/LiveRoomViewV2.swift`에 한정한다. +- 변경은 라이브룸 전역 표시, 키보드 레이아웃, 공용 입장 성공 처리와 콜드 스타트 푸시 처리에 직접 관련된 기존 파일에 한정한다. - 기존 `SodaV2ActionModal`과 외부 이동 확인 문구를 재사용한다. - 신규 사용자 노출 문자열이나 신규 API를 추가하지 않는다. - 자동화 테스트 번들 타깃이 없는 현재 프로젝트 구성에서는 정적 검색과 `SodaLive-dev` Debug 빌드로 자동 검증하고, 실제 키보드 높이는 수동 QA 항목으로 남긴다. @@ -67,6 +77,8 @@ - 라이브룸 배경이 상태 표시줄과 홈 인디케이터 영역을 포함한 화면 전체를 덮는다. - 라이브 중 외부 이동 요청 시 확인 다이얼로그가 라이브룸 위에 표시되고 확인/취소가 기존 의미대로 동작한다. - 채팅 입력 포커스 시 화면 이동량이 키보드 회피와 중복되지 않으며 입력창 아래에 큰 빈 공간이 생기지 않는다. +- 앱 내부에서 라이브 종료 시 입장 직전 화면과 navigation path가 유지된다. +- 콜드 스타트 라이브 푸시에서는 스플래시가 사라지고 메인 페이지 위에 라이브룸이 표시된다. - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`가 성공한다. ## 8. Open Questions