aboutsummaryrefslogtreecommitdiff
path: root/Hotline/macOS/FilesView.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Hotline/macOS/FilesView.swift')
-rw-r--r--Hotline/macOS/FilesView.swift481
1 files changed, 0 insertions, 481 deletions
diff --git a/Hotline/macOS/FilesView.swift b/Hotline/macOS/FilesView.swift
deleted file mode 100644
index fd5826f..0000000
--- a/Hotline/macOS/FilesView.swift
+++ /dev/null
@@ -1,481 +0,0 @@
-import SwiftUI
-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.
- let _ = await model.getFileList(path: filePath)
- }
- }
- }
-
- var body: some View {
- HStack(alignment: .center, spacing: 0) {
- Spacer()
- .frame(width: CGFloat(depth * (12 + 2)))
-
- Button {
- if file.isFolder {
- file.expanded.toggle()
- }
- } label: {
- Text(Image(systemName: file.expanded ? "chevron.down" : "chevron.right"))
- .bold()
- .font(.system(size: 10))
- .foregroundStyle(dragOver ? Color.white : Color.primary)
- .opacity(0.5)
- }
- .buttonStyle(.plain)
- .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 {
- Image("Admin Drop Box")
- .resizable()
- .scaledToFit()
- .frame(width: 16, height: 16)
- } else if file.isDropboxFolder {
- Image("Drop Box")
- .resizable()
- .scaledToFit()
- .frame(width: 16, height: 16)
- } else {
- Image("Folder")
- .resizable()
- .scaledToFit()
- .frame(width: 16, height: 16)
- }
- }
- .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)
- }
- Spacer()
- if !file.isUnavailable {
- Text(file.fileSize == 0 ? "Empty" : "^[\(file.fileSize) \("file")](inflect: true)")
- .foregroundStyle(dragOver ? Color.white.opacity(0.75) : Color.secondary)
- .lineLimit(1)
- .padding(.trailing, 6)
- }
- }
- .frame(maxWidth: .infinity, maxHeight: .infinity)
- .background(
- RoundedRectangle(cornerRadius: 4.0)
- .fill(dragOver ? Color(nsColor: NSColor.selectedContentBackgroundColor) : Color.clear)
- .padding(.horizontal, -6)
- .padding(.vertical, -4)
- )
- .onChange(of: file.expanded) {
- loading = false
- if file.expanded && file.fileSize > 0 {
- Task {
- loading = true
- let _ = await model.getFileList(path: file.path)
- loading = false
- }
- }
- }
- .onDrop(of: [.fileURL], isTargeted: $dragOver) { items in
- guard let item = items.first,
- 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)
- {
- 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 {
- FileView(file: childFile, depth: self.depth + 1).tag(file.id)
- }
- }
- }
- }
-}
-
-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 {
- 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)
- .opacity(file.isUnavailable ? 0.5 : 1.0)
-
- Spacer()
- if !file.isUnavailable {
- Text(formattedFileSize(file.fileSize))
- .foregroundStyle(.secondary)
- .lineLimit(1)
- .padding(.trailing, 6)
- }
- }
- .frame(maxWidth: .infinity, maxHeight: .infinity)
-
- if file.expanded {
- ForEach(file.children!, id: \.self) { childFile in
- if childFile.isFolder {
- FolderView(file: childFile, depth: self.depth + 1).tag(file.id)
- } 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
- return FileView.byteFormatter.string(fromByteCount: Int64(fileSize))
- }
-}
-
-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:
- openWindow(id: "preview-image", value: previewInfo)
- case .text:
- openWindow(id: "preview-text", value: previewInfo)
- default:
- return
- }
- }
-
- @MainActor private func getFileInfo(_ file: FileInfo) {
- Task {
- if let fileInfo = await model.getFileDetails(file.name, path: file.path) {
- Task { @MainActor in
- self.fileDetails = fileInfo
- }
- }
- }
- }
-
- @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 {
- // Refresh file listing to display newly uploaded file.
- let _ = await model.getFileList(path: path)
- }
- }
- }
-
- @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])
- }
-
- 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 {
- return file.path.first == "~" && file.path.count > 1
- }
- 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 {
- FileView(file: file, depth: 0).tag(file.id)
- }
- }
- .environment(\.defaultMinListRowHeight, 28)
- .listStyle(.inset)
- .alternatingRowBackgrounds(.enabled)
- .task {
- if !model.filesLoaded {
- let _ = await model.getFileList()
- }
- }
- .contextMenu(forSelectionType: FileInfo.self) { items in
- let selectedFile = items.first
-
- Button {
- if let s = selectedFile, !s.isFolder {
- downloadFile(s)
- }
- } label: {
- Label("Download", systemImage: "arrow.down")
- }
- .disabled(selectedFile == nil || (selectedFile != nil && selectedFile!.isFolder))
-
- Divider()
-
- Button {
- if let s = selectedFile {
- getFileInfo(s)
- }
- } label: {
- Label("Get Info", systemImage: "info.circle")
- }
- .disabled(selectedFile == nil)
-
- Button {
- if let s = selectedFile {
- previewFile(s)
- }
- } label: {
- Label("Preview", systemImage: "eye")
- }
- .disabled(selectedFile == nil || (selectedFile != nil && !selectedFile!.isPreviewable))
-
- if model.access?.contains(.canDeleteFiles) == true
- // Friendship Quest Remix
- || isInHomeFolder(selectedFile)
- {
- Divider()
-
- Button {
- if let s = selectedFile {
- Task {
- await deleteFile(s)
- }
- }
- } label: {
- Label("Delete", systemImage: "trash")
- }
- .disabled(selectedFile == nil)
- }
- } primaryAction: { items in
- guard let clickedFile = items.first else {
- return
- }
-
- self.selection = clickedFile
- if clickedFile.isFolder {
- clickedFile.expanded.toggle()
- } else {
- downloadFile(clickedFile)
- }
- }
- .onKeyPress(.rightArrow) {
- if let s = selection, s.isFolder {
- s.expanded = true
- return .handled
- }
- return .ignored
- }
- .onKeyPress(.leftArrow) {
- if let s = selection, s.isFolder {
- s.expanded = false
- return .handled
- }
- return .ignored
- }
- .onKeyPress(.space) {
- if let s = selection, s.isPreviewable {
- previewFile(s)
- return .handled
- }
- return .ignored
- }
- .overlay {
- if !model.filesLoaded {
- VStack {
- ProgressView()
- .controlSize(.large)
- }
- .frame(maxWidth: .infinity)
- }
- }
- .toolbar {
- ToolbarItem(placement: .primaryAction) {
- Button {
- if let selectedFile = selection, selectedFile.isPreviewable {
- previewFile(selectedFile)
- }
- } label: {
- Label("Preview", systemImage: "eye")
- }
- .help("Preview")
- .disabled(selection == nil || selection?.isPreviewable == false)
- }
-
- ToolbarItem(placement: .primaryAction) {
- Button {
- if let selectedFile = selection {
- getFileInfo(selectedFile)
- }
- } label: {
- Label("Get Info", systemImage: "info.circle")
- }
- .help("Get Info")
- .disabled(selection == nil)
- }
-
- ToolbarItem(placement: .primaryAction) {
- Button {
- uploadFileSelectorDisplayed = true
- } label: {
- Label("Upload", systemImage: "arrow.up")
- }
- .help("Upload")
- .disabled(model.access?.contains(.canUploadFiles) != true)
- }
-
- ToolbarItem(placement: .primaryAction) {
- Button {
- if let selectedFile = selection, !selectedFile.isFolder {
- downloadFile(selectedFile)
- }
- } label: {
- Label("Download", systemImage: "arrow.down")
- }
- .help("Download")
- .disabled(
- selection == nil || selection?.isFolder == true
- || model.access?.contains(.canDownloadFiles) != true)
- }
- }
- }
- .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
- } else {
- uploadPath = [String](selection.path)
- uploadPath.removeLast()
- }
- }
-
- print("UPLOAD PATH: \(uploadPath)")
- uploadFile(file: fileURL, to: uploadPath)
-
- case .failure(let error):
- print(error)
- }
- })
- }
-}
-
-#Preview {
- FilesView()
- .environment(Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient()))
-}