From c2d828b90af0bac61b20c581193df411b4406ff7 Mon Sep 17 00:00:00 2001 From: yilsem Date: Mon, 5 Oct 2026 04:18:53 +0300 Subject: [PATCH] feat(aiturk): say when AITURK IDE is closed in the chat banner When the tunnel reports that no computer is attached (close 4503) the reconnect banner now says that AITURK IDE is not open or Phone connection is off, instead of an endless 'reconnecting'. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01B8ppceaR5s6cvMnm7uGRnf --- .../com/m57/hermescontrol/data/ws/WsTransport.kt | 6 ++++++ .../ui/chat/components/ChatConnectionBanner.kt | 13 +++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/m57/hermescontrol/data/ws/WsTransport.kt b/app/src/main/java/com/m57/hermescontrol/data/ws/WsTransport.kt index b425ca4d..3ce464e5 100644 --- a/app/src/main/java/com/m57/hermescontrol/data/ws/WsTransport.kt +++ b/app/src/main/java/com/m57/hermescontrol/data/ws/WsTransport.kt @@ -730,6 +730,8 @@ internal class WsTransport( // Do NOT log [reason] — it may carry server-side context. The // reason is still inspected internally to detect auth failures. Log.i(TAG, "WebSocket closed: $code") + com.m57.hermescontrol.data.aiturk.AiturkRelayStatus + .onSocketEnded(null) connected.set(false) ActiveSessionHolder.clear() connectionHealth.stop() @@ -764,6 +766,10 @@ internal class WsTransport( connectionHealth.stop() rpcChannel.clearCapabilityRequests() val code = response?.code ?: 0 + // AITURK: lets the chat banner say "AITURK IDE is not open on the + // computer" when the tunnel reports that no host is attached. + com.m57.hermescontrol.data.aiturk.AiturkRelayStatus + .onSocketEnded(t) if (code == 401 || code == 4401 || code == 4403 || t.message?.contains("401") == true || t.message?.contains("4401") == true || diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/components/ChatConnectionBanner.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/components/ChatConnectionBanner.kt index c6cf431f..77e6e646 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/chat/components/ChatConnectionBanner.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/components/ChatConnectionBanner.kt @@ -17,6 +17,8 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -70,13 +72,20 @@ fun ChatConnectionBanner( color = LocalHermesStatusColors.current.error, ) } + // AITURK: over the relay, say why the reconnect keeps failing. + val aiturkHostOffline by com.m57.hermescontrol.data.aiturk.AiturkRelayStatus.hostOffline + .collectAsState() + val hostOffline = aiturkHostOffline && connectionStatus == ConnectionStatus.RECONNECTING Text( modifier = Modifier.weight(1f, fill = false), - maxLines = 1, + maxLines = if (hostOffline) 3 else 1, overflow = TextOverflow.Ellipsis, text = when (connectionStatus) { - ConnectionStatus.RECONNECTING -> stringResource(R.string.chat_status_reconnecting) + ConnectionStatus.RECONNECTING -> + stringResource( + if (hostOffline) R.string.aiturk_status_host_offline else R.string.chat_status_reconnecting, + ) ConnectionStatus.DISCONNECTED -> stringResource(R.string.chat_status_disconnected) ConnectionStatus.NO_NETWORK -> stringResource(R.string.chat_status_no_network) ConnectionStatus.AUTH_EXPIRED -> stringResource(R.string.chat_status_auth_expired)