aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Views
diff options
context:
space:
mode:
Diffstat (limited to 'Hotline/Views')
-rw-r--r--Hotline/Views/ChatView.swift25
-rw-r--r--Hotline/Views/FilesView.swift157
-rw-r--r--Hotline/Views/HotlineView.swift17
-rw-r--r--Hotline/Views/TrackerView.swift48
4 files changed, 58 insertions, 189 deletions
diff --git a/Hotline/Views/ChatView.swift b/Hotline/Views/ChatView.swift
index 28e548d..1b3ba52 100644
--- a/Hotline/Views/ChatView.swift
+++ b/Hotline/Views/ChatView.swift
@@ -25,12 +25,27 @@ struct ChatView: View {
ForEach(hotline.chatMessages) { msg in
if msg.type == .agreement {
VStack(alignment: .leading) {
- Text(msg.text)
- .font(.system(size: 11, weight: .regular, design: .monospaced))
+ VStack(alignment: .leading, spacing: 0) {
+ Text(msg.text)
+ .textSelection(.enabled)
+ .padding()
+ .opacity(0.75)
+ HStack {
+ Spacer()
+ Text((hotline.server?.name ?? "") + " Server Agreement")
+ .font(.caption)
+ .fontWeight(.medium)
+ .opacity(0.4)
+ .lineLimit(1)
+ .truncationMode(.middle)
+ Spacer()
+ }
.padding()
- .opacity(0.75)
- .background(colorScheme == .dark ? Color(white: 0.1) : Color(white: 0.96))
- .cornerRadius(16)
+ .background(colorScheme == .dark ? Color(white: 0.2) : Color(white: 0.9))
+ }
+ .background(colorScheme == .dark ? Color(white: 0.1) : Color(white: 0.96))
+ .cornerRadius(16)
+ .frame(maxWidth: .infinity)
}
.padding()
}
diff --git a/Hotline/Views/FilesView.swift b/Hotline/Views/FilesView.swift
index 091d718..23cd914 100644
--- a/Hotline/Views/FilesView.swift
+++ b/Hotline/Views/FilesView.swift
@@ -4,144 +4,6 @@ import UniformTypeIdentifiers
struct FileView: View {
@Environment(HotlineClient.self) private var hotline
- @State var file: HotlineFile
- @State var loaded = false
- @State var fileList: [HotlineFile] = []
-
- let depth: Int
- let path: [String]
-
- static let byteFormatter = ByteCountFormatter()
-
- private func formattedFileSize(_ fileSize: UInt32) -> String {
- // let bcf = ByteCountFormatter()
- FileView.byteFormatter.allowedUnits = [.useAll]
- FileView.byteFormatter.countStyle = .file
- return FileView.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")!
- }
-
- var body: some View {
- 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
- }
- }
- }
- }
- else {
- FileListView(fileList: fileList, depth: depth + 1, path: path + [file.name])
- }
- } label: {
- VStack {
- 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)
- }
- }
- .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))
- }
- 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 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
@@ -150,7 +12,7 @@ struct BestFileView: View {
if file.isFolder {
DisclosureGroup(isExpanded: $expanded) {
ForEach(file.files!) { childFile in
- BestFileView(file: childFile)
+ FileView(file: childFile)
.frame(height: 44)
}
} label: {
@@ -159,9 +21,9 @@ struct BestFileView: View {
Image(systemName: "folder.fill")
}
.frame(minWidth: 25)
- Text(file.name).fontWeight(.medium)
+ Text(file.name).fontWeight(.medium).lineLimit(1).truncationMode(.tail)
Spacer()
- Text("\(file.fileSize)").foregroundStyle(.secondary)
+ Text("\(file.fileSize)").foregroundStyle(.secondary).lineLimit(1)
}
}
.onChange(of: expanded) {
@@ -174,11 +36,12 @@ struct BestFileView: View {
HStack {
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) {
Image(uiImage: fileIcon(name: file.name))
+ .renderingMode(.template)
}
.frame(minWidth: 25)
- Text(file.name).fontWeight(.medium)
+ Text(file.name).lineLimit(1).truncationMode(.tail)
Spacer()
- Text(formattedFileSize(file.fileSize)).foregroundStyle(.secondary)
+ Text(formattedFileSize(file.fileSize)).foregroundStyle(.secondary).lineLimit(1)
}
}
}
@@ -187,9 +50,9 @@ struct BestFileView: View {
private func formattedFileSize(_ fileSize: UInt32) -> String {
// let bcf = ByteCountFormatter()
- BestFileView.byteFormatter.allowedUnits = [.useAll]
- BestFileView.byteFormatter.countStyle = .file
- return BestFileView.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 {
@@ -228,7 +91,7 @@ struct FilesView: View {
NavigationStack {
List(hotline.fileList) { file in
// OutlineGroup(hotline.fileList, children: \.files, expanded: $expandedFolders) { file in
- BestFileView(file: file)
+ FileView(file: file)
.frame(height: 44)
// }
}
diff --git a/Hotline/Views/HotlineView.swift b/Hotline/Views/HotlineView.swift
deleted file mode 100644
index f950dd7..0000000
--- a/Hotline/Views/HotlineView.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-import SwiftUI
-
-struct HotlineView: View {
- @Environment(HotlineState.self) private var appState
- @Environment(HotlineClient.self) private var hotline
- @Environment(HotlineTrackerClient.self) private var tracker
-
- var body: some View {
- TrackerView()
- }
-}
-
-#Preview {
- HotlineView()
- .environment(HotlineClient())
- .environment(HotlineTrackerClient(tracker: HotlineTracker("hltracker.com")))
-}
diff --git a/Hotline/Views/TrackerView.swift b/Hotline/Views/TrackerView.swift
index 1c61cf4..2d2032e 100644
--- a/Hotline/Views/TrackerView.swift
+++ b/Hotline/Views/TrackerView.swift
@@ -5,23 +5,23 @@ struct TrackerView: View {
// @Environment(\.modelContext) private var modelContext
// @Query private var items: [Item]
- @Environment(HotlineState.self) private var appState
@Environment(HotlineClient.self) private var hotline
- @Environment(HotlineTrackerClient.self) private var trackerClient
@Environment(Hotline.self) private var model: Hotline
@Environment(\.colorScheme) var colorScheme
// @State private var tracker = Tracker(address: "hltracker.com", service: trackerService)
- @State private var selectedServer: HotlineServer?
+ @State private var servers: [Server] = []
+ @State private var selectedServer: Server?
@State var scrollOffset: CGFloat = CGFloat.zero
+ @State private var initialLoadComplete = false
- func shouldDisplayDescription(server: HotlineServer) -> Bool {
- guard let name = server.name, let desc = server.description else {
+ func shouldDisplayDescription(server: Server) -> Bool {
+ guard let desc = server.description else {
return false
}
- return desc.count > 0 && desc != name && !desc.contains(/^-+/)
+ return desc.count > 0 && desc != server.name
}
func connectionStatusToProgress(status: HotlineClientStatus) -> Double {
@@ -43,10 +43,11 @@ struct TrackerView: View {
return (v - lower) / (upper - lower)
}
+ func updateServers() async {
+ self.servers = await model.getServers(address: "tracker.preterhuman.net")
+ }
+
var body: some View {
- @Bindable var config = appState
- @Bindable var client = hotline
-
ZStack(alignment: .center) {
VStack(alignment: .center) {
ZStack(alignment: .top) {
@@ -80,18 +81,18 @@ struct TrackerView: View {
}
ObservableScrollView(scrollOffset: $scrollOffset) {
LazyVStack(alignment: .leading) {
- ForEach(tracker.servers) { server in
+ ForEach(self.servers) { server in
VStack(alignment: .leading) {
HStack(alignment: .firstTextBaseline) {
Image(systemName: "globe.americas.fill").font(.title3)
VStack(alignment: .leading) {
- Text(server.name!).font(.title3).fontWeight(.medium)
+ Text(server.name).font(.title3).fontWeight(.medium)
if shouldDisplayDescription(server: server) {
Spacer()
Text(server.description!).opacity(0.5).font(.system(size: 16))
}
Spacer()
- Text("\(server.address)").opacity(0.3).font(.system(size: 13))
+ Text("\(server.address):" + String(format: "%i", server.port)).opacity(0.3).font(.system(size: 13))
}
Spacer()
if server.users > 0 {
@@ -101,14 +102,14 @@ struct TrackerView: View {
if server == selectedServer {
Spacer(minLength: 16)
- if hotline.server == server && hotline.connectionStatus != .disconnected {
+ if hotline.connectionStatus != .disconnected && hotline.server! == server {
ProgressView(value: connectionStatusToProgress(status: hotline.connectionStatus))
.frame(minHeight: 10)
.accentColor(colorScheme == .dark ? .white : .black)
}
else {
Button("Connect") {
- hotline.connect(to: server)
+ hotline.connect(to: HotlineServer(address: server.address, port: UInt16(server.port), users: UInt16(server.users), name: server.name, description: server.description))
}
.bold()
.padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
@@ -142,13 +143,19 @@ struct TrackerView: View {
}
.padding(EdgeInsets(top: 75, leading: 0, bottom: 0, trailing: 0))
}
- .refreshable {
- await withCheckedContinuation { continuation in
- tracker.fetch() {
- continuation.resume()
+ .overlay {
+ if !initialLoadComplete {
+ VStack {
+ ProgressView()
+ .controlSize(.large)
}
+ .frame(maxWidth: .infinity)
}
}
+ .refreshable {
+ initialLoadComplete = true
+ await updateServers()
+ }
}
.fullScreenCover(isPresented: Binding(get: { return hotline.connectionStatus == .loggedIn }, set: { _ in }), onDismiss: {
@@ -159,7 +166,9 @@ struct TrackerView: View {
.background(Color(uiColor: UIColor.systemGroupedBackground))
.frame(maxWidth: .infinity)
.task {
- tracker.fetch()
+ await updateServers()
+ initialLoadComplete = true
+// tracker.fetch()
}
}
}
@@ -167,7 +176,6 @@ struct TrackerView: View {
#Preview {
TrackerView()
.environment(HotlineClient())
- .environment(HotlineTrackerClient(tracker: HotlineTracker("hltracker.com")))
.environment(HotlineState())
// .modelContainer(for: Item.self, inMemory: true)
}