// // BrowseView.swift // Browse // // Created by Javier Cicchelli on 03/12/2022. // Copyright © 2022 Röck+Cöde. All rights reserved. // import DataModels import KeychainStorage import SwiftUI public struct BrowseView: View { // MARK: Storages @KeychainStorage(key: .KeychainStorage.account) private var account: Account? // MARK: States @State private var items: [any FileSystemItemIdentifiable] = [] @State private var stack: Stack? // MARK: Properties private let folder: Folder private let createFolder: ActionClosure private let uploadFile: ActionClosure private let showProfile: ActionClosure private let getItems: GetItemsUseCase = .init() // MARK: Initialisers public init( folder: Folder, createFolder: @escaping ActionClosure, uploadFile: @escaping ActionClosure, showProfile: @escaping ActionClosure ) { self.folder = folder self.createFolder = createFolder self.uploadFile = uploadFile self.showProfile = showProfile } // 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() } } .listStyle(.inset) .navigationTitle(folder.name) .toolbar { BrowseToolbar( createFolder: createFolder, uploadFile: uploadFile, showProfile: showProfile ) } .task(id: folder) { await getItemsOrStop() } } } // MARK: - UI private extension BrowseView { @ViewBuilder func makeFolderItem( for item: any FileSystemItemIdentifiable ) -> some View { let folder = Folder( id: item.id, name: item.name ) FolderItem(item: item) { stack = .browse(folder) } delete: { // TODO: delete the item id from the backend. } .navigate( to: BrowseView( folder: folder, createFolder: createFolder, uploadFile: uploadFile, showProfile: showProfile ), tagged: .browse(folder), in: $stack ) } } // MARK: - Helpers private extension BrowseView { func getItemsOrStop() async { guard let account else { return } do { items = try await getItems( id: folder.id, username: account.username, password: account.password ) } catch { // TODO: handle the error appropriately. } } } // MARK: - Previews struct BrowseView_Previews: PreviewProvider { static var previews: some View { NavigationView { BrowseView(folder: .init( id: UUID().uuidString, name: "Some folder name" )) { // ... } uploadFile: { // ... } showProfile: { // ... } } } }