diff options
Diffstat (limited to 'Hotline/macOS/FilesView.swift')
| -rw-r--r-- | Hotline/macOS/FilesView.swift | 182 |
1 files changed, 90 insertions, 92 deletions
diff --git a/Hotline/macOS/FilesView.swift b/Hotline/macOS/FilesView.swift index 57a9aeb..fd5826f 100644 --- a/Hotline/macOS/FilesView.swift +++ b/Hotline/macOS/FilesView.swift @@ -3,21 +3,21 @@ import UniformTypeIdentifiers struct FolderView: View { @Environment(Hotline.self) private var model: Hotline - + @State var loading = false @State var dragOver = false - + var file: FileInfo let depth: Int - + @MainActor private func uploadFile(file fileURL: URL) { var filePath: [String] = [String](self.file.path) if !self.file.isFolder { filePath.removeLast() } - + print("UPLOADING TO PATH: ", filePath) - + model.uploadFile(url: fileURL, path: filePath) { info in Task { // Refresh file listing to display newly uploaded file. @@ -25,12 +25,12 @@ struct FolderView: View { } } } - + var body: some View { HStack(alignment: .center, spacing: 0) { Spacer() .frame(width: CGFloat(depth * (12 + 2))) - + Button { if file.isFolder { file.expanded.toggle() @@ -46,26 +46,23 @@ struct FolderView: View { .frame(width: 10) .padding(.leading, 4) .padding(.trailing, 8) - + HStack(alignment: .center) { if file.isUnavailable { Image(systemName: "questionmark.app.fill") .frame(width: 16, height: 16) .opacity(0.5) - } - else if file.isAdminDropboxFolder { + } else if file.isAdminDropboxFolder { Image("Admin Drop Box") .resizable() .scaledToFit() .frame(width: 16, height: 16) - } - else if file.isDropboxFolder { + } else if file.isDropboxFolder { Image("Drop Box") .resizable() .scaledToFit() .frame(width: 16, height: 16) - } - else { + } else { Image("Folder") .resizable() .scaledToFit() @@ -74,13 +71,13 @@ struct FolderView: View { } .frame(width: 16) .padding(.trailing, 6) - + Text(file.name) .lineLimit(1) .truncationMode(.tail) .foregroundStyle(dragOver ? Color.white : Color.primary) .opacity(file.isUnavailable ? 0.5 : 1.0) - + if loading { ProgressView().controlSize(.small).padding([.leading, .trailing], 5) } @@ -111,28 +108,29 @@ struct FolderView: View { } .onDrop(of: [.fileURL], isTargeted: $dragOver) { items in guard let item = items.first, - let identifier = item.registeredTypeIdentifiers.first else { + let identifier = item.registeredTypeIdentifiers.first + else { return false } - + item.loadItem(forTypeIdentifier: identifier, options: nil) { (urlData, error) in DispatchQueue.main.async { if let urlData = urlData as? Data, - let fileURL = URL(dataRepresentation: urlData, relativeTo: nil, isAbsolute: true) { + let fileURL = URL(dataRepresentation: urlData, relativeTo: nil, isAbsolute: true) + { uploadFile(file: fileURL) } } } - + return true } - + if file.expanded { ForEach(file.children!, id: \.self) { childFile in if childFile.isFolder { FolderView(file: childFile, depth: self.depth + 1).tag(file.id) - } - else { + } else { FileView(file: childFile, depth: self.depth + 1).tag(file.id) } } @@ -142,34 +140,33 @@ struct FolderView: View { struct FileView: View { @Environment(Hotline.self) private var model: Hotline - + var file: FileInfo let depth: Int - + var body: some View { HStack(alignment: .center, spacing: 0) { Spacer() .frame(width: CGFloat(depth * (12 + 2))) - + Spacer() .frame(width: 10) .padding(.leading, 4) .padding(.trailing, 8) - + HStack(alignment: .center) { if file.isUnavailable { Image(systemName: "questionmark.app.fill") .frame(width: 16, height: 16) .opacity(0.5) - } - else { + } else { FileIconView(filename: file.name, fileType: file.type) .frame(width: 16, height: 16) } } .frame(width: 16) .padding(.trailing, 6) - + Text(file.name) .lineLimit(1) .truncationMode(.tail) @@ -189,16 +186,15 @@ struct FileView: View { ForEach(file.children!, id: \.self) { childFile in if childFile.isFolder { FolderView(file: childFile, depth: self.depth + 1).tag(file.id) - } - else { + } else { FileView(file: childFile, depth: self.depth + 1).tag(file.id) } } } } - + static let byteFormatter = ByteCountFormatter() - + private func formattedFileSize(_ fileSize: UInt) -> String { FileView.byteFormatter.allowedUnits = [.useAll] FileView.byteFormatter.countStyle = .file @@ -209,11 +205,11 @@ struct FileView: View { struct FilesView: View { @Environment(Hotline.self) private var model: Hotline @Environment(\.openWindow) private var openWindow - + @State private var selection: FileInfo? @State private var fileDetails: FileDetails? @State private var uploadFileSelectorDisplayed: Bool = false - + private func openPreviewWindow(_ previewInfo: PreviewFileInfo) { switch previewInfo.previewType { case .image: @@ -224,7 +220,7 @@ struct FilesView: View { return } } - + @MainActor private func getFileInfo(_ file: FileInfo) { Task { if let fileInfo = await model.getFileDetails(file.name, path: file.path) { @@ -234,15 +230,15 @@ struct FilesView: View { } } } - + @MainActor private func downloadFile(_ file: FileInfo) { guard !file.isFolder else { return } - + model.downloadFile(file.name, path: file.path) } - + @MainActor private func uploadFile(file fileURL: URL, to path: [String]) { model.uploadFile(url: fileURL, path: path) { info in Task { @@ -251,30 +247,30 @@ struct FilesView: View { } } } - + @MainActor private func previewFile(_ file: FileInfo) { guard file.isPreviewable else { return } - + model.previewFile(file.name, path: file.path) { info in if let info = info { openPreviewWindow(info) } } } - + private func deleteFile(_ file: FileInfo) async { var parentPath: [String] = [] if file.path.count > 1 { - parentPath = Array(file.path[0..<file.path.count-1]) + parentPath = Array(file.path[0..<file.path.count - 1]) } - + if await model.deleteFile(file.name, path: file.path) { let _ = await model.getFileList(path: parentPath) } } - + // Friendship Quest Remix private func isInHomeFolder(_ file: FileInfo?) -> Bool { if let file { @@ -282,14 +278,13 @@ struct FilesView: View { } return false } - + var body: some View { NavigationStack { List(model.files, id: \.self, selection: $selection) { file in if file.isFolder { FolderView(file: file, depth: 0).tag(file.id) - } - else { + } else { FileView(file: file, depth: 0).tag(file.id) } } @@ -303,7 +298,7 @@ struct FilesView: View { } .contextMenu(forSelectionType: FileInfo.self) { items in let selectedFile = items.first - + Button { if let s = selectedFile, !s.isFolder { downloadFile(s) @@ -312,9 +307,9 @@ struct FilesView: View { Label("Download", systemImage: "arrow.down") } .disabled(selectedFile == nil || (selectedFile != nil && selectedFile!.isFolder)) - + Divider() - + Button { if let s = selectedFile { getFileInfo(s) @@ -323,7 +318,7 @@ struct FilesView: View { Label("Get Info", systemImage: "info.circle") } .disabled(selectedFile == nil) - + Button { if let s = selectedFile { previewFile(s) @@ -332,13 +327,13 @@ struct FilesView: View { Label("Preview", systemImage: "eye") } .disabled(selectedFile == nil || (selectedFile != nil && !selectedFile!.isPreviewable)) - + if model.access?.contains(.canDeleteFiles) == true - // Friendship Quest Remix - || isInHomeFolder(selectedFile) + // Friendship Quest Remix + || isInHomeFolder(selectedFile) { Divider() - + Button { if let s = selectedFile { Task { @@ -354,12 +349,11 @@ struct FilesView: View { guard let clickedFile = items.first else { return } - + self.selection = clickedFile if clickedFile.isFolder { clickedFile.expanded.toggle() - } - else { + } else { downloadFile(clickedFile) } } @@ -405,7 +399,7 @@ struct FilesView: View { .help("Preview") .disabled(selection == nil || selection?.isPreviewable == false) } - + ToolbarItem(placement: .primaryAction) { Button { if let selectedFile = selection { @@ -417,7 +411,7 @@ struct FilesView: View { .help("Get Info") .disabled(selection == nil) } - + ToolbarItem(placement: .primaryAction) { Button { uploadFileSelectorDisplayed = true @@ -427,7 +421,7 @@ struct FilesView: View { .help("Upload") .disabled(model.access?.contains(.canUploadFiles) != true) } - + ToolbarItem(placement: .primaryAction) { Button { if let selectedFile = selection, !selectedFile.isFolder { @@ -437,43 +431,47 @@ struct FilesView: View { Label("Download", systemImage: "arrow.down") } .help("Download") - .disabled(selection == nil || selection?.isFolder == true || model.access?.contains(.canDownloadFiles) != true) + .disabled( + selection == nil || selection?.isFolder == true + || model.access?.contains(.canDownloadFiles) != true) } } } - .sheet(item: $fileDetails ) { item in + .sheet(item: $fileDetails) { item in FileDetailsView(fd: item) } - .fileImporter(isPresented: $uploadFileSelectorDisplayed, allowedContentTypes: [.data], allowsMultipleSelection: false, onCompletion: { results in - switch results { - case .success(let fileURLS): - guard fileURLS.count > 0 else { - return - } - - let fileURL = fileURLS.first! - - print(fileURL) - - var uploadPath: [String] = [] - - if let selection = selection { - if selection.isFolder { - uploadPath = selection.path + .fileImporter( + isPresented: $uploadFileSelectorDisplayed, allowedContentTypes: [.data], + allowsMultipleSelection: false, + onCompletion: { results in + switch results { + case .success(let fileURLS): + guard fileURLS.count > 0 else { + return } - else { - uploadPath = Array<String>(selection.path) - uploadPath.removeLast() + + let fileURL = fileURLS.first! + + print(fileURL) + + var uploadPath: [String] = [] + + if let selection = selection { + if selection.isFolder { + uploadPath = selection.path + } else { + uploadPath = [String](selection.path) + uploadPath.removeLast() + } } + + print("UPLOAD PATH: \(uploadPath)") + uploadFile(file: fileURL, to: uploadPath) + + case .failure(let error): + print(error) } - - print("UPLOAD PATH: \(uploadPath)") - uploadFile(file: fileURL, to: uploadPath) - - case .failure(let error): - print(error) - } - }) + }) } } |