android accounts: force chats/realtime resync on account switch
Some checks failed
Android CI / android (push) Failing after 5m15s
Android Release / release (push) Failing after 4m20s
CI / test (push) Has started running

This commit is contained in:
Codex
2026-03-10 00:17:13 +03:00
parent c609a7d72d
commit 4bab551f0e
3 changed files with 27 additions and 1 deletions

View File

@@ -780,3 +780,9 @@
- introduced dedicated `startup` route with session-check loader, - introduced dedicated `startup` route with session-check loader,
- delayed auth/chats navigation until session check is finished. - delayed auth/chats navigation until session check is finished.
- Added safe fallback in `MainActivity` theme bootstrap to prevent crash if `ThemeRepository` injection is unexpectedly unavailable during startup. - Added safe fallback in `MainActivity` theme bootstrap to prevent crash if `ThemeRepository` injection is unexpectedly unavailable during startup.
### Step 114 - Multi-account switch sync fix (chats + realtime)
- Fixed account switch flow to fully rebind app data context:
- restart realtime socket on new active account token,
- force refresh chats for both `archived=false` and `archived=true` right after switch.
- Fixed navigation behavior on account switch to avoid noisy `popBackStack ... not found` and stale restored stack state.

View File

@@ -12,9 +12,11 @@ import kotlinx.coroutines.launch
import ru.daemonlord.messenger.core.token.TokenRepository import ru.daemonlord.messenger.core.token.TokenRepository
import ru.daemonlord.messenger.domain.auth.usecase.LoginUseCase import ru.daemonlord.messenger.domain.auth.usecase.LoginUseCase
import ru.daemonlord.messenger.domain.account.repository.AccountRepository import ru.daemonlord.messenger.domain.account.repository.AccountRepository
import ru.daemonlord.messenger.domain.chat.repository.ChatRepository
import ru.daemonlord.messenger.domain.common.AppError import ru.daemonlord.messenger.domain.common.AppError
import ru.daemonlord.messenger.domain.common.AppResult import ru.daemonlord.messenger.domain.common.AppResult
import ru.daemonlord.messenger.domain.notifications.repository.NotificationSettingsRepository import ru.daemonlord.messenger.domain.notifications.repository.NotificationSettingsRepository
import ru.daemonlord.messenger.domain.realtime.RealtimeManager
import ru.daemonlord.messenger.domain.settings.model.AppThemeMode import ru.daemonlord.messenger.domain.settings.model.AppThemeMode
import ru.daemonlord.messenger.domain.settings.repository.ThemeRepository import ru.daemonlord.messenger.domain.settings.repository.ThemeRepository
import javax.inject.Inject import javax.inject.Inject
@@ -24,6 +26,8 @@ class AccountViewModel @Inject constructor(
private val accountRepository: AccountRepository, private val accountRepository: AccountRepository,
private val tokenRepository: TokenRepository, private val tokenRepository: TokenRepository,
private val loginUseCase: LoginUseCase, private val loginUseCase: LoginUseCase,
private val chatRepository: ChatRepository,
private val realtimeManager: RealtimeManager,
private val notificationSettingsRepository: NotificationSettingsRepository, private val notificationSettingsRepository: NotificationSettingsRepository,
private val themeRepository: ThemeRepository, private val themeRepository: ThemeRepository,
) : ViewModel() { ) : ViewModel() {
@@ -145,7 +149,20 @@ class AccountViewModel @Inject constructor(
onSwitched(false) onSwitched(false)
return@launch return@launch
} }
// Force data/context switch to the newly active account.
realtimeManager.disconnect()
realtimeManager.connect()
val allResult = chatRepository.refreshChats(archived = false)
val archivedResult = chatRepository.refreshChats(archived = true)
refresh() refresh()
val syncFailed = allResult is AppResult.Error && archivedResult is AppResult.Error
if (syncFailed) {
_uiState.update {
it.copy(
errorMessage = "Account switched, but chats sync failed. Pull to refresh.",
)
}
}
onSwitched(true) onSwitched(true)
} }
} }

View File

@@ -252,8 +252,11 @@ fun MessengerNavHost(
onSwitchAccount = { onSwitchAccount = {
viewModel.recheckSession() viewModel.recheckSession()
navController.navigate(Routes.Chats) { navController.navigate(Routes.Chats) {
popUpTo(Routes.Chats) { inclusive = true } popUpTo(navController.graph.findStartDestination().id) {
saveState = false
}
launchSingleTop = true launchSingleTop = true
restoreState = false
} }
}, },
onLogout = viewModel::logout, onLogout = viewModel::logout,