diff options
| author | Dustin Mierau <dustin@mierau.me> | 2023-12-19 20:38:13 -0800 |
|---|---|---|
| committer | Dustin Mierau <dustin@mierau.me> | 2023-12-19 20:38:13 -0800 |
| commit | 4fd69c02a3e7b581bb9229865336c315153f3b18 (patch) | |
| tree | e6e11d872424196f2b4033077902126ad5556e40 /Hotline/iOS/FilesView.swift | |
| parent | 5e87b5927cd931d46fb5f72fb035480a95969a9f (diff) | |
Beginnings of a UI for macOS as well as some visual changes to iOS client. :)
Diffstat (limited to 'Hotline/iOS/FilesView.swift')
| -rw-r--r-- | Hotline/iOS/FilesView.swift | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/Hotline/iOS/FilesView.swift b/Hotline/iOS/FilesView.swift new file mode 100644 index 0000000..5815ca2 --- /dev/null +++ b/Hotline/iOS/FilesView.swift @@ -0,0 +1,145 @@ +import SwiftUI +import UniformTypeIdentifiers + +struct FileView: View { + @Environment(Hotline.self) private var model: Hotline + + @State var expanded = false + + var file: FileInfo + + var body: some View { + if file.isFolder { + DisclosureGroup(isExpanded: $expanded) { + ForEach(file.children!) { childFile in + FileView(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).lineLimit(1).truncationMode(.tail) + Spacer() + Text("\(file.fileSize)").foregroundStyle(.secondary).lineLimit(1) + } + } + .onChange(of: expanded) { + if !expanded { + return + } + + Task { + await model.getFileList(path: file.path) + } + } + } + else { + HStack { + HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) { + fileIcon(name: file.name) + .renderingMode(.template) + } + .frame(minWidth: 25) + Text(file.name).lineLimit(1).truncationMode(.tail) + Spacer() + Text(formattedFileSize(file.fileSize)).foregroundStyle(.secondary).lineLimit(1) + } + } + } + + 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)) + } + + private func fileIcon(name: String) -> Image { + // 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 Image(systemName: "play.rectangle") +// return UIImage(systemName: "play.rectangle")! + } + else if fileType.isSubtype(of: .image) { + return Image(systemName: "photo") +// return UIImage(systemName: "photo")! + } + else if fileType.isSubtype(of: .archive) { + return Image(systemName: "doc.zipper") +// return UIImage(systemName: "doc.zipper")! + } + else if fileType.isSubtype(of: .text) { + return Image(systemName: "doc.text") +// return UIImage(systemName: "doc.text")! + } + else { + return Image(systemName: "doc") +// return UIImage(systemName: "doc")! + } + } + + return Image(systemName: "doc") + } +} + +struct FilesView: View { + @Environment(Hotline.self) private var model: Hotline + + @State var initialLoadComplete = false + + var body: some View { + NavigationStack { + List(model.files) { file in + FileView(file: file) + .frame(height: 44) + } + .task { + if !initialLoadComplete { + let _ = await model.getFileList() + initialLoadComplete = true + } + } + .overlay { + if !initialLoadComplete { + VStack { + ProgressView() + .controlSize(.large) + } + .frame(maxWidth: .infinity) + } + } + .listStyle(.plain) + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .principal) { + Text(model.serverTitle) + .font(.headline) + } + ToolbarItem(placement: .navigationBarLeading) { + Button { + model.disconnect() + } label: { + Text(Image(systemName: "xmark.circle.fill")) + .symbolRenderingMode(.hierarchical) + .font(.title2) + .foregroundColor(.secondary) + } + } + } + } + } +} + +#Preview { + FilesView() + .environment(Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient())) +} |