diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt
index 13a0f725..1aa98405 100644
--- a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt
+++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt
@@ -109,12 +109,14 @@ import androidx.core.content.FileProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
+import com.m57.hermescontrol.AuthLoginScreen
import com.m57.hermescontrol.NavigationController
import com.m57.hermescontrol.R
import com.m57.hermescontrol.data.model.Attachment
import com.m57.hermescontrol.data.ws.CommandCatalog
import com.m57.hermescontrol.data.ws.ConnectionStatus
import com.m57.hermescontrol.notification.NotificationHelper
+import com.m57.hermescontrol.theme.LocalHermesStatusColors
import com.m57.hermescontrol.theme.StatusRed
import com.m57.hermescontrol.ui.common.EmptyState
import com.m57.hermescontrol.ui.common.HermesScaffold
@@ -360,6 +362,7 @@ fun ChatScreen(
ChatTopBanner(
connectionStatus = state.connectionStatus,
onReconnect = viewModel::reconnect,
+ onAuthExpired = { NavigationController.navigateTo(AuthLoginScreen) },
)
Box(
@@ -1337,18 +1340,20 @@ private fun ChatLifecycleEffects(
private fun ChatTopBanner(
connectionStatus: ConnectionStatus,
onReconnect: () -> Unit,
+ onAuthExpired: () -> Unit,
) {
+ val isShown =
+ connectionStatus != ConnectionStatus.CONNECTED &&
+ connectionStatus != ConnectionStatus.CONNECTING
androidx.compose.animation.AnimatedVisibility(
- visible =
- connectionStatus == ConnectionStatus.RECONNECTING ||
- connectionStatus == ConnectionStatus.DISCONNECTED,
+ visible = isShown,
enter = androidx.compose.animation.expandVertically() + androidx.compose.animation.fadeIn(),
exit = androidx.compose.animation.shrinkVertically() + androidx.compose.animation.fadeOut(),
) {
androidx.compose.material3.Surface(
modifier = Modifier.fillMaxWidth(),
- color = MaterialTheme.colorScheme.errorContainer,
- contentColor = MaterialTheme.colorScheme.onErrorContainer,
+ color = LocalHermesStatusColors.current.errorContainer,
+ contentColor = LocalHermesStatusColors.current.error,
) {
Row(
modifier =
@@ -1358,25 +1363,52 @@ private fun ChatTopBanner(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
- Text(
- text =
- if (connectionStatus == ConnectionStatus.RECONNECTING) {
- stringResource(R.string.chat_status_reconnecting)
- } else {
- stringResource(R.string.chat_status_disconnected)
- },
- style = MaterialTheme.typography.bodyMedium,
- )
- if (connectionStatus == ConnectionStatus.DISCONNECTED) {
- TextButton(
- onClick = onReconnect,
- colors =
- androidx.compose.material3.ButtonDefaults.textButtonColors(
- contentColor = MaterialTheme.colorScheme.onErrorContainer,
- ),
- ) {
- Text(stringResource(R.string.chat_action_reconnect))
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ if (connectionStatus == ConnectionStatus.RECONNECTING) {
+ CircularProgressIndicator(
+ modifier = Modifier.size(16.dp).padding(end = 8.dp),
+ strokeWidth = 2.dp,
+ color = LocalHermesStatusColors.current.error,
+ )
}
+ Text(
+ text =
+ when (connectionStatus) {
+ ConnectionStatus.RECONNECTING -> stringResource(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)
+ else -> ""
+ },
+ style = MaterialTheme.typography.bodyMedium,
+ )
+ }
+ when (connectionStatus) {
+ ConnectionStatus.DISCONNECTED,
+ ConnectionStatus.NO_NETWORK,
+ -> {
+ TextButton(
+ onClick = onReconnect,
+ colors =
+ androidx.compose.material3.ButtonDefaults.textButtonColors(
+ contentColor = LocalHermesStatusColors.current.error,
+ ),
+ ) {
+ Text(stringResource(R.string.chat_action_reconnect))
+ }
+ }
+ ConnectionStatus.AUTH_EXPIRED -> {
+ TextButton(
+ onClick = onAuthExpired,
+ colors =
+ androidx.compose.material3.ButtonDefaults.textButtonColors(
+ contentColor = LocalHermesStatusColors.current.error,
+ ),
+ ) {
+ Text(stringResource(R.string.chat_action_sign_in))
+ }
+ }
+ else -> { /* RECONNECTING: auto, no button */ }
}
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 936d1307..dc0d12b5 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -82,11 +82,14 @@
Search
Close search
Reconnect
+ Sign in again
Ready to chat
Send a message to start a conversation
Connecting to Hermes\u2026
Reconnecting to Hermes\u2026
Disconnected from Hermes
+ No network connection
+ Session expired \u2014 please sign in again
Thinking\u2026
Thinking: %1$s\u2026
Not connected\u2026