190 lines
5.9 KiB
Swift
190 lines
5.9 KiB
Swift
import SwiftUI
|
|
|
|
struct GachaView: View {
|
|
@EnvironmentObject var authManager: AuthManager
|
|
@EnvironmentObject var cardManager: CardManager
|
|
@State private var showingAnimation = false
|
|
|
|
var body: some View {
|
|
ZStack {
|
|
// Background
|
|
LinearGradient(
|
|
gradient: Gradient(colors: [
|
|
Color(hex: "0a0a0a"),
|
|
Color(hex: "1a1a1a")
|
|
]),
|
|
startPoint: .top,
|
|
endPoint: .bottom
|
|
)
|
|
.ignoresSafeArea()
|
|
|
|
VStack(spacing: 40) {
|
|
// Title
|
|
VStack(spacing: 16) {
|
|
Text("カードを引く")
|
|
.font(.largeTitle)
|
|
.fontWeight(.bold)
|
|
.foregroundColor(.white)
|
|
|
|
if let user = authManager.currentUser {
|
|
Text("@\(user.handle)")
|
|
.font(.subheadline)
|
|
.foregroundColor(Color(hex: "fff700"))
|
|
}
|
|
}
|
|
|
|
Spacer()
|
|
|
|
// Gacha buttons
|
|
VStack(spacing: 20) {
|
|
GachaButton(
|
|
title: "通常ガチャ",
|
|
subtitle: "無料でカードを1枚引く",
|
|
colors: [Color(hex: "667eea"), Color(hex: "764ba2")],
|
|
action: {
|
|
drawCard(isPaid: false)
|
|
},
|
|
isLoading: cardManager.isDrawing
|
|
)
|
|
|
|
GachaButton(
|
|
title: "プレミアムガチャ",
|
|
subtitle: "レア確率アップ!",
|
|
colors: [Color(hex: "f093fb"), Color(hex: "f5576c")],
|
|
action: {
|
|
drawCard(isPaid: true)
|
|
},
|
|
isLoading: cardManager.isDrawing,
|
|
isPremium: true
|
|
)
|
|
}
|
|
.padding(.horizontal, 32)
|
|
|
|
if let errorMessage = cardManager.errorMessage {
|
|
Text(errorMessage)
|
|
.font(.caption)
|
|
.foregroundColor(.red)
|
|
.padding()
|
|
}
|
|
|
|
Spacer()
|
|
}
|
|
.padding()
|
|
|
|
// Gacha animation overlay
|
|
if let currentDraw = cardManager.currentDraw {
|
|
GachaAnimationView(
|
|
drawResult: currentDraw,
|
|
onComplete: {
|
|
cardManager.completeCardDraw()
|
|
}
|
|
)
|
|
.transition(.opacity)
|
|
.zIndex(1000)
|
|
}
|
|
}
|
|
.onAppear {
|
|
if let userDid = authManager.currentUser?.did {
|
|
cardManager.loadUserCards(userDid: userDid)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func drawCard(isPaid: Bool) {
|
|
guard let userDid = authManager.currentUser?.did else { return }
|
|
cardManager.drawCard(userDid: userDid, isPaid: isPaid)
|
|
}
|
|
}
|
|
|
|
struct GachaButton: View {
|
|
let title: String
|
|
let subtitle: String
|
|
let colors: [Color]
|
|
let action: () -> Void
|
|
let isLoading: Bool
|
|
let isPremium: Bool
|
|
|
|
init(title: String, subtitle: String, colors: [Color], action: @escaping () -> Void, isLoading: Bool, isPremium: Bool = false) {
|
|
self.title = title
|
|
self.subtitle = subtitle
|
|
self.colors = colors
|
|
self.action = action
|
|
self.isLoading = isLoading
|
|
self.isPremium = isPremium
|
|
}
|
|
|
|
var body: some View {
|
|
Button(action: action) {
|
|
VStack(spacing: 8) {
|
|
Text(title)
|
|
.font(.title2)
|
|
.fontWeight(.bold)
|
|
.foregroundColor(.white)
|
|
|
|
Text(subtitle)
|
|
.font(.caption)
|
|
.foregroundColor(.white.opacity(0.8))
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.frame(height: 80)
|
|
.background(
|
|
ZStack {
|
|
LinearGradient(
|
|
gradient: Gradient(colors: colors),
|
|
startPoint: .leading,
|
|
endPoint: .trailing
|
|
)
|
|
|
|
if isPremium {
|
|
// Shimmer effect for premium
|
|
ShimmerView()
|
|
}
|
|
}
|
|
)
|
|
.cornerRadius(16)
|
|
.shadow(color: colors.first?.opacity(0.3) ?? .clear, radius: 10, x: 0, y: 5)
|
|
.overlay(
|
|
Group {
|
|
if isLoading {
|
|
ProgressView()
|
|
.progressViewStyle(CircularProgressViewStyle(tint: .white))
|
|
}
|
|
}
|
|
)
|
|
}
|
|
.disabled(isLoading)
|
|
.scaleEffect(isLoading ? 0.95 : 1.0)
|
|
.animation(.easeInOut(duration: 0.1), value: isLoading)
|
|
}
|
|
}
|
|
|
|
struct ShimmerView: View {
|
|
@State private var phase: CGFloat = 0
|
|
|
|
var body: some View {
|
|
LinearGradient(
|
|
gradient: Gradient(colors: [
|
|
.clear,
|
|
.white.opacity(0.2),
|
|
.clear
|
|
]),
|
|
startPoint: .leading,
|
|
endPoint: .trailing
|
|
)
|
|
.rotationEffect(.degrees(45))
|
|
.offset(x: phase)
|
|
.onAppear {
|
|
withAnimation(.linear(duration: 2).repeatForever(autoreverses: false)) {
|
|
phase = 300
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct GachaView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
GachaView()
|
|
.environmentObject(AuthManager())
|
|
.environmentObject(CardManager())
|
|
}
|
|
} |