refactor: 重构盲盒页面
This commit is contained in:
parent
ea4a5617ec
commit
1026bbb987
47
wake/View/BlindBox/BlindBoxControls.swift
Normal file
47
wake/View/BlindBox/BlindBoxControls.swift
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// MARK: - Blind Box Controls
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct BlindBoxControls: View {
|
||||||
|
let mediaType: BlindBoxMediaType
|
||||||
|
let animationPhase: BlindBoxAnimationPhase
|
||||||
|
let countdown: (minutes: Int, seconds: Int, milliseconds: Int)
|
||||||
|
let onButtonTap: () -> Void
|
||||||
|
let onCountdownStart: () -> Void
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if mediaType == .all {
|
||||||
|
Button(action: onButtonTap) {
|
||||||
|
if animationPhase == .loading {
|
||||||
|
Text("Next: \(countdown.minutes):\(String(format: "%02d", countdown.seconds)).\(String(format: "%02d", countdown.milliseconds))")
|
||||||
|
.font(Typography.font(for: .body))
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.white)
|
||||||
|
.foregroundColor(.black)
|
||||||
|
.cornerRadius(32)
|
||||||
|
.onAppear(perform: onCountdownStart)
|
||||||
|
} else if animationPhase == .ready {
|
||||||
|
Text("Ready")
|
||||||
|
.font(Typography.font(for: .body))
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.themePrimary)
|
||||||
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
|
.cornerRadius(32)
|
||||||
|
} else {
|
||||||
|
Text("Go to Buy")
|
||||||
|
.font(Typography.font(for: .body))
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.themePrimary)
|
||||||
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
|
.cornerRadius(32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
wake/View/BlindBox/MediaOverlayView.swift
Normal file
76
wake/View/BlindBox/MediaOverlayView.swift
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// MARK: - Media Overlay View
|
||||||
|
import SwiftUI
|
||||||
|
import AVKit
|
||||||
|
|
||||||
|
struct MediaOverlayView: View {
|
||||||
|
@Binding var videoPlayer: AVPlayer?
|
||||||
|
@Binding var showControls: Bool
|
||||||
|
let mediaType: BlindBoxMediaType
|
||||||
|
let displayImage: UIImage?
|
||||||
|
let scaledWidth: CGFloat
|
||||||
|
let scaledHeight: CGFloat
|
||||||
|
let scale: CGFloat
|
||||||
|
let videoURL: String
|
||||||
|
let imageURL: String
|
||||||
|
let blindGenerate: BlindBoxData?
|
||||||
|
let onBackTap: () -> Void
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
VisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialLight))
|
||||||
|
.opacity(0.3)
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
|
||||||
|
Group {
|
||||||
|
if mediaType == .video, let player = videoPlayer {
|
||||||
|
AVPlayerController(player: $videoPlayer)
|
||||||
|
.frame(width: scaledWidth, height: scaledHeight)
|
||||||
|
.opacity(scale == 1 ? 1 : 0.7)
|
||||||
|
.onAppear { player.play() }
|
||||||
|
} else if mediaType == .image, let image = displayImage {
|
||||||
|
Image(uiImage: image)
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: scaledWidth, height: scaledHeight)
|
||||||
|
.opacity(scale == 1 ? 1 : 0.7)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.easeInOut(duration: 0.1)) {
|
||||||
|
showControls.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回按钮
|
||||||
|
if showControls {
|
||||||
|
VStack {
|
||||||
|
HStack {
|
||||||
|
Button(action: onBackTap) {
|
||||||
|
Image(systemName: "chevron.left")
|
||||||
|
.font(.system(size: 24))
|
||||||
|
.foregroundColor(.black)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.padding(.top, 50)
|
||||||
|
.padding(.leading, 20)
|
||||||
|
.zIndex(1000)
|
||||||
|
.transition(.opacity)
|
||||||
|
.onAppear {
|
||||||
|
// 2秒后显示按钮
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||||
|
withAnimation(.easeInOut(duration: 0.3)) {
|
||||||
|
// 这里应该设置 showControls = true,但由于是绑定,我们假设调用方会处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.animation(.easeInOut(duration: 1.0), value: scale)
|
||||||
|
.ignoresSafeArea()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user