feat(live): 라이브 상세를 전역 바텀시트로 표시한다
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
30
docs/20260306_라이브상세바텀시트표시.md
Normal file
30
docs/20260306_라이브상세바텀시트표시.md
Normal 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'`)가 표시되나, 실제 빌드는 정상 통과
|
||||||
Reference in New Issue
Block a user