Allow cap deletion

This commit is contained in:
Christoph Hagen 2023-03-13 11:07:22 +01:00
parent 441197144f
commit 37fb3b4a88
2 changed files with 71 additions and 9 deletions

View File

@ -46,6 +46,9 @@ struct ContentView: View {
@State
var showUpdateCapNameAlert = false
@State
var showDeleteCapAlert = false
@State
var updatedCapName = ""
@ -138,10 +141,13 @@ struct ContentView: View {
Label("Rename", systemSymbol: .pencil)
}
.tint(.purple)
Button(role: .destructive) { startDeleteCap(cap: cap)
Button {
selectedCapId = cap.id
showDeleteCapAlert = true
} label: {
Label("Delete", systemSymbol: .trashCircleFill)
}
.tint(.red)
}
.swipeActions(edge: .leading) {
Button {
@ -149,7 +155,7 @@ struct ContentView: View {
} label: {
Label("Images", systemSymbol: .photoStack)
}
.tint(.purple)
.tint(.blue)
}
}
.refreshable {
@ -288,6 +294,14 @@ struct ContentView: View {
primaryButton: .default(Text("Download"), action: downloadClassifier),
secondaryButton: .cancel())
}
.alert(Text("Delete cap"),
isPresented: $showDeleteCapAlert,
actions: {
Button("Delete", role: .destructive, action: saveNewCapName)
Button("Cancel", role: .cancel, action: {})
}, message: {
Text("Confirm the deletion of cap \(selectedCapId ?? 0)")
})
.alert("Update name", isPresented: $showUpdateCapNameAlert, actions: {
TextField("Name", text: $updatedCapName)
Button("Update", action: saveNewCapName)
@ -405,8 +419,15 @@ struct ContentView: View {
showImageOverviewForCap = true
}
private func startDeleteCap(cap: Cap) {
// TODO: Implement
private func startDeleteCap() {
guard let cap = selectedCapId else {
return
}
Task {
guard await database.delete(cap: cap) else {
return
}
}
}
}

View File

@ -35,7 +35,11 @@ final class Database: ObservableObject {
}
var nextCapId: Int {
(caps.values.max()?.id ?? 0) + 1
var next = 1
while caps[next] != nil {
next += 1
}
return next
}
@AppStorage("changed")
@ -621,15 +625,15 @@ final class Database: ObservableObject {
func delete(image: CapImage) async -> Bool {
guard hasServerAuthentication else {
log("No authorization to set main image")
log("No authorization to delete cap image")
return false
}
guard var cap = cap(for: image.cap) else {
log("No cap \(image.cap) to set main image")
guard let cap = cap(for: image.cap) else {
log("No cap \(image.cap) to delete cap image")
return false
}
guard image.version < cap.imageCount else {
log("Invalid main image \(image.version) for \(cap.id) with only \(cap.imageCount) images")
log("Invalid image \(image.version) to delete for \(cap.id) with only \(cap.imageCount) images")
return false
}
@ -667,6 +671,43 @@ final class Database: ObservableObject {
}
}
func delete(cap: Int) async -> Bool {
guard hasServerAuthentication else {
log("No authorization to delete cap")
return false
}
guard caps[cap] != nil else {
log("No cap \(cap) to delete")
return false
}
let url = serverUrl.appendingPathComponent("delete/\(cap)")
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue(serverAuthenticationKey, forHTTPHeaderField: "key")
do {
let (_, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse else {
log("Unexpected response deleting cap \(cap): \(response)")
return false
}
guard httpResponse.statusCode == 200 else {
log("Failed to delete cap \(cap): Response \(httpResponse.statusCode)")
return false
}
// Delete cached images
images.removeCachedImages(for: cap)
// Delete cap
caps[cap] = nil
log("Deleted cap \(cap)")
return true
} catch {
log("Failed to delete cap \(cap): \(error)")
return false
}
}
// MARK: Classification
/// The compiled recognition model on disk