@@ -188,11 +188,11 @@ extension SettingsProTab {
188188 self . setupStatusText = nil
189189 guard self . applySetupCode ( ) else { return }
190190 let host = self . manualGatewayHost. trimmingCharacters ( in: . whitespacesAndNewlines)
191- guard let port = self . resolvedManualPort ( host: host) else {
191+ guard self . resolvedManualPort ( host: host) != nil else {
192192 self . setupStatusText = " Failed: invalid port "
193193 return
194194 }
195- guard await self . preflightGateway ( host: host, port : port ) else { return }
195+ guard await self . preflightGateway ( host: host) else { return }
196196 self . setupStatusText = " Setup code applied. Connecting... "
197197 await self . connectManual ( )
198198 }
@@ -286,11 +286,11 @@ extension SettingsProTab {
286286
287287 func connectAfterScannedGatewayLink( ) async {
288288 let host = self . manualGatewayHost. trimmingCharacters ( in: . whitespacesAndNewlines)
289- guard let port = self . resolvedManualPort ( host: host) else {
289+ guard self . resolvedManualPort ( host: host) != nil else {
290290 self . setupStatusText = " Failed: invalid port "
291291 return
292292 }
293- guard await self . preflightGateway ( host: host, port : port ) else { return }
293+ guard await self . preflightGateway ( host: host) else { return }
294294 await self . connectManual ( )
295295 }
296296
@@ -319,20 +319,15 @@ extension SettingsProTab {
319319 authOverride: authOverride)
320320 }
321321
322- func preflightGateway( host: String , port : Int ) async -> Bool {
322+ func preflightGateway( host: String ) async -> Bool {
323323 let trimmed = host. trimmingCharacters ( in: . whitespacesAndNewlines)
324324 guard !trimmed. isEmpty else { return false }
325325 if Self . isTailnetHostOrIP ( trimmed) , !Self. hasTailnetIPv4 ( ) {
326326 self . setupStatusText = " Tailscale is off on this device. Turn it on, then try again. "
327327 return false
328328 }
329329 self . gatewayController. requestLocalNetworkAccess ( reason: " settings_preflight " )
330- self . setupStatusText = " Checking gateway reachability... "
331- let ok = await TCPProbe . probe ( host: trimmed, port: port, timeoutSeconds: 3 , queueLabel: " gateway.preflight " )
332- if !ok {
333- self . setupStatusText = " Can't reach gateway at \( trimmed) : \( port) . Check Tailscale or LAN. "
334- }
335- return ok
330+ return true
336331 }
337332
338333 func resetOnboarding( ) {
@@ -562,6 +557,12 @@ extension SettingsProTab {
562557 let gatewayStatus = self . appModel. gatewayStatusText. trimmingCharacters ( in: . whitespacesAndNewlines)
563558 if let friendly = self . friendlyGatewayMessage ( from: gatewayStatus) { return friendly }
564559 if let friendly = self . friendlyGatewayMessage ( from: trimmedSetup) { return friendly }
560+ if self . isTransientSetupStatus ( trimmedSetup) ,
561+ !gatewayStatus. isEmpty,
562+ gatewayStatus != " Offline "
563+ {
564+ return gatewayStatus
565+ }
565566 if !trimmedSetup. isEmpty { return trimmedSetup }
566567 if gatewayStatus. isEmpty || gatewayStatus == " Offline " { return nil }
567568 return gatewayStatus
@@ -586,6 +587,11 @@ extension SettingsProTab {
586587 if lower. contains ( " device nonce required " ) || lower. contains ( " device nonce mismatch " ) {
587588 return " Secure handshake failed. Check Tailscale, then connect again. "
588589 }
590+ if lower. contains ( " tls fingerprint verification timed out " )
591+ || lower. contains ( " no tls endpoint detected " )
592+ {
593+ return raw. trimmingCharacters ( in: . whitespacesAndNewlines)
594+ }
589595 if lower. contains ( " timed out " ) {
590596 return " Connection timed out. Make sure Tailscale is connected, then try again. "
591597 }
@@ -595,6 +601,13 @@ extension SettingsProTab {
595601 return nil
596602 }
597603
604+ func isTransientSetupStatus( _ raw: String ) -> Bool {
605+ let lower = raw. trimmingCharacters ( in: . whitespacesAndNewlines) . lowercased ( )
606+ return lower == " setup code applied. connecting... "
607+ || lower. hasPrefix ( " qr loaded. connecting to " )
608+ || lower == " checking gateway reachability... "
609+ }
610+
598611 var shouldShowRealtimeVoicePicker : Bool {
599612 let providerSelection = TalkModeProviderSelection . resolved ( self . talkProviderSelectionRaw)
600613 return providerSelection == . openAIRealtime || self . appModel. talkMode. gatewayTalkUsesRealtime
0 commit comments