Add RemoteConfig feature and like it to the LandingPage.
This commit is contained in:
parent
e62b558c21
commit
1040f54d23
23 changed files with 485 additions and 298 deletions
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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<FetchErrorUio?>(null)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -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<Map<String, List<Attack>>>(emptyMap())
|
||||
val actions: StateFlow<Map<String, List<Attack>>> =
|
||||
|
|
|
|||
|
|
@ -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<Map<String, List<Alteration>>> =
|
||||
alterationRepository.getAlterations()
|
||||
|
|
|
|||
|
|
@ -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<Map<String, List<Alteration>>>(emptyMap())
|
||||
private val assignedAlterations: StateFlow<Map<String, List<Alteration>>> =
|
||||
|
|
|
|||
|
|
@ -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<Map<String, List<Skill>>>(emptyMap())
|
||||
val skills: StateFlow<Map<String, List<Skill>>> =
|
||||
|
|
|
|||
|
|
@ -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<List<Spell>>(emptyList())
|
||||
val spellsBook: StateFlow<List<Spell>> get() = _spellsBook
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
@ -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<LexiconConfig> 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<String, Any?> = 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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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<List<LandingItemUio>>,
|
||||
onCharacter: (LandingItemUio) -> Unit,
|
||||
onSearch: () -> Unit,
|
||||
onGameMaster: () -> Unit,
|
||||
onLexicon: () -> Unit,
|
||||
onQuest: () -> Unit,
|
||||
onMap: () -> Unit,
|
||||
onAdventure: () -> Unit,
|
||||
characters: State<List<List<LandingItemUio>>>,
|
||||
tools: State<List<List<LandingItemUio>>>,
|
||||
encyclopedia: State<List<List<LandingItemUio>>>,
|
||||
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 = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<List<LandingItemUio>>(emptyList())
|
||||
val landing: State<List<LandingItemUio>> = _landing
|
||||
val characterSheets: State<List<List<LandingItemUio>>>
|
||||
@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<List<List<LandingItemUio>>>
|
||||
@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<List<List<LandingItemUio>>>
|
||||
@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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue