96 lines
3.2 KiB
Swift
96 lines
3.2 KiB
Swift
import SwiftUI
|
||
|
||
struct GameView: View {
|
||
let service: StreamingService
|
||
|
||
@State private var isScanning = false
|
||
@State private var isLoading = false
|
||
@State private var alert: AlertInfo?
|
||
|
||
var body: some View {
|
||
ZStack {
|
||
Color("Background").ignoresSafeArea()
|
||
|
||
VStack(spacing: 48) {
|
||
Image("AppLogo")
|
||
.resizable()
|
||
.scaledToFit()
|
||
.frame(width: 160, height: 160)
|
||
|
||
if isLoading {
|
||
ProgressView()
|
||
.tint(Color("Primary"))
|
||
.scaleEffect(1.4)
|
||
} else {
|
||
Button(action: { isScanning = true }) {
|
||
Text("Nächste Karte")
|
||
.font(.system(size: 17, weight: .bold))
|
||
.foregroundColor(.white)
|
||
.frame(width: 220, height: 56)
|
||
.background(Color("Primary"))
|
||
.cornerRadius(8)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.navigationBarTitleDisplayMode(.inline)
|
||
.sheet(isPresented: $isScanning) {
|
||
QRScannerView { scannedUrl in
|
||
isScanning = false
|
||
handleScanned(url: scannedUrl)
|
||
}
|
||
}
|
||
.alert(item: $alert) { info in
|
||
Alert(
|
||
title: Text(info.title),
|
||
message: Text(info.message),
|
||
dismissButton: info.scanNext
|
||
? .default(Text("Nächste Karte")) { isScanning = true }
|
||
: .default(Text("OK"))
|
||
)
|
||
}
|
||
.onAppear { isScanning = true }
|
||
}
|
||
|
||
private func handleScanned(url: String) {
|
||
isLoading = true
|
||
Task {
|
||
do {
|
||
let song = try await ApiClient.shared.resolve(url: url)
|
||
await MainActor.run {
|
||
isLoading = false
|
||
guard let song else {
|
||
alert = AlertInfo(
|
||
title: "Nicht gefunden",
|
||
message: "Dieser QR-Code ist keiner bekannten Hitster-Karte zugeordnet.",
|
||
scanNext: false
|
||
)
|
||
return
|
||
}
|
||
guard let serviceUrl = song.url(for: service) else {
|
||
alert = AlertInfo(
|
||
title: "Nicht verfügbar",
|
||
message: "\(song.artist) – \(song.title)\n\nist auf \(service.displayName) nicht verfügbar.\n\nBitte ziehe die nächste Karte.",
|
||
scanNext: true
|
||
)
|
||
return
|
||
}
|
||
UIApplication.shared.open(serviceUrl)
|
||
}
|
||
} catch {
|
||
await MainActor.run {
|
||
isLoading = false
|
||
alert = AlertInfo(title: "Fehler", message: error.localizedDescription, scanNext: false)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private struct AlertInfo: Identifiable {
|
||
let id = UUID()
|
||
let title: String
|
||
let message: String
|
||
let scanNext: Bool
|
||
}
|