Files
linkster-ios/Linkster/GameView.swift
2026-04-19 19:55:22 +02:00

96 lines
3.2 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}