diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 29748bf..2b956b8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -31,7 +31,7 @@ android { applicationId = "com.pixelized.rplexicon" minSdk = 26 targetSdk = 34 - versionName = "0.5.0-beta" + versionName = "0.5.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheetFire.kt b/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheetFire.kt index 4e31826..222c638 100644 --- a/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheetFire.kt +++ b/app/src/main/java/com/pixelized/rplexicon/model/CharacterSheetFire.kt @@ -1,7 +1,11 @@ package com.pixelized.rplexicon.model +import androidx.annotation.Keep +import com.google.firebase.database.IgnoreExtraProperties import com.google.firebase.database.PropertyName +@Keep +@IgnoreExtraProperties data class CharacterSheetFire( @get:PropertyName(HIT_POINT) @set:PropertyName(HIT_POINT) @@ -59,6 +63,8 @@ data class CharacterSheetFire( @set:PropertyName("${SPELL_SLOT_LEVEL_X}9") var spell9: Int? = null, ) { + @Keep + @IgnoreExtraProperties data class HitPoint( @get:PropertyName("additional") @set:PropertyName("additional") diff --git a/app/src/main/java/com/pixelized/rplexicon/repository/authentication/FirebaseRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/authentication/FirebaseRepository.kt index ccb7369..94550b2 100644 --- a/app/src/main/java/com/pixelized/rplexicon/repository/authentication/FirebaseRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/authentication/FirebaseRepository.kt @@ -43,6 +43,7 @@ class FirebaseRepository @Inject constructor( val value = try { dataSnapshot.getValue(CharacterSheetFire::class.java) } catch (exception: Exception) { + Log.e(TAG, "Failed to parse value.", exception) _error.tryEmit(exception) null } @@ -52,7 +53,7 @@ class FirebaseRepository @Inject constructor( } override fun onCancelled(error: DatabaseError) { - Log.w(TAG, "Failed to read value.", error.toException()) + Log.e(TAG, "Failed to read value.", error.toException()) cancel() } }) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/composable/error/FetchErrorUio.kt b/app/src/main/java/com/pixelized/rplexicon/ui/composable/error/FetchErrorUio.kt index 38e11a1..3a1b8d2 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/composable/error/FetchErrorUio.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/composable/error/FetchErrorUio.kt @@ -13,6 +13,9 @@ import kotlinx.coroutines.flow.SharedFlow @Stable sealed class FetchErrorUio { + @Stable + data class Firebase(val exception: Exception) : FetchErrorUio() + @Stable data object Structure : FetchErrorUio() @@ -39,6 +42,8 @@ fun HandleFetchError( LaunchedEffect(key1 = "HandleFetchError") { errors.collect { error -> when (error) { + is FetchErrorUio.Firebase -> Unit + is FetchErrorUio.Structure -> currentOnStructureError.value.invoke( context, snack, error, ) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt index 7e5d46f..9c74f19 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetScreen.kt @@ -35,6 +35,7 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -48,6 +49,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.pixelized.rplexicon.LocalRollOverlay +import com.pixelized.rplexicon.LocalSnack import com.pixelized.rplexicon.NO_WINDOW_INSETS import com.pixelized.rplexicon.R import com.pixelized.rplexicon.ui.composable.IndicatorStep @@ -83,6 +85,7 @@ fun CharacterSheetScreen( spellsViewModel: SpellsActionViewModel = hiltViewModel(), alterationsViewModel: AlterationViewModel = hiltViewModel(), ) { + val snack = LocalSnack.current val screen = LocalScreenNavHost.current val overlay = LocalRollOverlay.current val scope = rememberCoroutineScope() @@ -158,6 +161,14 @@ fun CharacterSheetScreen( }, ) + LaunchedEffect(key1 = "Error") { + viewModel.errors.collect { error -> + snack.showSnackbar( + message = error.exception.localizedMessage ?: "" + ) + } + } + BackHandler(enabled = sheetState.isVisible) { scope.launch { sheetState.hide() } } diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetViewModel.kt index 4cf1749..4868b2a 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/CharacterSheetViewModel.kt @@ -5,14 +5,18 @@ import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.pixelized.rplexicon.repository.authentication.FirebaseRepository import com.pixelized.rplexicon.repository.data.ActionRepository import com.pixelized.rplexicon.repository.data.AlterationRepository import com.pixelized.rplexicon.repository.data.CharacterSheetRepository import com.pixelized.rplexicon.repository.data.SpellRepository +import com.pixelized.rplexicon.ui.composable.error.FetchErrorUio import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch import javax.inject.Inject @@ -22,15 +26,24 @@ class CharacterSheetViewModel @Inject constructor( private val alterationRepository: AlterationRepository, private val actionRepository: ActionRepository, private val spellRepository: SpellRepository, + private val firebaseRepository: FirebaseRepository, ) : ViewModel() { private val _isLoading = mutableStateOf(false) val isLoading: State get() = _isLoading + private val _error = MutableSharedFlow() + val errors: SharedFlow get() = _error + init { viewModelScope.launch { launch { update(force = false) } + launch { + firebaseRepository.error.collect { exception -> + _error.emit(FetchErrorUio.Firebase(exception = exception)) + } + } } }