Allow cap deletion
This commit is contained in:
parent
441197144f
commit
37fb3b4a88
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user