implement alerts, delete

This commit is contained in:
2026-01-28 23:43:50 +01:00
parent a607e33ce9
commit 93cf6f8483
3 changed files with 51 additions and 9 deletions

View File

@@ -62,6 +62,7 @@ struct ContentView: View {
@State private var isShowingSettings = false
@State private var selectedStopwatch: Stopwatch?
@State private var draggingStopwatch: Stopwatch?
@State private var stopwatchToDelete: Stopwatch?
@Environment(\.scenePhase) private var scenePhase
var body: some View {
@@ -73,7 +74,8 @@ struct ContentView: View {
stopwatch: stopwatch,
viewModel: viewModel,
selectedStopwatch: $selectedStopwatch,
draggingStopwatch: $draggingStopwatch
draggingStopwatch: $draggingStopwatch,
stopwatchToDelete: $stopwatchToDelete
)
}
}
@@ -119,9 +121,26 @@ struct ContentView: View {
stopwatch.reset()
viewModel.save()
selectedStopwatch = nil
},
onDelete: {
viewModel.deleteStopwatch(id: stopwatch.id)
selectedStopwatch = nil
}
)
}
.alert("Are you sure you want to delete the Stopwatch \(stopwatchToDelete?.name ?? "")?", isPresented: Binding(
get: { stopwatchToDelete != nil },
set: { if !$0 { stopwatchToDelete = nil } }
)) {
if let stopwatch = stopwatchToDelete {
Button("Delete", role: .destructive) {
withAnimation {
viewModel.deleteStopwatch(id: stopwatch.id)
}
}
}
Button("Cancel", role: .cancel) {}
}
.overlay {
if viewModel.stopwatches.isEmpty {
ContentUnavailableView(
@@ -145,15 +164,14 @@ struct StopwatchListItem: View {
@ObservedObject var viewModel: ContentViewModel
@Binding var selectedStopwatch: Stopwatch?
@Binding var draggingStopwatch: Stopwatch?
@Binding var stopwatchToDelete: Stopwatch?
var body: some View {
Button {
selectedStopwatch = stopwatch
} label: {
StopwatchRow(stopwatch: stopwatch, onDelete: {
withAnimation {
viewModel.deleteStopwatch(id: stopwatch.id)
}
stopwatchToDelete = stopwatch
})
}
.buttonStyle(.plain)
@@ -163,9 +181,7 @@ struct StopwatchListItem: View {
.contentShape(Rectangle())
.contextMenu {
Button(role: .destructive) {
withAnimation {
viewModel.deleteStopwatch(id: stopwatch.id)
}
stopwatchToDelete = stopwatch
} label: {
Label("Delete", systemImage: "trash")
}

View File

@@ -12,9 +12,11 @@ struct StopwatchDetailView: View {
let onSave: (String) -> Void
let onCancel: () -> Void
let onReset: () -> Void
let onDelete: () -> Void
@State private var draftName: String
@State private var isShowingResetAlert = false
@State private var isShowingDeleteAlert = false
private let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
@@ -22,11 +24,12 @@ struct StopwatchDetailView: View {
return formatter
}()
init(stopwatch: Stopwatch, onSave: @escaping (String) -> Void, onCancel: @escaping () -> Void, onReset: @escaping () -> Void) {
init(stopwatch: Stopwatch, onSave: @escaping (String) -> Void, onCancel: @escaping () -> Void, onReset: @escaping () -> Void, onDelete: @escaping () -> Void) {
self.stopwatch = stopwatch
self.onSave = onSave
self.onCancel = onCancel
self.onReset = onReset
self.onDelete = onDelete
_draftName = State(initialValue: stopwatch.name)
}
@@ -112,6 +115,18 @@ struct StopwatchDetailView: View {
}
}
}
Section {
Button(role: .destructive) {
isShowingDeleteAlert = true
} label: {
HStack {
Spacer()
Text("Delete Stopwatch")
Spacer()
}
}
}
}
.navigationTitle("Edit Stopwatch")
.navigationBarTitleDisplayMode(.inline)
@@ -121,6 +136,12 @@ struct StopwatchDetailView: View {
}
Button("Cancel", role: .cancel) {}
}
.alert("Are you sure you want to delete the Stopwatch \(stopwatch.name)?", isPresented: $isShowingDeleteAlert) {
Button("Delete", role: .destructive) {
onDelete()
}
Button("Cancel", role: .cancel) {}
}
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
@@ -143,6 +164,7 @@ struct StopwatchDetailView: View {
stopwatch: Stopwatch(name: "Test Timer"),
onSave: { _ in },
onCancel: {},
onReset: {}
onReset: {},
onDelete: {}
)
}

View File

@@ -20,6 +20,10 @@ struct StopwatchRow: View {
Text("\(stopwatch.formattedTime(format: settings.timeFormat))")
.font(.largeTitle)
.monospacedDigit()
Text("Laps: \(stopwatch.laps.count + (stopwatch.isRunning ? 1 : 0))")
.font(.caption)
.monospaced()
.foregroundStyle(.secondary)
}
Spacer()