aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2023-12-04 14:31:12 -0800
committerDustin Mierau <dustin@mierau.me>2023-12-04 14:31:12 -0800
commitb1a176ba3da2c7cf815084f0f8109008fe763809 (patch)
tree5bbf52900d5dab9091216cc0f1e5dc84ad69cc9f
parent471546236b8991f61d26c0e3aa8ee48b83b983af (diff)
Starting to get app views displaying data (roughly)
-rw-r--r--Hotline.xcodeproj/project.pbxproj18
-rw-r--r--Hotline/Hotline/HotlineClient.swift63
-rw-r--r--Hotline/Hotline/HotlineProtocol.swift4
-rw-r--r--Hotline/HotlineApp.swift2
-rw-r--r--Hotline/Views/AgreementView.swift7
-rw-r--r--Hotline/Views/ChatView.swift78
-rw-r--r--Hotline/Views/FilesView.swift32
-rw-r--r--Hotline/Views/HotlineState.swift24
-rw-r--r--Hotline/Views/HotlineView.swift11
-rw-r--r--Hotline/Views/MessageBoardView.swift42
-rw-r--r--Hotline/Views/ServerView.swift57
-rw-r--r--Hotline/Views/TrackerServerView.swift13
-rw-r--r--Hotline/Views/TrackerView.swift85
-rw-r--r--Hotline/Views/UserListView.swift21
14 files changed, 334 insertions, 123 deletions
diff --git a/Hotline.xcodeproj/project.pbxproj b/Hotline.xcodeproj/project.pbxproj
index 0bd761f..93931f6 100644
--- a/Hotline.xcodeproj/project.pbxproj
+++ b/Hotline.xcodeproj/project.pbxproj
@@ -7,6 +7,10 @@
objects = {
/* Begin PBXBuildFile section */
+ DA0D698B2B1E5A5200C71DF5 /* HotlineState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0D698A2B1E5A5200C71DF5 /* HotlineState.swift */; };
+ DA0D698D2B1E7CF700C71DF5 /* UserListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0D698C2B1E7CF700C71DF5 /* UserListView.swift */; };
+ DA0D698F2B1E841600C71DF5 /* MessageBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0D698E2B1E841600C71DF5 /* MessageBoardView.swift */; };
+ DA0D69912B1E894800C71DF5 /* FilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0D69902B1E894800C71DF5 /* FilesView.swift */; };
DA43205C2B1D003B00FC8843 /* HotlineClientModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA43205B2B1D003B00FC8843 /* HotlineClientModel.swift */; };
DA43205E2B1D615600FC8843 /* ServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA43205D2B1D615600FC8843 /* ServerView.swift */; };
DA4F2BF62B1668A700D8ADDC /* HotlineClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4F2BF52B1668A700D8ADDC /* HotlineClient.swift */; };
@@ -24,6 +28,10 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ DA0D698A2B1E5A5200C71DF5 /* HotlineState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotlineState.swift; sourceTree = "<group>"; };
+ DA0D698C2B1E7CF700C71DF5 /* UserListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListView.swift; sourceTree = "<group>"; };
+ DA0D698E2B1E841600C71DF5 /* MessageBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBoardView.swift; sourceTree = "<group>"; };
+ DA0D69902B1E894800C71DF5 /* FilesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilesView.swift; sourceTree = "<group>"; };
DA43205B2B1D003B00FC8843 /* HotlineClientModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotlineClientModel.swift; sourceTree = "<group>"; };
DA43205D2B1D615600FC8843 /* ServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerView.swift; sourceTree = "<group>"; };
DA4F2BF52B1668A700D8ADDC /* HotlineClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotlineClient.swift; sourceTree = "<group>"; };
@@ -55,10 +63,14 @@
DA4F2BF92B1A516F00D8ADDC /* Views */ = {
isa = PBXGroup;
children = (
- DA4F2BFA2B1A518500D8ADDC /* AgreementView.swift */,
DA4F2BFE2B1A54FF00D8ADDC /* HotlineView.swift */,
+ DA0D698A2B1E5A5200C71DF5 /* HotlineState.swift */,
+ DA4F2BFA2B1A518500D8ADDC /* AgreementView.swift */,
+ DA0D698E2B1E841600C71DF5 /* MessageBoardView.swift */,
DA43205D2B1D615600FC8843 /* ServerView.swift */,
DA4F2C002B1A558E00D8ADDC /* ChatView.swift */,
+ DA0D698C2B1E7CF700C71DF5 /* UserListView.swift */,
+ DA0D69902B1E894800C71DF5 /* FilesView.swift */,
DA4F2BFC2B1A52EF00D8ADDC /* TrackerServerView.swift */,
DA9CAFBC2B126D5700CDA197 /* TrackerView.swift */,
);
@@ -194,14 +206,18 @@
DA43205C2B1D003B00FC8843 /* HotlineClientModel.swift in Sources */,
DA4F2BFB2B1A518500D8ADDC /* AgreementView.swift in Sources */,
DA43205E2B1D615600FC8843 /* ServerView.swift in Sources */,
+ DA0D69912B1E894800C71DF5 /* FilesView.swift in Sources */,
DA4F2BFD2B1A52EF00D8ADDC /* TrackerServerView.swift in Sources */,
+ DA0D698B2B1E5A5200C71DF5 /* HotlineState.swift in Sources */,
DA9CAFBD2B126D5700CDA197 /* TrackerView.swift in Sources */,
DA9CAFCB2B126E3300CDA197 /* HotlineTrackerClient.swift in Sources */,
DA9CAFBB2B126D5700CDA197 /* HotlineApp.swift in Sources */,
+ DA0D698F2B1E841600C71DF5 /* MessageBoardView.swift in Sources */,
DA4F2BFF2B1A54FF00D8ADDC /* HotlineView.swift in Sources */,
DA4F2BF62B1668A700D8ADDC /* HotlineClient.swift in Sources */,
DABFCC292B1530DC009F40D2 /* DataExtensions.swift in Sources */,
DA4F2BF82B16A17200D8ADDC /* HotlineProtocol.swift in Sources */,
+ DA0D698D2B1E7CF700C71DF5 /* UserListView.swift in Sources */,
DA4F2C012B1A558E00D8ADDC /* ChatView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/Hotline/Hotline/HotlineClient.swift b/Hotline/Hotline/HotlineClient.swift
index b5ea1d9..de01ae9 100644
--- a/Hotline/Hotline/HotlineClient.swift
+++ b/Hotline/Hotline/HotlineClient.swift
@@ -9,10 +9,26 @@ enum HotlineClientStatus: Int {
case loggedIn
}
-struct HotlineChat {
+struct HotlineChat: Identifiable {
+ let id = UUID()
let message: String
- let userID: UInt16?
+ let username: String
let isTopic: Bool
+
+ static let parser = /\s+(.+):\s+(.*)/
+
+ init(message: String, isTopic: Bool = false) {
+ self.isTopic = isTopic
+
+ if let match = message.firstMatch(of: HotlineChat.parser) {
+ self.username = String(match.1)
+ self.message = String(match.2)
+ }
+ else {
+ self.username = ""
+ self.message = message
+ }
+ }
}
@Observable
@@ -29,8 +45,9 @@ class HotlineClient {
var connectionStatus: HotlineClientStatus = .disconnected
var agreement: String?
var users: [UInt16:HotlineUser] = [:]
- var userList: [UInt16] = []
+ var userList: [HotlineUser] = []
var chatMessages: [HotlineChat] = []
+ var messageBoard: String = ""
var userName: String = "bolt"
var userIconID: UInt16 = 128
@@ -324,6 +341,19 @@ class HotlineClient {
self.sendTransaction(t, callback: callback)
}
+ func sendGetNews(callback: (() -> Void)? = nil) {
+ let t = HotlineTransaction(type: .getMessages)
+ self.sendTransaction(t, callback: callback)
+ }
+
+ func sendGetFileList(path: String? = nil, callback: (() -> Void)? = nil) {
+ let t = HotlineTransaction(type: .getFileNameList)
+ if let p = path {
+// t.setFieldString(type: .filePath)
+ }
+ self.sendTransaction(t, callback: callback)
+ }
+
// MARK: - Incoming
private func processReply(_ transaction: HotlineTransaction) {
@@ -356,11 +386,11 @@ class HotlineClient {
case .getUserNameList:
print("GOT USER LIST")
var newUsers: [UInt16:HotlineUser] = [:]
- var newUserList: [UInt16] = []
+ var newUserList: [HotlineUser] = []
for u in transaction.getFieldList(type: .userNameWithInfo) {
let user = u.getUser()
newUsers[user.id] = user
- newUserList.append(user.id)
+ newUserList.append(user)
}
DispatchQueue.main.async {
self.users = newUsers
@@ -369,6 +399,13 @@ class HotlineClient {
print("HotlineClient got users:\n")
print("\(self.userList)\n\n")
}
+ case .getMessages:
+ print("GOT MESSAGE BOARD")
+ if let textField = transaction.getField(type: .data), let text = textField.getString() {
+ DispatchQueue.main.async {
+ self.messageBoard = text
+ }
+ }
default:
break
}
@@ -389,16 +426,18 @@ class HotlineClient {
// print("HotlineClient: Received reply transaction: \(transaction)")
case .chatMessage:
+ print("HotlineClient: chat \(transaction)")
if
let chatTextParam = transaction.getField(type: .data),
- let chatText = chatTextParam.getString(),
- let userNameParam = transaction.getField(type: .userName),
- let userName = userNameParam.getString(),
- let userIDParam = transaction.getField(type: .userID),
- let userID = userIDParam.getUInt16() {
- print("HotlineClient: \(userName):\(userID): \(chatText)")
+ let chatText = chatTextParam.getString()
+// let userNameParam = transaction.getField(type: .userName),
+// let userName = userNameParam.getString(),
+// let userIDParam = transaction.getField(type: .userID),
+// let userID = userIDParam.getUInt16() {
+ {
+ print("HotlineClient: \(chatText)")
DispatchQueue.main.async {
- self.chatMessages.append(HotlineChat(message: chatText, userID: userID, isTopic: false))
+ self.chatMessages.append(HotlineChat(message: chatText, isTopic: false))
}
}
case .notifyOfUserChange:
diff --git a/Hotline/Hotline/HotlineProtocol.swift b/Hotline/Hotline/HotlineProtocol.swift
index 200ac47..20168b0 100644
--- a/Hotline/Hotline/HotlineProtocol.swift
+++ b/Hotline/Hotline/HotlineProtocol.swift
@@ -285,6 +285,7 @@ enum HotlineTransactionFieldType: UInt16 {
case versionNumber = 160 // Integer
case communityBannerID = 161 // Integer
case serverName = 162 // String
+ case fileNameWithInfo = 200 // Data { type: 4, creator: 4, file size: 4, reserved: 4, name script: 2, name size: 2, name data: size }
// TODO: Add file field types
case quotingMessage = 214 // String?
case automaticResponse = 215 // String
@@ -348,6 +349,9 @@ enum HotlineTransactionType: UInt16 {
case downloadInfo = 211 // Server
case downloadBanner = 212
case uploadFolder = 213
+ case getNewsFile = 294
+ case postNews = 295
+ case receiveNewsFile = 296 // Server
case getUserNameList = 300
case notifyOfUserChange = 301 // Server
case notifyOfUserDelete = 302 // Server
diff --git a/Hotline/HotlineApp.swift b/Hotline/HotlineApp.swift
index 238ca48..d999e89 100644
--- a/Hotline/HotlineApp.swift
+++ b/Hotline/HotlineApp.swift
@@ -16,6 +16,7 @@ struct HotlineApp: App {
// }
// }()
+ @State private var appState = HotlineState()
@State private var hotline = HotlineClient()
@State private var tracker = HotlineTrackerClient(tracker: HotlineTracker("hltracker.com"))
@@ -23,6 +24,7 @@ struct HotlineApp: App {
WindowGroup {
HotlineView()
+ .environment(appState)
.environment(hotline)
.environment(tracker)
}
diff --git a/Hotline/Views/AgreementView.swift b/Hotline/Views/AgreementView.swift
index c61c9d7..39730ce 100644
--- a/Hotline/Views/AgreementView.swift
+++ b/Hotline/Views/AgreementView.swift
@@ -1,11 +1,13 @@
import SwiftUI
struct AgreementView: View {
- @Environment(\.dismiss) var dismiss
+ @Environment(HotlineState.self) private var appState
let text: String
var body: some View {
+// @Bindable var config = appState
+
VStack(alignment: .leading) {
ScrollView {
VStack(alignment: .leading) {
@@ -18,11 +20,14 @@ struct AgreementView: View {
}
Button("OK") {
print("DONE")
+ appState.dismissAgreement()
}
.bold()
.padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
.frame(maxWidth: .infinity)
}
+ .presentationDetents([.fraction(0.6)])
+ .presentationDragIndicator(.visible)
}
}
diff --git a/Hotline/Views/ChatView.swift b/Hotline/Views/ChatView.swift
index 532a890..6dc7318 100644
--- a/Hotline/Views/ChatView.swift
+++ b/Hotline/Views/ChatView.swift
@@ -1,55 +1,64 @@
import SwiftUI
struct ChatView: View {
-// @Binding private var input: String
+ @Environment(HotlineClient.self) private var hotline
+
@State var input: String = ""
@State private var scrollPos: Int?
@State private var contentHeight: CGFloat = 0
var body: some View {
VStack(spacing: 0) {
- GeometryReader { geometry in
- ScrollView(.vertical) {
- ScrollViewReader { scrollReader in
- VStack(alignment: .leading) {
- Spacer()
- LazyVStack(alignment: .leading, spacing: 10) {
- HStack(alignment: .firstTextBaseline) {
- Text("bolt:").bold().fontDesign(.monospaced).frame(minWidth: 60)
- Text("hello!").fontDesign(.monospaced).textSelection(.enabled)
- }
- ForEach(0..<50) { i in
- HStack(alignment: .firstTextBaseline) {
- Text("mierau:").bold().fontDesign(.monospaced)
- Text("g'day to you. what's going on this afternoon?")
- .fontDesign(.monospaced)
- .textSelection(.enabled)
- }
- }
- Text("").font(.system(size: 0)).id("bottomScroll")
- }
- .padding()
- }
- // .frame(width: geometry.size.width)
- .frame(minHeight: geometry.size.height)
-// .background(Color.red)
- .onAppear() {
- scrollReader.scrollTo("bottomScroll", anchor: .bottom)
- }
- // .onChange() {
- // scrollReader.scrollTo(10000, anchor: .bottomTrailing)
- // }
- }
+ List(hotline.chatMessages) { msg in
+ if msg.username == "" {
+
+ }
+ HStack(alignment: .firstTextBaseline) {
+ Text("\(msg.username):").bold().fontDesign(.monospaced).font(.system(size: 12))
+ Text(msg.message)
+ .fontDesign(.monospaced)
+ .textSelection(.enabled)
+ .font(.system(size: 12))
}
}
+ .padding()
+
+// GeometryReader { geometry in
+// ScrollView(.vertical) {
+// ScrollViewReader { scrollReader in
+// VStack(alignment: .leading) {
+// Spacer()
+// List(hotline.chatMessages) { msg in
+// HStack(alignment: .firstTextBaseline) {
+// Text("\(msg.username):").bold().fontDesign(.monospaced)
+// Text(msg.message)
+// .fontDesign(.monospaced)
+// .textSelection(.enabled)
+// }
+// }
+// .padding()
+// }
+// // .frame(width: geometry.size.width)
+// .frame(minHeight: geometry.size.height)
+//// .background(Color.red)
+// .onAppear() {
+//// scrollReader.scrollTo("bottomScroll", anchor: .bottom)
+// }
+// // .onChange() {
+// // scrollReader.scrollTo(10000, anchor: .bottomTrailing)
+// // }
+// }
+// }
+// }
Divider()
HStack(alignment: .top) {
Image(systemName: "chevron.right")
- TextField("This is a chat topic", text: $input, axis: .vertical)
+ TextField("", text: $input, axis: .vertical)
.lineLimit(1...5)
.onSubmit {
+ hotline.sendChat(message: self.input)
// HotlineClient.shared.sendChat(message: self.input)
self.input = ""
}
@@ -60,4 +69,5 @@ struct ChatView: View {
#Preview {
ChatView()
+ .environment(HotlineClient())
}
diff --git a/Hotline/Views/FilesView.swift b/Hotline/Views/FilesView.swift
new file mode 100644
index 0000000..0e1bb91
--- /dev/null
+++ b/Hotline/Views/FilesView.swift
@@ -0,0 +1,32 @@
+import SwiftUI
+
+struct FilesView: View {
+ @Environment(HotlineClient.self) private var hotline
+
+ @State private var fetched = false
+
+ var body: some View {
+ ScrollView {
+ VStack(spacing: 0) {
+ List(hotline.userList) { u in
+ HStack(alignment: .firstTextBaseline) {
+ Text(u.name).bold().foregroundStyle(u.isAdmin ? Color.red : Color.black)
+ }
+ }
+ .padding()
+ }
+ }
+ .task {
+ if !fetched {
+ hotline.sendGetFileList() {
+ fetched = true
+ }
+ }
+ }
+ }
+}
+
+#Preview {
+ FilesView()
+ .environment(HotlineClient())
+}
diff --git a/Hotline/Views/HotlineState.swift b/Hotline/Views/HotlineState.swift
new file mode 100644
index 0000000..9ae4940
--- /dev/null
+++ b/Hotline/Views/HotlineState.swift
@@ -0,0 +1,24 @@
+import Foundation
+import SwiftUI
+
+@Observable
+class HotlineState {
+ var agreementPresented = false
+ var trackerPresented = true
+
+ func presentTracker() {
+ self.trackerPresented = true
+ }
+
+ func dismissTracker() {
+ self.trackerPresented = false
+ }
+
+ func presentAgreement() {
+ self.agreementPresented = true
+ }
+
+ func dismissAgreement() {
+ self.agreementPresented = false
+ }
+}
diff --git a/Hotline/Views/HotlineView.swift b/Hotline/Views/HotlineView.swift
index 67ef067..fe67f79 100644
--- a/Hotline/Views/HotlineView.swift
+++ b/Hotline/Views/HotlineView.swift
@@ -1,13 +1,22 @@
import SwiftUI
struct HotlineView: View {
+ @Environment(HotlineState.self) private var appState
@Environment(HotlineClient.self) private var hotline
@Environment(HotlineTrackerClient.self) private var tracker
- @State private var isTrackerVisible = false
+ @State private var isTrackerVisible = true
var body: some View {
+ @Bindable var config = appState
+
NavigationStack {
+ ServerView()
+ }
+ .sheet(isPresented: $config.agreementPresented) {
+ AgreementView(text: hotline.agreement!)
+ }
+ .sheet(isPresented: $config.trackerPresented) {
TrackerView()
}
}
diff --git a/Hotline/Views/MessageBoardView.swift b/Hotline/Views/MessageBoardView.swift
new file mode 100644
index 0000000..e5f1521
--- /dev/null
+++ b/Hotline/Views/MessageBoardView.swift
@@ -0,0 +1,42 @@
+import SwiftUI
+
+struct MessageBoardView: View {
+ @Environment(HotlineState.self) private var appState
+ @Environment(HotlineClient.self) private var hotline
+
+ @State private var fetched = false
+
+ var body: some View {
+// @Bindable var config = appState
+
+ VStack(alignment: .leading) {
+ ScrollView {
+ VStack(alignment: .leading) {
+ Text(hotline.messageBoard)
+ .fontDesign(.monospaced)
+ .padding()
+ .dynamicTypeSize(.small)
+ .textSelection(.enabled)
+ }
+ }
+ }
+ .presentationDetents([.fraction(0.6)])
+ .presentationDragIndicator(.visible)
+ .task {
+ if !fetched {
+ hotline.sendGetNews() {
+ fetched = true
+ }
+ }
+ }
+ .refreshable {
+ hotline.sendGetNews()
+ }
+ }
+}
+
+#Preview {
+ MessageBoardView()
+ .environment(HotlineState())
+ .environment(HotlineClient())
+}
diff --git a/Hotline/Views/ServerView.swift b/Hotline/Views/ServerView.swift
index 1610aa7..0dafbce 100644
--- a/Hotline/Views/ServerView.swift
+++ b/Hotline/Views/ServerView.swift
@@ -1,53 +1,64 @@
import SwiftUI
struct ServerView: View {
+ @Environment(HotlineState.self) private var appState
@Environment(HotlineClient.self) private var hotline
@Environment(HotlineTrackerClient.self) private var tracker
-
- @State private var isTrackerVisible = false
-
+
var body: some View {
+ @Bindable var config = appState
+
TabView {
NavigationView {
ChatView()
- .navigationTitle("Badmoon")
+ .navigationTitle(hotline.server?.name ?? "Hotline")
+ .navigationBarTitleDisplayMode(.inline)
.navigationBarItems(
leading: Button(action: {
- withAnimation {
- isTrackerVisible.toggle()
- }
+ appState.presentTracker()
}) {
- Image(systemName: "line.horizontal.3") // Hamburger icon or similar
+ Image(systemName: "globe.americas.fill") // Hamburger icon or similar
.imageScale(.large)
}
)
- .toolbarBackground(.visible, for: .navigationBar)
- .toolbarBackground(.red, for: .navigationBar)
+// .toolbarBackground(.visible, for: .navigationBar)
+// .toolbarBackground(.red, for: .navigationBar)
}
- .navigationBarTitleDisplayMode(.inline)
.tabItem {
Image(systemName: "message")
}
- Text("Users")
- .tabItem {
- Image(systemName: "person.fill")
- }
+ NavigationView {
+ UserListView()
+ .navigationTitle("User List")
+ .navigationBarTitleDisplayMode(.inline)
+ }
+ .tabItem {
+ Image(systemName: "person.fill")
+ }
Text("News")
.tabItem {
Image(systemName: "newspaper")
}
- Text("Files")
- .tabItem {
- Image(systemName: "folder")
- }
+ NavigationView {
+ MessageBoardView()
+ .navigationTitle("Message Board")
+ .navigationBarTitleDisplayMode(.inline)
+ }
+ .tabItem {
+ Image(systemName: "pin")
+ }
- Text("Transfers")
- .tabItem {
- Image(systemName: "network")
- }
+ NavigationView {
+ FilesView()
+ .navigationTitle("Files")
+ .navigationBarTitleDisplayMode(.inline)
+ }
+ .tabItem {
+ Image(systemName: "folder")
+ }
}
// .sheet(isPresented: Binding(get: { hotline.connectionStatus != .loggedIn }, set: { _ in })) {
// TrackerView()
diff --git a/Hotline/Views/TrackerServerView.swift b/Hotline/Views/TrackerServerView.swift
index 5be6f7a..2c0f3e3 100644
--- a/Hotline/Views/TrackerServerView.swift
+++ b/Hotline/Views/TrackerServerView.swift
@@ -1,11 +1,15 @@
import SwiftUI
struct TrackerServerView: View {
- @Environment(\.dismiss) var dismiss
+ @Environment(HotlineState.self) private var appState
+ @Environment(HotlineClient.self) private var hotline
+ @Environment(\.dismiss) private var dismiss
let server: HotlineServer
var body: some View {
+ @Bindable var config = appState
+
VStack(alignment: .leading) {
HStack {
Text("🌎").dynamicTypeSize(.xxxLarge)
@@ -20,9 +24,9 @@ struct TrackerServerView: View {
HStack(alignment: .center) {
Button("Connect") {
- print("WHAT", "HELLO", server.address)
-// HotlineClient.shared.connect(to: server)
- dismiss()
+ hotline.connect(to: server)
+ config.dismissTracker()
+// dismiss()
}
.bold()
.padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
@@ -44,4 +48,5 @@ struct TrackerServerView: View {
#Preview {
TrackerServerView(server: HotlineServer(address: "192.168.1.1", port: 5050, users: 5, name: "Ye Olde Server", description: "This is a server"))
+ .environment(HotlineClient())
}
diff --git a/Hotline/Views/TrackerView.swift b/Hotline/Views/TrackerView.swift
index 5d1afe2..edb2330 100644
--- a/Hotline/Views/TrackerView.swift
+++ b/Hotline/Views/TrackerView.swift
@@ -5,63 +5,54 @@ 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 tracker
- // @StateObject var tracker = HotlineTrackerClient(address: "hltracker.com")
- // @StateObject var client = HotlineClient.shared
-
@State private var selectedServer: HotlineServer?
- @State private var showingAgreement = false
- @State private var showingConnectSheet = false
-
- // @Bindable var trackerTest = tracker
var body: some View {
- List(selection: $selectedServer) {
- ForEach(tracker.servers) { server in
- HStack {
- Text("🌎")
- Text(server.name!).bold()
- Spacer()
- Text("\(server.users)").opacity(0.6)
+ @Bindable var config = appState
+
+ NavigationView {
+ List(selection: $selectedServer) {
+ ForEach(tracker.servers) { server in
+ TrackerServerView(server: server)
}
- .listRowBackground(Color(white: 0.96))
- .listRowInsets(EdgeInsets(top: 0, leading: 16.0, bottom: 0, trailing: 16.0))
- .listRowSeparator(.visible, edges: VerticalEdge.Set.all)
- .listRowSeparatorTint(Color(white: 1.0))
- .tag(server)
}
- }
- .background(Color(white: 0.96))
- .listStyle(.plain)
- .frame(maxWidth: .infinity)
- .task {
- tracker.fetch()
- }
- .sheet(item: $selectedServer) { item in
- TrackerServerView(server: item)
- }
- .sheet(isPresented: Binding(get: { hotline.agreement != nil }, set: { _ in })) {
- AgreementView(text: hotline.agreement!)
- }
- .navigationTitle("Tracker")
- .navigationBarTitleDisplayMode(.inline)
- .toolbar {
- ToolbarItem(placement: .topBarTrailing) {
- Image(systemName: "gearshape.fill")
+ .background(Color(white: 0.96))
+ .listStyle(.plain)
+ .frame(maxWidth: .infinity)
+ .task {
+ tracker.fetch()
+ }
+// .sheet(item: $selectedServer) { item in
+// TrackerServerView(server: item)
+// }
+ .refreshable {
+ tracker.fetch()
+ }
+ .navigationTitle("Tracker")
+ .navigationBarTitleDisplayMode(.inline)
+ .toolbar {
+ ToolbarItem(placement: .topBarTrailing) {
+ Button {
+ config.dismissTracker()
+ } label: {
+ Image(systemName: "xmark.circle.fill")
+ .symbolRenderingMode(.hierarchical)
+ .foregroundColor(.gray)
+ }
+ }
+ // ToolbarItem(placement: .topBarTrailing) {
+ // Image(systemName: "camera.fill")
+ // }
+ // ToolbarItem(placement: .principal) {
+ // Text("Username")
+ // }
}
- // ToolbarItem(placement: .topBarTrailing) {
- // Image(systemName: "camera.fill")
- // }
- // ToolbarItem(placement: .principal) {
- // Text("Username")
- // }
- }
- .refreshable {
- tracker.fetch()
}
- .interactiveDismissDisabled()
+// .interactiveDismissDisabled()
}
}
diff --git a/Hotline/Views/UserListView.swift b/Hotline/Views/UserListView.swift
new file mode 100644
index 0000000..cbb029d
--- /dev/null
+++ b/Hotline/Views/UserListView.swift
@@ -0,0 +1,21 @@
+import SwiftUI
+
+struct UserListView: View {
+ @Environment(HotlineClient.self) private var hotline
+
+ var body: some View {
+ VStack(spacing: 0) {
+ List(hotline.userList) { u in
+ HStack(alignment: .firstTextBaseline) {
+ Text(u.name).bold().foregroundStyle(u.isAdmin ? Color.red : Color.black)
+ }
+ }
+ .padding()
+ }
+ }
+}
+
+#Preview {
+ ChatView()
+ .environment(HotlineClient())
+}