@@ -26,6 +26,7 @@ import kotlinx.coroutines.delay
26import kotlinx.coroutines.flow.MutableStateFlow
26import kotlinx.coroutines.flow.MutableStateFlow
27import kotlinx.coroutines.flow.StateFlow
27import kotlinx.coroutines.flow.StateFlow
28import kotlinx.coroutines.flow.asStateFlow
28import kotlinx.coroutines.flow.asStateFlow
29+import kotlinx.coroutines.flow.collectLatest
29import kotlinx.coroutines.flow.update
30import kotlinx.coroutines.flow.update
30import kotlinx.coroutines.launch
31import kotlinx.coroutines.launch
31import kotlinx.coroutines.sync.Semaphore
32import kotlinx.coroutines.sync.Semaphore
@@ -102,6 +103,28 @@ class GlobalSearchViewModel(private val container: AppContainer) : ViewModel() {
102 @Volatile private var sessionsCache: List<Session>? = null
103 @Volatile private var sessionsCache: List<Session>? = null
103 private val messageCache = ConcurrentHashMap<String, List<MessageWithParts>>()
104 private val messageCache = ConcurrentHashMap<String, List<MessageWithParts>>()
107+ // Observe the active connection so a server switch clears the cross-server caches
108+ // and re-runs the current query against the new server. Without this, a search run
109+ // on server A leaves sessionsCache / messageCache populated with A's sessions, so
110+ // re-running the same query on server B reuses A's cached list — returning sessions
111+ // that don't exist on B (opening them navigates to a non-existent conversation) and
112+ // B's history for sessions that happen to share an id. Also covers the reconnect
113+ // window: if the screen opens while activeConnection.value is null, the first search
114+ // shows "not connected" and never auto-retries once the connection lands. Mirrors
115+ // FileBrowserViewModel's activeConnection.collectLatest pattern.
116+ viewModelScope.launch {
117+ container.activeConnection.collectLatest { conn ->
118+ sessionsCache = null
119+ messageCache.clear()
121+ val trimmed = _state.value.query.trim()
122+ if (trimmed.length >= NetworkConfig.minSearchQueryLength) runSearch(trimmed)
105 fun setQuery(query: String) {
128 fun setQuery(query: String) {
106 _state.update { it.copy(query = query) }
129 _state.update { it.copy(query = query) }
107 searchJob?.cancel()
130 searchJob?.cancel()