fix(navigation): 라이브 재생 중 외부 이동을 확인 후 처리한다
This commit is contained in:
@@ -747,6 +747,13 @@ enum I18n {
|
||||
|
||||
static var quitTitle: String { pick(ko: "라이브 나가기", en: "Leave live", ja: "ライブを退出") }
|
||||
static var quitDesc: String { pick(ko: "라이브에서 나가시겠습니까?", en: "Do you want to leave the live?", ja: "ライブから退出しますか?") }
|
||||
static var leaveLiveForNavigationDesc: String {
|
||||
pick(
|
||||
ko: "다른 페이지로 이동시 현재 라이브에서 나가게 됩니다.",
|
||||
en: "Moving to another page will leave the current live.",
|
||||
ja: "別のページに移動すると、現在のライブから退出します。"
|
||||
)
|
||||
}
|
||||
|
||||
static var endTitle: String { pick(ko: "라이브 종료", en: "End live", ja: "ライブ終了") }
|
||||
static var endDesc: String {
|
||||
|
||||
@@ -862,6 +862,9 @@ struct LiveRoomViewV2: View {
|
||||
waterProgress = 0
|
||||
}
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: .requestLiveRoomQuitForExternalNavigation)) { _ in
|
||||
viewModel.quitRoom()
|
||||
}
|
||||
.ignoresSafeArea(.keyboard)
|
||||
.edgesIgnoringSafeArea(keyboardHandler.keyboardHeight > 0 ? .bottom : .init())
|
||||
.sheet(
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user