aboutsummaryrefslogtreecommitdiff
path: root/Hotline/iOS/TrackerView.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Hotline/iOS/TrackerView.swift')
-rw-r--r--Hotline/iOS/TrackerView.swift302
1 files changed, 158 insertions, 144 deletions
diff --git a/Hotline/iOS/TrackerView.swift b/Hotline/iOS/TrackerView.swift
index 2a3583b..43b1916 100644
--- a/Hotline/iOS/TrackerView.swift
+++ b/Hotline/iOS/TrackerView.swift
@@ -4,13 +4,13 @@ struct TrackerConnectView: View {
@Environment(Hotline.self) private var model: Hotline
@Environment(\.dismiss) var dismiss
@Environment(\.colorScheme) var colorScheme
-
+
@State private var server: Server?
@State private var address = ""
@State private var login = ""
@State private var password = ""
-// @State private var connecting = false
-
+ // @State private var connecting = false
+
func connectionStatusToProgress(status: HotlineClientStatus) -> Double {
switch status {
case .disconnected:
@@ -25,118 +25,126 @@ struct TrackerConnectView: View {
return 1.0
}
}
-
+
var body: some View {
- VStack(alignment: .leading) {
- if self.model.status == .disconnected {
- TextField("Server Address", text: $address)
- .keyboardType(.URL)
- .disableAutocorrection(true)
- .frame(height: 48)
- .textFieldStyle(.plain)
- .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
- .background {
- Color.black.cornerRadius(8).blendMode(.overlay)
- }
- TextField("Login", text: $login)
- .disableAutocorrection(true)
- .frame(height: 48)
- .textFieldStyle(.plain)
- .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
- .background {
- Color.black.cornerRadius(8).blendMode(.overlay)
- }
- SecureField("Password", text: $password)
- .disableAutocorrection(true)
- .textFieldStyle(.plain)
- .frame(height: 48)
- .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
- .background {
- Color.black.cornerRadius(8).blendMode(.overlay)
- }
- }
- else {
- ProgressView(value: connectionStatusToProgress(status: model.status))
- .frame(minHeight: 10)
- .accentColor(colorScheme == .dark ? .white : .black)
- }
-
- Spacer()
-
- HStack {
- Button {
- dismiss()
- server = nil
- model.disconnect()
- } label: {
- Text("Cancel")
+ VStack(alignment: .leading) {
+ if self.model.status == .disconnected {
+ TextField("Server Address", text: $address)
+ .keyboardType(.URL)
+ .disableAutocorrection(true)
+ .frame(height: 48)
+ .textFieldStyle(.plain)
+ .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
+ .background {
+ Color.black.cornerRadius(8).blendMode(.overlay)
}
- .bold()
- .padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
- .frame(maxWidth: .infinity)
- .foregroundColor(colorScheme == .dark ? .white : .black)
- .background(
- colorScheme == .dark ?
- LinearGradient(gradient: Gradient(colors: [Color(white: 0.4), Color(white: 0.3)]), startPoint: .top, endPoint: .bottom)
- :
- LinearGradient(gradient: Gradient(colors: [Color(white: 0.95), Color(white: 0.91)]), startPoint: .top, endPoint: .bottom)
- )
- .overlay(
- RoundedRectangle(cornerRadius: 10.0).stroke(.black, lineWidth: 3).opacity(colorScheme == .dark ? 0.0 : 0.2)
- )
- .cornerRadius(10.0)
- Button {
- let s = Server(name: nil, description: nil, address: address, port: HotlinePorts.DefaultServerPort, users: 0, login: login, password: password)
- server = s
- self.model.login(server: s, username: "bolt", iconID: 128) { success in
- if !success {
- print("FAILED LOGIN??")
- }
- else {
- self.model.sendUserInfo(username: "bolt", iconID: 128)
- self.model.getUserList()
- }
+ TextField("Login", text: $login)
+ .disableAutocorrection(true)
+ .frame(height: 48)
+ .textFieldStyle(.plain)
+ .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
+ .background {
+ Color.black.cornerRadius(8).blendMode(.overlay)
+ }
+ SecureField("Password", text: $password)
+ .disableAutocorrection(true)
+ .textFieldStyle(.plain)
+ .frame(height: 48)
+ .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
+ .background {
+ Color.black.cornerRadius(8).blendMode(.overlay)
+ }
+ } else {
+ ProgressView(value: connectionStatusToProgress(status: model.status))
+ .frame(minHeight: 10)
+ .accentColor(colorScheme == .dark ? .white : .black)
+ }
+
+ Spacer()
+
+ HStack {
+ Button {
+ dismiss()
+ server = nil
+ model.disconnect()
+ } label: {
+ Text("Cancel")
+ }
+ .bold()
+ .padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
+ .frame(maxWidth: .infinity)
+ .foregroundColor(colorScheme == .dark ? .white : .black)
+ .background(
+ colorScheme == .dark
+ ? LinearGradient(
+ gradient: Gradient(colors: [Color(white: 0.4), Color(white: 0.3)]), startPoint: .top,
+ endPoint: .bottom)
+ : LinearGradient(
+ gradient: Gradient(colors: [Color(white: 0.95), Color(white: 0.91)]),
+ startPoint: .top, endPoint: .bottom)
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 10.0).stroke(.black, lineWidth: 3).opacity(
+ colorScheme == .dark ? 0.0 : 0.2)
+ )
+ .cornerRadius(10.0)
+ Button {
+ let s = Server(
+ name: nil, description: nil, address: address, port: HotlinePorts.DefaultServerPort,
+ users: 0, login: login, password: password)
+ server = s
+ self.model.login(server: s, username: "bolt", iconID: 128) { success in
+ if !success {
+ print("FAILED LOGIN??")
+ } else {
+ self.model.sendUserInfo(username: "bolt", iconID: 128)
+ self.model.getUserList()
}
- } label: {
- Text("Connect")
}
- .disabled(self.model.status != .disconnected)
- .bold()
- .padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
- .frame(maxWidth: .infinity)
- .foregroundColor(colorScheme == .dark ? .white : .black)
- .background(
- colorScheme == .dark ?
- LinearGradient(gradient: Gradient(colors: [Color(white: 0.4), Color(white: 0.3)]), startPoint: .top, endPoint: .bottom)
- :
- LinearGradient(gradient: Gradient(colors: [Color(white: 0.95), Color(white: 0.91)]), startPoint: .top, endPoint: .bottom)
- )
- .overlay(
- RoundedRectangle(cornerRadius: 10.0).stroke(.black, lineWidth: 3).opacity(colorScheme == .dark ? 0.0 : 0.2)
- )
- .cornerRadius(10.0)
+ } label: {
+ Text("Connect")
}
- .padding()
+ .disabled(self.model.status != .disconnected)
+ .bold()
+ .padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
+ .frame(maxWidth: .infinity)
+ .foregroundColor(colorScheme == .dark ? .white : .black)
+ .background(
+ colorScheme == .dark
+ ? LinearGradient(
+ gradient: Gradient(colors: [Color(white: 0.4), Color(white: 0.3)]), startPoint: .top,
+ endPoint: .bottom)
+ : LinearGradient(
+ gradient: Gradient(colors: [Color(white: 0.95), Color(white: 0.91)]),
+ startPoint: .top, endPoint: .bottom)
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 10.0).stroke(.black, lineWidth: 3).opacity(
+ colorScheme == .dark ? 0.0 : 0.2)
+ )
+ .cornerRadius(10.0)
}
.padding()
- .onChange(of: model.status) {
- print("MODEL STATUS CHANGED")
- if model.server != nil && server != nil && model.server! == server! {
- if model.status == .loggedIn {
- dismiss()
- }
-// else {
-// connecting = (model.status != .disconnected)
-// }
+ }
+ .padding()
+ .onChange(of: model.status) {
+ print("MODEL STATUS CHANGED")
+ if model.server != nil && server != nil && model.server! == server! {
+ if model.status == .loggedIn {
+ dismiss()
}
+ // else {
+ // connecting = (model.status != .disconnected)
+ // }
}
- .toolbar {
- ToolbarItem(placement: .principal) {
- Text("Connect to Server")
- .font(.headline)
- }
+ }
+ .toolbar {
+ ToolbarItem(placement: .principal) {
+ Text("Connect to Server")
+ .font(.headline)
}
-// .presentationBackground(.regularMaterial, in: Color(uiColor: .systemGroupedBackground))
+ }
+ // .presentationBackground(.regularMaterial, in: Color(uiColor: .systemGroupedBackground))
.presentationBackground {
Color.clear
.background(Material.regular)
@@ -151,7 +159,7 @@ struct TrackerConnectView: View {
struct TrackerView: View {
@Environment(Hotline.self) private var model: Hotline
@Environment(\.colorScheme) var colorScheme
-
+
@State private var servers: [Server] = []
@State private var selectedServer: Server?
@State private var scrollOffset: CGFloat = CGFloat.zero
@@ -161,15 +169,15 @@ struct TrackerView: View {
@State private var connectVisible = false
@State private var connectDismissed = true
@State private var serverVisible = false
-
+
func shouldDisplayDescription(server: Server) -> Bool {
guard let desc = server.description else {
return false
}
-
+
return desc.count > 0 && desc != server.name
}
-
+
func connectionStatusToProgress(status: HotlineClientStatus) -> Double {
switch status {
case .disconnected:
@@ -184,21 +192,21 @@ struct TrackerView: View {
return 1.0
}
}
-
+
func inverseLerp(lower: Double, upper: Double, v: Double) -> Double {
return (v - lower) / (upper - lower)
}
-
+
func updateServers() async {
-// "hltracker.com"
-// "tracker.preterhuman.net"
-// "hotline.ubersoft.org"
-// "tracked.nailbat.com"
-// "hotline.duckdns.org"
-// "tracked.agent79.org"
+ // "hltracker.com"
+ // "tracker.preterhuman.net"
+ // "hotline.ubersoft.org"
+ // "tracked.nailbat.com"
+ // "hotline.duckdns.org"
+ // "tracked.agent79.org"
self.servers = await model.getServerList(tracker: "hltracker.com")
}
-
+
var body: some View {
ZStack(alignment: .center) {
VStack(alignment: .center) {
@@ -249,7 +257,7 @@ struct TrackerView: View {
.frame(height: 40.0)
}
.padding()
-
+
Spacer()
}
.opacity(inverseLerp(lower: -50, upper: 0, v: scrollOffset))
@@ -269,7 +277,8 @@ struct TrackerView: View {
Text(server.description!).opacity(0.5).font(.system(size: 16))
}
Spacer()
- Text("\(server.address):" + String(format: "%i", server.port)).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 {
@@ -278,19 +287,17 @@ struct TrackerView: View {
}
if server == selectedServer {
Spacer(minLength: 16)
-
+
if model.status != .disconnected && model.server != nil && model.server! == server {
ProgressView(value: connectionStatusToProgress(status: model.status))
.frame(minHeight: 10)
.accentColor(colorScheme == .dark ? .white : .black)
- }
- else {
+ } else {
Button("Connect") {
self.model.login(server: server, username: "bolt", iconID: 128) { success in
if !success {
print("FAILED LOGIN??")
- }
- else {
+ } else {
self.model.sendUserInfo(username: "bolt", iconID: 128)
self.model.getUserList()
self.model.downloadBanner()
@@ -302,13 +309,17 @@ struct TrackerView: View {
.frame(maxWidth: .infinity)
.foregroundColor(colorScheme == .dark ? .white : .black)
.background(
- colorScheme == .dark ?
- LinearGradient(gradient: Gradient(colors: [Color(white: 0.4), Color(white: 0.3)]), startPoint: .top, endPoint: .bottom)
- :
- LinearGradient(gradient: Gradient(colors: [Color(white: 0.95), Color(white: 0.91)]), startPoint: .top, endPoint: .bottom)
+ colorScheme == .dark
+ ? LinearGradient(
+ gradient: Gradient(colors: [Color(white: 0.4), Color(white: 0.3)]),
+ startPoint: .top, endPoint: .bottom)
+ : LinearGradient(
+ gradient: Gradient(colors: [Color(white: 0.95), Color(white: 0.91)]),
+ startPoint: .top, endPoint: .bottom)
)
.overlay(
- RoundedRectangle(cornerRadius: 10.0).stroke(.black, lineWidth: 3).opacity(colorScheme == .dark ? 0.0 : 0.2)
+ RoundedRectangle(cornerRadius: 10.0).stroke(.black, lineWidth: 3).opacity(
+ colorScheme == .dark ? 0.0 : 0.2)
)
.cornerRadius(10.0)
}
@@ -346,22 +357,24 @@ struct TrackerView: View {
}
initialLoadComplete = true
}
-
+
model.disconnectTracker()
await updateServers()
-
+
DispatchQueue.main.async {
withAnimation(.easeOut(duration: 1.0).delay(0.75)) {
topBarOpacity = 1.0
}
}
}
-
-
+
}
- .fullScreenCover(isPresented: Binding(get: { return (connectDismissed && serverVisible) }, set: { _ in }), onDismiss: {
- model.disconnect()
- }) {
+ .fullScreenCover(
+ isPresented: Binding(get: { return (connectDismissed && serverVisible) }, set: { _ in }),
+ onDismiss: {
+ model.disconnect()
+ }
+ ) {
ServerView()
}
.onChange(of: model.status) {
@@ -377,26 +390,27 @@ struct TrackerView: View {
guard url.scheme == "hotline" else {
return
}
-
+
if let address = url.host() {
let login = url.user(percentEncoded: false) ?? ""
let password = url.password(percentEncoded: false) ?? ""
let port = url.port ?? HotlinePorts.DefaultServerPort
-
+
self.model.disconnect()
-
- let tempServer = Server(name: nil, description: nil, address: address, port: port, users: 0, login: login, password: password)
+
+ let tempServer = Server(
+ name: nil, description: nil, address: address, port: port, users: 0, login: login,
+ password: password)
self.model.login(server: tempServer, username: "bolt", iconID: 128) { success in
if !success {
print("FAILED LOGIN??")
- }
- else {
+ } else {
self.model.sendUserInfo(username: "bolt", iconID: 128)
self.model.getUserList()
self.model.downloadBanner()
}
}
-
+
// TODO: Find a better way to show login status when trying to connect outside of the Tracker server list. Perhaps this opens the connect sheet prefilled.
}
})