From c735bd0381671600a3d5ecb32bd6ee0100e8b18d Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Thu, 15 Dec 2022 02:13:14 +0100 Subject: [PATCH] Implemented the support for the view status in the BrowseView view for the Browse module. --- BeReal/UI/Views/ContentView.swift | 6 +- .../Sources/Browse/UI/Views/BrowseView.swift | 134 +++++++++++++----- 2 files changed, 103 insertions(+), 37 deletions(-) diff --git a/BeReal/UI/Views/ContentView.swift b/BeReal/UI/Views/ContentView.swift index e0c3f70..a3b8a2c 100644 --- a/BeReal/UI/Views/ContentView.swift +++ b/BeReal/UI/Views/ContentView.swift @@ -38,6 +38,8 @@ struct ContentView: View { // TODO: upload a new file } showProfile: { showSheet = .profile + } login: { + showSheet = .login } .sheet(item: $showSheet) { sheet in switch sheet { @@ -71,6 +73,7 @@ private extension ContentView { let createFolder: ActionClosure let uploadFile: ActionClosure let showProfile: ActionClosure + let login: ActionClosure // MARK: Body @@ -84,7 +87,8 @@ private extension ContentView { ), createFolder: createFolder, uploadFile: uploadFile, - showProfile: showProfile + showProfile: showProfile, + login: login ) } } else { diff --git a/Modules/Sources/Browse/UI/Views/BrowseView.swift b/Modules/Sources/Browse/UI/Views/BrowseView.swift index ab7dcfe..030c0ed 100644 --- a/Modules/Sources/Browse/UI/Views/BrowseView.swift +++ b/Modules/Sources/Browse/UI/Views/BrowseView.swift @@ -18,6 +18,7 @@ public struct BrowseView: View { // MARK: States + @State private var status: ViewStatus = .loading @State private var items: [any FileSystemItemIdentifiable] = [] @State private var stack: Stack? @@ -27,6 +28,7 @@ public struct BrowseView: View { private let createFolder: ActionClosure private let uploadFile: ActionClosure private let showProfile: ActionClosure + private let login: ActionClosure private let getItems: GetItemsUseCase = .init() @@ -36,51 +38,83 @@ public struct BrowseView: View { folder: Folder, createFolder: @escaping ActionClosure, uploadFile: @escaping ActionClosure, - showProfile: @escaping ActionClosure + showProfile: @escaping ActionClosure, + login: @escaping ActionClosure ) { self.folder = folder self.createFolder = createFolder self.uploadFile = uploadFile self.showProfile = showProfile + self.login = login } // MARK: Body public var body: some View { - List(items, id: \.id) { item in - switch item { - case is Folder: - makeFolderItem(for: item) - case is Document: - DocumentItem(item: item) { - // TODO: show the item id in a viewer... - } download: { - // TODO: download the item id from the backend. - } delete: { - // TODO: delete the item id from the backend. - } - default: - EmptyView() + content + .navigationTitle(folder.name) + .toolbar { + BrowseToolbar( + createFolder: createFolder, + uploadFile: uploadFile, + showProfile: showProfile + ) + } + .task(id: folder) { + await loadItems() } - } - .listStyle(.inset) - .navigationTitle(folder.name) - .toolbar { - BrowseToolbar( - createFolder: createFolder, - uploadFile: uploadFile, - showProfile: showProfile - ) - } - .task(id: folder) { - await getItemsOrStop() - } } } // MARK: - UI private extension BrowseView { + + // MARK: Properties + + @ViewBuilder var content: some View { + switch status { + case .noCredentials: + MessageView( + type: .noCredentials, + action: login + ) + case .loading: + LoadingView() + case .loaded: + List(items, id: \.id) { item in + switch item { + case is Folder: + makeFolderItem(for: item) + case is Document: + DocumentItem(item: item) { + // TODO: show the item id in a viewer... + } download: { + // TODO: download the item id from the backend. + } delete: { + // TODO: delete the item id from the backend. + } + default: + EmptyView() + } + } + .listStyle(.inset) + case .empty: + MessageView( + type: .empty, + action: uploadFile + ) + case .error: + MessageView(type: .error) { + Task { + await loadItems() + } + } + } + } + + // MARK: Functions + @ViewBuilder func makeFolderItem( for item: any FileSystemItemIdentifiable ) -> some View { @@ -99,32 +133,58 @@ private extension BrowseView { folder: folder, createFolder: createFolder, uploadFile: uploadFile, - showProfile: showProfile + showProfile: showProfile, + login: login ), tagged: .browse(folder), in: $stack ) } + } // MARK: - Helpers private extension BrowseView { - func getItemsOrStop() async { - guard let account else { return } + func loadItems() async { + guard let account else { + status = .noCredentials + return + } do { - items = try await getItems( + status = .loading + + let loadedItems = try await getItems( id: folder.id, username: account.username, password: account.password ) + + if loadedItems.isEmpty { + status = .empty + } else { + items = loadedItems + status = .loaded + } } catch { - // TODO: handle the error appropriately. + status = .error } } } +// MARK: - Enumerations + +private extension BrowseView { + enum ViewStatus { + case noCredentials + case loading + case loaded + case empty + case error + } +} + // MARK: - Previews struct BrowseView_Previews: PreviewProvider { @@ -134,11 +194,13 @@ struct BrowseView_Previews: PreviewProvider { id: UUID().uuidString, name: "Some folder name" )) { - // ... + // create folder closure. } uploadFile: { - // ... + // upload file closure. } showProfile: { - // ... + // show profile closure. + } login: { + // login closure. } } }