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