Initalier Commit

This commit is contained in:
2026-04-19 19:55:22 +02:00
commit 93e2c811b6
10 changed files with 318 additions and 0 deletions

95
Linkster/GameView.swift Normal file
View File

@@ -0,0 +1,95 @@
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
}