mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-01-27 16:05:32 +00:00
Few things
- Finished working with the card fusions - Added the GUI part to access the data - Cleaned up a bit of the code, separated a few things from the SettingsScreenControllerImpl.kt into separate classes. - Removed a few LaunchedEffect in exchange of Flows (UI now updates automatically when an action happens)
This commit is contained in:
parent
3fa072ce1e
commit
ffa6958a89
@ -3,6 +3,7 @@ package com.github.nacabaro.vbhelper.daos
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface CardAdventureDao {
|
||||
@ -52,7 +53,7 @@ interface CardAdventureDao {
|
||||
WHERE
|
||||
cc.cardId = :cardId
|
||||
""")
|
||||
suspend fun getAdventureForCard(
|
||||
fun getAdventureForCard(
|
||||
cardId: Long
|
||||
): List<CardDtos.CardAdventureWithSprites>
|
||||
): Flow<List<CardDtos.CardAdventureWithSprites>>
|
||||
}
|
||||
@ -2,6 +2,9 @@ package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface CardFusionsDao {
|
||||
@ -9,24 +12,37 @@ interface CardFusionsDao {
|
||||
INSERT INTO
|
||||
CardFusions (
|
||||
fromCharaId,
|
||||
attribute1Fusion,
|
||||
attribute2Fusion,
|
||||
attribute3Fusion,
|
||||
attribute4Fusion
|
||||
attribute,
|
||||
toCharaId
|
||||
)
|
||||
SELECT
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :fromCharaId),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr1),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr2),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr3),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr4)
|
||||
:attribute,
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaId)
|
||||
""")
|
||||
suspend fun insertNewFusion(
|
||||
cardId: Long,
|
||||
fromCharaId: Int,
|
||||
toCharaIdAttr1: Int,
|
||||
toCharaIdAttr2: Int,
|
||||
toCharaIdAttr3: Int,
|
||||
toCharaIdAttr4: Int
|
||||
attribute: NfcCharacter.Attribute,
|
||||
toCharaId: Int
|
||||
)
|
||||
|
||||
@Query("""
|
||||
SELECT
|
||||
cf.toCharaId as charaId,
|
||||
cf.fromCharaId as fromCharaId,
|
||||
s.spriteIdle1 as spriteIdle,
|
||||
cc.attribute as attribute,
|
||||
s.width as spriteWidth,
|
||||
s.height as spriteHeight,
|
||||
d.discoveredOn as discoveredOn,
|
||||
cf.attribute as fusionAttribute
|
||||
FROM CardFusions cf
|
||||
JOIN CardCharacter cc ON cc.id = cf.toCharaId
|
||||
JOIN Sprite s ON s.id = cc.id
|
||||
LEFT JOIN Dex d ON d.id = cc.id
|
||||
WHERE cf.fromCharaId = :charaId
|
||||
ORDER BY cc.charaIndex
|
||||
""")
|
||||
fun getFusionsForCharacter(charaId: Long): Flow<List<CharacterDtos.FusionsWithSpritesAndObtained>>
|
||||
}
|
||||
@ -5,6 +5,7 @@ import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface CardProgressDao {
|
||||
@ -21,7 +22,7 @@ interface CardProgressDao {
|
||||
@Query(
|
||||
"SELECT currentStage FROM CardProgress WHERE cardId = :cardId"
|
||||
)
|
||||
fun getCardProgress(cardId: Long): Int
|
||||
fun getCardProgress(cardId: Long): Flow<Int>
|
||||
|
||||
@Insert
|
||||
fun insertCardProgress(cardProgress: CardProgress)
|
||||
|
||||
@ -6,6 +6,7 @@ import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface CharacterDao {
|
||||
@ -82,8 +83,8 @@ interface CharacterDao {
|
||||
JOIN Sprite s ON s.id = c.spriteId
|
||||
LEFT JOIN Dex d ON d.id = pt.toCharaId
|
||||
WHERE
|
||||
c.cardId = :cardId
|
||||
pt.charaId = :characterId
|
||||
"""
|
||||
)
|
||||
suspend fun getEvolutionRequirementsForCard(cardId: Long): List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>
|
||||
fun getEvolutionRequirementsForCard(characterId: Long): Flow<List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>>
|
||||
}
|
||||
@ -4,6 +4,7 @@ import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface DexDao {
|
||||
@ -40,7 +41,7 @@ interface DexDao {
|
||||
WHERE c.cardId = :cardId
|
||||
"""
|
||||
)
|
||||
suspend fun getSingleCardProgress(cardId: Long): List<CharacterDtos.CardCharaProgress>
|
||||
fun getSingleCardProgress(cardId: Long): Flow<List<CharacterDtos.CardCharaProgress>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
@ -55,5 +56,5 @@ interface DexDao {
|
||||
FROM Card c
|
||||
"""
|
||||
)
|
||||
suspend fun getCardsWithProgress(): List<CardDtos.CardProgress>
|
||||
fun getCardsWithProgress(): Flow<List<CardDtos.CardProgress>>
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.github.nacabaro.vbhelper.domain.card
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
@ -15,25 +16,7 @@ import androidx.room.PrimaryKey
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["attribute1Fusion"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["attribute2Fusion"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["attribute3Fusion"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["attribute4Fusion"],
|
||||
childColumns = ["toCharaId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
@ -41,8 +24,6 @@ import androidx.room.PrimaryKey
|
||||
data class CardFusions(
|
||||
@PrimaryKey(autoGenerate = true) val id: Long,
|
||||
val fromCharaId: Long,
|
||||
val attribute1Fusion: Long?,
|
||||
val attribute2Fusion: Long?,
|
||||
val attribute3Fusion: Long?,
|
||||
val attribute4Fusion: Long?
|
||||
val attribute: NfcCharacter.Attribute,
|
||||
val toCharaId: Long
|
||||
)
|
||||
@ -114,4 +114,14 @@ object CharacterDtos {
|
||||
val changeTimerHours: Int,
|
||||
val requiredAdventureLevelCompleted: Int
|
||||
)
|
||||
|
||||
data class FusionsWithSpritesAndObtained(
|
||||
val charaId: Long,
|
||||
val fromCharaId: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val discoveredOn: Long?,
|
||||
val fusionAttribute: NfcCharacter.Attribute
|
||||
)
|
||||
}
|
||||
@ -6,18 +6,11 @@ import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@Composable
|
||||
fun CardAdventureScreen(
|
||||
@ -25,20 +18,12 @@ fun CardAdventureScreen(
|
||||
cardScreenController: CardScreenControllerImpl,
|
||||
cardId: Long
|
||||
) {
|
||||
val cardAdventureMissions = remember { mutableStateOf(emptyList<CardDtos.CardAdventureWithSprites>()) }
|
||||
var currentCardAdventure by remember { mutableIntStateOf(0) }
|
||||
|
||||
LaunchedEffect(cardId) {
|
||||
withContext(Dispatchers.IO) {
|
||||
cardAdventureMissions.value =
|
||||
cardScreenController
|
||||
.getCardAdventureMissions(cardId)
|
||||
|
||||
currentCardAdventure =
|
||||
cardScreenController
|
||||
.getCardProgress(cardId)
|
||||
}
|
||||
}
|
||||
val cardAdventureMissions by cardScreenController
|
||||
.getCardAdventureMissions(cardId)
|
||||
.collectAsState(emptyList())
|
||||
val currentCardAdventure by cardScreenController
|
||||
.getCardProgress(cardId)
|
||||
.collectAsState(0)
|
||||
|
||||
Scaffold (
|
||||
topBar = {
|
||||
@ -55,7 +40,7 @@ fun CardAdventureScreen(
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.verticalScroll(state = rememberScrollState())
|
||||
) {
|
||||
cardAdventureMissions.value.mapIndexed { index, it ->
|
||||
cardAdventureMissions.mapIndexed { index, it ->
|
||||
CardAdventureEntry(
|
||||
cardAdventureEntry = it,
|
||||
obscure = index > currentCardAdventure - 1
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
||||
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface CardScreenController {
|
||||
fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit)
|
||||
fun deleteCard(cardId: Long, onDeleted: () -> Unit)
|
||||
suspend fun getCardAdventureMissions(cardId: Long): List<CardDtos.CardAdventureWithSprites>
|
||||
suspend fun getCardProgress(cardId: Long): Int
|
||||
fun getCardAdventureMissions(cardId: Long): Flow<List<CardDtos.CardAdventureWithSprites>>
|
||||
fun getCardProgress(cardId: Long): Flow<Int>
|
||||
fun getFusionsForCharacters(characterId: Long): Flow<List<CharacterDtos.FusionsWithSpritesAndObtained>>
|
||||
}
|
||||
@ -4,6 +4,8 @@ import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class CardScreenControllerImpl(
|
||||
@ -32,15 +34,22 @@ class CardScreenControllerImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getCardAdventureMissions(cardId: Long): List<CardDtos.CardAdventureWithSprites> {
|
||||
override fun getCardAdventureMissions(cardId: Long): Flow<List<CardDtos.CardAdventureWithSprites>> {
|
||||
return database
|
||||
.cardAdventureDao()
|
||||
.getAdventureForCard(cardId)
|
||||
}
|
||||
|
||||
override suspend fun getCardProgress(cardId: Long): Int {
|
||||
override fun getCardProgress(cardId: Long): Flow<Int> {
|
||||
return database
|
||||
.cardProgressDao()
|
||||
.getCardProgress(cardId)
|
||||
}
|
||||
|
||||
override fun getFusionsForCharacters(characterId: Long): Flow<List<CharacterDtos.FusionsWithSpritesAndObtained>> {
|
||||
return database
|
||||
.cardFusionsDao()
|
||||
.getFusionsForCharacter(characterId)
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,10 +5,10 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
@ -19,32 +19,19 @@ import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.DexCharaDetailsDialog
|
||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun CardViewScreen(
|
||||
navController: NavController,
|
||||
cardId: Long
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val dexRepository = DexRepository(application.container.db)
|
||||
|
||||
val characterList = remember { mutableStateOf<List<CharacterDtos.CardCharaProgress>>(emptyList()) }
|
||||
val cardPossibleTransformations = remember { mutableStateOf<List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>>(emptyList()) }
|
||||
val characterList by dexRepository.getCharactersByCardId(cardId).collectAsState(emptyList())
|
||||
|
||||
val selectedCharacter = remember { mutableStateOf<CharacterDtos.CardCharaProgress?>(null) }
|
||||
|
||||
LaunchedEffect(dexRepository) {
|
||||
coroutineScope.launch {
|
||||
val newCharacterList = dexRepository.getCharactersByCardId(cardId)
|
||||
characterList.value = newCharacterList
|
||||
|
||||
val newCardPossibleTransformations = dexRepository.getCardPossibleTransformations(cardId)
|
||||
cardPossibleTransformations.value = newCardPossibleTransformations
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
@ -70,7 +57,7 @@ fun CardViewScreen(
|
||||
columns = GridCells.Fixed(3),
|
||||
contentPadding = contentPadding
|
||||
) {
|
||||
items(characterList.value) { character ->
|
||||
items(characterList) { character ->
|
||||
CharacterEntry(
|
||||
onClick = {
|
||||
selectedCharacter.value = character
|
||||
@ -88,7 +75,6 @@ fun CardViewScreen(
|
||||
if (selectedCharacter.value != null) {
|
||||
DexCharaDetailsDialog(
|
||||
currentChara = selectedCharacter.value!!,
|
||||
possibleTransformations = cardPossibleTransformations.value,
|
||||
obscure = selectedCharacter.value!!.discoveredOn == null,
|
||||
onClickClose = {
|
||||
selectedCharacter.value = null
|
||||
|
||||
@ -7,11 +7,10 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -25,17 +24,15 @@ import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardDeleteDialog
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardRenameDialog
|
||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun CardsScreen(
|
||||
navController: NavController,
|
||||
cardScreenController: CardScreenControllerImpl
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val dexRepository = DexRepository(application.container.db)
|
||||
val cardList = remember { mutableStateOf<List<CardDtos.CardProgress>>(emptyList()) }
|
||||
val cardList by dexRepository.getAllDims().collectAsState(emptyList())
|
||||
|
||||
val selectedCard = remember { mutableStateOf<CardDtos.CardProgress?>(null) }
|
||||
var clickedDelete by remember { mutableStateOf(false) }
|
||||
@ -43,13 +40,6 @@ fun CardsScreen(
|
||||
|
||||
var modifyCards by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(dexRepository) {
|
||||
coroutineScope.launch {
|
||||
val newDimList = dexRepository.getAllDims()
|
||||
cardList.value = newDimList
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
@ -64,7 +54,7 @@ fun CardsScreen(
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(cardList.value) {
|
||||
items(cardList) {
|
||||
CardEntry(
|
||||
name = it.cardName,
|
||||
logo = BitmapData(
|
||||
|
||||
@ -16,6 +16,11 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.contentColorFor
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
@ -23,7 +28,9 @@ import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
||||
|
||||
@ -31,14 +38,25 @@ import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
||||
@Composable
|
||||
fun DexCharaDetailsDialog(
|
||||
currentChara: CharacterDtos.CardCharaProgress,
|
||||
possibleTransformations: List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>,
|
||||
obscure: Boolean,
|
||||
onClickClose: () -> Unit
|
||||
) {
|
||||
val nameMultiplier = 3
|
||||
val charaMultiplier = 4
|
||||
|
||||
val currentCharaPossibleTransformations = possibleTransformations.filter { it.fromCharaId == currentChara.id }
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val database = application.container.db
|
||||
val dexRepository = DexRepository(database)
|
||||
|
||||
var showFusions by remember { mutableStateOf(false) }
|
||||
|
||||
val currentCharaPossibleTransformations by dexRepository
|
||||
.getCharacterPossibleTransformations(currentChara.id)
|
||||
.collectAsState(emptyList())
|
||||
|
||||
val currentCharaPossibleFusions by dexRepository
|
||||
.getCharacterPossibleFusions(currentChara.id)
|
||||
.collectAsState(emptyList())
|
||||
|
||||
val romanNumeralsStage = when (currentChara.stage) {
|
||||
1 -> "II"
|
||||
@ -204,12 +222,40 @@ fun DexCharaDetailsDialog(
|
||||
}
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = onClickClose
|
||||
) {
|
||||
Text("Close")
|
||||
Row {
|
||||
if (currentCharaPossibleFusions.isNotEmpty()) {
|
||||
Button(
|
||||
onClick = {
|
||||
showFusions = true
|
||||
}
|
||||
) {
|
||||
Text("Fusions")
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = onClickClose
|
||||
) {
|
||||
Text("Close")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showFusions) {
|
||||
DexCharaFusionsDialog(
|
||||
currentChara = currentChara,
|
||||
currentCharaPossibleFusions = currentCharaPossibleFusions,
|
||||
onClickDismiss = {
|
||||
showFusions = false
|
||||
},
|
||||
obscure = obscure
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,191 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen.dialogs
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardColors
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.contentColorFor
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
||||
|
||||
@Composable
|
||||
fun DexCharaFusionsDialog(
|
||||
currentChara: CharacterDtos.CardCharaProgress,
|
||||
currentCharaPossibleFusions: List<CharacterDtos.FusionsWithSpritesAndObtained>,
|
||||
obscure: Boolean,
|
||||
onClickDismiss: () -> Unit,
|
||||
) {
|
||||
val nameMultiplier = 3
|
||||
val charaMultiplier = 4
|
||||
|
||||
val charaBitmapData = BitmapData(
|
||||
bitmap = currentChara.spriteIdle,
|
||||
width = currentChara.spriteWidth,
|
||||
height = currentChara.spriteHeight
|
||||
)
|
||||
val charaImageBitmapData = charaBitmapData.getImageBitmap(
|
||||
context = LocalContext.current,
|
||||
multiplier = charaMultiplier,
|
||||
obscure = obscure
|
||||
)
|
||||
|
||||
val nameBitmapData = BitmapData(
|
||||
bitmap = currentChara.nameSprite,
|
||||
width = currentChara.nameSpriteWidth,
|
||||
height = currentChara.nameSpriteHeight
|
||||
)
|
||||
val nameImageBitmapData = nameBitmapData.getImageBitmap(
|
||||
context = LocalContext.current,
|
||||
multiplier = nameMultiplier,
|
||||
obscure = obscure
|
||||
)
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onClickDismiss,
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row {
|
||||
Card (
|
||||
colors = CardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
),
|
||||
disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
disabledContentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
)
|
||||
)
|
||||
) {
|
||||
Image(
|
||||
bitmap = charaImageBitmapData.imageBitmap,
|
||||
contentDescription = "Icon",
|
||||
modifier = Modifier
|
||||
.size(charaImageBitmapData.dpWidth)
|
||||
.padding(8.dp),
|
||||
colorFilter = when (obscure) {
|
||||
true -> ColorFilter.tint(color = MaterialTheme.colorScheme.secondary)
|
||||
false -> null
|
||||
},
|
||||
filterQuality = FilterQuality.None
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
)
|
||||
|
||||
if (!obscure) {
|
||||
Column {
|
||||
Image(
|
||||
bitmap = nameImageBitmapData.imageBitmap,
|
||||
contentDescription = "Icon",
|
||||
modifier = Modifier
|
||||
.width(nameImageBitmapData.dpWidth)
|
||||
.height(nameImageBitmapData.dpHeight),
|
||||
filterQuality = FilterQuality.None
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Column {
|
||||
Text(text = "????????????????")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.padding(16.dp))
|
||||
Column {
|
||||
currentCharaPossibleFusions.map {
|
||||
val selectedCharaBitmap = BitmapData(
|
||||
bitmap = it.spriteIdle,
|
||||
width = it.spriteWidth,
|
||||
height = it.spriteHeight
|
||||
)
|
||||
val selectedCharaImageBitmap = selectedCharaBitmap.getImageBitmap(
|
||||
context = LocalContext.current,
|
||||
multiplier = 4,
|
||||
obscure = it.discoveredOn == null
|
||||
)
|
||||
|
||||
Card (
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
) {
|
||||
Row (
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Card (
|
||||
colors = CardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
),
|
||||
disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
disabledContentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
)
|
||||
)
|
||||
) {
|
||||
Image(
|
||||
bitmap = selectedCharaImageBitmap.imageBitmap,
|
||||
contentDescription = "Icon",
|
||||
modifier = Modifier
|
||||
.size(selectedCharaImageBitmap.dpWidth)
|
||||
.padding(8.dp),
|
||||
colorFilter = when (it.discoveredOn == null) {
|
||||
true -> ColorFilter.tint(color = MaterialTheme.colorScheme.secondary)
|
||||
false -> null
|
||||
},
|
||||
filterQuality = FilterQuality.None
|
||||
)
|
||||
}
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
)
|
||||
Column {
|
||||
Text("Combine with ${it.fusionAttribute}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = onClickDismiss
|
||||
) {
|
||||
Text("Close")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@ -92,7 +91,6 @@ fun HomeScreen(
|
||||
}
|
||||
) { contentPadding ->
|
||||
if (activeMon.value == null || (beData.value == null && vbData.value == null) || transformationHistory.value == null) {
|
||||
Log.d("TetTet", "Something is null")
|
||||
Column (
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
@ -103,7 +101,6 @@ fun HomeScreen(
|
||||
Text(text = "Nothing to see here")
|
||||
}
|
||||
} else {
|
||||
Log.d("TetTet", "Something is not null")
|
||||
if (activeMon.value!!.isBemCard) {
|
||||
BEBEmHomeScreen(
|
||||
activeMon = activeMon.value!!,
|
||||
|
||||
@ -3,36 +3,24 @@ package com.github.nacabaro.vbhelper.screens.settingsScreen
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.launch
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.github.cfogrady.vb.dim.card.BemCard
|
||||
import com.github.cfogrady.vb.dim.card.DimCard
|
||||
import com.github.cfogrady.vb.dim.card.DimReader
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.controllers.CardImportController
|
||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.controllers.DatabaseManagementController
|
||||
import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
|
||||
import com.github.nacabaro.vbhelper.source.SecretsImporter
|
||||
import com.github.nacabaro.vbhelper.source.SecretsRepository
|
||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
|
||||
class SettingsScreenControllerImpl(
|
||||
private val context: ComponentActivity,
|
||||
): SettingsScreenController {
|
||||
private val roomDbName = "internalDb"
|
||||
private val filePickerLauncher: ActivityResultLauncher<String>
|
||||
private val filePickerOpenerLauncher: ActivityResultLauncher<Array<String>>
|
||||
private val filePickerApk: ActivityResultLauncher<Array<String>>
|
||||
@ -41,13 +29,17 @@ class SettingsScreenControllerImpl(
|
||||
private val application = context.applicationContext as VBHelper
|
||||
private val secretsRepository: SecretsRepository = application.container.dataStoreSecretsRepository
|
||||
private val database: AppDatabase = application.container.db
|
||||
private val databaseManagementController = DatabaseManagementController(
|
||||
componentActivity = context,
|
||||
application = application
|
||||
)
|
||||
|
||||
init {
|
||||
filePickerLauncher = context.registerForActivityResult(
|
||||
ActivityResultContracts.CreateDocument("application/octet-stream")
|
||||
) { uri ->
|
||||
if (uri != null) {
|
||||
exportDatabase(uri)
|
||||
databaseManagementController.exportDatabase(uri)
|
||||
} else {
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "No destination selected", Toast.LENGTH_SHORT)
|
||||
@ -60,7 +52,7 @@ class SettingsScreenControllerImpl(
|
||||
ActivityResultContracts.OpenDocument()
|
||||
) { uri ->
|
||||
if (uri != null) {
|
||||
importDatabase(uri)
|
||||
databaseManagementController.importDatabase(uri)
|
||||
} else {
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "No source selected", Toast.LENGTH_SHORT).show()
|
||||
@ -109,276 +101,14 @@ class SettingsScreenControllerImpl(
|
||||
filePickerCard.launch(arrayOf("*/*"))
|
||||
}
|
||||
|
||||
private suspend fun importEvoData(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
for (index in 0 until card.transformationRequirements.transformationEntries.size) {
|
||||
val evo = card.transformationRequirements.transformationEntries[index]
|
||||
|
||||
var transformationTimerHours: Int
|
||||
var unlockAdventureLevel: Int
|
||||
|
||||
if (card is BemCard) {
|
||||
transformationTimerHours = card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.minutesUntilTransformation / 60
|
||||
unlockAdventureLevel = if (
|
||||
card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.requiredCompletedAdventureLevel == 65535
|
||||
) {
|
||||
0
|
||||
} else {
|
||||
card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.requiredCompletedAdventureLevel
|
||||
}
|
||||
} else {
|
||||
transformationTimerHours = (card as DimCard)
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.hoursUntilEvolution
|
||||
unlockAdventureLevel = if (
|
||||
card
|
||||
.adventureLevels
|
||||
.levels
|
||||
.last()
|
||||
.bossCharacterIndex == card.transformationRequirements.transformationEntries[index].toCharacterIndex
|
||||
) {
|
||||
14
|
||||
/*
|
||||
Magic number incoming!!
|
||||
|
||||
In the case of DiMCards, stage 15 is the one that unlocks the locked character.
|
||||
We know it is a locked character if the last adventure level's boss character index
|
||||
is the current index. If it is, we add stage 15 complete as a requirement for transformation.
|
||||
*/
|
||||
} else {
|
||||
0
|
||||
/*
|
||||
Another magic number...
|
||||
|
||||
The rest of the characters are not locked.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.characterDao()
|
||||
.insertPossibleTransformation(
|
||||
cardId = cardId,
|
||||
fromChraraIndex = evo.fromCharacterIndex,
|
||||
toChraraIndex = evo.toCharacterIndex,
|
||||
requiredVitals = evo.requiredVitalValues,
|
||||
requiredTrophies = evo.requiredTrophies,
|
||||
requiredBattles = evo.requiredBattles,
|
||||
requiredWinRate = evo.requiredWinRatio,
|
||||
requiredAdventureLevelCompleted = unlockAdventureLevel,
|
||||
changeTimerHours = transformationTimerHours
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importCharacterData(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
var spriteCounter = when (card is BemCard) {
|
||||
true -> 54
|
||||
false -> 10
|
||||
}
|
||||
|
||||
val domainCharacters = mutableListOf<CardCharacter>()
|
||||
|
||||
val characters = card
|
||||
.characterStats
|
||||
.characterEntries
|
||||
|
||||
for (index in 0 until characters.size) {
|
||||
var domainSprite: Sprite?
|
||||
if (index < 2 && card is DimCard) {
|
||||
domainSprite = Sprite(
|
||||
width = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.width,
|
||||
height = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.height,
|
||||
spriteIdle1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteIdle2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteWalk1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteWalk2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteRun1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteRun2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteTrain1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteTrain2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteHappy = card.spriteData.sprites[spriteCounter + 4].pixelData,
|
||||
spriteSleep = card.spriteData.sprites[spriteCounter + 5].pixelData,
|
||||
spriteAttack = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteDodge = card.spriteData.sprites[spriteCounter + 3].pixelData
|
||||
)
|
||||
} else {
|
||||
domainSprite = Sprite(
|
||||
width = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.width,
|
||||
height = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.height,
|
||||
spriteIdle1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteIdle2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteWalk1 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteWalk2 = card.spriteData.sprites[spriteCounter + 4].pixelData,
|
||||
spriteRun1 = card.spriteData.sprites[spriteCounter + 5].pixelData,
|
||||
spriteRun2 = card.spriteData.sprites[spriteCounter + 6].pixelData,
|
||||
spriteTrain1 = card.spriteData.sprites[spriteCounter + 7].pixelData,
|
||||
spriteTrain2 = card.spriteData.sprites[spriteCounter + 8].pixelData,
|
||||
spriteHappy = card.spriteData.sprites[spriteCounter + 9].pixelData,
|
||||
spriteSleep = card.spriteData.sprites[spriteCounter + 10].pixelData,
|
||||
spriteAttack = card.spriteData.sprites[spriteCounter + 11].pixelData,
|
||||
spriteDodge = card.spriteData.sprites[spriteCounter + 12].pixelData
|
||||
)
|
||||
}
|
||||
|
||||
val spriteId = database
|
||||
.spriteDao()
|
||||
.insertSprite(domainSprite)
|
||||
|
||||
|
||||
domainCharacters.add(
|
||||
CardCharacter(
|
||||
cardId = cardId,
|
||||
spriteId = spriteId,
|
||||
charaIndex = index,
|
||||
nameSprite = card.spriteData.sprites[spriteCounter].pixelData,
|
||||
stage = characters[index].stage,
|
||||
attribute = NfcCharacter.Attribute.entries[characters[index].attribute],
|
||||
baseHp = characters[index].hp,
|
||||
baseBp = characters[index].dp,
|
||||
baseAp = characters[index].ap,
|
||||
nameWidth = card.spriteData.sprites[spriteCounter].spriteDimensions.width,
|
||||
nameHeight = card.spriteData.sprites[spriteCounter].spriteDimensions.height
|
||||
)
|
||||
)
|
||||
|
||||
spriteCounter += if (card is BemCard) {
|
||||
14
|
||||
} else {
|
||||
when (index) {
|
||||
0 -> 6
|
||||
1 -> 7
|
||||
else -> 14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.characterDao()
|
||||
.insertCharacter(*domainCharacters.toTypedArray())
|
||||
}
|
||||
|
||||
private suspend fun importAdventureMissions(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
Log.d("importAdventureMissions", "Importing adventure missions")
|
||||
if (card is BemCard) {
|
||||
card.adventureLevels.levels.forEach {
|
||||
database
|
||||
.cardAdventureDao()
|
||||
.insertNewAdventure(
|
||||
cardId = cardId,
|
||||
characterId = it.bossCharacterIndex,
|
||||
steps = it.steps,
|
||||
bossAp = it.bossAp,
|
||||
bossHp = it.bossHp,
|
||||
bossDp = it.bossDp,
|
||||
bossBp = it.bossBp
|
||||
)
|
||||
}
|
||||
} else if (card is DimCard) {
|
||||
card.adventureLevels.levels.map {
|
||||
database
|
||||
.cardAdventureDao()
|
||||
.insertNewAdventure(
|
||||
cardId = cardId,
|
||||
characterId = it.bossCharacterIndex,
|
||||
steps = it.steps,
|
||||
bossAp = it.bossAp,
|
||||
bossHp = it.bossHp,
|
||||
bossDp = it.bossDp,
|
||||
bossBp = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importCardFusions(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
Log.d("importCardFusions", "Importing card fusions")
|
||||
if (card is DimCard) {
|
||||
card
|
||||
.attributeFusions
|
||||
.entries
|
||||
.forEach {
|
||||
database
|
||||
.cardFusionsDao()
|
||||
.insertNewFusion(
|
||||
cardId = cardId,
|
||||
fromCharaId = it.characterIndex,
|
||||
toCharaIdAttr1 = it.attribute1Fusion,
|
||||
toCharaIdAttr2 = it.attribute2Fusion,
|
||||
toCharaIdAttr3 = it.attribute3Fusion,
|
||||
toCharaIdAttr4 = it.attribute4Fusion
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCardProgress(
|
||||
cardId: Long,
|
||||
) {
|
||||
database
|
||||
.cardProgressDao()
|
||||
.insertCardProgress(
|
||||
CardProgress(
|
||||
cardId = cardId,
|
||||
currentStage = 1,
|
||||
unlocked = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun importCard(uri: Uri) {
|
||||
context.lifecycleScope.launch(Dispatchers.IO) {
|
||||
val contentResolver = context.contentResolver
|
||||
val inputStream = contentResolver.openInputStream(uri)
|
||||
|
||||
inputStream.use { fileReader ->
|
||||
val dimReader = DimReader()
|
||||
val card = dimReader.readCard(fileReader, false)
|
||||
|
||||
val cardModel = Card(
|
||||
cardId = card.header.dimId,
|
||||
logo = card.spriteData.sprites[0].pixelData,
|
||||
name = card.spriteData.text,
|
||||
stageCount = card.adventureLevels.levels.size,
|
||||
logoHeight = card.spriteData.sprites[0].height,
|
||||
logoWidth = card.spriteData.sprites[0].width,
|
||||
isBEm = card is BemCard
|
||||
)
|
||||
|
||||
val cardId = database
|
||||
.cardDao()
|
||||
.insertNewCard(cardModel)
|
||||
|
||||
updateCardProgress(cardId = cardId)
|
||||
|
||||
importCharacterData(cardId, card)
|
||||
|
||||
importEvoData(cardId, card)
|
||||
|
||||
importAdventureMissions(cardId, card)
|
||||
|
||||
importCardFusions(cardId, card)
|
||||
val cardImportController = CardImportController(database)
|
||||
cardImportController.importCard(fileReader)
|
||||
}
|
||||
|
||||
inputStream?.close()
|
||||
@ -388,100 +118,6 @@ class SettingsScreenControllerImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun exportDatabase(destinationUri: Uri) {
|
||||
context.lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val dbFile = File(context.getDatabasePath(roomDbName).absolutePath)
|
||||
if (!dbFile.exists()) {
|
||||
throw IllegalStateException("Database file does not exist!")
|
||||
}
|
||||
|
||||
application.container.db.close()
|
||||
|
||||
context.contentResolver.openOutputStream(destinationUri)?.use { outputStream ->
|
||||
dbFile.inputStream().use { inputStream ->
|
||||
copyFile(inputStream, outputStream)
|
||||
}
|
||||
} ?: throw IllegalArgumentException("Unable to open destination Uri for writing")
|
||||
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "Database exported successfully!", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context, "Closing application to avoid changes.", Toast.LENGTH_LONG).show()
|
||||
context.finishAffinity()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ScanScreenController", "Error exporting database $e")
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "Error exporting database: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun importDatabase(sourceUri: Uri) {
|
||||
context.lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
if (!getFileNameFromUri(sourceUri)!!.endsWith(".vbhelper")) {
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "Invalid file format", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
application.container.db.close()
|
||||
|
||||
val dbPath = context.getDatabasePath(roomDbName)
|
||||
val shmFile = File(dbPath.parent, "$roomDbName-shm")
|
||||
val walFile = File(dbPath.parent, "$roomDbName-wal")
|
||||
|
||||
// Delete existing database files
|
||||
if (dbPath.exists()) dbPath.delete()
|
||||
if (shmFile.exists()) shmFile.delete()
|
||||
if (walFile.exists()) walFile.delete()
|
||||
|
||||
val dbFile = File(dbPath.absolutePath)
|
||||
|
||||
context.contentResolver.openInputStream(sourceUri)?.use { inputStream ->
|
||||
dbFile.outputStream().use { outputStream ->
|
||||
copyFile(inputStream, outputStream)
|
||||
}
|
||||
} ?: throw IllegalArgumentException("Unable to open source Uri for reading")
|
||||
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "Database imported successfully!", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context, "Reopen the app to finish import process!", Toast.LENGTH_LONG).show()
|
||||
context.finishAffinity()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ScanScreenController", "Error importing database $e")
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "Error importing database: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFileNameFromUri(uri: Uri): String? {
|
||||
var fileName: String? = null
|
||||
val cursor = context.contentResolver.query(uri, null, null, null, null)
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val nameIndex = it.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)
|
||||
fileName = it.getString(nameIndex)
|
||||
}
|
||||
}
|
||||
return fileName
|
||||
}
|
||||
|
||||
private fun copyFile(inputStream: InputStream, outputStream: OutputStream) {
|
||||
val buffer = ByteArray(1024)
|
||||
var bytesRead: Int
|
||||
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead)
|
||||
}
|
||||
outputStream.flush()
|
||||
}
|
||||
|
||||
private fun importApk(uri: Uri) {
|
||||
context.lifecycleScope.launch(Dispatchers.IO) {
|
||||
context.contentResolver.openInputStream(uri).use {
|
||||
|
||||
@ -0,0 +1,320 @@
|
||||
package com.github.nacabaro.vbhelper.screens.settingsScreen.controllers
|
||||
|
||||
import android.util.Log
|
||||
import com.github.cfogrady.vb.dim.card.BemCard
|
||||
import com.github.cfogrady.vb.dim.card.DimCard
|
||||
import com.github.cfogrady.vb.dim.card.DimReader
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
import java.io.InputStream
|
||||
|
||||
class CardImportController(
|
||||
private val database: AppDatabase
|
||||
) {
|
||||
suspend fun importCard(
|
||||
fileReader: InputStream?
|
||||
) {
|
||||
val dimReader = DimReader()
|
||||
val card = dimReader.readCard(fileReader, false)
|
||||
|
||||
val cardModel = Card(
|
||||
cardId = card.header.dimId,
|
||||
logo = card.spriteData.sprites[0].pixelData,
|
||||
name = card.spriteData.text,
|
||||
stageCount = card.adventureLevels.levels.size,
|
||||
logoHeight = card.spriteData.sprites[0].height,
|
||||
logoWidth = card.spriteData.sprites[0].width,
|
||||
isBEm = card is BemCard
|
||||
)
|
||||
|
||||
val cardId = database
|
||||
.cardDao()
|
||||
.insertNewCard(cardModel)
|
||||
|
||||
updateCardProgress(cardId = cardId)
|
||||
|
||||
importCharacterData(cardId, card)
|
||||
|
||||
importEvoData(cardId, card)
|
||||
|
||||
importAdventureMissions(cardId, card)
|
||||
|
||||
importCardFusions(cardId, card)
|
||||
}
|
||||
|
||||
private fun updateCardProgress(
|
||||
cardId: Long,
|
||||
) {
|
||||
database
|
||||
.cardProgressDao()
|
||||
.insertCardProgress(
|
||||
CardProgress(
|
||||
cardId = cardId,
|
||||
currentStage = 1,
|
||||
unlocked = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun importCharacterData(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
var spriteCounter = when (card is BemCard) {
|
||||
true -> 54
|
||||
false -> 10
|
||||
}
|
||||
|
||||
val domainCharacters = mutableListOf<CardCharacter>()
|
||||
|
||||
val characters = card
|
||||
.characterStats
|
||||
.characterEntries
|
||||
|
||||
for (index in 0 until characters.size) {
|
||||
var domainSprite: Sprite?
|
||||
if (index < 2 && card is DimCard) {
|
||||
domainSprite = Sprite(
|
||||
width = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.width,
|
||||
height = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.height,
|
||||
spriteIdle1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteIdle2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteWalk1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteWalk2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteRun1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteRun2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteTrain1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteTrain2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteHappy = card.spriteData.sprites[spriteCounter + 4].pixelData,
|
||||
spriteSleep = card.spriteData.sprites[spriteCounter + 5].pixelData,
|
||||
spriteAttack = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteDodge = card.spriteData.sprites[spriteCounter + 3].pixelData
|
||||
)
|
||||
} else {
|
||||
domainSprite = Sprite(
|
||||
width = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.width,
|
||||
height = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.height,
|
||||
spriteIdle1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteIdle2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteWalk1 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteWalk2 = card.spriteData.sprites[spriteCounter + 4].pixelData,
|
||||
spriteRun1 = card.spriteData.sprites[spriteCounter + 5].pixelData,
|
||||
spriteRun2 = card.spriteData.sprites[spriteCounter + 6].pixelData,
|
||||
spriteTrain1 = card.spriteData.sprites[spriteCounter + 7].pixelData,
|
||||
spriteTrain2 = card.spriteData.sprites[spriteCounter + 8].pixelData,
|
||||
spriteHappy = card.spriteData.sprites[spriteCounter + 9].pixelData,
|
||||
spriteSleep = card.spriteData.sprites[spriteCounter + 10].pixelData,
|
||||
spriteAttack = card.spriteData.sprites[spriteCounter + 11].pixelData,
|
||||
spriteDodge = card.spriteData.sprites[spriteCounter + 12].pixelData
|
||||
)
|
||||
}
|
||||
|
||||
val spriteId = database
|
||||
.spriteDao()
|
||||
.insertSprite(domainSprite)
|
||||
|
||||
|
||||
domainCharacters.add(
|
||||
CardCharacter(
|
||||
cardId = cardId,
|
||||
spriteId = spriteId,
|
||||
charaIndex = index,
|
||||
nameSprite = card.spriteData.sprites[spriteCounter].pixelData,
|
||||
stage = characters[index].stage,
|
||||
attribute = NfcCharacter.Attribute.entries[characters[index].attribute],
|
||||
baseHp = characters[index].hp,
|
||||
baseBp = characters[index].dp,
|
||||
baseAp = characters[index].ap,
|
||||
nameWidth = card.spriteData.sprites[spriteCounter].spriteDimensions.width,
|
||||
nameHeight = card.spriteData.sprites[spriteCounter].spriteDimensions.height
|
||||
)
|
||||
)
|
||||
|
||||
spriteCounter += if (card is BemCard) {
|
||||
14
|
||||
} else {
|
||||
when (index) {
|
||||
0 -> 6
|
||||
1 -> 7
|
||||
else -> 14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.characterDao()
|
||||
.insertCharacter(*domainCharacters.toTypedArray())
|
||||
}
|
||||
|
||||
private suspend fun importAdventureMissions(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
Log.d("importAdventureMissions", "Importing adventure missions")
|
||||
if (card is BemCard) {
|
||||
card.adventureLevels.levels.forEach {
|
||||
database
|
||||
.cardAdventureDao()
|
||||
.insertNewAdventure(
|
||||
cardId = cardId,
|
||||
characterId = it.bossCharacterIndex,
|
||||
steps = it.steps,
|
||||
bossAp = it.bossAp,
|
||||
bossHp = it.bossHp,
|
||||
bossDp = it.bossDp,
|
||||
bossBp = it.bossBp
|
||||
)
|
||||
}
|
||||
} else if (card is DimCard) {
|
||||
card.adventureLevels.levels.map {
|
||||
database
|
||||
.cardAdventureDao()
|
||||
.insertNewAdventure(
|
||||
cardId = cardId,
|
||||
characterId = it.bossCharacterIndex,
|
||||
steps = it.steps,
|
||||
bossAp = it.bossAp,
|
||||
bossHp = it.bossHp,
|
||||
bossDp = it.bossDp,
|
||||
bossBp = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importCardFusions(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
Log.d("importCardFusions", "Importing card fusions")
|
||||
if (card is DimCard) {
|
||||
card
|
||||
.attributeFusions
|
||||
.entries
|
||||
.forEach {
|
||||
Log.d("importCardFusions", "Importing fusion: ${it.attribute1Fusion}")
|
||||
if (it.attribute1Fusion != 65535 && it.characterIndex != 65535) {
|
||||
database
|
||||
.cardFusionsDao()
|
||||
.insertNewFusion(
|
||||
cardId = cardId,
|
||||
fromCharaId = it.characterIndex,
|
||||
attribute = NfcCharacter.Attribute.Virus,
|
||||
toCharaId = it.attribute1Fusion,
|
||||
)
|
||||
}
|
||||
|
||||
if (it.attribute2Fusion != 65535 && it.characterIndex != 65535) {
|
||||
database
|
||||
.cardFusionsDao()
|
||||
.insertNewFusion(
|
||||
cardId = cardId,
|
||||
fromCharaId = it.characterIndex,
|
||||
attribute = NfcCharacter.Attribute.Data,
|
||||
toCharaId = it.attribute2Fusion,
|
||||
)
|
||||
}
|
||||
|
||||
if (it.attribute3Fusion != 65535 && it.characterIndex != 65535) {
|
||||
database
|
||||
.cardFusionsDao()
|
||||
.insertNewFusion(
|
||||
cardId = cardId,
|
||||
fromCharaId = it.characterIndex,
|
||||
attribute = NfcCharacter.Attribute.Vaccine,
|
||||
toCharaId = it.attribute3Fusion,
|
||||
)
|
||||
}
|
||||
|
||||
if (it.attribute4Fusion != 65535 && it.characterIndex != 65535) {
|
||||
database
|
||||
.cardFusionsDao()
|
||||
.insertNewFusion(
|
||||
cardId = cardId,
|
||||
fromCharaId = it.characterIndex,
|
||||
attribute = NfcCharacter.Attribute.Free,
|
||||
toCharaId = it.attribute4Fusion,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importEvoData(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
for (index in 0 until card.transformationRequirements.transformationEntries.size) {
|
||||
val evo = card.transformationRequirements.transformationEntries[index]
|
||||
|
||||
var transformationTimerHours: Int
|
||||
var unlockAdventureLevel: Int
|
||||
|
||||
if (card is BemCard) {
|
||||
transformationTimerHours = card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.minutesUntilTransformation / 60
|
||||
unlockAdventureLevel = if (
|
||||
card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.requiredCompletedAdventureLevel == 65535
|
||||
) {
|
||||
0
|
||||
} else {
|
||||
card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.requiredCompletedAdventureLevel
|
||||
}
|
||||
} else {
|
||||
transformationTimerHours = (card as DimCard)
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.hoursUntilEvolution
|
||||
unlockAdventureLevel = if (
|
||||
card
|
||||
.adventureLevels
|
||||
.levels
|
||||
.last()
|
||||
.bossCharacterIndex == card.transformationRequirements.transformationEntries[index].toCharacterIndex
|
||||
) {
|
||||
14
|
||||
/*
|
||||
Magic number incoming!!
|
||||
|
||||
In the case of DiMCards, stage 15 is the one that unlocks the locked character.
|
||||
We know it is a locked character if the last adventure level's boss character index
|
||||
is the current index. If it is, we add stage 15 complete as a requirement for transformation.
|
||||
*/
|
||||
} else {
|
||||
0
|
||||
/*
|
||||
Another magic number...
|
||||
|
||||
The rest of the characters are not locked.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.characterDao()
|
||||
.insertPossibleTransformation(
|
||||
cardId = cardId,
|
||||
fromChraraIndex = evo.fromCharacterIndex,
|
||||
toChraraIndex = evo.toCharacterIndex,
|
||||
requiredVitals = evo.requiredVitalValues,
|
||||
requiredTrophies = evo.requiredTrophies,
|
||||
requiredBattles = evo.requiredBattles,
|
||||
requiredWinRate = evo.requiredWinRatio,
|
||||
requiredAdventureLevelCompleted = unlockAdventureLevel,
|
||||
changeTimerHours = transformationTimerHours
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
package com.github.nacabaro.vbhelper.screens.settingsScreen.controllers
|
||||
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
class DatabaseManagementController(
|
||||
val componentActivity: ComponentActivity,
|
||||
val application: VBHelper
|
||||
) {
|
||||
private val roomDbName = "internalDb"
|
||||
|
||||
fun exportDatabase( destinationUri: Uri) {
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val dbFile = File(componentActivity.getDatabasePath(roomDbName).absolutePath)
|
||||
if (!dbFile.exists()) {
|
||||
throw IllegalStateException("Database file does not exist!")
|
||||
}
|
||||
|
||||
application.container.db.close()
|
||||
|
||||
componentActivity.contentResolver.openOutputStream(destinationUri)?.use { outputStream ->
|
||||
dbFile.inputStream().use { inputStream ->
|
||||
copyFile(inputStream, outputStream)
|
||||
}
|
||||
} ?: throw IllegalArgumentException("Unable to open destination Uri for writing")
|
||||
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, "Database exported successfully!", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(componentActivity, "Closing application to avoid changes.", Toast.LENGTH_LONG).show()
|
||||
componentActivity.finishAffinity()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ScanScreenController", "Error exporting database $e")
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, "Error exporting database: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun importDatabase(sourceUri: Uri) {
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
if (!getFileNameFromUri(sourceUri)!!.endsWith(".vbhelper")) {
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, "Invalid file format", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
application.container.db.close()
|
||||
|
||||
val dbPath = componentActivity.getDatabasePath(roomDbName)
|
||||
val shmFile = File(dbPath.parent, "$roomDbName-shm")
|
||||
val walFile = File(dbPath.parent, "$roomDbName-wal")
|
||||
|
||||
// Delete existing database files
|
||||
if (dbPath.exists()) dbPath.delete()
|
||||
if (shmFile.exists()) shmFile.delete()
|
||||
if (walFile.exists()) walFile.delete()
|
||||
|
||||
val dbFile = File(dbPath.absolutePath)
|
||||
|
||||
componentActivity.contentResolver.openInputStream(sourceUri)?.use { inputStream ->
|
||||
dbFile.outputStream().use { outputStream ->
|
||||
copyFile(inputStream, outputStream)
|
||||
}
|
||||
} ?: throw IllegalArgumentException("Unable to open source Uri for reading")
|
||||
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, "Database imported successfully!", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(componentActivity, "Reopen the app to finish import process!", Toast.LENGTH_LONG).show()
|
||||
componentActivity.finishAffinity()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ScanScreenController", "Error importing database $e")
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, "Error importing database: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyFile(inputStream: InputStream, outputStream: OutputStream) {
|
||||
val buffer = ByteArray(1024)
|
||||
var bytesRead: Int
|
||||
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead)
|
||||
}
|
||||
outputStream.flush()
|
||||
}
|
||||
|
||||
private fun getFileNameFromUri(uri: Uri): String? {
|
||||
var fileName: String? = null
|
||||
val cursor = componentActivity.contentResolver.query(uri, null, null, null, null)
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val nameIndex = it.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)
|
||||
fileName = it.getString(nameIndex)
|
||||
}
|
||||
}
|
||||
return fileName
|
||||
}
|
||||
}
|
||||
@ -3,19 +3,24 @@ package com.github.nacabaro.vbhelper.source
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class DexRepository (
|
||||
private val db: AppDatabase
|
||||
) {
|
||||
suspend fun getAllDims(): List<CardDtos.CardProgress> {
|
||||
fun getAllDims(): Flow<List<CardDtos.CardProgress>> {
|
||||
return db.dexDao().getCardsWithProgress()
|
||||
}
|
||||
|
||||
suspend fun getCharactersByCardId(cardId: Long): List<CharacterDtos.CardCharaProgress> {
|
||||
fun getCharactersByCardId(cardId: Long): Flow<List<CharacterDtos.CardCharaProgress>> {
|
||||
return db.dexDao().getSingleCardProgress(cardId)
|
||||
}
|
||||
|
||||
suspend fun getCardPossibleTransformations(cardId: Long): List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained> {
|
||||
return db.characterDao().getEvolutionRequirementsForCard(cardId)
|
||||
fun getCharacterPossibleTransformations(characterId: Long): Flow<List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>> {
|
||||
return db.characterDao().getEvolutionRequirementsForCard(characterId)
|
||||
}
|
||||
|
||||
fun getCharacterPossibleFusions(characterId: Long): Flow<List<CharacterDtos.FusionsWithSpritesAndObtained>> {
|
||||
return db.cardFusionsDao().getFusionsForCharacter(characterId)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user