fix: use real-time session observation in WaitingForPartnerScreen, add credential type check in Google sign-in

This commit is contained in:
null 2026-06-18 02:50:21 -05:00
parent c894dd8c67
commit dfd9974683
2 changed files with 26 additions and 37 deletions

View File

@ -5,6 +5,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.credentials.CredentialManager
import androidx.credentials.CustomCredential
import androidx.credentials.GetCredentialRequest
import androidx.credentials.exceptions.GetCredentialCancellationException
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
@ -190,8 +191,15 @@ fun LoginScreen(
.build()
val request = GetCredentialRequest.Builder().addCredentialOption(option).build()
val result = credMgr.getCredential(context, request)
val idToken = GoogleIdTokenCredential.createFrom(result.credential.data).idToken
viewModel.signInWithGoogle(idToken)
val credential = result.credential
if (credential is CustomCredential &&
credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
) {
val idToken = GoogleIdTokenCredential.createFrom(credential.data).idToken
viewModel.signInWithGoogle(idToken)
} else {
viewModel.reportError("Google sign-in failed. Please try again.")
}
} catch (_: GetCredentialCancellationException) {
// user dismissed — do nothing
} catch (e: Exception) {

View File

@ -30,15 +30,9 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.core.navigation.AppRoute
import app.closer.domain.model.QuestionSession
import app.closer.domain.repository.AuthRepository
import app.closer.domain.repository.CoupleRepository
import app.closer.domain.repository.UserRepository
import app.closer.domain.usecase.GameSessionManager
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@ -63,41 +57,28 @@ class WaitingForPartnerViewModel @Inject constructor(
init {
viewModelScope.launch {
loadGameInfo()
// Poll for partner's session completion
while (isActive && _uiState.value.navigateTo == null) {
delay(5000) // Check every 5 seconds
val userId = gameSessionManager.currentUserId ?: ""
val couple = gameSessionManager.getCoupleForUser(userId)
if (couple != null) {
val hasActive = gameSessionManager.hasActiveSession(couple.id)
if (!hasActive) {
// Partner finished - go back to games menu
_uiState.update { it.copy(navigateTo = AppRoute.PLAY) }
break
val userId = gameSessionManager.currentUserId ?: return@launch
val couple = gameSessionManager.getCoupleForUser(userId) ?: return@launch
val partnerId = couple.userIds.firstOrNull { it != userId }
val partnerName = partnerId?.let { gameSessionManager.getUser(it) }?.displayName ?: "Partner"
gameSessionManager.observeActiveSession(couple.id).collect { session ->
if (session == null) {
_uiState.update { it.copy(navigateTo = AppRoute.PLAY) }
} else {
_uiState.update {
it.copy(
isLoading = false,
gameType = session.gameType,
partnerName = partnerName
)
}
}
}
}
}
private suspend fun loadGameInfo() {
val userId = gameSessionManager.currentUserId ?: ""
val couple = gameSessionManager.getCoupleForUser(userId)
val activeSession = gameSessionManager.getActiveSession(couple?.id ?: "")
val partnerId = couple?.userIds?.firstOrNull { it != userId }
val partnerName = partnerId?.let { gameSessionManager.getUser(it) }?.displayName ?: "Partner"
_uiState.update {
it.copy(
isLoading = false,
gameType = activeSession?.gameType ?: "wheel",
partnerName = partnerName
)
}
}
fun onNavigated() {
_uiState.update { it.copy(navigateTo = null) }
}