fix: use real-time session observation in WaitingForPartnerScreen, add credential type check in Google sign-in
This commit is contained in:
parent
c894dd8c67
commit
dfd9974683
|
|
@ -5,6 +5,7 @@ import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.credentials.CredentialManager
|
import androidx.credentials.CredentialManager
|
||||||
|
import androidx.credentials.CustomCredential
|
||||||
import androidx.credentials.GetCredentialRequest
|
import androidx.credentials.GetCredentialRequest
|
||||||
import androidx.credentials.exceptions.GetCredentialCancellationException
|
import androidx.credentials.exceptions.GetCredentialCancellationException
|
||||||
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
|
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
|
||||||
|
|
@ -190,8 +191,15 @@ fun LoginScreen(
|
||||||
.build()
|
.build()
|
||||||
val request = GetCredentialRequest.Builder().addCredentialOption(option).build()
|
val request = GetCredentialRequest.Builder().addCredentialOption(option).build()
|
||||||
val result = credMgr.getCredential(context, request)
|
val result = credMgr.getCredential(context, request)
|
||||||
val idToken = GoogleIdTokenCredential.createFrom(result.credential.data).idToken
|
val credential = result.credential
|
||||||
viewModel.signInWithGoogle(idToken)
|
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) {
|
} catch (_: GetCredentialCancellationException) {
|
||||||
// user dismissed — do nothing
|
// user dismissed — do nothing
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,9 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import app.closer.core.navigation.AppRoute
|
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 app.closer.domain.usecase.GameSessionManager
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.isActive
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
@ -63,41 +57,28 @@ class WaitingForPartnerViewModel @Inject constructor(
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
loadGameInfo()
|
val userId = gameSessionManager.currentUserId ?: return@launch
|
||||||
// Poll for partner's session completion
|
val couple = gameSessionManager.getCoupleForUser(userId) ?: return@launch
|
||||||
while (isActive && _uiState.value.navigateTo == null) {
|
|
||||||
delay(5000) // Check every 5 seconds
|
val partnerId = couple.userIds.firstOrNull { it != userId }
|
||||||
val userId = gameSessionManager.currentUserId ?: ""
|
val partnerName = partnerId?.let { gameSessionManager.getUser(it) }?.displayName ?: "Partner"
|
||||||
val couple = gameSessionManager.getCoupleForUser(userId)
|
|
||||||
if (couple != null) {
|
gameSessionManager.observeActiveSession(couple.id).collect { session ->
|
||||||
val hasActive = gameSessionManager.hasActiveSession(couple.id)
|
if (session == null) {
|
||||||
if (!hasActive) {
|
_uiState.update { it.copy(navigateTo = AppRoute.PLAY) }
|
||||||
// Partner finished - go back to games menu
|
} else {
|
||||||
_uiState.update { it.copy(navigateTo = AppRoute.PLAY) }
|
_uiState.update {
|
||||||
break
|
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() {
|
fun onNavigated() {
|
||||||
_uiState.update { it.copy(navigateTo = null) }
|
_uiState.update { it.copy(navigateTo = null) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue