aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Views/TrackerView.swift
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2023-12-11 23:32:28 -0800
committerDustin Mierau <dustin@mierau.me>2023-12-11 23:32:28 -0800
commit18c4b8643df09be4ce52a4b110ea21ac1ad053fc (patch)
tree335d4f0a6b430b983b6f00567b91eb1ee6b16b4b /Hotline/Views/TrackerView.swift
parent84aaa9ef0a1be6986e38d7e4f58e07d3cb84979e (diff)
Move to new Hotline model for data observation and let client exist standalone.
Diffstat (limited to 'Hotline/Views/TrackerView.swift')
-rw-r--r--Hotline/Views/TrackerView.swift214
1 files changed, 195 insertions, 19 deletions
diff --git a/Hotline/Views/TrackerView.swift b/Hotline/Views/TrackerView.swift
index 2d2032e..2fc27c7 100644
--- a/Hotline/Views/TrackerView.swift
+++ b/Hotline/Views/TrackerView.swift
@@ -1,20 +1,172 @@
import SwiftUI
+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
+
+ func connectionStatusToProgress(status: HotlineNewClientStatus) -> Double {
+ switch status {
+ case .disconnected:
+ return 0.0
+ case .connecting:
+ return 0.1
+ case .connected:
+ return 0.25
+ case .loggingIn:
+ return 0.5
+ case .loggedIn:
+ return 1.0
+ }
+ }
+
+
+
+ var body: some View {
+ VStack(alignment: .leading) {
+ if !connecting {
+ 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")
+ }
+ .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: address, description: nil, address: address, port: Server.defaultPort, users: 0)
+ server = s
+ connecting = true
+ Task {
+ let loggedIn = await model.login(server: s, login: login, password: password, username: "bolt", iconID: 128)
+ if !loggedIn {
+ connecting = false
+ }
+ }
+ } label: {
+ Text("Connect")
+ }
+ .disabled(connecting)
+ .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()
+ }
+ .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)
+ }
+ }
+// .presentationBackground(.regularMaterial, in: Color(uiColor: .systemGroupedBackground))
+ .presentationBackground {
+ Color.clear
+ .background(Material.regular)
+ }
+ .presentationDetents([.height(300), .large])
+ .presentationDragIndicator(.visible)
+ .presentationCornerRadius(20)
+ // .background(Color(uiColor: .systemGroupedBackground))
+ }
+}
+
struct TrackerView: View {
// @Environment(\.modelContext) private var modelContext
// @Query private var items: [Item]
- @Environment(HotlineClient.self) private var hotline
@Environment(Hotline.self) private var model: Hotline
@Environment(\.colorScheme) var colorScheme
-// @State private var tracker = Tracker(address: "hltracker.com", service: trackerService)
+ // @State private var tracker = Tracker(address: "hltracker.com", service: trackerService)
@State private var servers: [Server] = []
@State private var selectedServer: Server?
- @State var scrollOffset: CGFloat = CGFloat.zero
+ @State private var scrollOffset: CGFloat = CGFloat.zero
@State private var initialLoadComplete = false
+ @State private var refreshing = false
+ @State private var topBarOpacity: Double = 1.0
+ @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 {
@@ -24,7 +176,7 @@ struct TrackerView: View {
return desc.count > 0 && desc != server.name
}
- func connectionStatusToProgress(status: HotlineClientStatus) -> Double {
+ func connectionStatusToProgress(status: HotlineNewClientStatus) -> Double {
switch status {
case .disconnected:
return 0.0
@@ -60,7 +212,8 @@ struct TrackerView: View {
HStack(alignment: .center) {
Spacer()
Button {
- // hotline.disconnect()
+ connectVisible = true
+ connectDismissed = false
} label: {
Text(Image(systemName: "point.3.connected.trianglepath.dotted"))
.symbolRenderingMode(.hierarchical)
@@ -68,17 +221,22 @@ struct TrackerView: View {
.font(.title2)
.padding(.trailing, 16)
}
+ .sheet(isPresented: $connectVisible) {
+ connectDismissed = true
+ } content: {
+ TrackerConnectView()
+ }
}
.frame(height: 40.0)
}
.padding()
- .opacity(scrollOffset > 80 ? 0 : 1.0)
-// .padding(.top, 5)
- .opacity(inverseLerp(lower: -80, upper: 0, v: scrollOffset))
-// .opacity(inverseLerp(lower: 20, upper: 0, v: scrollOffset))
Spacer()
}
+ .opacity(inverseLerp(lower: -50, upper: 0, v: scrollOffset))
+ .opacity(scrollOffset > 65 ? 0.0 : 1.0)
+ .opacity(topBarOpacity)
+ .zIndex(scrollOffset > 0 ? 1 : 3)
ObservableScrollView(scrollOffset: $scrollOffset) {
LazyVStack(alignment: .leading) {
ForEach(self.servers) { server in
@@ -102,14 +260,16 @@ struct TrackerView: View {
if server == selectedServer {
Spacer(minLength: 16)
- if hotline.connectionStatus != .disconnected && hotline.server! == server {
- ProgressView(value: connectionStatusToProgress(status: hotline.connectionStatus))
+ 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 {
Button("Connect") {
- hotline.connect(to: HotlineServer(address: server.address, port: UInt16(server.port), users: UInt16(server.users), name: server.name, description: server.description))
+ Task {
+ await model.login(server: server, login: "", password: "", username: "bolt", iconID: 128)
+ }
}
.bold()
.padding(EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24))
@@ -119,7 +279,7 @@ struct TrackerView: View {
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)
+ 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)
@@ -143,6 +303,7 @@ struct TrackerView: View {
}
.padding(EdgeInsets(top: 75, leading: 0, bottom: 0, trailing: 0))
}
+ .zIndex(2)
.overlay {
if !initialLoadComplete {
VStack {
@@ -153,29 +314,44 @@ struct TrackerView: View {
}
}
.refreshable {
- initialLoadComplete = true
+ DispatchQueue.main.async {
+ withAnimation(.easeOut(duration: 0.1)) {
+ topBarOpacity = 0.0
+ }
+ 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 hotline.connectionStatus == .loggedIn }, set: { _ in }), onDismiss: {
- hotline.disconnect()
+ .fullScreenCover(isPresented: Binding(get: { return (connectDismissed && serverVisible) }, set: { _ in }), onDismiss: {
+ model.disconnect()
}) {
ServerView()
}
+ .onChange(of: model.status) {
+ serverVisible = (model.status == .loggedIn)
+ }
.background(Color(uiColor: UIColor.systemGroupedBackground))
.frame(maxWidth: .infinity)
.task {
await updateServers()
initialLoadComplete = true
-// tracker.fetch()
}
}
}
#Preview {
TrackerView()
- .environment(HotlineClient())
- .environment(HotlineState())
+ .environment(Hotline(trackerClient: HotlineTrackerClient(), client: HotlineNewClient()))
// .modelContainer(for: Item.self, inMemory: true)
}