diff --git a/SodaLive/Sources/Explorer/Profile/UserProfileView.swift b/SodaLive/Sources/Explorer/Profile/UserProfileView.swift index 9248a0f..5e678f6 100644 --- a/SodaLive/Sources/Explorer/Profile/UserProfileView.swift +++ b/SodaLive/Sources/Explorer/Profile/UserProfileView.swift @@ -27,6 +27,7 @@ struct UserProfileView: View { @State private var didTriggerAutoBackOnLoadFailure: Bool = false @State private var isViewVisible: Bool = false @State private var loadedUserId: Int? = nil + @State private var profileLiveDetailSheet: LiveDetailSheetState? = nil @State private var maxCommunityPostHeight: CGFloat? = nil @@ -244,23 +245,16 @@ struct UserProfileView: View { userId: userId, liveRoomList: creatorProfile.liveRoomList, onClickParticipant: { liveRoom in - if creatorProfile.creator.creatorId == UserDefaults.int(forKey: .userId) { - viewModel.errorMessage = I18n.MemberChannel.liveOnNow - viewModel.isShowPopup = true - } else { - AppState.shared.isShowPlayer = false - DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { - viewModel.enterLiveRoom(roomId: liveRoom.roomId) - } - } + showProfileLiveDetail( + liveRoom: liveRoom, + creatorId: creatorProfile.creator.creatorId + ) }, onClickReservation: { liveRoom in - if creatorProfile.creator.creatorId == UserDefaults.int(forKey: .userId) { - viewModel.errorMessage = I18n.MemberChannel.cannotReserveOwnLive - viewModel.isShowPopup = true - } else { - viewModel.reservationLiveRoom(roomId: liveRoom.roomId) - } + showProfileLiveDetail( + liveRoom: liveRoom, + creatorId: creatorProfile.creator.creatorId + ) } ) } @@ -436,6 +430,19 @@ struct UserProfileView: View { } ZStack { + if let liveDetailSheet = profileLiveDetailSheet { + LiveDetailView( + roomId: liveDetailSheet.roomId, + onClickParticipant: liveDetailSheet.onClickParticipant, + onClickReservation: liveDetailSheet.onClickReservation, + onClickStart: liveDetailSheet.onClickStart, + onClickCancel: liveDetailSheet.onClickCancel, + onClickClose: { + profileLiveDetailSheet = nil + } + ) + } + if isShowChannelDonationDialog { LiveRoomDonationDialogView( isShowing: $isShowChannelDonationDialog, @@ -673,6 +680,33 @@ struct UserProfileView: View { AppState.shared.back() } } + + private func showProfileLiveDetail(liveRoom: LiveRoomResponse, creatorId: Int) { + profileLiveDetailSheet = LiveDetailSheetState( + roomId: liveRoom.roomId, + onClickParticipant: { + if creatorId == UserDefaults.int(forKey: .userId) { + viewModel.errorMessage = I18n.MemberChannel.liveOnNow + viewModel.isShowPopup = true + } else { + AppState.shared.isShowPlayer = false + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + viewModel.enterLiveRoom(roomId: liveRoom.roomId) + } + } + }, + onClickReservation: { + if creatorId == UserDefaults.int(forKey: .userId) { + viewModel.errorMessage = I18n.MemberChannel.cannotReserveOwnLive + viewModel.isShowPopup = true + } else { + viewModel.reservationLiveRoom(roomId: liveRoom.roomId) + } + }, + onClickStart: {}, + onClickCancel: {} + ) + } private func creatorCommunityWriteSuccess() { viewModel.getCreatorProfile(userId: userId) diff --git a/docs/20260306_프로필라이브상세표시위치수정.md b/docs/20260306_프로필라이브상세표시위치수정.md new file mode 100644 index 0000000..3589cf7 --- /dev/null +++ b/docs/20260306_프로필라이브상세표시위치수정.md @@ -0,0 +1,13 @@ +## 구현 체크리스트 +- [x] `UserProfileView`에서 라이브 카드 탭 시 어떤 뷰 계층에서 `LiveDetailView`가 표시되는지 확인한다. +- [x] `LiveDetailView`가 `HomeView`가 아닌 `UserProfileView` 컨텍스트에서 표시되도록 수정한다. +- [x] 관련 진단/빌드/테스트를 수행한다. +- [x] 검증 기록을 누적한다. + +## 검증 기록 +- (완료) 최초 문서 생성 +- (확인) 무엇: 표시 위치 원인 분석 / 왜: `HomeView` 컨텍스트 표시 원인 파악 / 어떻게: `ContentView.swift`, `AppState.swift`, `AppStep.swift` 흐름 점검 / 결과: 전역 `liveDetailSheet`가 `ContentView` 루트 ZStack에서 렌더링되어 Home 배경으로 표시됨 +- (수정) 무엇: 프로필 라이브 상세 표시 컨텍스트 변경 / 왜: `UserProfileView` 위에서 `LiveDetailView`를 표시하기 위해 / 어떻게: `UserProfileView`에 `profileLiveDetailSheet` 상태 추가 후 로컬 `LiveDetailView` 오버레이로 전환 / 결과: 프로필 화면 컨텍스트에서 라이브 상세 표시 +- (검증) 무엇: 수정 파일 LSP 진단 / 왜: 문법·타입 확인 / 어떻게: `lsp_diagnostics(UserProfileView.swift)` / 결과: `No such module 'Kingfisher'` 1건(로컬 SourceKit 인덱싱 환경 이슈) +- (검증) 무엇: 앱 빌드 / 왜: 컴파일 안정성 확인 / 어떻게: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` / 결과: `** BUILD SUCCEEDED **` +- (검증) 무엇: 테스트 실행 / 왜: 회귀 확인 / 어떻게: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` / 결과: `Scheme SodaLive is not currently configured for the test action.` diff --git a/docs/20260306_프로필라이브카드상세진입수정.md b/docs/20260306_프로필라이브카드상세진입수정.md new file mode 100644 index 0000000..ca34807 --- /dev/null +++ b/docs/20260306_프로필라이브카드상세진입수정.md @@ -0,0 +1,15 @@ +## 구현 체크리스트 +- [x] 라이브 카드 탭 동작과 `AppStep.liveDetail` 연결 패턴을 확인한다. +- [x] `UserProfileView`의 라이브 카드 탭 동작을 라이브 상세 페이지 진입으로 변경한다. +- [x] 관련 파일 진단 및 빌드/테스트 검증을 수행한다. +- [x] 결과 및 검증 기록을 문서 하단에 누적한다. + +## 검증 기록 +- (완료) 최초 문서 생성 +- (완료) `SodaLive/Sources/Explorer/Profile/UserProfileView.swift`의 라이브 카드 탭 콜백을 `.liveDetail` 진입 방식으로 수정 +- (검증) 무엇: 수정 파일 LSP 진단 / 왜: 문법·타입 오류 확인 / 어떻게: `lsp_diagnostics(UserProfileView.swift)` / 결과: `No such module 'Kingfisher'` 1건(로컬 SourceKit 모듈 인덱싱 환경 이슈) +- (검증) 무엇: 앱 빌드 / 왜: 변경사항 컴파일 안정성 확인 / 어떻게: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` / 결과: `** BUILD SUCCEEDED **` +- (검증) 무엇: 테스트 실행 / 왜: 회귀 확인 / 어떻게: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` / 결과: `Scheme SodaLive is not currently configured for the test action.` +- (재검증) 무엇: 최종 수정 후 앱 빌드 / 왜: 최종 코드 기준 컴파일 재확인 / 어떻게: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` / 결과: `** BUILD SUCCEEDED **` +- (재검증) 무엇: 최종 수정 후 LSP 진단 / 왜: 최종 코드 기준 문법·타입 확인 / 어떻게: `lsp_diagnostics(UserProfileView.swift)` / 결과: `No such module 'Kingfisher'` 1건(로컬 SourceKit 모듈 인덱싱 환경 이슈) +- (재검증) 무엇: 최종 수정 후 테스트 실행 / 왜: 최종 코드 기준 회귀 재확인 / 어떻게: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` / 결과: `Scheme SodaLive is not currently configured for the test action.`