feat(#1222): add background connection toggle to chat menu (#1235)

This commit is contained in:
m57 authored and GitHub committed 2026-09-23 11:50:18 +03:00
1 parent ee634e2abb
commit 721edef618
4 files changed
+112 -1

No files matched your search

@@ -37,6 +37,7 @@ import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -117,6 +118,7 @@ import com.m57.hermescontrol.ui.common.CredentialWarningBanner
import com.m57.hermescontrol.ui.common.HermesScaffold
import com.m57.hermescontrol.ui.common.NavIcon
import com.m57.hermescontrol.ui.model.components.ModelPickerDialog
import com.m57.hermescontrol.ui.settings.SettingsViewModel
import com.m57.hermescontrol.util.ConnectorUrlValidator
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -160,6 +162,8 @@ fun ChatScreen(
val connectorsState by connectorsViewModel.uiState.collectAsStateWithLifecycle()
val actionProgressState by viewModel.actionProgress.state.collectAsStateWithLifecycle()
val connectionOperationState by viewModel.connectionOperationState.collectAsStateWithLifecycle()
val settingsViewModel: SettingsViewModel = viewModel()
val settingsState by settingsViewModel.uiState.collectAsStateWithLifecycle()
// Snapshot-backed search state — read directly so only the scopes that
// read its fields recompose on search changes (bar, matched bubbles).
val searchState = viewModel.searchState
@@ -539,7 +543,10 @@ fun ChatScreen(
var showSessionMenu by remember { mutableStateOf(false) }
Box {
IconButton(
onClick = { showSessionMenu = true },
onClick = {
settingsViewModel.refreshKeepConnectedInBackground()
showSessionMenu = true
},
modifier = Modifier.testTag("chat_session_menu_button"),
) {
Icon(
@@ -609,6 +616,10 @@ fun ChatScreen(
},
modifier = Modifier.testTag("chat_menu_session_integrations"),
)
ChatBackgroundConnectionMenuItem(
checked = settingsState.keepConnectedInBackground,
onToggle = settingsViewModel::onKeepConnectedInBackgroundChange,
)
}
}
},
@@ -1029,3 +1040,22 @@ fun ChatScreen(
)
}
}
@Composable
internal fun ChatBackgroundConnectionMenuItem(
checked: Boolean,
onToggle: (Boolean) -> Unit,
) {
DropdownMenuItem(
text = { Text(stringResource(R.string.settings_keep_connected_in_background_title)) },
trailingIcon = {
Checkbox(
checked = checked,
onCheckedChange = onToggle,
modifier = Modifier.testTag("chat_menu_keep_connected_checkbox"),
)
},
onClick = { onToggle(!checked) },
modifier = Modifier.testTag("chat_menu_keep_connected"),
)
}
@@ -376,6 +376,12 @@ class SettingsViewModel(
AuthManager.setKeepConnectedInBackground(enabled)
}
/** Reconcile the chat shortcut with changes made through Settings or another screen. */
fun refreshKeepConnectedInBackground() {
val enabled = AuthManager.isKeepConnectedInBackground()
_uiState.update { it.copy(keepConnectedInBackground = enabled) }
}
/** Clear all auth credentials — logs out and returns to landing screen. */
fun logout() {
AuthManager.setToken(null)