130 lines
4.7 KiB
Swift
130 lines
4.7 KiB
Swift
//
|
|
// ContentView.swift
|
|
// MagicCounter
|
|
//
|
|
// Created by Atridad Lahiji on 2025-12-06.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct ContentView: View {
|
|
@EnvironmentObject var gameManager: GameManager
|
|
@State private var showSetup = false
|
|
@AppStorage("accentColorName") private var accentColorName = "Blue"
|
|
|
|
var selectedColor: Color {
|
|
switch accentColorName {
|
|
case "Blue": return .blue
|
|
case "Purple": return .purple
|
|
case "Pink": return .pink
|
|
case "Red": return .red
|
|
case "Orange": return .orange
|
|
case "Green": return .green
|
|
case "Teal": return .teal
|
|
case "Indigo": return .indigo
|
|
case "Mint": return .mint
|
|
case "Brown": return .brown
|
|
case "Cyan": return .cyan
|
|
default: return .blue
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
Group {
|
|
if let activeMatch = gameManager.activeMatch {
|
|
GameView(match: activeMatch)
|
|
.transition(.move(edge: .bottom))
|
|
} else {
|
|
TabView {
|
|
NavigationStack {
|
|
List {
|
|
if gameManager.matchHistory.isEmpty {
|
|
ContentUnavailableView("No Matches", systemImage: "gamecontroller", description: Text("Start a new game to begin tracking."))
|
|
} else {
|
|
ForEach(gameManager.matchHistory) { match in
|
|
MatchHistoryRow(match: match)
|
|
.contentShape(Rectangle()) // Ensure the whole row is tappable
|
|
.onTapGesture {
|
|
withAnimation {
|
|
gameManager.resumeMatch(match)
|
|
}
|
|
}
|
|
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
|
Button(role: .destructive) {
|
|
withAnimation {
|
|
gameManager.deleteMatch(id: match.id)
|
|
}
|
|
} label: {
|
|
Label("Delete", systemImage: "trash")
|
|
}
|
|
.tint(.red)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.listStyle(.insetGrouped)
|
|
.navigationTitle("Games")
|
|
.toolbar {
|
|
ToolbarItem(placement: .primaryAction) {
|
|
Button(action: { showSetup = true }) {
|
|
Image(systemName: "plus")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.tabItem {
|
|
Label("Games", systemImage: "clock.fill")
|
|
}
|
|
|
|
SettingsView()
|
|
.tabItem {
|
|
Label("Settings", systemImage: "gear")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.tint(selectedColor)
|
|
.sheet(isPresented: $showSetup) {
|
|
SetupView()
|
|
.tint(selectedColor)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct MatchHistoryRow: View {
|
|
let match: MatchRecord
|
|
|
|
var body: some View {
|
|
HStack {
|
|
VStack(alignment: .leading) {
|
|
Text(match.name)
|
|
.font(.headline)
|
|
.foregroundStyle(.primary)
|
|
Text(match.startedAt.formatted(date: .abbreviated, time: .shortened))
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
Spacer()
|
|
|
|
if match.state.stopped {
|
|
Text("Stopped")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
} else if let winner = match.state.winner {
|
|
Text("Winner: \(winner.name)")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
} else {
|
|
Text("Ongoing")
|
|
.font(.caption)
|
|
.padding(.horizontal, 8)
|
|
.padding(.vertical, 4)
|
|
.background(Color.green.opacity(0.2))
|
|
.foregroundStyle(.green)
|
|
.cornerRadius(8)
|
|
}
|
|
}
|
|
.padding(.vertical, 8)
|
|
}
|
|
}
|