aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Views
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2023-12-07 18:03:44 -0800
committerDustin Mierau <dustin@mierau.me>2023-12-07 18:03:44 -0800
commit767eb58da13d83aa321fff12c97fe433cd8fa734 (patch)
treea796f07731bd39818e0267a3beae3e6b633729c8 /Hotline/Views
parent154763b8e2b14ff2a92d5a1f1f3e14a18167e6fc (diff)
A semi working file browser.
Diffstat (limited to 'Hotline/Views')
-rw-r--r--Hotline/Views/ChatView.swift4
-rw-r--r--Hotline/Views/FilesView.swift254
-rw-r--r--Hotline/Views/MessageBoardView.swift4
-rw-r--r--Hotline/Views/NewsView.swift4
-rw-r--r--Hotline/Views/UserListView.swift5
5 files changed, 185 insertions, 86 deletions
diff --git a/Hotline/Views/ChatView.swift b/Hotline/Views/ChatView.swift
index 2283cdd..28e548d 100644
--- a/Hotline/Views/ChatView.swift
+++ b/Hotline/Views/ChatView.swift
@@ -106,11 +106,11 @@ struct ChatView: View {
Button {
hotline.disconnect()
} label: {
- Image(systemName: "xmark.circle.fill")
+ Text(Image(systemName: "xmark.circle.fill"))
.symbolRenderingMode(.hierarchical)
+ .font(.title2)
.foregroundColor(.secondary)
}
-
}
}
diff --git a/Hotline/Views/FilesView.swift b/Hotline/Views/FilesView.swift
index 52963e0..091d718 100644
--- a/Hotline/Views/FilesView.swift
+++ b/Hotline/Views/FilesView.swift
@@ -1,21 +1,23 @@
import SwiftUI
import UniformTypeIdentifiers
-struct FileListView: View {
+struct FileView: View {
@Environment(HotlineClient.self) private var hotline
- @State private var fetched = false
+ @State var file: HotlineFile
+ @State var loaded = false
@State var fileList: [HotlineFile] = []
- var path: [String] = []
+ let depth: Int
+ let path: [String]
static let byteFormatter = ByteCountFormatter()
private func formattedFileSize(_ fileSize: UInt32) -> String {
// let bcf = ByteCountFormatter()
- FileListView.byteFormatter.allowedUnits = [.useAll]
- FileListView.byteFormatter.countStyle = .file
- return FileListView.byteFormatter.string(fromByteCount: Int64(fileSize))
+ FileView.byteFormatter.allowedUnits = [.useAll]
+ FileView.byteFormatter.countStyle = .file
+ return FileView.byteFormatter.string(fromByteCount: Int64(fileSize))
}
private func fileIcon(name: String) -> UIImage {
@@ -45,103 +47,199 @@ struct FileListView: View {
}
var body: some View {
- List {
- ForEach(fileList, id: \.self) { file in
- if file.isFolder {
- DisclosureGroup {
- if !fetched {
- ProgressView()
- }
- else {
- FileListView(path: [])
- }
- } label: {
- HStack {
- HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) {
- Image(systemName: "folder.fill")
+ if file.isFolder {
+ DisclosureGroup {
+ if !loaded {
+ Text("Loading...")
+ .task {
+ if !loaded {
+ hotline.sendGetFileList(path: path) {
+ print("FETCHED!")
+ } reply: { newFiles in
+ print("GOT FILES REPLY?", newFiles)
+
+ fileList = newFiles
+ loaded = true
+ }
}
- .frame(minWidth: 25)
- Text(file.name).fontWeight(.medium)
- Spacer()
- Text("\(file.fileSize)").foregroundStyle(.secondary)
}
- }
}
else {
+ FileListView(fileList: fileList, depth: depth + 1, path: path + [file.name])
+ }
+ } label: {
+ VStack {
HStack {
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) {
- Image(uiImage: fileIcon(name: file.name))
- .renderingMode(.template)
- .foregroundColor(.accentColor)
+ Image(systemName: "folder.fill")
}
.frame(minWidth: 25)
- Text(file.name)
+ Text(file.name).fontWeight(.medium)
Spacer()
- Text(formattedFileSize(file.fileSize)).foregroundStyle(.gray)
+ Text("\(file.fileSize)").foregroundStyle(.secondary)
}
}
+ .frame(height: 44)
+ .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
+
+ // Divider()
+ // .padding(EdgeInsets(top: 0, leading: 16 + 25 + 8, bottom: 0, trailing: 0))
}
+ .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: depth == 0 ? 16 : 0))
+ .background(Color(uiColor: UIColor.systemBackground))
}
- .listStyle(.plain)
- .task {
- if !fetched {
- hotline.sendGetFileList() {
- print("FETCHED!")
- fetched = true
- } reply: {
- print("GOT FILES REPLY?")
- fileList = hotline.fileList
+ else {
+ VStack {
+ HStack {
+ HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) {
+ Image(uiImage: fileIcon(name: file.name))
+ .renderingMode(.template)
+ .foregroundColor(.accentColor)
+ }
+ .frame(minWidth: 25)
+ Text(file.name)
+ Spacer()
+ Text(formattedFileSize(file.fileSize)).foregroundStyle(.gray)
}
+ .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0))
}
+ .frame(height: 44)
+ .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: depth == 0 ? 16 : 0))
+ .background(Color(uiColor: UIColor.systemBackground))
+
+ Divider()
+ .padding(EdgeInsets(top: 0, leading: 16 + 25 + 8, bottom: 0, trailing: 0))
}
}
}
-struct FilesView: View {
+struct FileListView: View {
@Environment(HotlineClient.self) private var hotline
@State private var fetched = false
+ @State private var loaded = false
+ @State var fileList: [HotlineFile] = []
+ @State var expanded = false
+
+ var depth = 0
+
+ var path: [String] = []
+
+ var body: some View {
+ LazyVStack(alignment: .leading, spacing: 0) {
+ Section {
+ ForEach(fileList, id: \.self) { file in
+ FileView(file: file, depth: depth, path: path + [file.name])
+ }
+ }
+ Spacer()
+ }
+ .listStyle(.plain)
+ .animation(.default, value: fileList)
+ }
+}
+
+struct BestFileView: View {
+ @Environment(HotlineClient.self) private var hotline
+
+ @State var expanded = false
+
+ var file: HotlineFile
+
+ var body: some View {
+ if file.isFolder {
+ DisclosureGroup(isExpanded: $expanded) {
+ ForEach(file.files!) { childFile in
+ BestFileView(file: childFile)
+ .frame(height: 44)
+ }
+ } label: {
+ HStack {
+ HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) {
+ Image(systemName: "folder.fill")
+ }
+ .frame(minWidth: 25)
+ Text(file.name).fontWeight(.medium)
+ Spacer()
+ Text("\(file.fileSize)").foregroundStyle(.secondary)
+ }
+ }
+ .onChange(of: expanded) {
+ print("EXPANDED CHANGED")
+
+ hotline.sendGetFileList(path: file.path)
+ }
+ }
+ else {
+ HStack {
+ HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) {
+ Image(uiImage: fileIcon(name: file.name))
+ }
+ .frame(minWidth: 25)
+ Text(file.name).fontWeight(.medium)
+ Spacer()
+ Text(formattedFileSize(file.fileSize)).foregroundStyle(.secondary)
+ }
+ }
+ }
+
+ static let byteFormatter = ByteCountFormatter()
-// let fileList: [HotlineFile]
+ private func formattedFileSize(_ fileSize: UInt32) -> String {
+ // let bcf = ByteCountFormatter()
+ BestFileView.byteFormatter.allowedUnits = [.useAll]
+ BestFileView.byteFormatter.countStyle = .file
+ return BestFileView.byteFormatter.string(fromByteCount: Int64(fileSize))
+ }
-// static let byteFormatter = ByteCountFormatter()
-//
-// private func formattedFileSize(_ fileSize: UInt32) -> String {
-// // let bcf = ByteCountFormatter()
-// FilesView.byteFormatter.allowedUnits = [.useAll]
-// FilesView.byteFormatter.countStyle = .file
-// return FilesView.byteFormatter.string(fromByteCount: Int64(fileSize))
-// }
-//
-// private func fileIcon(name: String) -> UIImage {
-// // func utTypeForFilename(_ filename: String) -> UTType? {
-// let fileExtension = (name as NSString).pathExtension
-// if let fileType = UTType(filenameExtension: fileExtension) {
-// print("\(name) \(fileExtension) = \(fileType)")
-//
-// if fileType.isSubtype(of: .movie) {
-// return UIImage(systemName: "play.rectangle")!
-// }
-// else if fileType.isSubtype(of: .image) {
-// return UIImage(systemName: "photo")!
-// }
-// else if fileType.isSubtype(of: .archive) {
-// return UIImage(systemName: "doc.zipper")!
-// }
-// else if fileType.isSubtype(of: .text) {
-// return UIImage(systemName: "doc.text")!
-// }
-// else {
-// return UIImage(systemName: "doc")!
-// }
-// }
-//
-// return UIImage(systemName: "doc")!
-// }
+ private func fileIcon(name: String) -> UIImage {
+ // func utTypeForFilename(_ filename: String) -> UTType? {
+ let fileExtension = (name as NSString).pathExtension
+ if let fileType = UTType(filenameExtension: fileExtension) {
+ print("\(name) \(fileExtension) = \(fileType)")
+
+ if fileType.isSubtype(of: .movie) {
+ return UIImage(systemName: "play.rectangle")!
+ }
+ else if fileType.isSubtype(of: .image) {
+ return UIImage(systemName: "photo")!
+ }
+ else if fileType.isSubtype(of: .archive) {
+ return UIImage(systemName: "doc.zipper")!
+ }
+ else if fileType.isSubtype(of: .text) {
+ return UIImage(systemName: "doc.text")!
+ }
+ else {
+ return UIImage(systemName: "doc")!
+ }
+ }
+
+ return UIImage(systemName: "doc")!
+ }
+}
+
+struct FilesView: View {
+ @Environment(HotlineClient.self) private var hotline
+
+ @State var initialLoad = false
var body: some View {
NavigationStack {
- FileListView(path: [])
+ List(hotline.fileList) { file in
+// OutlineGroup(hotline.fileList, children: \.files, expanded: $expandedFolders) { file in
+ BestFileView(file: file)
+ .frame(height: 44)
+// }
+ }
+ .task {
+ if !initialLoad {
+ hotline.sendGetFileList(path: []) {
+ initialLoad = true
+ }
+ }
+ }
+ .listStyle(.plain)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
@@ -152,11 +250,11 @@ struct FilesView: View {
Button {
hotline.disconnect()
} label: {
- Image(systemName: "xmark.circle.fill")
+ Text(Image(systemName: "xmark.circle.fill"))
.symbolRenderingMode(.hierarchical)
+ .font(.title2)
.foregroundColor(.secondary)
}
-
}
}
}
diff --git a/Hotline/Views/MessageBoardView.swift b/Hotline/Views/MessageBoardView.swift
index 35b4282..04f51df 100644
--- a/Hotline/Views/MessageBoardView.swift
+++ b/Hotline/Views/MessageBoardView.swift
@@ -41,11 +41,11 @@ struct MessageBoardView: View {
Button {
hotline.disconnect()
} label: {
- Image(systemName: "xmark.circle.fill")
+ Text(Image(systemName: "xmark.circle.fill"))
.symbolRenderingMode(.hierarchical)
+ .font(.title2)
.foregroundColor(.secondary)
}
-
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
diff --git a/Hotline/Views/NewsView.swift b/Hotline/Views/NewsView.swift
index 78282d6..539ead8 100644
--- a/Hotline/Views/NewsView.swift
+++ b/Hotline/Views/NewsView.swift
@@ -105,11 +105,11 @@ struct NewsView: View {
Button {
hotline.disconnect()
} label: {
- Image(systemName: "xmark.circle.fill")
+ Text(Image(systemName: "xmark.circle.fill"))
.symbolRenderingMode(.hierarchical)
+ .font(.title2)
.foregroundColor(.secondary)
}
-
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
diff --git a/Hotline/Views/UserListView.swift b/Hotline/Views/UserListView.swift
index e0fa7fb..8ea186e 100644
--- a/Hotline/Views/UserListView.swift
+++ b/Hotline/Views/UserListView.swift
@@ -6,7 +6,7 @@ struct UserListView: View {
var body: some View {
NavigationStack {
List(hotline.userList) { u in
- Text(u.name)
+ Text("🤖 \(u.name)")
.fontWeight(.medium)
.lineLimit(1)
.truncationMode(.tail)
@@ -24,8 +24,9 @@ struct UserListView: View {
Button {
hotline.disconnect()
} label: {
- Image(systemName: "xmark.circle.fill")
+ Text(Image(systemName: "xmark.circle.fill"))
.symbolRenderingMode(.hierarchical)
+ .font(.title2)
.foregroundColor(.secondary)
}
}