From 27df9d3ffde449395509db8dc121baf64c33948d Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 10:47:20 +0100 Subject: [PATCH 1/7] Implemented the DeleteItemViewModifier view modifier. --- .../Resources/en.lproj/Localizable.strings | 10 +++ .../UI/Extensions/View+ViewModifiers.swift | 6 ++ .../DeleteItemViewModifier.swift | 76 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift diff --git a/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings b/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings index 6cef50f..91ca247 100644 --- a/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings +++ b/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings @@ -25,6 +25,16 @@ "message.type_not_supported.text.second" = "Please be patient while the support for this type of document is being built by our development team."; "message.type_not_supported.button.text" = "Go back to folder"; +// DeleteItemViewModifier + +"delete_item.action_sheet.title" = "Delete an item"; +"delete_item.action_sheet.message" = "You are about to delete an item named \"%@\" from this folder.\n\nAre you sure you wish to proceed?"; +"delete_item.action_sheet.button.ok" = "Yes, please delete it."; +"delete_item.action_sheet.button.cancel" = "No, I reconsidered."; +"delete_item.system_alert.title" = "..."; +"delete_item.system_alert.message" = "..."; +"delete_item.system_alert.button.dismiss" = "..."; + // BrowseView "browse.toolbar_item.menu.add_actions.text" = "Add file and/or folder"; diff --git a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift index 7b199c9..d2f9003 100644 --- a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift +++ b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift @@ -20,4 +20,10 @@ extension View { destination: { destination } )) } + + func delete( + item: Binding<(any FileSystemItemIdentifiable)?> + ) -> some View { + modifier(DeleteItemViewModifier(item: item)) + } } diff --git a/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift new file mode 100644 index 0000000..d92ce12 --- /dev/null +++ b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift @@ -0,0 +1,76 @@ +// +// DeleteItemViewModifier.swift +// Browse +// +// Created by Javier Cicchelli on 16/12/2022. +// + +import SwiftUI + +struct DeleteItemViewModifier: ViewModifier { + + // MARK: States + + @State private var showErrorAlert: Bool = false + + // MARK: Bindings + + @Binding var item: (any FileSystemItemIdentifiable)? + + // MARK: Body + + func body(content: Content) -> some View { + content + .actionSheet(isPresented: showDeletionConfirmation) { + ActionSheet( + title: Text( + "delete_item.action_sheet.title", + bundle: .module + ), + message: Text( + "delete_item.action_sheet.message", + bundle: .module + ), + buttons: [ + .destructive(Text( + "delete_item.action_sheet.button.ok", + bundle: .module + )) { + // TODO: implement the deletion of an item from the backend. + }, + .cancel(Text( + "delete_item.action_sheet.button.cancel", + bundle: .module + )) { + item = nil + }, + ] + ) + } + .alert(isPresented: $showErrorAlert) { + Alert( + title: Text( + "delete_item.system_alert.title", + bundle: .module + ), + message: Text( + "delete_item.system_alert.message", + bundle: .module + ), + dismissButton: .cancel(Text( + "delete_item.system_alert.button.dismiss", + bundle: .module + )) + ) + } + } + +} + +// MARK: - Helpers + +private extension DeleteItemViewModifier { + var showDeletionConfirmation: Binding { + .init { item != nil } set: { _ in } + } +} From 34f7813a5c58d674fc05806df7b9450933006ad5 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 10:48:21 +0100 Subject: [PATCH 2/7] Implemented the "delete(item:)" view modifier in the BrowseView view for the Browse module. --- Modules/Sources/Browse/UI/Views/BrowseView.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/Sources/Browse/UI/Views/BrowseView.swift b/Modules/Sources/Browse/UI/Views/BrowseView.swift index 74821b9..29ffc97 100644 --- a/Modules/Sources/Browse/UI/Views/BrowseView.swift +++ b/Modules/Sources/Browse/UI/Views/BrowseView.swift @@ -21,6 +21,7 @@ public struct BrowseView: View { @State private var status: ViewStatus = .loading @State private var items: [any FileSystemItemIdentifiable] = [] @State private var stack: Stack? + @State private var itemToDelete: (any FileSystemItemIdentifiable)? // MARK: Properties @@ -60,6 +61,7 @@ public struct BrowseView: View { showProfile: showProfile ) } + .delete(item: $itemToDelete) .task(id: folder) { await loadItems() } @@ -118,7 +120,7 @@ private extension BrowseView { FolderItem(item: item) { stack = .browse(folder) } delete: { - // TODO: delete the item id from the backend. + itemToDelete = item } .navigate( to: BrowseView( @@ -145,7 +147,7 @@ private extension BrowseView { } download: { // TODO: download the item id from the backend. } delete: { - // TODO: delete the item id from the backend. + itemToDelete = item } .navigate( to: DocumentView( From d357c1a069719b514abaa652549c6f694c0cfd69 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 16:37:49 +0100 Subject: [PATCH 3/7] Renamed the FileSystemItemIdentifiable protocol as FileSystemItemable for the Browse module. --- .../Sources/Browse/Logic/Models/Document.swift | 4 ++-- .../Sources/Browse/Logic/Models/Folder.swift | 4 ++-- .../Logic/Protocols/FileSystemItem.swift | 2 +- .../Logic/Use Cases/GetDataUseCase.swift | 14 ++++++++++++-- .../Logic/Use Cases/GetItemsUseCase.swift | 18 ++++++++++++++---- .../UI/Extensions/View+ViewModifiers.swift | 2 +- .../DeleteItemViewModifier.swift | 2 +- .../Sources/Browse/UI/Views/BrowseView.swift | 10 +++++----- 8 files changed, 38 insertions(+), 18 deletions(-) diff --git a/Modules/Sources/Browse/Logic/Models/Document.swift b/Modules/Sources/Browse/Logic/Models/Document.swift index 46df5eb..053a7d1 100644 --- a/Modules/Sources/Browse/Logic/Models/Document.swift +++ b/Modules/Sources/Browse/Logic/Models/Document.swift @@ -36,6 +36,6 @@ struct Document { } -// MARK: - FileSystemIdIdentifiable +// MARK: - FileSystemItemable -extension Document: FileSystemItemIdentifiable {} +extension Document: FileSystemItemable {} diff --git a/Modules/Sources/Browse/Logic/Models/Folder.swift b/Modules/Sources/Browse/Logic/Models/Folder.swift index b089e36..abf8b8e 100644 --- a/Modules/Sources/Browse/Logic/Models/Folder.swift +++ b/Modules/Sources/Browse/Logic/Models/Folder.swift @@ -25,9 +25,9 @@ public struct Folder { } -// MARK: - FileSystemIdIdentifiable +// MARK: - FileSystemItemable -extension Folder: FileSystemItemIdentifiable {} +extension Folder: FileSystemItemable {} // MARK: - Equatable diff --git a/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift b/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift index d4f4d04..c4a9ae8 100644 --- a/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift +++ b/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift @@ -13,4 +13,4 @@ protocol FileSystemItem { // MARK: - Type aliases -typealias FileSystemItemIdentifiable = FileSystemItem & Identifiable & Hashable +typealias FileSystemItemable = FileSystemItem & Identifiable & Hashable diff --git a/Modules/Sources/Browse/Logic/Use Cases/GetDataUseCase.swift b/Modules/Sources/Browse/Logic/Use Cases/GetDataUseCase.swift index 5b87e28..daee2de 100644 --- a/Modules/Sources/Browse/Logic/Use Cases/GetDataUseCase.swift +++ b/Modules/Sources/Browse/Logic/Use Cases/GetDataUseCase.swift @@ -13,9 +13,9 @@ import Foundation struct GetDataUseCase { - // MARK: Dependencies + // MARK: Properties - @Dependency(\.apiService) private var apiService + let apiService: APIService // MARK: Functions @@ -34,3 +34,13 @@ struct GetDataUseCase { } } + +// MARK: - Initialisers + +extension GetDataUseCase { + init() { + @Dependency(\.apiService) var apiService + + self.init(apiService: apiService) + } +} diff --git a/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift b/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift index bbd219f..54aa3c9 100644 --- a/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift +++ b/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift @@ -12,9 +12,9 @@ import Dependencies struct GetItemsUseCase { - // MARK: Dependencies + // MARK: Properties - @Dependency(\.apiService) private var apiService + let apiService: APIService // MARK: Functions @@ -22,7 +22,7 @@ struct GetItemsUseCase { id: String, username: String, password: String - ) async throws -> [any FileSystemItemIdentifiable] { + ) async throws -> [any FileSystemItemable] { let items = try await apiService.getItems( id: id, credentials: .init( @@ -32,7 +32,7 @@ struct GetItemsUseCase { ) return items - .compactMap { item -> any FileSystemItemIdentifiable in + .compactMap { item -> any FileSystemItemable in if item.isDirectory { return Folder( id: item.id, @@ -51,3 +51,13 @@ struct GetItemsUseCase { } } + +// MARK: - Initialisers + +extension GetItemsUseCase { + init() { + @Dependency(\.apiService) var apiService + + self.init(apiService: apiService) + } +} diff --git a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift index d2f9003..8e3d494 100644 --- a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift +++ b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift @@ -22,7 +22,7 @@ extension View { } func delete( - item: Binding<(any FileSystemItemIdentifiable)?> + item: Binding<(any FileSystemItemable)?>, ) -> some View { modifier(DeleteItemViewModifier(item: item)) } diff --git a/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift index d92ce12..ac5a170 100644 --- a/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift +++ b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift @@ -15,7 +15,7 @@ struct DeleteItemViewModifier: ViewModifier { // MARK: Bindings - @Binding var item: (any FileSystemItemIdentifiable)? + @Binding var item: (any FileSystemItemable)? // MARK: Body diff --git a/Modules/Sources/Browse/UI/Views/BrowseView.swift b/Modules/Sources/Browse/UI/Views/BrowseView.swift index 29ffc97..f47cc48 100644 --- a/Modules/Sources/Browse/UI/Views/BrowseView.swift +++ b/Modules/Sources/Browse/UI/Views/BrowseView.swift @@ -19,9 +19,9 @@ public struct BrowseView: View { // MARK: States @State private var status: ViewStatus = .loading - @State private var items: [any FileSystemItemIdentifiable] = [] + @State private var items: [any FileSystemItemable] = [] @State private var stack: Stack? - @State private var itemToDelete: (any FileSystemItemIdentifiable)? + @State private var itemToDelete: (any FileSystemItemable)? // MARK: Properties @@ -32,7 +32,7 @@ public struct BrowseView: View { private let login: ActionClosure private let getItems: GetItemsUseCase = .init() - + // MARK: Initialisers public init( @@ -114,7 +114,7 @@ private extension BrowseView { // MARK: Functions @ViewBuilder func makeFolderItem( - for item: any FileSystemItemIdentifiable + for item: any FileSystemItemable ) -> some View { if let folder = item as? Folder { FolderItem(item: item) { @@ -139,7 +139,7 @@ private extension BrowseView { } @ViewBuilder func makeDocumentItem( - for item: any FileSystemItemIdentifiable + for item: any FileSystemItemable ) -> some View { if let document = item as? Document { DocumentItem(item: item) { From 228438454feaf3a41e132f84b398a44be824c12e Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 16:38:48 +0100 Subject: [PATCH 4/7] Implemented the DeleteItemUseCase use case for the Browse module. --- .../Logic/Use Cases/DeleteItemUseCase.swift | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Modules/Sources/Browse/Logic/Use Cases/DeleteItemUseCase.swift diff --git a/Modules/Sources/Browse/Logic/Use Cases/DeleteItemUseCase.swift b/Modules/Sources/Browse/Logic/Use Cases/DeleteItemUseCase.swift new file mode 100644 index 0000000..505353b --- /dev/null +++ b/Modules/Sources/Browse/Logic/Use Cases/DeleteItemUseCase.swift @@ -0,0 +1,45 @@ +// +// DeleteItemUseCase.swift +// Browse +// +// Created by Javier Cicchelli on 16/12/2022. +// Copyright © 2022 Röck+Cöde. All rights reserved. +// + +import APIService +import DependencyInjection +import Dependencies + +struct DeleteItemUseCase { + + // MARK: Properties + + let apiService: APIService + + // MARK: Functions + + func callAsFunction( + id: String, + username: String, + password: String + ) async throws { + try await apiService.deleteItem( + id: id, + credentials: .init( + username: username, + password: password + ) + ) + } + +} + +// MARK: - Initialisers + +extension DeleteItemUseCase { + init() { + @Dependency(\.apiService) var apiService + + self.init(apiService: apiService) + } +} From 13010816e151b16728951301f733cc86d9c735bd Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 17:20:19 +0100 Subject: [PATCH 5/7] Replaced the FileSystemItemable protocol with the FileSystemItem one for the Browse module. --- Modules/Sources/Browse/Logic/Models/Document.swift | 6 +----- Modules/Sources/Browse/Logic/Models/Folder.swift | 10 +--------- .../Browse/Logic/Protocols/FileSystemItem.swift | 6 +----- .../Browse/Logic/Use Cases/GetItemsUseCase.swift | 4 ++-- .../Sources/Browse/UI/Components/DocumentItem.swift | 2 +- Modules/Sources/Browse/UI/Components/FolderItem.swift | 2 +- .../Browse/UI/Extensions/View+ViewModifiers.swift | 2 +- .../UI/View Modifiers/DeleteItemViewModifier.swift | 2 +- Modules/Sources/Browse/UI/Views/BrowseView.swift | 8 ++++---- 9 files changed, 13 insertions(+), 29 deletions(-) diff --git a/Modules/Sources/Browse/Logic/Models/Document.swift b/Modules/Sources/Browse/Logic/Models/Document.swift index 053a7d1..913a310 100644 --- a/Modules/Sources/Browse/Logic/Models/Document.swift +++ b/Modules/Sources/Browse/Logic/Models/Document.swift @@ -8,7 +8,7 @@ import Foundation -struct Document { +struct Document: FileSystemItem { // MARK: Properties @@ -35,7 +35,3 @@ struct Document { } } - -// MARK: - FileSystemItemable - -extension Document: FileSystemItemable {} diff --git a/Modules/Sources/Browse/Logic/Models/Folder.swift b/Modules/Sources/Browse/Logic/Models/Folder.swift index abf8b8e..63c22ea 100644 --- a/Modules/Sources/Browse/Logic/Models/Folder.swift +++ b/Modules/Sources/Browse/Logic/Models/Folder.swift @@ -6,7 +6,7 @@ // Copyright © 2022 Röck+Cöde. All rights reserved. // -public struct Folder { +public struct Folder: FileSystemItem { // MARK: Properties @@ -24,11 +24,3 @@ public struct Folder { } } - -// MARK: - FileSystemItemable - -extension Folder: FileSystemItemable {} - -// MARK: - Equatable - -extension Folder: Equatable {} diff --git a/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift b/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift index c4a9ae8..69b3931 100644 --- a/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift +++ b/Modules/Sources/Browse/Logic/Protocols/FileSystemItem.swift @@ -6,11 +6,7 @@ // Copyright © 2022 Röck+Cöde. All rights reserved. // -protocol FileSystemItem { +protocol FileSystemItem: Identifiable, Hashable, Equatable { var id: String { get } var name: String { get } } - -// MARK: - Type aliases - -typealias FileSystemItemable = FileSystemItem & Identifiable & Hashable diff --git a/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift b/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift index 54aa3c9..281b6dc 100644 --- a/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift +++ b/Modules/Sources/Browse/Logic/Use Cases/GetItemsUseCase.swift @@ -22,7 +22,7 @@ struct GetItemsUseCase { id: String, username: String, password: String - ) async throws -> [any FileSystemItemable] { + ) async throws -> [any FileSystemItem] { let items = try await apiService.getItems( id: id, credentials: .init( @@ -32,7 +32,7 @@ struct GetItemsUseCase { ) return items - .compactMap { item -> any FileSystemItemable in + .compactMap { item -> any FileSystemItem in if item.isDirectory { return Folder( id: item.id, diff --git a/Modules/Sources/Browse/UI/Components/DocumentItem.swift b/Modules/Sources/Browse/UI/Components/DocumentItem.swift index 73b9f48..f895f2d 100644 --- a/Modules/Sources/Browse/UI/Components/DocumentItem.swift +++ b/Modules/Sources/Browse/UI/Components/DocumentItem.swift @@ -13,7 +13,7 @@ struct DocumentItem: View { // MARK: Properties - let item: FileSystemItem + let item: any FileSystemItem let select: ActionClosure let download: ActionClosure let delete: ActionClosure diff --git a/Modules/Sources/Browse/UI/Components/FolderItem.swift b/Modules/Sources/Browse/UI/Components/FolderItem.swift index 40733f4..fc1811b 100644 --- a/Modules/Sources/Browse/UI/Components/FolderItem.swift +++ b/Modules/Sources/Browse/UI/Components/FolderItem.swift @@ -13,7 +13,7 @@ struct FolderItem: View { // MARK: Properties - let item: FileSystemItem + let item: any FileSystemItem let select: ActionClosure let delete: ActionClosure diff --git a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift index 8e3d494..9f01b9c 100644 --- a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift +++ b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift @@ -22,7 +22,7 @@ extension View { } func delete( - item: Binding<(any FileSystemItemable)?>, + item: Binding<(any FileSystemItem)?>, ) -> some View { modifier(DeleteItemViewModifier(item: item)) } diff --git a/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift index ac5a170..c4e9960 100644 --- a/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift +++ b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift @@ -15,7 +15,7 @@ struct DeleteItemViewModifier: ViewModifier { // MARK: Bindings - @Binding var item: (any FileSystemItemable)? + @Binding var item: (any FileSystemItem)? // MARK: Body diff --git a/Modules/Sources/Browse/UI/Views/BrowseView.swift b/Modules/Sources/Browse/UI/Views/BrowseView.swift index f47cc48..f31931f 100644 --- a/Modules/Sources/Browse/UI/Views/BrowseView.swift +++ b/Modules/Sources/Browse/UI/Views/BrowseView.swift @@ -19,9 +19,9 @@ public struct BrowseView: View { // MARK: States @State private var status: ViewStatus = .loading - @State private var items: [any FileSystemItemable] = [] + @State private var items: [any FileSystemItem] = [] @State private var stack: Stack? - @State private var itemToDelete: (any FileSystemItemable)? + @State private var itemToDelete: (any FileSystemItem)? // MARK: Properties @@ -114,7 +114,7 @@ private extension BrowseView { // MARK: Functions @ViewBuilder func makeFolderItem( - for item: any FileSystemItemable + for item: any FileSystemItem ) -> some View { if let folder = item as? Folder { FolderItem(item: item) { @@ -139,7 +139,7 @@ private extension BrowseView { } @ViewBuilder func makeDocumentItem( - for item: any FileSystemItemable + for item: any FileSystemItem ) -> some View { if let document = item as? Document { DocumentItem(item: item) { From b333c7acac9f48b5fdca3cc26f78df278a456ba8 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 17:22:02 +0100 Subject: [PATCH 6/7] Implemented the item deletion in the DeleteItemViewModifier view modifier for the Browse module. --- .../Resources/en.lproj/Localizable.strings | 2 +- .../UI/Extensions/View+ViewModifiers.swift | 7 ++- .../DeleteItemViewModifier.swift | 63 +++++++++++++++++-- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings b/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings index 91ca247..5336bc7 100644 --- a/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings +++ b/Modules/Sources/Browse/Resources/en.lproj/Localizable.strings @@ -28,7 +28,7 @@ // DeleteItemViewModifier "delete_item.action_sheet.title" = "Delete an item"; -"delete_item.action_sheet.message" = "You are about to delete an item named \"%@\" from this folder.\n\nAre you sure you wish to proceed?"; +"delete_item.action_sheet.message %@" = "You are about to delete an item named \"%@\" from this folder.\n\nAre you sure you wish to proceed?"; "delete_item.action_sheet.button.ok" = "Yes, please delete it."; "delete_item.action_sheet.button.cancel" = "No, I reconsidered."; "delete_item.system_alert.title" = "..."; diff --git a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift index 9f01b9c..ce602dc 100644 --- a/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift +++ b/Modules/Sources/Browse/UI/Extensions/View+ViewModifiers.swift @@ -6,6 +6,7 @@ // Copyright © 2022 Röck+Cöde. All rights reserved. // +import DataModels import SwiftUI extension View { @@ -23,7 +24,11 @@ extension View { func delete( item: Binding<(any FileSystemItem)?>, + deleted: @escaping ActionClosure ) -> some View { - modifier(DeleteItemViewModifier(item: item)) + modifier(DeleteItemViewModifier( + item: item, + deleted: deleted + )) } } diff --git a/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift index c4e9960..aa1e6ab 100644 --- a/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift +++ b/Modules/Sources/Browse/UI/View Modifiers/DeleteItemViewModifier.swift @@ -5,9 +5,15 @@ // Created by Javier Cicchelli on 16/12/2022. // +import DataModels +import KeychainStorage import SwiftUI struct DeleteItemViewModifier: ViewModifier { + + // MARK: Storages + + @KeychainStorage(key: .KeychainStorage.account) private var account: Account? // MARK: States @@ -17,6 +23,12 @@ struct DeleteItemViewModifier: ViewModifier { @Binding var item: (any FileSystemItem)? + // MARK: Properties + + let deleted: ActionClosure + + private let deleteItem: DeleteItemUseCase = .init() + // MARK: Body func body(content: Content) -> some View { @@ -28,7 +40,7 @@ struct DeleteItemViewModifier: ViewModifier { bundle: .module ), message: Text( - "delete_item.action_sheet.message", + "delete_item.action_sheet.message \(itemName)", bundle: .module ), buttons: [ @@ -36,7 +48,9 @@ struct DeleteItemViewModifier: ViewModifier { "delete_item.action_sheet.button.ok", bundle: .module )) { - // TODO: implement the deletion of an item from the backend. + Task { + await removeItem() + } }, .cancel(Text( "delete_item.action_sheet.button.cancel", @@ -58,9 +72,11 @@ struct DeleteItemViewModifier: ViewModifier { bundle: .module ), dismissButton: .cancel(Text( - "delete_item.system_alert.button.dismiss", + "delete_item.system_alert.button.cancel", bundle: .module - )) + )) { + item = nil + } ) } } @@ -70,7 +86,46 @@ struct DeleteItemViewModifier: ViewModifier { // MARK: - Helpers private extension DeleteItemViewModifier { + + // MARK: Computed + + var itemName: String { + item?.name ?? .Constants.noName + } + var showDeletionConfirmation: Binding { .init { item != nil } set: { _ in } } + + // MARK: Functions + + func removeItem() async { + guard + let id = item?.id, + let account + else { + showErrorAlert = true + return + } + + do { + try await deleteItem( + id: id, + username: account.username, + password: account.password + ) + + deleted() + } catch { + showErrorAlert = true + } + } +} + +// MARK: - String+Constants + +private extension String { + enum Constants { + static let noName = "no name" + } } From 10b686c11827b467a045adac5f796b7fa23f06b6 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 17:22:31 +0100 Subject: [PATCH 7/7] Integrated the item deletion into the BrowseView view for the Browse module. --- Modules/Sources/Browse/UI/Views/BrowseView.swift | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Modules/Sources/Browse/UI/Views/BrowseView.swift b/Modules/Sources/Browse/UI/Views/BrowseView.swift index f31931f..067521c 100644 --- a/Modules/Sources/Browse/UI/Views/BrowseView.swift +++ b/Modules/Sources/Browse/UI/Views/BrowseView.swift @@ -61,7 +61,11 @@ public struct BrowseView: View { showProfile: showProfile ) } - .delete(item: $itemToDelete) + .delete(item: $itemToDelete) { + Task { + await updateItems() + } + } .task(id: folder) { await loadItems() } @@ -192,6 +196,11 @@ private extension BrowseView { status = .error } } + + func updateItems() async { + items = items.filter { $0.id != itemToDelete?.id } + itemToDelete = nil + } } // MARK: - Previews