diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a2904d4..582ba95 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -148,6 +148,7 @@ dependencies { implementation("com.google.firebase:firebase-analytics-ktx") implementation("com.google.firebase:firebase-auth-ktx") implementation("com.google.firebase:firebase-database-ktx") + implementation("com.google.firebase:firebase-config-ktx") // Hilt: Dependency injection implementation("androidx.hilt:hilt-navigation-compose:1.2.0") diff --git a/app/src/main/java/com/pixelized/rplexicon/LauncherViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/LauncherViewModel.kt index 754120c..f324722 100644 --- a/app/src/main/java/com/pixelized/rplexicon/LauncherViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/LauncherViewModel.kt @@ -6,7 +6,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.pixelized.rplexicon.data.repository.adventure.AdventureRepository import com.pixelized.rplexicon.data.repository.character.ActionRepository import com.pixelized.rplexicon.data.repository.character.AlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository @@ -16,6 +15,7 @@ import com.pixelized.rplexicon.data.repository.character.InventoryRepository import com.pixelized.rplexicon.data.repository.character.ObjectActionRepository import com.pixelized.rplexicon.data.repository.character.SkillRepository import com.pixelized.rplexicon.data.repository.character.SpellRepository +import com.pixelized.rplexicon.data.repository.firebase.RemoteConfigRepository import com.pixelized.rplexicon.data.repository.lexicon.CategoryOrderRepository import com.pixelized.rplexicon.data.repository.lexicon.LexiconRepository import com.pixelized.rplexicon.data.repository.lexicon.LocationRepository @@ -47,7 +47,7 @@ class LauncherViewModel @Inject constructor( descriptionRepository: DescriptionRepository, inventoryRepository: InventoryRepository, equipmentRepository: EquipmentRepository, - adventureRepository: AdventureRepository, + removeConRepository: RemoteConfigRepository // Unused but injected to initialize it. ) : ViewModel() { private val _error = MutableStateFlow(null) diff --git a/app/src/main/java/com/pixelized/rplexicon/data/model/LexiconConfig.kt b/app/src/main/java/com/pixelized/rplexicon/data/model/LexiconConfig.kt new file mode 100644 index 0000000..314d00b --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/data/model/LexiconConfig.kt @@ -0,0 +1,10 @@ +package com.pixelized.rplexicon.data.model + +data class LexiconConfig( + val featureAdventure: Boolean, + val featureLexicon: Boolean, + val featureMaps: Boolean, + val featureQuests: Boolean, + val featureSummary: Boolean, + val featureSearch: Boolean, +) \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActionRepository.kt b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActionRepository.kt index 6ece31d..d29cf3f 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActionRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActionRepository.kt @@ -5,7 +5,7 @@ import com.pixelized.rplexicon.data.model.CharacterSheet import com.pixelized.rplexicon.data.parser.AttackParser import com.pixelized.rplexicon.data.repository.CharacterBinder import com.pixelized.rplexicon.data.repository.GoogleSheetServiceRepository -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.script.ScriptExecutor import com.pixelized.rplexicon.utilitary.Update import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure @@ -24,7 +24,7 @@ import javax.inject.Singleton class ActionRepository @Inject constructor( private val googleRepository: GoogleSheetServiceRepository, private val actionParser: AttackParser, - firebaseRepository: FirebaseRepository, + firebaseRepository: RealtimeDatabaseRepository, ) { private val _actions = MutableStateFlow>>(emptyMap()) val actions: StateFlow>> = diff --git a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActiveAlterationRepository.kt b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActiveAlterationRepository.kt index e4780df..9a0a34b 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActiveAlterationRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/ActiveAlterationRepository.kt @@ -2,7 +2,7 @@ package com.pixelized.rplexicon.data.repository.character import com.pixelized.rplexicon.data.model.alteration.Alteration import com.pixelized.rplexicon.data.model.alteration.AlterationStatus -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -18,7 +18,7 @@ import javax.inject.Singleton @Singleton class ActiveAlterationRepository @Inject constructor( alterationRepository: AlterationRepository, - firebaseRepository: FirebaseRepository, + firebaseRepository: RealtimeDatabaseRepository, ) { private val activeAlterations: StateFlow>> = alterationRepository.getAlterations() diff --git a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/AlterationRepository.kt b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/AlterationRepository.kt index e9c3579..2408026 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/AlterationRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/AlterationRepository.kt @@ -6,7 +6,7 @@ import com.pixelized.rplexicon.data.model.alteration.Alteration import com.pixelized.rplexicon.data.parser.alteration.AlterationParser import com.pixelized.rplexicon.data.repository.CharacterBinder import com.pixelized.rplexicon.data.repository.GoogleSheetServiceRepository -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.script.ScriptExecutor import com.pixelized.rplexicon.utilitary.Update import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure @@ -27,7 +27,7 @@ import javax.inject.Singleton class AlterationRepository @Inject constructor( private val googleRepository: GoogleSheetServiceRepository, private val alterationParser: AlterationParser, - firebaseRepository: FirebaseRepository, + firebaseRepository: RealtimeDatabaseRepository, ) { private val alterations = MutableStateFlow>>(emptyMap()) private val assignedAlterations: StateFlow>> = diff --git a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SkillRepository.kt b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SkillRepository.kt index d8a327f..e867921 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SkillRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SkillRepository.kt @@ -5,7 +5,7 @@ import com.pixelized.rplexicon.data.model.Skill import com.pixelized.rplexicon.data.parser.SkillParser import com.pixelized.rplexicon.data.repository.CharacterBinder import com.pixelized.rplexicon.data.repository.GoogleSheetServiceRepository -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.script.ScriptExecutor import com.pixelized.rplexicon.utilitary.Update import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure @@ -24,7 +24,7 @@ import javax.inject.Singleton class SkillRepository @Inject constructor( private val googleRepository: GoogleSheetServiceRepository, private val skillParser: SkillParser, - firebaseRepository: FirebaseRepository, + firebaseRepository: RealtimeDatabaseRepository, ) { private val _skills = MutableStateFlow>>(emptyMap()) val skills: StateFlow>> = diff --git a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SpellRepository.kt b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SpellRepository.kt index 0d2e2ec..e683e10 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SpellRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/repository/character/SpellRepository.kt @@ -6,7 +6,7 @@ import com.pixelized.rplexicon.data.parser.spell.AssignedSpellParser import com.pixelized.rplexicon.data.parser.spell.SpellBookParser import com.pixelized.rplexicon.data.repository.CharacterBinder import com.pixelized.rplexicon.data.repository.GoogleSheetServiceRepository -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.script.ScriptExecutor import com.pixelized.rplexicon.utilitary.Update import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure @@ -28,7 +28,7 @@ class SpellRepository @Inject constructor( private val googleRepository: GoogleSheetServiceRepository, private val spellBookParser: SpellBookParser, private val assignedSpellParser: AssignedSpellParser, - firebaseRepository: FirebaseRepository, + firebaseRepository: RealtimeDatabaseRepository, ) { private var _spellsBook = MutableStateFlow>(emptyList()) val spellsBook: StateFlow> get() = _spellsBook diff --git a/app/src/main/java/com/pixelized/rplexicon/data/repository/authentication/FirebaseRepository.kt b/app/src/main/java/com/pixelized/rplexicon/data/repository/firebase/RealtimeDatabaseRepository.kt similarity index 98% rename from app/src/main/java/com/pixelized/rplexicon/data/repository/authentication/FirebaseRepository.kt rename to app/src/main/java/com/pixelized/rplexicon/data/repository/firebase/RealtimeDatabaseRepository.kt index 95f2b9a..28a6761 100644 --- a/app/src/main/java/com/pixelized/rplexicon/data/repository/authentication/FirebaseRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/data/repository/firebase/RealtimeDatabaseRepository.kt @@ -1,4 +1,4 @@ -package com.pixelized.rplexicon.data.repository.authentication +package com.pixelized.rplexicon.data.repository.firebase import android.app.Application import android.util.Log @@ -32,7 +32,7 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class FirebaseRepository @Inject constructor( +class RealtimeDatabaseRepository @Inject constructor( application: Application, ) { private val database = Firebase.database( diff --git a/app/src/main/java/com/pixelized/rplexicon/data/repository/firebase/RemoteConfigRepository.kt b/app/src/main/java/com/pixelized/rplexicon/data/repository/firebase/RemoteConfigRepository.kt new file mode 100644 index 0000000..ecd905d --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/data/repository/firebase/RemoteConfigRepository.kt @@ -0,0 +1,83 @@ +package com.pixelized.rplexicon.data.repository.firebase + +import com.google.firebase.ktx.Firebase +import com.google.firebase.remoteconfig.FirebaseRemoteConfig +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings +import com.google.firebase.remoteconfig.ktx.remoteConfig +import com.google.firebase.remoteconfig.ktx.remoteConfigSettings +import com.pixelized.rplexicon.BuildConfig +import com.pixelized.rplexicon.data.model.LexiconConfig +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class RemoteConfigRepository @Inject constructor() { + private val firebase: FirebaseRemoteConfig = Firebase.remoteConfig + + private val _config = MutableStateFlow( + LexiconConfig( + featureAdventure = DEFAULT[FEATURE_ADVENTURE] as Boolean, + featureLexicon = DEFAULT[FEATURE_LEXICON] as Boolean, + featureMaps = DEFAULT[FEATURE_MAPS] as Boolean, + featureQuests = DEFAULT[FEATURE_QUESTS] as Boolean, + featureSummary = DEFAULT[FEATURE_SUMMARY] as Boolean, + featureSearch = DEFAULT[FEATURE_SEARCH] as Boolean, + ) + ) + val config: StateFlow get() = _config + + init { + val configSettings = when { + BuildConfig.DEBUG -> remoteConfigSettings { + minimumFetchIntervalInSeconds = MINIMUM_FETCH_INTERVAL_IN_SECONDS + } + else -> { + FirebaseRemoteConfigSettings.Builder().build() + } + } + firebase.apply { + setConfigSettingsAsync(configSettings) + setDefaultsAsync(DEFAULT) + refreshConfig() + } + } + + private fun refreshConfig() { + firebase.fetchAndActivate().addOnCompleteListener { remoteConfig -> + if (remoteConfig.isSuccessful) { + val config = LexiconConfig( + featureAdventure = firebase.getBoolean(FEATURE_ADVENTURE), + featureLexicon = firebase.getBoolean(FEATURE_LEXICON), + featureMaps = firebase.getBoolean(FEATURE_MAPS), + featureQuests = firebase.getBoolean(FEATURE_QUESTS), + featureSummary = firebase.getBoolean(FEATURE_SUMMARY), + featureSearch = firebase.getBoolean(FEATURE_SEARCH), + ) + _config.value = config + } + } + } + + companion object { + private const val MINIMUM_FETCH_INTERVAL_IN_SECONDS: Long = 0 + + // The feature key + private const val FEATURE_ADVENTURE = "feature_adventure" + private const val FEATURE_LEXICON = "feature_lexicon" + private const val FEATURE_MAPS = "feature_maps" + private const val FEATURE_QUESTS = "feature_quests" + private const val FEATURE_SUMMARY = "feature_summary" + private const val FEATURE_SEARCH = "feature_search" + + private val DEFAULT: HashMap = hashMapOf( + FEATURE_ADVENTURE to false, + FEATURE_LEXICON to false, + FEATURE_MAPS to false, + FEATURE_QUESTS to false, + FEATURE_SUMMARY to false, + FEATURE_SEARCH to false, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt index cee7226..235fa8b 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt @@ -12,7 +12,7 @@ import com.google.firebase.auth.GoogleAuthProvider import com.google.firebase.auth.ktx.auth import com.google.firebase.ktx.Firebase import com.pixelized.rplexicon.R -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -28,7 +28,7 @@ import javax.inject.Inject */ @HiltViewModel class AuthenticationViewModel @Inject constructor( - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val sheetRepository: CharacterSheetRepository, ) : ViewModel() { 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 64e20e6..9e459ae 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 @@ -6,7 +6,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.ActionRepository import com.pixelized.rplexicon.data.repository.character.AlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository @@ -39,7 +39,7 @@ class CharacterSheetViewModel @Inject constructor( private val objectRepository: ObjectActionRepository, private val spellRepository: SpellRepository, private val skillRepository: SkillRepository, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, savedStateHandle: SavedStateHandle, ) : ViewModel() { private val _isLoading = mutableStateOf(false) diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt index d7d58fe..95d1796 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/HeaderViewModel.kt @@ -14,7 +14,7 @@ import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.alteration.Alteration import com.pixelized.rplexicon.data.model.alteration.AlterationStatus import com.pixelized.rplexicon.data.network.CharacterSheetFire -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.ActiveAlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository import com.pixelized.rplexicon.ui.composable.edit.HpPointDialogUio @@ -37,7 +37,7 @@ import javax.inject.Inject @HiltViewModel class HeaderViewModel @Inject constructor( private val headerFactory: CharacterSheetHeaderUioFactory, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val activeAlterationRepository: ActiveAlterationRepository, characterRepository: CharacterSheetRepository, savedStateHandle: SavedStateHandle, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SkillsViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SkillsViewModel.kt index 464246c..d00e9fa 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SkillsViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SkillsViewModel.kt @@ -10,7 +10,7 @@ import com.pixelized.rplexicon.data.model.CharacterSheet import com.pixelized.rplexicon.data.model.DiceThrow import com.pixelized.rplexicon.data.model.Skill import com.pixelized.rplexicon.data.network.CharacterSheetFire -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository import com.pixelized.rplexicon.data.repository.character.DescriptionRepository import com.pixelized.rplexicon.data.repository.character.SkillRepository @@ -19,7 +19,6 @@ import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument import com.pixelized.rplexicon.ui.screens.character.composable.actions.SkillItemUio import com.pixelized.rplexicon.ui.screens.character.factory.SkillFactoryUioFactory import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio -import com.pixelized.rplexicon.utilitary.extentions.string.skillIcon import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest @@ -31,7 +30,7 @@ import javax.inject.Inject @HiltViewModel class SkillsViewModel @Inject constructor( private val sheetRepository: CharacterSheetRepository, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val skillRepository: SkillRepository, private val descriptionRepository: DescriptionRepository, private val skillFactory: SkillFactoryUioFactory, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SpellsViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SpellsViewModel.kt index 433329d..2e35003 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SpellsViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/actions/SpellsViewModel.kt @@ -14,7 +14,7 @@ import com.pixelized.rplexicon.data.model.DiceThrow import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.roll.Throw import com.pixelized.rplexicon.data.network.CharacterSheetFire -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository import com.pixelized.rplexicon.data.repository.character.DescriptionRepository import com.pixelized.rplexicon.data.repository.character.SpellRepository @@ -32,7 +32,6 @@ import com.pixelized.rplexicon.utilitary.extentions.local.label import com.pixelized.rplexicon.utilitary.extentions.local.spell import com.pixelized.rplexicon.utilitary.extentions.modifier import com.pixelized.rplexicon.utilitary.extentions.signLabel -import com.pixelized.rplexicon.utilitary.extentions.string.spellIcon import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest @@ -46,7 +45,7 @@ import kotlin.math.max @HiltViewModel class SpellsViewModel @Inject constructor( private val characterRepository: CharacterSheetRepository, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val spellRepository: SpellRepository, private val descriptionRepository: DescriptionRepository, application: Application, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/alteration/AlterationViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/alteration/AlterationViewModel.kt index 9c40fa4..11ce90b 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/alteration/AlterationViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/alteration/AlterationViewModel.kt @@ -13,7 +13,7 @@ import com.pixelized.rplexicon.data.model.CharacterSheet import com.pixelized.rplexicon.data.model.Description import com.pixelized.rplexicon.data.model.alteration.Alteration import com.pixelized.rplexicon.data.model.alteration.AlterationStatus -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.ActiveAlterationRepository import com.pixelized.rplexicon.data.repository.character.AlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository @@ -22,7 +22,6 @@ import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDialogDetailUio import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory import com.pixelized.rplexicon.utilitary.extentions.context -import com.pixelized.rplexicon.utilitary.extentions.string.alterationIcon import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest @@ -36,7 +35,7 @@ class AlterationViewModel @Inject constructor( private val characterSheetRepository: CharacterSheetRepository, private val alterationRepository: AlterationRepository, private val activeAlterationRepository: ActiveAlterationRepository, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val descriptionRepository: DescriptionRepository, private val factory: AlterationFactory, savedStateHandle: SavedStateHandle, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/proficiency/ProficiencyViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/proficiency/ProficiencyViewModel.kt index e9af5e7..cef5d68 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/proficiency/ProficiencyViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/character/pages/proficiency/ProficiencyViewModel.kt @@ -12,7 +12,7 @@ import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.Skill import com.pixelized.rplexicon.data.model.alteration.Alteration import com.pixelized.rplexicon.data.network.CharacterSheetFire -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.ActiveAlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository import com.pixelized.rplexicon.data.repository.character.DescriptionRepository @@ -26,7 +26,6 @@ import com.pixelized.rplexicon.ui.screens.character.factory.CharacterSheetUioFac import com.pixelized.rplexicon.ui.screens.character.factory.SkillFactoryUioFactory import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.SkillDialogDetailUio import com.pixelized.rplexicon.utilitary.extentions.local.toStatus -import com.pixelized.rplexicon.utilitary.extentions.string.skillIcon import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.combine @@ -37,7 +36,7 @@ import javax.inject.Inject @HiltViewModel class ProficiencyViewModel @Inject constructor( private val characterRepository: CharacterSheetRepository, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val activeAlterationRepository: ActiveAlterationRepository, private val characterSheetFactory: CharacterSheetUioFactory, private val skillRepository: SkillRepository, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingItem.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingItem.kt index 6441719..9a1dd7f 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingItem.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingItem.kt @@ -45,10 +45,21 @@ import com.pixelized.rplexicon.utilitary.extentions.lexicon @Stable data class LandingItemUio( + val feature: Feature, @DrawableRes val icon: Int?, val title: String?, val subTitle: String?, -) +) { + enum class Feature { + CHARACTER, + GAME_MASTER, + SEARCH, + LEXICON, + QUEST, + MAP, + ADVENTURE, + } +} @Composable fun LandingItem( @@ -64,12 +75,12 @@ fun LandingItem( @FloatRange(from = 0.0, to = 1.0) backgroundGradientTo: Float = 1f, rotation: Float = 0f, alpha: Float = 0.6f, - onClick: () -> Unit, + onClick: (LandingItemUio) -> Unit, ) { Box( modifier = Modifier .clip(shape = shape) - .clickable(onClick = onClick) + .clickable { onClick(item) } .padding(paddingValues = paddings) .then(other = modifier), contentAlignment = Alignment.BottomCenter @@ -167,26 +178,31 @@ private fun LandingItemPreview( fun landingItems() = listOf( LandingItemUio( + feature = LandingItemUio.Feature.CHARACTER, icon = R.drawable.icbg_class_barbarian, title = "Brulkhai", subTitle = "Barbare" ), LandingItemUio( + feature = LandingItemUio.Feature.CHARACTER, icon = R.drawable.icbg_class_cleric, title = "Léandre", subTitle = "Clerc" ), LandingItemUio( + feature = LandingItemUio.Feature.CHARACTER, icon = R.drawable.icbg_class_ranger, title = "Nélia", subTitle = "Rôdeur" ), LandingItemUio( + feature = LandingItemUio.Feature.CHARACTER, icon = R.drawable.icbg_class_warlock, title = "Tigrane", subTitle = "Occultiste", ), LandingItemUio( + feature = LandingItemUio.Feature.CHARACTER, icon = R.drawable.icbg_class_bard, title = "Unathana", subTitle = "Barde", diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingScreen.kt index 084ace9..a35ff8e 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingScreen.kt @@ -30,7 +30,6 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.State -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -58,6 +57,12 @@ import com.pixelized.rplexicon.ui.navigation.screens.navigateToLocation import com.pixelized.rplexicon.ui.navigation.screens.navigateToQuestList import com.pixelized.rplexicon.ui.navigation.screens.navigateToSearch import com.pixelized.rplexicon.ui.navigation.screens.navigateToSummary +import com.pixelized.rplexicon.ui.screens.landing.LandingItemUio.Feature.ADVENTURE +import com.pixelized.rplexicon.ui.screens.landing.LandingItemUio.Feature.CHARACTER +import com.pixelized.rplexicon.ui.screens.landing.LandingItemUio.Feature.GAME_MASTER +import com.pixelized.rplexicon.ui.screens.landing.LandingItemUio.Feature.LEXICON +import com.pixelized.rplexicon.ui.screens.landing.LandingItemUio.Feature.MAP +import com.pixelized.rplexicon.ui.screens.landing.LandingItemUio.Feature.SEARCH import com.pixelized.rplexicon.ui.theme.LexiconTheme import com.pixelized.rplexicon.utilitary.annotateMajWithDropCap import com.pixelized.rplexicon.utilitary.extentions.lexicon @@ -82,23 +87,45 @@ fun LandingScreen( end = 16.dp, bottom = 16.dp, ), - characters = viewModel.landing, - onCharacter = { character -> - character.title?.let { screen.navigateToCharacterSheet(name = it) } - }, - onSearch = { - screen.navigateToSearch( - enableLexicon = true, - enableQuests = true, - enableLocations = true, - enableSpells = true, - ) - }, - onGameMaster = { screen.navigateToSummary() }, - onLexicon = { screen.navigateToLexicon() }, - onQuest = { screen.navigateToQuestList() }, - onMap = { screen.navigateToLocation() }, - onAdventure = { screen.navigateToAdventures() }, + characters = viewModel.characterSheets, + tools = viewModel.toolFeatures, + encyclopedia = viewModel.lexiconFeatures, + onFeature = { + when (it.feature) { + CHARACTER -> it.title?.let { name -> + screen.navigateToCharacterSheet(name = name) + } + + GAME_MASTER -> { + screen.navigateToSummary() + } + + SEARCH -> { + screen.navigateToSearch( + enableLexicon = true, + enableQuests = true, + enableLocations = true, + enableSpells = true, + ) + } + + LEXICON -> { + screen.navigateToLexicon() + } + + LandingItemUio.Feature.QUEST -> { + screen.navigateToQuestList() + } + + MAP -> { + screen.navigateToLocation() + } + + ADVENTURE -> { + screen.navigateToAdventures() + } + } + } ) } } @@ -114,23 +141,11 @@ private fun LandingContent( bottom = 16.dp, ), sectionPadding: Dp = 32.dp, - characters: State>, - onCharacter: (LandingItemUio) -> Unit, - onSearch: () -> Unit, - onGameMaster: () -> Unit, - onLexicon: () -> Unit, - onQuest: () -> Unit, - onMap: () -> Unit, - onAdventure: () -> Unit, + characters: State>>, + tools: State>>, + encyclopedia: State>>, + onFeature: (LandingItemUio) -> Unit, ) { - val charactersSection = remember { - derivedStateOf { - characters.value - .groupBy { characters.value.indexOf(it) / 3 } - .values.toList() - } - } - Box( modifier = modifier.verticalScroll(scrollState), ) { @@ -140,7 +155,6 @@ private fun LandingContent( .aspectRatio(1f) .clip(RectangleShape), ) { - Image( modifier = Modifier .matchParentSize() @@ -187,15 +201,16 @@ private fun LandingContent( ), ) - Text( - modifier = Modifier.padding(top = sectionPadding), - style = MaterialTheme.typography.labelSmall, - fontStyle = FontStyle.Italic, - fontWeight = FontWeight.Light, - text = stringResource(id = R.string.landing__caterogy__character), - ) - - charactersSection.value.forEach { charactersGroup -> + if (characters.value.isNotEmpty()) { + Text( + modifier = Modifier.padding(top = sectionPadding), + style = MaterialTheme.typography.labelSmall, + fontStyle = FontStyle.Italic, + fontWeight = FontWeight.Light, + text = stringResource(id = R.string.landing__caterogy__character), + ) + } + characters.value.forEach { charactersGroup -> Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(space = 8.dp), @@ -212,7 +227,7 @@ private fun LandingContent( backgroundFilter = null, backgroundGradientFrom = 0f, backgroundGradientTo = 0.5f, - onClick = { onCharacter(character) }, + onClick = { onFeature(character) }, ) } repeat(3 - charactersGroup.size) { @@ -221,161 +236,80 @@ private fun LandingContent( } } - Text( - modifier = Modifier.padding(top = sectionPadding), - style = MaterialTheme.typography.labelSmall, - fontStyle = FontStyle.Italic, - fontWeight = FontWeight.Light, - text = stringResource(id = R.string.landing__caterogy__tools), - ) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(space = 8.dp), - ) { - LandingItem( - modifier = Modifier - .weight(1f) - .aspectRatio(ratio = 1f), - imagePadding = PaddingValues( - top = 8.dp, - start = 16.dp, - end = 16.dp, - bottom = 24.dp - ), - item = LandingItemUio( - title = stringResource(id = R.string.summary__title), - subTitle = null, - icon = R.drawable.icbg_skull_b_unfaded, - ), - backgroundFilter = null, - backgroundGradientFrom = 0.0f, - backgroundGradientTo = 0.5f, - onClick = onGameMaster, - ) - LandingItem( - modifier = Modifier - .weight(1f) - .aspectRatio(ratio = 1f), - imagePadding = PaddingValues( - top = 8.dp, - start = 16.dp, - end = 16.dp, - bottom = 24.dp - ), - item = LandingItemUio( - title = stringResource(id = R.string.default_search_label), - subTitle = null, - icon = R.drawable.icbg_magnifying_glass, - ), - backgroundFilter = null, - backgroundGradientFrom = 0.0f, - backgroundGradientTo = 0.5f, - onClick = onSearch, - ) - Spacer(modifier = Modifier.weight(1f)) - } - - Text( - modifier = Modifier.padding(top = sectionPadding), - style = MaterialTheme.typography.labelSmall, - fontStyle = FontStyle.Italic, - fontWeight = FontWeight.Light, - text = stringResource(id = R.string.landing__caterogy__encyclopedia), - ) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(space = 8.dp), - ) { - LandingItem( - modifier = Modifier - .weight(1f) - .aspectRatio(ratio = 1f), - imagePadding = PaddingValues( - top = 8.dp, - start = 16.dp, - end = 16.dp, - bottom = 24.dp - ), - item = LandingItemUio( - title = stringResource(id = R.string.lexicon_list__title), - subTitle = null, - icon = R.drawable.icbg_book_note_k, - ), - backgroundFilter = null, - backgroundGradientFrom = 0.0f, - backgroundGradientTo = 0.5f, - onClick = onLexicon, - ) - LandingItem( - modifier = Modifier - .weight(1f) - .aspectRatio(ratio = 1f), - imagePadding = PaddingValues( - top = 8.dp, - start = 16.dp, - end = 16.dp, - bottom = 24.dp - ), - item = LandingItemUio( - title = stringResource(id = R.string.quest_list__title), - subTitle = null, - icon = R.drawable.icbg_book_parchment_e, - ), - backgroundFilter = null, - backgroundGradientFrom = 0.0f, - backgroundGradientTo = 0.5f, - onClick = onQuest, - ) - LandingItem( - modifier = Modifier - .weight(1f) - .aspectRatio(ratio = 1f), - imagePadding = PaddingValues( - top = 8.dp, - start = 16.dp, - end = 16.dp, - bottom = 24.dp - ), - item = LandingItemUio( - title = stringResource(id = R.string.location_list__title), - subTitle = null, - icon = R.drawable.icbg_map_world_a, - ), - backgroundFilter = null, - backgroundGradientFrom = 0.0f, - backgroundGradientTo = 0.5f, - onClick = onMap, + if (tools.value.isNotEmpty()) { + Text( + modifier = Modifier.padding(top = sectionPadding), + style = MaterialTheme.typography.labelSmall, + fontStyle = FontStyle.Italic, + fontWeight = FontWeight.Light, + text = stringResource(id = R.string.landing__caterogy__tools), ) } + tools.value.forEach { group -> + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(space = 8.dp), + ) { + group.forEach { item -> + LandingItem( + modifier = Modifier + .weight(1f) + .aspectRatio(ratio = 1f), + imagePadding = PaddingValues( + top = 8.dp, + start = 16.dp, + end = 16.dp, + bottom = 24.dp, + ), + item = item, + backgroundFilter = null, + backgroundGradientFrom = 0.0f, + backgroundGradientTo = 0.5f, + onClick = { onFeature(item) }, + ) + } + repeat(3 - group.size) { + Spacer(modifier = Modifier.weight(1f)) + } + } + } - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(space = 8.dp), - ) { - LandingItem( - modifier = Modifier - .weight(1f) - .aspectRatio(ratio = 1f), - imagePadding = PaddingValues( - top = 8.dp, - start = 16.dp, - end = 16.dp, - bottom = 24.dp - ), - item = LandingItemUio( - title = stringResource(id = R.string.adventures_title), - subTitle = null, - icon = R.drawable.icbg_book_generic_c_unfaded, - ), - backgroundFilter = null, - backgroundGradientFrom = 0.0f, - backgroundGradientTo = 0.5f, - onClick = onAdventure, + if (encyclopedia.value.isNotEmpty()) { + Text( + modifier = Modifier.padding(top = sectionPadding), + style = MaterialTheme.typography.labelSmall, + fontStyle = FontStyle.Italic, + fontWeight = FontWeight.Light, + text = stringResource(id = R.string.landing__caterogy__encyclopedia), ) - - Spacer(modifier = Modifier.weight(2f)) + } + encyclopedia.value.forEach { group -> + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(space = 8.dp), + ) { + group.forEach { item -> + LandingItem( + modifier = Modifier + .weight(1f) + .aspectRatio(ratio = 1f), + imagePadding = PaddingValues( + top = 8.dp, + start = 16.dp, + end = 16.dp, + bottom = 24.dp, + ), + item = item, + backgroundFilter = null, + backgroundGradientFrom = 0.0f, + backgroundGradientTo = 0.5f, + onClick = { onFeature(item) }, + ) + } + repeat(3 - group.size) { + Spacer(modifier = Modifier.weight(1f)) + } + } } } } @@ -428,41 +362,98 @@ private fun LandingPreview() { characters = remember { mutableStateOf( listOf( - LandingItemUio( - icon = R.drawable.icbg_class_barbarian, - title = "Brulkhai", - subTitle = "Barbarian, Warrior", - ), - LandingItemUio( - icon = R.drawable.icbg_class_cleric, - title = "Léandre", - subTitle = "Cleric", - ), - LandingItemUio( - icon = R.drawable.icbg_class_ranger, - title = "Nelia", - subTitle = "Ranger, Druid", - ), - LandingItemUio( - icon = R.drawable.icbg_class_warlock, - title = "Tigrane", - subTitle = "Warlock", - ), - LandingItemUio( - icon = R.drawable.icbg_class_bard, - title = "Unathana", - subTitle = "Bard", + listOf( + LandingItemUio( + feature = CHARACTER, + icon = R.drawable.icbg_class_barbarian, + title = "Brulkhai", + subTitle = "Barbarian, Warrior", + ), + LandingItemUio( + feature = CHARACTER, + icon = R.drawable.icbg_class_cleric, + title = "Léandre", + subTitle = "Cleric", + ), + LandingItemUio( + feature = CHARACTER, + icon = R.drawable.icbg_class_ranger, + title = "Nelia", + subTitle = "Ranger, Druid", + ), ), + listOf( + LandingItemUio( + feature = CHARACTER, + icon = R.drawable.icbg_class_warlock, + title = "Tigrane", + subTitle = "Warlock", + ), + LandingItemUio( + feature = CHARACTER, + icon = R.drawable.icbg_class_bard, + title = "Unathana", + subTitle = "Bard", + ), + ) ) ) }, - onCharacter = { }, - onSearch = { }, - onGameMaster = { }, - onLexicon = { }, - onQuest = { }, - onMap = { }, - onAdventure = { }, + tools = remember { + mutableStateOf( + listOf( + listOf( + LandingItemUio( + feature = LandingItemUio.Feature.GAME_MASTER, + title = "Game Master", + subTitle = null, + icon = R.drawable.icbg_skull_b_unfaded, + ), + LandingItemUio( + feature = LandingItemUio.Feature.SEARCH, + title = "Search", + subTitle = null, + icon = R.drawable.icbg_magnifying_glass, + ) + ), + ), + ) + }, + encyclopedia = remember { + mutableStateOf( + listOf( + listOf( + LandingItemUio( + feature = LandingItemUio.Feature.LEXICON, + title = "Lexicon", + subTitle = null, + icon = R.drawable.icbg_book_note_k, + ), + LandingItemUio( + feature = LandingItemUio.Feature.QUEST, + title = "Quest logs", + subTitle = null, + icon = R.drawable.icbg_book_parchment_e, + ), + LandingItemUio( + feature = LandingItemUio.Feature.MAP, + title = "Location", + subTitle = null, + icon = R.drawable.icbg_map_world_a, + ), + ), + listOf( + LandingItemUio( + feature = LandingItemUio.Feature.ADVENTURE, + title = "Stories & Adventures", + subTitle = null, + icon = R.drawable.icbg_book_generic_c_unfaded, + ), + ), + ), + ) + }, + onFeature = { }, ) } } diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingViewModel.kt index 9af246a..8ebacd3 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/landing/LandingViewModel.kt @@ -1,48 +1,140 @@ package com.pixelized.rplexicon.ui.screens.landing import android.app.Application +import androidx.compose.runtime.Composable import androidx.compose.runtime.State -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.viewModelScope +import com.pixelized.rplexicon.R import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository +import com.pixelized.rplexicon.data.repository.firebase.RemoteConfigRepository import com.pixelized.rplexicon.utilitary.extentions.context import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import kotlinx.coroutines.flow.map import javax.inject.Inject @HiltViewModel class LandingViewModel @Inject constructor( private val sheetRepository: CharacterSheetRepository, + private val configRepository: RemoteConfigRepository, application: Application, ) : AndroidViewModel(application = application) { - private val _landing = mutableStateOf>(emptyList()) - val landing: State> = _landing + val characterSheets: State>> + @Composable + get() = remember { + sheetRepository.data + .map { sheets -> + sheets.mapNotNull { entry -> + val icon = entry.value.characterClass.firstOrNull()?.icon + val title = entry.key + val subTitle = entry.value.characterClass + .map { context.getString(it.label) } + .joinToString(separator = ", ") { it } - init { - viewModelScope.launch(Dispatchers.Default) { - sheetRepository.data.collectLatest { sheets -> - val landing = sheets.mapNotNull { entry -> - val icon = entry.value.characterClass.firstOrNull()?.icon - val title = entry.key - val subTitle = entry.value.characterClass - .map { context.getString(it.label) } - .joinToString(separator = ", ") { it } + LandingItemUio( + feature = LandingItemUio.Feature.CHARACTER, + icon = icon, + title = title, + subTitle = subTitle, + ) + } + } + .map { items -> + items.groupBy { items.indexOf(it) / 3 }.values.toList() + } + }.collectAsState(initial = emptyList()) - LandingItemUio( - icon = icon, - title = title, - subTitle = subTitle, - ) - } - withContext(Dispatchers.Main) { - _landing.value = landing - } - } + val toolFeatures: State>> + @Composable + get() { + val context = LocalContext.current + return remember { + configRepository.config + .map { config -> + listOfNotNull( + when (config.featureSummary) { + true -> LandingItemUio( + feature = LandingItemUio.Feature.GAME_MASTER, + title = context.getString(R.string.summary__title), + subTitle = null, + icon = R.drawable.icbg_skull_b_unfaded, + ) + + else -> null + }, + when (config.featureSearch) { + true -> LandingItemUio( + feature = LandingItemUio.Feature.SEARCH, + title = context.getString(R.string.default_search_label), + subTitle = null, + icon = R.drawable.icbg_magnifying_glass, + ) + + else -> null + }, + ) + }.map { items -> + items.groupBy { items.indexOf(it) / 3 }.values.toList() + } + }.collectAsState(initial = emptyList()) + } + + val lexiconFeatures: State>> + @Composable + get() { + val context = LocalContext.current + return remember { + configRepository.config + .map { config -> + listOfNotNull( + when (config.featureLexicon) { + true -> LandingItemUio( + feature = LandingItemUio.Feature.LEXICON, + title = context.getString(R.string.lexicon_list__title), + subTitle = null, + icon = R.drawable.icbg_book_note_k, + ) + + else -> null + }, + when (config.featureQuests) { + true -> LandingItemUio( + feature = LandingItemUio.Feature.QUEST, + title = context.getString(R.string.quest_list__title), + subTitle = null, + icon = R.drawable.icbg_book_parchment_e, + ) + + else -> null + }, + when (config.featureMaps) { + true -> LandingItemUio( + feature = LandingItemUio.Feature.MAP, + title = context.getString(R.string.location_list__title), + subTitle = null, + icon = R.drawable.icbg_map_world_a, + ) + + else -> null + }, + when (config.featureAdventure) { + true -> LandingItemUio( + feature = LandingItemUio.Feature.ADVENTURE, + title = context.getString(R.string.adventures_title), + subTitle = null, + icon = R.drawable.icbg_book_generic_c_unfaded, + ) + + else -> null + }, + ) + } + .map { items -> + items.groupBy { items.indexOf(it) / 3 }.values.toList() + } + }.collectAsState(initial = emptyList()) } - } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt index 98ad409..05c760b 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/rolls/RollOverlayViewModel.kt @@ -14,7 +14,7 @@ import com.pixelized.rplexicon.data.model.CharacterSheet import com.pixelized.rplexicon.data.model.Description import com.pixelized.rplexicon.data.model.DiceThrow import com.pixelized.rplexicon.data.model.alteration.AlterationStatus -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.ActiveAlterationRepository import com.pixelized.rplexicon.data.repository.character.AlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository @@ -28,7 +28,6 @@ import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory import com.pixelized.rplexicon.ui.screens.rolls.factory.DiceFactory import com.pixelized.rplexicon.utilitary.extentions.context -import com.pixelized.rplexicon.utilitary.extentions.string.alterationIcon import com.pixelized.rplexicon.utilitary.extentions.switch import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -50,7 +49,7 @@ class RollOverlayViewModel @Inject constructor( private val rollUseCase: DiceThrowUseCase, private val diceFactory: DiceFactory, private val alterationFactory: AlterationFactory, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val throwCardFactory: ThrowCardFactory, application: Application, ) : AndroidViewModel(application) { diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/StatisticViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/StatisticViewModel.kt index f93f3f9..c7a7b8b 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/StatisticViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/StatisticViewModel.kt @@ -6,7 +6,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import com.pixelized.rplexicon.R -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.AlterationRepository import com.pixelized.rplexicon.data.repository.character.DescriptionRepository import com.pixelized.rplexicon.ui.screens.character.composable.dialogs.AlterationDialogDetailUio @@ -14,7 +14,6 @@ import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowCardFactory import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio import com.pixelized.rplexicon.ui.screens.summary.composable.ClassHeaderSummaryUio import com.pixelized.rplexicon.utilitary.extentions.context -import com.pixelized.rplexicon.utilitary.extentions.string.alterationIcon import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -26,7 +25,7 @@ import javax.inject.Inject @HiltViewModel class StatisticViewModel @Inject constructor( - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, private val throwCardFactory: ThrowCardFactory, private val alterationRepository: AlterationRepository, private val descriptionRepository: DescriptionRepository, diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/SummaryFactory.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/SummaryFactory.kt index 5e29a12..9f3c106 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/SummaryFactory.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/summary/pages/statistic/SummaryFactory.kt @@ -8,7 +8,7 @@ import com.pixelized.rplexicon.data.model.Property import com.pixelized.rplexicon.data.model.alteration.Alteration import com.pixelized.rplexicon.data.network.CharacterSheetFire import com.pixelized.rplexicon.data.network.NetworkThrow -import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository +import com.pixelized.rplexicon.data.repository.firebase.RealtimeDatabaseRepository import com.pixelized.rplexicon.data.repository.character.ActiveAlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository import com.pixelized.rplexicon.ui.screens.summary.composable.AttributesSummaryUio @@ -44,7 +44,7 @@ import kotlin.math.max class SummaryFactory @Inject constructor( private val characterSheetRepository: CharacterSheetRepository, private val activeAlterationRepository: ActiveAlterationRepository, - private val firebaseRepository: FirebaseRepository, + private val firebaseRepository: RealtimeDatabaseRepository, ) { fun fetchSummary(scope: CoroutineScope): StatisticSummaryUio { val headerVisibility = mutableStateOf(false)