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.swift196
1 files changed, 141 insertions, 55 deletions
diff --git a/Hotline/macOS/FilesView.swift b/Hotline/macOS/FilesView.swift
index e34c7b5..80d89f9 100644
--- a/Hotline/macOS/FilesView.swift
+++ b/Hotline/macOS/FilesView.swift
@@ -1,39 +1,51 @@
import SwiftUI
import UniformTypeIdentifiers
-struct FileView: View {
+struct FolderView: View {
@Environment(Hotline.self) private var model: Hotline
- @State var expanded = false
@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) {
- if file.isFolder {
- Button {
- if file.isFolder {
- file.expanded.toggle()
- }
- } label: {
- Text(Image(systemName: file.expanded ? "chevron.down" : "chevron.right"))
- .bold()
- .font(.system(size: 10))
- .opacity(0.5)
+ Spacer()
+ .frame(width: CGFloat(depth * (12 + 2)))
+
+ Button {
+ if file.isFolder {
+ file.expanded.toggle()
}
- .buttonStyle(.plain)
- .frame(width: 10)
- .padding(.leading, 4)
- .padding(.trailing, 8)
- }
- else {
- Spacer()
- .frame(width: 10)
- .padding(.leading, 4)
- .padding(.trailing, 8)
+ } 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 {
@@ -53,17 +65,11 @@ struct FileView: View {
.scaledToFit()
.frame(width: 16, height: 16)
}
- else if file.isFolder {
+ else {
Image("Folder")
.resizable()
.scaledToFit()
.frame(width: 16, height: 16)
-// FolderIconView(dropbox: file.isUploadFolder)
-// .frame(width: 16, height: 16)
- }
- else {
- FileIconView(filename: file.name)
- .frame(width: 16, height: 16)
}
}
.frame(width: 16)
@@ -72,47 +78,123 @@ struct FileView: View {
Text(file.name)
.lineLimit(1)
.truncationMode(.tail)
+ .foregroundStyle(dragOver ? Color.white : Color.primary)
.opacity(file.isUnavailable ? 0.5 : 1.0)
- if file.isFolder && loading {
+ if loading {
ProgressView().controlSize(.small).padding([.leading, .trailing], 5)
}
Spacer()
if !file.isUnavailable {
- if file.isFolder {
- Text(file.fileSize == 0 ? "Empty" : "^[\(file.fileSize) \("file")](inflect: true)")
- .foregroundStyle(.secondary)
- .lineLimit(1)
- .padding(.trailing, 6)
- }
- else {
- Text(formattedFileSize(file.fileSize))
- .foregroundStyle(.secondary)
- .lineLimit(1)
- .padding(.trailing, 6)
- }
+ 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)
- .padding(.leading, CGFloat(depth * (12 + 10)))
+ .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.isFolder && file.fileSize > 0 {
- if file.expanded {
- Task {
- loading = true
- let _ = await model.getFileList(path: file.path)
- 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
+ print("WHAT?", Thread.isMainThread)
+ DispatchQueue.main.async {
+ print("WHAT 2?", Thread.isMainThread)
+ 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
- FileView(file: childFile, depth: self.depth + 1).tag(file.id)
-// .environment(self.selectedFile)
-// .frame(height: 34)
+ 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)
+ }
}
}
}
@@ -120,7 +202,6 @@ struct FileView: View {
static let byteFormatter = ByteCountFormatter()
private func formattedFileSize(_ fileSize: UInt) -> String {
- // let bcf = ByteCountFormatter()
FileView.byteFormatter.allowedUnits = [.useAll]
FileView.byteFormatter.countStyle = .file
return FileView.byteFormatter.string(fromByteCount: Int64(fileSize))
@@ -199,9 +280,14 @@ struct FilesView: View {
var body: some View {
NavigationStack {
List(model.files, id: \.self, selection: $selection) { file in
- FileView(file: file, depth: 0).tag(file.id)
+ if file.isFolder {
+ FolderView(file: file, depth: 0).tag(file.id)
+ }
+ else {
+ FileView(file: file, depth: 0).tag(file.id)
+ }
}
- .environment(\.defaultMinListRowHeight, 34)
+ .environment(\.defaultMinListRowHeight, 28)
.listStyle(.inset)
.alternatingRowBackgrounds(.enabled)
.task {