fix: ViewModel and repository error handling improvements
This commit is contained in:
parent
c89e4f6bba
commit
e5c734d3b2
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.data.repository
|
||||
|
||||
import app.closer.core.crash.CrashReporter
|
||||
import app.closer.data.remote.FirestoreCoupleDataSource
|
||||
import app.closer.data.remote.FirestoreUserDataSource
|
||||
import app.closer.domain.model.Couple
|
||||
|
|
@ -10,12 +11,17 @@ import javax.inject.Singleton
|
|||
@Singleton
|
||||
class CoupleRepositoryImpl @Inject constructor(
|
||||
private val coupleDataSource: FirestoreCoupleDataSource,
|
||||
private val userDataSource: FirestoreUserDataSource
|
||||
private val userDataSource: FirestoreUserDataSource,
|
||||
private val crashReporter: CrashReporter
|
||||
) : CoupleRepository {
|
||||
|
||||
override suspend fun getCoupleForUser(userId: String): Couple? {
|
||||
val coupleId = runCatching { userDataSource.getUser(userId)?.coupleId }.getOrNull() ?: return null
|
||||
return runCatching { coupleDataSource.getCoupleById(coupleId) }.getOrNull()
|
||||
val coupleId = runCatching { userDataSource.getUser(userId)?.coupleId }
|
||||
.onFailure { crashReporter.recordException(it) }
|
||||
.getOrNull() ?: return null
|
||||
return runCatching { coupleDataSource.getCoupleById(coupleId) }
|
||||
.onFailure { crashReporter.recordException(it) }
|
||||
.getOrNull()
|
||||
}
|
||||
|
||||
override suspend fun createCouple(inviterUserId: String, acceptorUserId: String, inviteCode: String): Result<String> = runCatching {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.data.repository
|
||||
|
||||
import app.closer.core.crash.CrashReporter
|
||||
import app.closer.data.remote.FirestoreCollections
|
||||
import app.closer.domain.model.QuestionSession
|
||||
import app.closer.domain.repository.QuestionSessionRepository
|
||||
|
|
@ -10,7 +11,8 @@ import javax.inject.Singleton
|
|||
|
||||
@Singleton
|
||||
class QuestionSessionRepositoryImpl @Inject constructor(
|
||||
private val firestore: FirebaseFirestore
|
||||
private val firestore: FirebaseFirestore,
|
||||
private val crashReporter: CrashReporter
|
||||
) : QuestionSessionRepository {
|
||||
|
||||
override suspend fun saveSession(session: QuestionSession): Result<Unit> = runCatching {
|
||||
|
|
@ -64,7 +66,9 @@ class QuestionSessionRepositoryImpl @Inject constructor(
|
|||
isPremium = doc.getBoolean("isPremium") ?: false,
|
||||
status = doc.getString("status") ?: "completed"
|
||||
)
|
||||
}.getOrNull()
|
||||
}
|
||||
.onFailure { crashReporter.recordException(it) }
|
||||
.getOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.ui.dates
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.closer.domain.model.DateIdea
|
||||
|
|
@ -62,7 +63,9 @@ class DateMatchViewModel @Inject constructor(
|
|||
val uid = authRepository.currentUserId
|
||||
val couple = uid?.let { runCatching { coupleRepository.getCoupleForUser(it) }.getOrNull() }
|
||||
val partnerName = couple?.userIds?.firstOrNull { it != uid }?.let { partnerId ->
|
||||
runCatching { userRepository.getUser(partnerId)?.displayName }.getOrNull()
|
||||
runCatching { userRepository.getUser(partnerId)?.displayName }
|
||||
.onFailure { Log.w(TAG, "Could not load partner display name", it) }
|
||||
.getOrNull()
|
||||
}
|
||||
val ideas = repository.getDateIdeas()
|
||||
_uiState.value = DateMatchUiState(
|
||||
|
|
@ -145,4 +148,8 @@ class DateMatchViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun retry() = loadDateMatch()
|
||||
|
||||
companion object {
|
||||
private const val TAG = "DateMatchViewModel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.ui.dates
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.closer.data.repository.DateIdeaSeed
|
||||
|
|
@ -59,7 +60,9 @@ class DateMatchesViewModel @Inject constructor(
|
|||
val couple = uid?.let { runCatching { coupleRepository.getCoupleForUser(it) }.getOrNull() }
|
||||
val partnerId = couple?.userIds?.firstOrNull { it != uid }
|
||||
val partnerName = partnerId?.let { id ->
|
||||
runCatching { userRepository.getUser(id)?.displayName }.getOrNull()
|
||||
runCatching { userRepository.getUser(id)?.displayName }
|
||||
.onFailure { Log.w(TAG, "Could not load partner display name", it) }
|
||||
.getOrNull()
|
||||
}
|
||||
|
||||
_uiState.value = DateMatchesUiState(
|
||||
|
|
@ -132,4 +135,8 @@ class DateMatchesViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun retry() = loadMatches()
|
||||
|
||||
companion object {
|
||||
private const val TAG = "DateMatchesViewModel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.ui.home
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.closer.domain.model.LocalAnswer
|
||||
|
|
@ -106,7 +107,9 @@ class HomeViewModel @Inject constructor(
|
|||
val uid = authRepository.currentUserId
|
||||
val couple = uid?.let { runCatching { coupleRepository.getCoupleForUser(it) }.getOrNull() }
|
||||
val partnerName = couple?.userIds?.firstOrNull { it != uid }?.let { partnerId ->
|
||||
runCatching { userRepository.getUser(partnerId)?.displayName }.getOrNull()
|
||||
runCatching { userRepository.getUser(partnerId)?.displayName }
|
||||
.onFailure { Log.w(TAG, "Could not load partner display name", it) }
|
||||
.getOrNull()
|
||||
}
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
|
|
@ -261,4 +264,8 @@ class HomeViewModel @Inject constructor(
|
|||
split("_", "-")
|
||||
.filter { part -> part.isNotBlank() }
|
||||
.joinToString(" ") { part -> part.replaceFirstChar { it.uppercaseChar() } }
|
||||
|
||||
companion object {
|
||||
private const val TAG = "HomeViewModel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.ui.onboarding
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.closer.domain.model.AuthState
|
||||
|
|
@ -34,7 +35,9 @@ class OnboardingViewModel @Inject constructor(
|
|||
is AuthState.Loading -> _uiState.update { it.copy(isCheckingAuth = true) }
|
||||
is AuthState.Unauthenticated -> _uiState.update { it.copy(isCheckingAuth = false, navigateTo = null) }
|
||||
is AuthState.Authenticated -> {
|
||||
val user = runCatching { userRepository.getUser(authState.userId) }.getOrNull()
|
||||
val user = runCatching { userRepository.getUser(authState.userId) }
|
||||
.onFailure { Log.w(TAG, "Could not load user profile during onboarding", it) }
|
||||
.getOrNull()
|
||||
val destination = when {
|
||||
user == null || user.displayName.isBlank() -> "create_profile"
|
||||
else -> "home"
|
||||
|
|
@ -47,4 +50,8 @@ class OnboardingViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun onNavigated() = _uiState.update { it.copy(navigateTo = null) }
|
||||
|
||||
companion object {
|
||||
private const val TAG = "OnboardingViewModel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.ui.pairing
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
|
@ -46,7 +47,9 @@ class InviteConfirmViewModel @Inject constructor(
|
|||
.onSuccess { invite ->
|
||||
loadedInvite = invite
|
||||
val inviterName = invite?.let {
|
||||
runCatching { userRepository.getUser(it.inviterUserId)?.displayName }.getOrNull()
|
||||
runCatching { userRepository.getUser(it.inviterUserId)?.displayName }
|
||||
.onFailure { e -> Log.w(TAG, "Could not load inviter display name", e) }
|
||||
.getOrNull()
|
||||
}
|
||||
_uiState.update { it.copy(isLoading = false, inviterName = inviterName ?: "your partner") }
|
||||
}
|
||||
|
|
@ -80,4 +83,8 @@ class InviteConfirmViewModel @Inject constructor(
|
|||
|
||||
fun onNavigated() = _uiState.update { it.copy(navigateTo = null) }
|
||||
fun dismissError() = _uiState.update { it.copy(error = null) }
|
||||
|
||||
companion object {
|
||||
private const val TAG = "InviteConfirmViewModel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.ui.settings
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.closer.core.navigation.AppRoute
|
||||
|
|
@ -45,11 +46,15 @@ class SettingsViewModel @Inject constructor(
|
|||
return@launch
|
||||
}
|
||||
val email = authRepository.currentUserEmail ?: ""
|
||||
val user = runCatching { userRepository.getUser(userId) }.getOrNull()
|
||||
val user = runCatching { userRepository.getUser(userId) }
|
||||
.onFailure { Log.w(TAG, "Could not load current user profile", it) }
|
||||
.getOrNull()
|
||||
val couple = coupleRepository.getCoupleForUser(userId)
|
||||
val partnerId = couple?.userIds?.firstOrNull { it != userId }
|
||||
val partnerName = partnerId?.let {
|
||||
runCatching { userRepository.getUser(it)?.displayName }.getOrNull()
|
||||
runCatching { userRepository.getUser(it)?.displayName }
|
||||
.onFailure { e -> Log.w(TAG, "Could not load partner display name", e) }
|
||||
.getOrNull()
|
||||
}
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
|
|
@ -72,4 +77,8 @@ class SettingsViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun onNavigated() = _uiState.update { it.copy(navigateTo = null) }
|
||||
|
||||
companion object {
|
||||
private const val TAG = "SettingsViewModel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package app.closer.ui.wheel
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
|
@ -40,7 +41,9 @@ class SpinWheelViewModel @Inject constructor(
|
|||
|
||||
private fun loadCategory() {
|
||||
viewModelScope.launch {
|
||||
val category = runCatching { repository.getCategoryById(categoryId) }.getOrNull()
|
||||
val category = runCatching { repository.getCategoryById(categoryId) }
|
||||
.onFailure { Log.w(TAG, "Could not load wheel category", it) }
|
||||
.getOrNull()
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
|
|
@ -56,7 +59,9 @@ class SpinWheelViewModel @Inject constructor(
|
|||
_uiState.update { it.copy(isSpinning = true, error = null) }
|
||||
val questions = runCatching {
|
||||
repository.getQuestionsByCategory(categoryId).shuffled().take(SESSION_SIZE)
|
||||
}.getOrElse { emptyList() }
|
||||
}
|
||||
.onFailure { Log.w(TAG, "Could not load wheel questions", it) }
|
||||
.getOrElse { emptyList() }
|
||||
|
||||
if (questions.isEmpty()) {
|
||||
_uiState.update {
|
||||
|
|
@ -65,7 +70,9 @@ class SpinWheelViewModel @Inject constructor(
|
|||
return@launch
|
||||
}
|
||||
|
||||
val category = runCatching { repository.getCategoryById(categoryId) }.getOrNull()
|
||||
val category = runCatching { repository.getCategoryById(categoryId) }
|
||||
.onFailure { Log.w(TAG, "Could not load wheel category for session", it) }
|
||||
.getOrNull()
|
||||
sessionStore.activeSession = LocalWheelSession(
|
||||
categoryId = categoryId,
|
||||
categoryName = category?.displayName ?: categoryId,
|
||||
|
|
@ -85,5 +92,6 @@ class SpinWheelViewModel @Inject constructor(
|
|||
|
||||
companion object {
|
||||
const val SESSION_SIZE = 10
|
||||
private const val TAG = "SpinWheelViewModel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue