fix(navigation): 라이브 재생 중 외부 이동을 확인 후 처리한다

This commit is contained in:
Yu Sung
2026-03-06 18:56:49 +09:00
parent 33f9ddfd12
commit cab9795557
5 changed files with 219 additions and 23 deletions

View File

@@ -36,6 +36,9 @@ struct HomeView: View {
@State private var isShowAuthView: Bool = false
@State private var isShowAuthConfirmView: Bool = false
@State private var pendingAction: (() -> Void)? = nil
@State private var isShowLeaveLiveNavigationDialog: Bool = false
@State private var pendingExternalNavigationAction: (() -> Void)? = nil
@State private var pendingExternalNavigationCancelAction: (() -> Void)? = nil
@State private var payload = Payload()
var body: some View {
@@ -265,6 +268,21 @@ struct HomeView: View {
if appState.isShowPlayer {
LiveRoomViewV2()
}
if isShowLeaveLiveNavigationDialog {
SodaDialog(
title: I18n.Common.alertTitle,
desc: I18n.LiveRoom.leaveLiveForNavigationDesc,
confirmButtonTitle: I18n.Common.confirm,
confirmButtonAction: {
confirmExternalNavigation()
},
cancelButtonTitle: I18n.Common.cancel,
cancelButtonAction: {
cancelExternalNavigation()
}
)
}
}
.edgesIgnoringSafeArea(.bottom)
.fullScreenCover(isPresented: $isShowAuthView) {
@@ -296,47 +314,124 @@ struct HomeView: View {
}
}
.valueChanged(value: appState.pushRoomId) { value in
guard value > 0 else {
return
}
let roomId = value
appState.pushRoomId = 0
DispatchQueue.main.async {
appState.setAppStep(step: .main)
if value > 0 {
liveViewModel.enterLiveRoom(roomId: value)
}
handleExternalNavigationRequest(
value: roomId,
navigationAction: {
appState.setAppStep(step: .main)
liveViewModel.enterLiveRoom(roomId: roomId)
},
cancelAction: {
appState.pushRoomId = 0
}
)
}
}
.valueChanged(value: appState.pushChannelId) { value in
guard value > 0 else {
return
}
let channelId = value
appState.pushChannelId = 0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if value > 0 {
appState.setAppStep(step: .main)
appState.setAppStep(step: .creatorDetail(userId: value))
}
handleExternalNavigationRequest(
value: channelId,
navigationAction: {
appState.setAppStep(step: .main)
appState.setAppStep(step: .creatorDetail(userId: channelId))
},
cancelAction: {
appState.pushChannelId = 0
}
)
}
}
.valueChanged(value: appState.pushMessageId) { value in
guard value > 0 else {
return
}
let messageId = value
appState.pushMessageId = 0
DispatchQueue.main.async {
appState.setAppStep(step: .main)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if value > 0 {
appState.setAppStep(step: .message)
handleExternalNavigationRequest(
value: messageId,
navigationAction: {
appState.setAppStep(step: .main)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
appState.setAppStep(step: .message)
}
},
cancelAction: {
appState.pushMessageId = 0
}
}
)
}
}
.valueChanged(value: appState.pushAudioContentId) { value in
guard value > 0 else {
return
}
let contentId = value
appState.pushAudioContentId = 0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if value > 0 {
appState.setAppStep(step: .main)
appState.setAppStep(step: .contentDetail(contentId: value))
}
handleExternalNavigationRequest(
value: contentId,
navigationAction: {
appState.setAppStep(step: .main)
appState.setAppStep(step: .contentDetail(contentId: contentId))
},
cancelAction: {
appState.pushAudioContentId = 0
}
)
}
}
.valueChanged(value: appState.pushSeriesId) { value in
guard value > 0 else {
return
}
let seriesId = value
appState.pushSeriesId = 0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if value > 0 {
appState.setAppStep(step: .main)
appState.setAppStep(step: .seriesDetail(seriesId: value))
}
handleExternalNavigationRequest(
value: seriesId,
navigationAction: {
appState.setAppStep(step: .main)
appState.setAppStep(step: .seriesDetail(seriesId: seriesId))
},
cancelAction: {
appState.pushSeriesId = 0
}
)
}
}
.valueChanged(value: appState.isShowPlayer) { isShowPlayer in
guard !isShowPlayer,
let pendingExternalNavigationAction = pendingExternalNavigationAction else {
return
}
self.pendingExternalNavigationAction = nil
self.pendingExternalNavigationCancelAction = nil
DispatchQueue.main.async {
pendingExternalNavigationAction()
}
}
.onAppear {
@@ -377,6 +472,42 @@ struct HomeView: View {
)
)
}
private func handleExternalNavigationRequest(
value: Int,
navigationAction: @escaping () -> Void,
cancelAction: @escaping () -> Void
) {
guard value > 0 else {
return
}
if appState.isShowPlayer {
pendingExternalNavigationAction = navigationAction
pendingExternalNavigationCancelAction = cancelAction
isShowLeaveLiveNavigationDialog = true
return
}
navigationAction()
}
private func confirmExternalNavigation() {
guard pendingExternalNavigationAction != nil else {
isShowLeaveLiveNavigationDialog = false
return
}
isShowLeaveLiveNavigationDialog = false
NotificationCenter.default.post(name: .requestLiveRoomQuitForExternalNavigation, object: nil)
}
private func cancelExternalNavigation() {
isShowLeaveLiveNavigationDialog = false
pendingExternalNavigationAction = nil
pendingExternalNavigationCancelAction?()
pendingExternalNavigationCancelAction = nil
}
private func pushTokenUpdate() {
let pushToken = UserDefaults.string(forKey: .pushToken)
@@ -386,6 +517,10 @@ struct HomeView: View {
}
}
extension Notification.Name {
static let requestLiveRoomQuitForExternalNavigation = Notification.Name("REQUEST_LIVE_ROOM_QUIT_FOR_EXTERNAL_NAVIGATION")
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()