129 lines
3.8 KiB
Swift
129 lines
3.8 KiB
Swift
//
|
|
// ContentView.swift
|
|
// MultiChrono
|
|
//
|
|
// Created by Beatrice Dellacà on 26/01/26.
|
|
//
|
|
|
|
import SwiftUI
|
|
import Combine
|
|
|
|
class ContentViewModel: ObservableObject {
|
|
@Published var stopwatches: [Stopwatch] = []
|
|
|
|
private let saveKey = "SavedStopwatches"
|
|
|
|
init() {
|
|
load()
|
|
}
|
|
|
|
func addStopwatch(name: String) {
|
|
let newStopwatch = Stopwatch(name: name)
|
|
stopwatches.append(newStopwatch)
|
|
save()
|
|
}
|
|
|
|
func deleteStopwatch(at index: Int) {
|
|
stopwatches[index].pause() // Ensure timer is stopped
|
|
stopwatches.remove(at: index)
|
|
save()
|
|
}
|
|
|
|
func deleteStopwatch(id: UUID) {
|
|
if let index = stopwatches.firstIndex(where: { $0.id == id }) {
|
|
deleteStopwatch(at: index)
|
|
}
|
|
}
|
|
|
|
func save() {
|
|
if let encoded = try? JSONEncoder().encode(stopwatches) {
|
|
UserDefaults.standard.set(encoded, forKey: saveKey)
|
|
}
|
|
}
|
|
|
|
func load() {
|
|
if let data = UserDefaults.standard.data(forKey: saveKey) {
|
|
if let decoded = try? JSONDecoder().decode([Stopwatch].self, from: data) {
|
|
stopwatches = decoded
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ContentView: View {
|
|
@StateObject private var viewModel = ContentViewModel()
|
|
@State private var isShowingAddSheet = false
|
|
@State private var selectedStopwatch: Stopwatch?
|
|
@Environment(\.scenePhase) private var scenePhase
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
List {
|
|
ForEach(viewModel.stopwatches) { stopwatch in
|
|
Button {
|
|
selectedStopwatch = stopwatch
|
|
} label: {
|
|
StopwatchRow(stopwatch: stopwatch, onDelete: {
|
|
viewModel.deleteStopwatch(id: stopwatch.id)
|
|
})
|
|
}
|
|
.buttonStyle(.plain) // Preserves the row layout and interactions
|
|
}
|
|
.onDelete { indexSet in
|
|
for index in indexSet {
|
|
viewModel.deleteStopwatch(at: index)
|
|
}
|
|
}
|
|
}
|
|
.listStyle(.plain)
|
|
.navigationTitle("MultiChrono")
|
|
.toolbar {
|
|
ToolbarItem(placement: .primaryAction) {
|
|
Button(action: {
|
|
isShowingAddSheet = true
|
|
}) {
|
|
Image(systemName: "plus")
|
|
}
|
|
}
|
|
}
|
|
.sheet(isPresented: $isShowingAddSheet) {
|
|
AddStopwatchView { name in
|
|
viewModel.addStopwatch(name: name)
|
|
isShowingAddSheet = false
|
|
}
|
|
}
|
|
.sheet(item: $selectedStopwatch) { stopwatch in
|
|
StopwatchDetailView(
|
|
stopwatch: stopwatch,
|
|
onSave: { newName in
|
|
stopwatch.name = newName
|
|
viewModel.save()
|
|
selectedStopwatch = nil
|
|
},
|
|
onCancel: {
|
|
selectedStopwatch = nil
|
|
}
|
|
)
|
|
}
|
|
.overlay {
|
|
if viewModel.stopwatches.isEmpty {
|
|
ContentUnavailableView(
|
|
"No Stopwatches",
|
|
systemImage: "timer",
|
|
description: Text("Tap the + button to create a stopwatch.")
|
|
)
|
|
}
|
|
}
|
|
}
|
|
.onChange(of: scenePhase) { newPhase in
|
|
if newPhase == .background || newPhase == .inactive {
|
|
viewModel.save()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
ContentView()
|
|
}
|