feat: 优化开启时按钮状态
This commit is contained in:
parent
d62e8373f8
commit
c4c33158fd
@ -37,6 +37,15 @@ struct BlindBoxActionButton: View {
|
|||||||
.background(Color.themePrimary)
|
.background(Color.themePrimary)
|
||||||
.foregroundColor(Color.themeTextMessageMain)
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
.cornerRadius(32)
|
.cornerRadius(32)
|
||||||
|
case .opening:
|
||||||
|
Text("Ready")
|
||||||
|
.font(Typography.font(for: .body))
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.themePrimary)
|
||||||
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
|
.cornerRadius(32)
|
||||||
default:
|
default:
|
||||||
Text("Go to Buy")
|
Text("Go to Buy")
|
||||||
.font(Typography.font(for: .body))
|
.font(Typography.font(for: .body))
|
||||||
|
|||||||
@ -22,6 +22,8 @@ struct BlindBoxView: View {
|
|||||||
@State private var showLogin = false
|
@State private var showLogin = false
|
||||||
// 倒计时由 ViewModel 管理(countdownText)
|
// 倒计时由 ViewModel 管理(countdownText)
|
||||||
@State private var animationPhase: BlindBoxAnimationPhase = .none
|
@State private var animationPhase: BlindBoxAnimationPhase = .none
|
||||||
|
// 防止开箱二次点击
|
||||||
|
@State private var isOpening: Bool = false
|
||||||
|
|
||||||
// 查询数据 - 简单查询
|
// 查询数据 - 简单查询
|
||||||
@Query private var login: [Login]
|
@Query private var login: [Login]
|
||||||
@ -55,6 +57,8 @@ struct BlindBoxView: View {
|
|||||||
viewModel.player?.pause()
|
viewModel.player?.pause()
|
||||||
viewModel.player?.replaceCurrentItem(with: nil)
|
viewModel.player?.replaceCurrentItem(with: nil)
|
||||||
viewModel.player = nil
|
viewModel.player = nil
|
||||||
|
// 重置防连点状态
|
||||||
|
isOpening = false
|
||||||
|
|
||||||
NotificationCenter.default.removeObserver(
|
NotificationCenter.default.removeObserver(
|
||||||
self,
|
self,
|
||||||
@ -153,6 +157,8 @@ struct BlindBoxView: View {
|
|||||||
maxWidth: .infinity,
|
maxWidth: .infinity,
|
||||||
maxHeight: UIScreen.main.bounds.height * 0.65
|
maxHeight: UIScreen.main.bounds.height * 0.65
|
||||||
)
|
)
|
||||||
|
// 确保开启动画层级更高
|
||||||
|
.zIndex(animationPhase == .opening ? 1 : 0)
|
||||||
|
|
||||||
|
|
||||||
// 打开 TODO 引导时,也要有按钮
|
// 打开 TODO 引导时,也要有按钮
|
||||||
@ -161,12 +167,23 @@ struct BlindBoxView: View {
|
|||||||
phase: animationPhase,
|
phase: animationPhase,
|
||||||
countdownText: viewModel.countdownText,
|
countdownText: viewModel.countdownText,
|
||||||
onOpen: {
|
onOpen: {
|
||||||
openBlindBoxAndUpdateState(navigateAfterOpen: true)
|
// 防连点:若已在处理则忽略
|
||||||
|
guard !isOpening else { return }
|
||||||
|
isOpening = true
|
||||||
|
// 先播放开箱动画,动画结束后再在 onOpeningCompleted 内导航
|
||||||
|
openBlindBoxAndUpdateState(navigateAfterOpen: false)
|
||||||
},
|
},
|
||||||
onGoToBuy: {
|
onGoToBuy: {
|
||||||
Router.shared.navigate(to: .mediaUpload)
|
Router.shared.navigate(to: .mediaUpload)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.disabled(isOpening)
|
||||||
|
// 开启动画时隐藏按钮,避免覆盖在动画之上
|
||||||
|
.opacity(animationPhase == .opening ? 0 : 1)
|
||||||
|
// 可见性切换时进行轻微淡入淡出
|
||||||
|
.animation(.easeInOut(duration: 0.2), value: animationPhase)
|
||||||
|
// 开启动画时完全屏蔽交互
|
||||||
|
.allowsHitTesting(animationPhase != .opening)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,6 +276,8 @@ struct BlindBoxView: View {
|
|||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
print("❌ 开启盲盒失败: \(error)")
|
print("❌ 开启盲盒失败: \(error)")
|
||||||
|
// 失败时允许再次点击
|
||||||
|
isOpening = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,6 +308,8 @@ struct BlindBoxView: View {
|
|||||||
goToFeedback: false
|
goToFeedback: false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
// 导航后立即重置状态,确保返回时按钮可用
|
||||||
|
isOpening = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if mediaType == .image {
|
} else if mediaType == .image {
|
||||||
@ -310,11 +331,15 @@ struct BlindBoxView: View {
|
|||||||
goToFeedback: true
|
goToFeedback: true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
// 导航后立即重置状态,确保返回时按钮可用
|
||||||
|
isOpening = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 若仍未获取到媒体,记录日志以便排查
|
// 若仍未获取到媒体,记录日志以便排查
|
||||||
print("⚠️ navigateToOutcome: 媒体尚未准备好,videoURL=\(viewModel.videoURL), image=\(String(describing: viewModel.displayImage))")
|
print("⚠️ navigateToOutcome: 媒体尚未准备好,videoURL=\(viewModel.videoURL), image=\(String(describing: viewModel.displayImage))")
|
||||||
|
// 如果因为媒体未就绪而导航失败,也应解锁按钮
|
||||||
|
isOpening = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,13 +115,17 @@ struct BlindOutcomeView: View {
|
|||||||
.background(Color.themePrimary)
|
.background(Color.themePrimary)
|
||||||
.cornerRadius(26)
|
.cornerRadius(26)
|
||||||
}
|
}
|
||||||
|
// 弹窗显示时,按钮淡出且不可交互
|
||||||
|
.opacity(showIPListModal ? 0 : 1)
|
||||||
|
.animation(.easeInOut(duration: 0.2), value: showIPListModal)
|
||||||
|
.allowsHitTesting(!showIPListModal)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
.padding(.bottom, 20)
|
.padding(.bottom, 20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// .navigationBarHidden(true)
|
.navigationBarHidden(true)
|
||||||
// .navigationBarBackButtonHidden(true)
|
.navigationBarBackButtonHidden(true)
|
||||||
.overlay(
|
.overlay(
|
||||||
JoinModal(isPresented: $showIPListModal, onClose: { onContinue() })
|
JoinModal(isPresented: $showIPListModal, onClose: { onContinue() })
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user