diff --git a/.DS_Store b/.DS_Store index 769c722..d36304b 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/dock-g/dock-g.xcodeproj/project.xcworkspace/xcuserdata/sven.xcuserdatad/UserInterfaceState.xcuserstate b/dock-g/dock-g.xcodeproj/project.xcworkspace/xcuserdata/sven.xcuserdatad/UserInterfaceState.xcuserstate index 9e1a04a..26b1b2c 100644 Binary files a/dock-g/dock-g.xcodeproj/project.xcworkspace/xcuserdata/sven.xcuserdatad/UserInterfaceState.xcuserstate and b/dock-g/dock-g.xcodeproj/project.xcworkspace/xcuserdata/sven.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/dock-g/dock-g/Models/DockgeServer.swift b/dock-g/dock-g/Models/DockgeServer.swift index ccc1561..92640dd 100644 --- a/dock-g/dock-g/Models/DockgeServer.swift +++ b/dock-g/dock-g/Models/DockgeServer.swift @@ -15,7 +15,15 @@ struct DockgeServer: Identifiable, Codable { var baseURL: URL? { let scheme = useSSL ? "https" : "http" - return URL(string: "\(scheme)://\(host)") + var cleanHost = host.trimmingCharacters(in: .whitespaces) + for prefix in ["https://", "http://"] { + if cleanHost.lowercased().hasPrefix(prefix) { + cleanHost = String(cleanHost.dropFirst(prefix.count)) + break + } + } + cleanHost = cleanHost.trimmingCharacters(in: CharacterSet(charactersIn: "/")) + return URL(string: "\(scheme)://\(cleanHost)") } var displayHost: String { host } diff --git a/dock-g/dock-g/Services/SocketIOClient.swift b/dock-g/dock-g/Services/SocketIOClient.swift index b6bef78..f921540 100644 --- a/dock-g/dock-g/Services/SocketIOClient.swift +++ b/dock-g/dock-g/Services/SocketIOClient.swift @@ -153,6 +153,9 @@ final class SocketIOClient: NSObject { Task { @MainActor [weak self] in guard let self else { return } self.connectionState = .disconnected + self.webSocketTask?.cancel(with: .goingAway, reason: nil) + self.webSocketTask = nil + self.pendingAcks.removeAll() self.errorHandlers.forEach { $0(error) } self.disconnectHandlers.forEach { $0() } } diff --git a/dock-g/dock-g/Views/Servers/AddServerView.swift b/dock-g/dock-g/Views/Servers/AddServerView.swift index 72d7433..db80431 100644 --- a/dock-g/dock-g/Views/Servers/AddServerView.swift +++ b/dock-g/dock-g/Views/Servers/AddServerView.swift @@ -62,7 +62,17 @@ struct AddServerView: View { } private func save() { - let trimmedHost = host.trimmingCharacters(in: .whitespaces) + var trimmedHost = host.trimmingCharacters(in: .whitespaces) + // Strip any scheme the user may have pasted in + if trimmedHost.lowercased().hasPrefix("https://") { + trimmedHost = String(trimmedHost.dropFirst("https://".count)) + useSSL = true + } else if trimmedHost.lowercased().hasPrefix("http://") { + trimmedHost = String(trimmedHost.dropFirst("http://".count)) + useSSL = false + } + // Strip trailing slash + trimmedHost = trimmedHost.trimmingCharacters(in: CharacterSet(charactersIn: "/")) if var existing = editingServer { existing.name = name.trimmingCharacters(in: .whitespaces) existing.host = trimmedHost diff --git a/dock-g/dock-g/Views/Servers/LoginView.swift b/dock-g/dock-g/Views/Servers/LoginView.swift index b348a67..ea5bc72 100644 --- a/dock-g/dock-g/Views/Servers/LoginView.swift +++ b/dock-g/dock-g/Views/Servers/LoginView.swift @@ -7,6 +7,7 @@ struct LoginView: View { @Environment(\.dismiss) private var dismiss @State private var username = "" @State private var password = "" + @State private var showPassword = false @State private var twoFAToken = "" @State private var showTwoFA = false @State private var showSetup = false @@ -53,10 +54,26 @@ struct LoginView: View { .padding() .background(Color.appSurface, in: RoundedRectangle(cornerRadius: 10)) - SecureField("Password", text: $password) + HStack { + Group { + if showPassword { + TextField("Password", text: $password) + } else { + SecureField("Password", text: $password) + } + } .textFieldStyle(.plain) - .padding() - .background(Color.appSurface, in: RoundedRectangle(cornerRadius: 10)) + .autocorrectionDisabled() + .textInputAutocapitalization(.never) + Button { + showPassword.toggle() + } label: { + Image(systemName: showPassword ? "eye.slash" : "eye") + .foregroundStyle(.appGray) + } + } + .padding() + .background(Color.appSurface, in: RoundedRectangle(cornerRadius: 10)) if showTwoFA { TextField("2FA Code", text: $twoFAToken)