feat(live): 라이브 상세를 전역 바텀시트로 표시한다

This commit is contained in:
Yu Sung
2026-03-06 17:46:26 +09:00
parent 42ce09d927
commit 298c02b83f
4 changed files with 79 additions and 1 deletions

View File

@@ -11,6 +11,14 @@ struct AppRoute: Hashable {
let id = UUID() let id = UUID()
} }
struct LiveDetailSheetState {
let roomId: Int
let onClickParticipant: () -> Void
let onClickReservation: () -> Void
let onClickStart: () -> Void
let onClickCancel: () -> Void
}
class AppState: ObservableObject { class AppState: ObservableObject {
static let shared = AppState() static let shared = AppState()
@@ -62,6 +70,7 @@ class AppState: ObservableObject {
@Published var isShowErrorPopup = false @Published var isShowErrorPopup = false
@Published var errorMessage = "" @Published var errorMessage = ""
@Published var liveDetailSheet: LiveDetailSheetState? = nil
private func syncStepWithNavigationPath() { private func syncStepWithNavigationPath() {
let validRoutes = Set(navigationPath) let validRoutes = Set(navigationPath)
@@ -83,11 +92,22 @@ class AppState: ObservableObject {
DispatchQueue.main.async { DispatchQueue.main.async {
switch step { switch step {
case .splash, .main: case .splash, .main:
self.liveDetailSheet = nil
self.rootStep = step self.rootStep = step
self.routeStepMap.removeAll() self.routeStepMap.removeAll()
self.navigationPath.removeAll() self.navigationPath.removeAll()
self.appStep = step self.appStep = step
case .liveDetail(let roomId, let onClickParticipant, let onClickReservation, let onClickStart, let onClickCancel):
self.liveDetailSheet = LiveDetailSheetState(
roomId: roomId,
onClickParticipant: onClickParticipant,
onClickReservation: onClickReservation,
onClickStart: onClickStart,
onClickCancel: onClickCancel
)
self.appStep = step
default: default:
let route = AppRoute() let route = AppRoute()
self.routeStepMap[route] = step self.routeStepMap[route] = step
@@ -99,6 +119,12 @@ class AppState: ObservableObject {
func back() { func back() {
DispatchQueue.main.async { DispatchQueue.main.async {
if self.liveDetailSheet != nil {
self.liveDetailSheet = nil
self.syncStepWithNavigationPath()
return
}
if self.navigationPath.isEmpty { if self.navigationPath.isEmpty {
self.rootStep = .main self.rootStep = .main
self.appStep = .main self.appStep = .main
@@ -109,6 +135,13 @@ class AppState: ObservableObject {
} }
} }
func hideLiveDetailSheet() {
DispatchQueue.main.async {
self.liveDetailSheet = nil
self.syncStepWithNavigationPath()
}
}
// ( -> ) UI // ( -> ) UI
func softRestart() { func softRestart() {
isRestartApp = true isRestartApp = true

View File

@@ -30,6 +30,21 @@ struct ContentView: View {
.navigationBarBackButtonHidden(true) .navigationBarBackButtonHidden(true)
} }
if let liveDetailSheet = appState.liveDetailSheet {
LiveDetailView(
roomId: liveDetailSheet.roomId,
onClickParticipant: liveDetailSheet.onClickParticipant,
onClickReservation: liveDetailSheet.onClickReservation,
onClickStart: liveDetailSheet.onClickStart,
onClickCancel: liveDetailSheet.onClickCancel,
onClickClose: {
withAnimation {
appState.hideLiveDetailSheet()
}
}
)
}
if isShowDialog { if isShowDialog {
SodaDialog( SodaDialog(
title: I18n.Common.pointGrantTitle, title: I18n.Common.pointGrantTitle,

View File

@@ -33,7 +33,7 @@ struct LiveDetailView: View {
var onClickClose: (() -> Void)? = nil var onClickClose: (() -> Void)? = nil
var body: some View { var body: some View {
BaseView(isLoading: $viewModel.isLoading) { ZStack {
Color.black.opacity(0.7) Color.black.opacity(0.7)
.onTapGesture { .onTapGesture {
viewModel.onBack { viewModel.onBack {

View File

@@ -0,0 +1,30 @@
# 20260306 라이브 상세 바텀시트 표시 전환
## 작업 체크리스트
- [x] LiveDetailView 진입 경로(현재 페이지 이동 방식) 확인
- [x] LiveDetailView를 BottomSheet로 표시하도록 화면 전환 로직 수정
- [x] 영향 범위 컴파일/진단 확인
## 검증 기록
- 2026-03-06 / LiveDetailView 표시 방식 전환 검증
- 무엇: `AppState``.liveDetail` 처리에서 네비게이션 푸시 대신 전역 BottomSheet 상태(`liveDetailSheet`)를 사용하도록 변경하고, `ContentView`에서 해당 상태를 감지해 `LiveDetailView`를 오버레이 표시하도록 반영.
- 왜: `LiveDetailView` 진입 시 페이지 이동(push) 없이 동일 화면 맥락에서 바텀시트로 표시하기 위함.
- 어떻게:
- `lsp_diagnostics` 실행: `SodaLive/Sources/App/AppState.swift`, `SodaLive/Sources/ContentView.swift`
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test`
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build`
- 결과:
- `xcodebuild` 빌드: `SodaLive`, `SodaLive-dev` 모두 `** BUILD SUCCEEDED **`
- `xcodebuild test`: `Scheme SodaLive is not currently configured for the test action.`로 테스트 실행 불가
- `lsp_diagnostics`: 현재 SourceKit 컨텍스트에서 프로젝트 타입 해석 실패로 다수 심볼 미해결 오류가 표시되어, 최종 검증은 실제 `xcodebuild` 결과 기준으로 확인
- 2026-03-06 / LiveDetailView 배경 dim 표시 보정
- 무엇: `LiveDetailView`의 루트 컨테이너를 `BaseView`에서 `ZStack`으로 변경하여 전체 검정 배경 고정 레이어를 제거.
- 왜: 오버레이 표시 시 현재 화면이 완전히 검정으로 가려지는 문제를 제거하고, 현재 화면 위에 dim 레이어가 덮이는 형태로 보이게 하기 위함.
- 어떻게:
- `lsp_diagnostics` 실행: `SodaLive/Sources/Live/Room/Detail/LiveDetailView.swift`
- `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`
- 결과:
- `xcodebuild` 빌드: `SodaLive` `** BUILD SUCCEEDED **`
- `lsp_diagnostics`: 현재 SourceKit 컨텍스트에서 `Kingfisher` 모듈 인식 실패(`No such module 'Kingfisher'`)가 표시되나, 실제 빌드는 정상 통과