add ability to delete labels from ios

This commit is contained in:
Satindar Dhillon
2022-04-05 14:51:06 -07:00
parent aec8059dbb
commit 7ef4b383fb
2 changed files with 99 additions and 3 deletions

View File

@ -46,20 +46,53 @@ final class LabelsViewModel: ObservableObject {
)
.store(in: &subscriptions)
}
func deleteLabel(dataService: DataService, labelID: String) {
isLoading = true
dataService.removeLabelPublisher(labelID: labelID).sink(
receiveCompletion: { [weak self] _ in
self?.isLoading = false
},
receiveValue: { [weak self] _ in
self?.isLoading = false
self?.labels.removeAll { $0.id == labelID }
}
)
.store(in: &subscriptions)
}
}
struct LabelsView: View {
@EnvironmentObject var dataService: DataService
@StateObject var viewModel = LabelsViewModel()
@State private var showDeleteConfirmation = false
@State private var labelToRemoveID: String?
let footerText = "Use labels to create curated collections of links."
var body: some View {
Group {
#if os(iOS)
Form {
innerBody
if #available(iOS 15.0, *) {
Form {
innerBody
.alert("Are you sure you want to delete this label?", isPresented: $showDeleteConfirmation) {
Button("Remove Link", role: .destructive) {
if let labelID = labelToRemoveID {
withAnimation {
viewModel.deleteLabel(dataService: dataService, labelID: labelID)
}
}
self.labelToRemoveID = nil
}
Button("Cancel", role: .cancel) { self.labelToRemoveID = nil }
}
}
} else {
Form { innerBody }
}
#elseif os(macOS)
List {
innerBody
@ -89,7 +122,17 @@ struct LabelsView: View {
if !viewModel.labels.isEmpty {
Section(header: Text("Labels")) {
ForEach(viewModel.labels, id: \.id) { label in
Text(label.name)
HStack {
Text(label.name)
Spacer()
Button(
action: {
labelToRemoveID = label.id
showDeleteConfirmation = true
},
label: { Image(systemName: "trash") }
)
}
}
}
}

View File

@ -0,0 +1,53 @@
import Combine
import Foundation
import Models
import SwiftGraphQL
public extension DataService {
func removeLabelPublisher(labelID: String) -> AnyPublisher<Bool, BasicError> {
enum MutationResult {
case success(labelID: String)
case error(errorCode: Enums.DeleteLabelErrorCode)
}
let selection = Selection<MutationResult, Unions.DeleteLabelResult> {
try $0.on(
deleteLabelSuccess: .init {
.success(labelID: try $0.label(selection: Selection.Label { try $0.id() }))
},
deleteLabelError: .init { .error(errorCode: try $0.errorCodes().first ?? .badRequest) }
)
}
let mutation = Selection.Mutation {
try $0.deleteLabel(id: labelID, selection: selection)
}
let path = appEnvironment.graphqlPath
let headers = networker.defaultHeaders
return Deferred {
Future { promise in
send(mutation, to: path, headers: headers) { result in
switch result {
case let .success(payload):
if payload.errors != nil {
promise(.failure(.message(messageText: "Error removing label")))
}
switch payload.data {
case .success:
promise(.success(true))
case .error:
promise(.failure(.message(messageText: "Error removing label")))
}
case .failure:
promise(.failure(.message(messageText: "Error removing label")))
}
}
}
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}