refactor: 重构盲盒页面

This commit is contained in:
Junhui Chen 2025-09-05 19:12:30 +08:00
parent ea4a5617ec
commit 1026bbb987
2 changed files with 123 additions and 0 deletions

View 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)
}
}
}

View 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()
}
}