mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-09-30 23:21:36 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fa072ce1e | ||
|
|
69245be8dd | ||
|
|
73c393df64 | ||
|
|
0b3ce486cb |
@@ -1,38 +1,69 @@
|
||||
# VBHelper
|
||||
|
||||
## Developer Setup
|
||||
Application to interact with the Vital series, VB, VH, VBC and VBBE.
|
||||
|
||||
1. Clone vb-nfc-reader (https://github.com/cfogrady/lib-vb-nfc)
|
||||
2. Run vb-nfc-reader/publishToMavenLocal gradle task in the lib-vb-nfc project.
|
||||
3. Clone vb-dim-reader (https://github.com/cfogrady/vb-dim-reader)
|
||||
4. Run publishToMavenLocal gradle task in the vb-dim-reader project.
|
||||
5. Create res/values/keys.xml within the app module.
|
||||
6. Populate with:
|
||||
```
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="password1">beHmacKey1</string>
|
||||
<string name="password2">beHmacKey2</string>
|
||||
<string name="decryptionKey">aesKey</string>
|
||||
<integer-array name="substitutionArray">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>6</item>
|
||||
<item>7</item>
|
||||
<item>8</item>
|
||||
<item>9</item>
|
||||
<item>10</item>
|
||||
<item>11</item>
|
||||
<item>12</item>
|
||||
<item>13</item>
|
||||
<item>14</item>
|
||||
<item>15</item>
|
||||
</integer-array>
|
||||
</resources>
|
||||
```
|
||||
7. Replace the values in the keys.xml file with those extracted from the original app.
|
||||
8. Run
|
||||
## Current state of the project
|
||||
|
||||
Right now the project is still under development, and until further notice, any database updates will result in having to erase application data.
|
||||
|
||||
This document will be updated once the application does not need any more database resets.
|
||||
|
||||
## Features
|
||||
|
||||
As of now, the project allows you to read characters, view characters stats, and send them back to your watch.
|
||||
|
||||
You can also apply items to the characters read, such as special missions, or change timers, and store characters in the storage section.
|
||||
|
||||
You also earn new items every time an item such as a special mission (VB only) or a character completes an in-app adventure mission.
|
||||
|
||||
App also comes with a dex that will update every time a new character is added, and allows you to see evolution requirements and current adventure stage in the watch.
|
||||
|
||||
## How to set up
|
||||
|
||||
1. Download the latest version for VB Arena APK from a trustworthy source. If your download is a standalone APK, continue to step 2. Otherwise, if your download is an XAPK, do the following:
|
||||
|
||||
1. Using your phone file manager, rename the XAPK file to ZIP, and extract its contents. You can also do this with any other device, such as Windows, macOS and Linux.
|
||||
|
||||
2. Once the files are extracted, look for an APK called `com.bandai.vitalbraceletarena.apk`. Copy it somewhere else, you will need it.
|
||||
|
||||
2. Install an APK release for VB Arena. You will find the releases [here](http://github.com/nacabaro/vbhelper/releases). Download the latest release and install its APK.
|
||||
|
||||
Note, in the current stage of the project, you will have to delete the old application from your device. If the app keeps crashing after installing, clear application data and storage.
|
||||
|
||||
3. Import secrets in the app. These secrets will allow the app to talk to the watch. On the main screen, click on the gear icon, then `Import secrets`.
|
||||
|
||||
You will be prompted to choose a file. Choose the APK file that was previously obtained.
|
||||
|
||||
4. Import cards. Due to copyright laws, we cannot offer the characters and sprites themselves in the application. In order to import the cards do the following.
|
||||
|
||||
1. Using your own DiM/BEm cards, dump the cards to your device. You can get an in-depth tutorial in [here](http://mrblinky.net/digimon/vb/dimcardtool/dimcardtool.html). You can download the dump tool from [here](http://mrblinky.net/digimon/vb/dimcardtool/)
|
||||
|
||||
2. Once installed the tool and drivers, open the tool, connect your DiM/BEm reader hardware to yout computer and click on Read card.
|
||||
|
||||
3. Transfer the resulting file to your mobile device. You can put them anywhere, as long as they are accessible. My recommendation is to put them under a folder called `Cards` in your `Internal storage` or `SD Card`
|
||||
|
||||
4. In the app, click on import card. Next choose the BIN file corresponding to the card you want to import.
|
||||
|
||||
**Note: if you do not import the card, whenever you attempt to read a character from th watch, the character you read will get deleted.**
|
||||
|
||||
5. App will now be ready to be used.
|
||||
|
||||
## Planned features
|
||||
|
||||
- Online battles, undegoing development by `lightheel`.
|
||||
|
||||
- VitalWear compatibility, undergoing development by `cfogrady`.
|
||||
|
||||
- Support for multiple languages, not yet started.
|
||||
|
||||
- Database backup/restore.
|
||||
|
||||
## Credits
|
||||
|
||||
- `cyanic` for helping us understand more about the VB connection protocol.
|
||||
|
||||
- `cfogrady` for making both [`VB-DIM-Reader`](https://github.com/cfogrady/VB-DIM-Reader) and [`lib-vb-nfc`](https://github.com/cfogrady/lib-vb-nfc)
|
||||
|
||||
- `lightheel` for working on the online component in the application, both server and battle client.
|
||||
|
||||
- `shvstrz` for the app icon.
|
||||
@@ -91,4 +91,5 @@ dependencies {
|
||||
implementation("com.google.android.material:material:1.2.0")
|
||||
implementation(libs.protobuf.javalite)
|
||||
implementation("androidx.compose.material:material")
|
||||
implementation("androidx.datastore:datastore-preferences:1.1.7")
|
||||
}
|
||||
@@ -1,17 +1,28 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.Upsert
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
|
||||
@Dao
|
||||
interface CardProgressDao {
|
||||
@Upsert
|
||||
fun updateDimProgress(vararg cardProgresses: CardProgress)
|
||||
@Query("""
|
||||
UPDATE CardProgress
|
||||
SET
|
||||
currentStage = :currentStage,
|
||||
unlocked = :unlocked
|
||||
WHERE cardId = :cardId AND
|
||||
currentStage < :currentStage
|
||||
""")
|
||||
fun updateCardProgress(currentStage: Int, cardId: Long, unlocked: Boolean)
|
||||
|
||||
@Query(
|
||||
"SELECT currentStage FROM CardProgress WHERE cardId = :cardId"
|
||||
)
|
||||
fun getCardProgress(cardId: Long): Int
|
||||
|
||||
@Insert
|
||||
fun insertCardProgress(cardProgress: CardProgress)
|
||||
}
|
||||
@@ -24,10 +24,12 @@ interface CharacterDao {
|
||||
d.cardId as cardId,
|
||||
c.charaIndex as charId,
|
||||
c.stage as stage,
|
||||
c.attribute as attribute
|
||||
c.attribute as attribute,
|
||||
cp.currentStage as currentStage
|
||||
FROM CardCharacter c
|
||||
JOIN UserCharacter uc ON c.id = uc.charId
|
||||
JOIN Card d ON c.cardId = d.id
|
||||
JOIN CardProgress cp ON d.id = cp.cardId
|
||||
WHERE c.id = :charId
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.github.nacabaro.vbhelper.daos
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface ItemDao {
|
||||
@@ -13,7 +14,7 @@ interface ItemDao {
|
||||
ORDER BY Items.itemIcon ASC
|
||||
"""
|
||||
)
|
||||
suspend fun getAllItems(): List<ItemDtos.ItemsWithQuantities>
|
||||
fun getAllItems(): Flow<List<ItemDtos.ItemsWithQuantities>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
@@ -22,7 +23,7 @@ interface ItemDao {
|
||||
WHERE quantity > 0
|
||||
"""
|
||||
)
|
||||
suspend fun getAllUserItems(): List<ItemDtos.ItemsWithQuantities>
|
||||
fun getAllUserItems(): Flow<List<ItemDtos.ItemsWithQuantities>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.github.nacabaro.vbhelper.di
|
||||
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.source.CurrencyRepository
|
||||
import com.github.nacabaro.vbhelper.source.DataStoreSecretsRepository
|
||||
|
||||
interface AppContainer {
|
||||
val db: AppDatabase
|
||||
val dataStoreSecretsRepository: DataStoreSecretsRepository
|
||||
val currencyRepository: CurrencyRepository
|
||||
}
|
||||
@@ -1,20 +1,27 @@
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.dataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import androidx.room.Room
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.di.AppContainer
|
||||
import com.github.nacabaro.vbhelper.source.CurrencyRepository
|
||||
import com.github.nacabaro.vbhelper.source.DataStoreSecretsRepository
|
||||
import com.github.nacabaro.vbhelper.source.SecretsSerializer
|
||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||
|
||||
private const val SECRETS_DATA_STORE_NAME = "secrets.pb"
|
||||
|
||||
private const val USER_PREFERENCES_NAME = "user_preferences"
|
||||
val Context.secretsStore: DataStore<Secrets> by dataStore(
|
||||
fileName = SECRETS_DATA_STORE_NAME,
|
||||
serializer = SecretsSerializer
|
||||
)
|
||||
|
||||
val Context.currencyStore: DataStore<Preferences> by preferencesDataStore(
|
||||
name = USER_PREFERENCES_NAME
|
||||
)
|
||||
|
||||
class DefaultAppContainer(private val context: Context) : AppContainer {
|
||||
|
||||
override val db: AppDatabase by lazy {
|
||||
@@ -29,5 +36,6 @@ class DefaultAppContainer(private val context: Context) : AppContainer {
|
||||
|
||||
override val dataStoreSecretsRepository = DataStoreSecretsRepository(context.secretsStore)
|
||||
|
||||
override val currencyRepository = CurrencyRepository(context.currencyStore)
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ object CharacterDtos {
|
||||
val cardId: Long,
|
||||
val charId: Int,
|
||||
val stage: Int,
|
||||
val attribute: NfcCharacter.Attribute
|
||||
val attribute: NfcCharacter.Attribute,
|
||||
val currentStage: Int
|
||||
)
|
||||
|
||||
data class TransformationHistory(
|
||||
|
||||
+2
@@ -6,6 +6,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
@@ -77,6 +78,7 @@ class AdventureScreenControllerImpl(
|
||||
val randomItem = database
|
||||
.itemDao()
|
||||
.getAllItems()
|
||||
.first()
|
||||
.random()
|
||||
|
||||
val random = ((Random.nextFloat() * character.stage) + 3).roundToInt()
|
||||
|
||||
+5
-2
@@ -7,8 +7,11 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
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
|
||||
@@ -23,7 +26,7 @@ fun CardAdventureScreen(
|
||||
cardId: Long
|
||||
) {
|
||||
val cardAdventureMissions = remember { mutableStateOf(emptyList<CardDtos.CardAdventureWithSprites>()) }
|
||||
var currentCardAdventure = remember { 0 }
|
||||
var currentCardAdventure by remember { mutableIntStateOf(0) }
|
||||
|
||||
LaunchedEffect(cardId) {
|
||||
withContext(Dispatchers.IO) {
|
||||
@@ -55,7 +58,7 @@ fun CardAdventureScreen(
|
||||
cardAdventureMissions.value.mapIndexed { index, it ->
|
||||
CardAdventureEntry(
|
||||
cardAdventureEntry = it,
|
||||
obscure = index > currentCardAdventure
|
||||
obscure = index > currentCardAdventure - 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -5,6 +5,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.Instant
|
||||
import kotlin.math.roundToInt
|
||||
@@ -41,6 +42,7 @@ class HomeScreenControllerImpl(
|
||||
val randomItem = database
|
||||
.itemDao()
|
||||
.getAllItems()
|
||||
.first()
|
||||
.random()
|
||||
|
||||
val randomItemAmount = (Random.nextFloat() * 5).roundToInt()
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.github.nacabaro.vbhelper.R
|
||||
import com.github.nacabaro.vbhelper.domain.items.ItemType
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
|
||||
|
||||
@Composable
|
||||
fun ItemDialog(
|
||||
item: ItemDtos.ItemsWithQuantities,
|
||||
onClickCancel: () -> Unit,
|
||||
onClickUse: (() -> Unit)? = null,
|
||||
onClickPurchase: (() -> Unit)? = null,
|
||||
) {
|
||||
Dialog(
|
||||
onDismissRequest = onClickCancel,
|
||||
properties = DialogProperties(
|
||||
dismissOnBackPress = true,
|
||||
dismissOnClickOutside = true
|
||||
)
|
||||
) {
|
||||
Card (
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row {
|
||||
Box(modifier = Modifier) {
|
||||
// Background image (full size)
|
||||
Icon(
|
||||
painter = painterResource(id = getIconResource(item.itemIcon)),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(96.dp)
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = getLengthResource(item.itemLength)),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier
|
||||
.size(64.dp) // Set the size of the overlay image
|
||||
.align(Alignment.BottomEnd) // Align to the top end (top-right corner)
|
||||
)
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
fontSize = MaterialTheme.typography.titleLarge.fontSize,
|
||||
text = item.name,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodyMedium.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodyMedium.fontFamily,
|
||||
text = item.description,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp)
|
||||
)
|
||||
if (onClickPurchase != null) {
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
||||
text = "Costs ${item.price} credits",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
||||
text = "You have ${item.quantity} of this item",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
)
|
||||
|
||||
Row (
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
if (onClickUse != null) {
|
||||
Button(
|
||||
onClick = onClickUse
|
||||
) {
|
||||
Text("Use item")
|
||||
}
|
||||
}
|
||||
|
||||
if (onClickPurchase != null) {
|
||||
Button(
|
||||
onClick = onClickPurchase
|
||||
) {
|
||||
Text("Purchase")
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.size(8.dp))
|
||||
Button(
|
||||
onClick = onClickCancel
|
||||
) {
|
||||
Text("Cancel")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true)
|
||||
fun PreviewItemDialog() {
|
||||
VBHelperTheme {
|
||||
ItemDialog(
|
||||
item = ItemDtos.ItemsWithQuantities(
|
||||
name = "AP Training x3 (60 min)",
|
||||
description = "Boosts AP during training (for 60 minutes)",
|
||||
itemIcon = R.drawable.baseline_attack_24,
|
||||
itemLength = R.drawable.baseline_60_min_timer,
|
||||
quantity = 19,
|
||||
id = 1,
|
||||
price = 500,
|
||||
itemType = ItemType.BEITEM
|
||||
),
|
||||
onClickUse = { },
|
||||
onClickCancel = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,23 @@
|
||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.github.nacabaro.vbhelper.R
|
||||
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
|
||||
@Composable
|
||||
fun ItemElement(
|
||||
itemIcon: Int,
|
||||
lengthIcon: Int,
|
||||
item: ItemDtos.ItemsWithQuantities,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: (() -> Unit) = { }
|
||||
) {
|
||||
@@ -41,7 +28,7 @@ fun ItemElement(
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Icon(
|
||||
painter = painterResource(id = itemIcon),
|
||||
painter = painterResource(id = getIconResource(item.itemIcon)),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(96.dp)
|
||||
@@ -49,164 +36,14 @@ fun ItemElement(
|
||||
.padding(16.dp)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = lengthIcon),
|
||||
painter = painterResource(id = getLengthResource(item.itemLength)),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.surfaceTint,
|
||||
modifier = Modifier
|
||||
.size(48.dp) // Set the size of the overlay image
|
||||
.align(Alignment.TopStart) // Align to the top end (top-right corner)
|
||||
.size(48.dp)
|
||||
.align(Alignment.TopStart)
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ItemDialog(
|
||||
name: String,
|
||||
description: String,
|
||||
itemIcon: Int,
|
||||
lengthIcon: Int,
|
||||
amount: Int,
|
||||
onClickUse: () -> Unit,
|
||||
onClickCancel: () -> Unit
|
||||
) {
|
||||
Dialog(
|
||||
onDismissRequest = onClickCancel,
|
||||
properties = DialogProperties(
|
||||
dismissOnBackPress = true,
|
||||
dismissOnClickOutside = true
|
||||
)
|
||||
) {
|
||||
Card (
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row {
|
||||
Box(modifier = Modifier) {
|
||||
// Background image (full size)
|
||||
Icon(
|
||||
painter = painterResource(id = itemIcon),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(96.dp)
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = lengthIcon),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier
|
||||
.size(64.dp) // Set the size of the overlay image
|
||||
.align(Alignment.BottomEnd) // Align to the top end (top-right corner)
|
||||
)
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
fontSize = MaterialTheme.typography.titleLarge.fontSize,
|
||||
text = name,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodyMedium.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodyMedium.fontFamily,
|
||||
text = description,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp)
|
||||
)
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
||||
text = "You have $amount of this item",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp)
|
||||
)
|
||||
Row (
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Button(
|
||||
onClick = onClickUse
|
||||
) {
|
||||
Text("Use item")
|
||||
}
|
||||
Spacer(modifier = Modifier.size(8.dp))
|
||||
Button(
|
||||
onClick = onClickCancel
|
||||
) {
|
||||
Text("Cancel")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getIconResource(index: Int): Int {
|
||||
return when (index) {
|
||||
ItemsScreenControllerImpl.ItemTypes.PPTraining.id -> R.drawable.baseline_agility_24
|
||||
ItemsScreenControllerImpl.ItemTypes.APTraining.id -> R.drawable.baseline_attack_24
|
||||
ItemsScreenControllerImpl.ItemTypes.HPTraining.id -> R.drawable.baseline_shield_24
|
||||
ItemsScreenControllerImpl.ItemTypes.BPTraining.id -> R.drawable.baseline_trophy_24
|
||||
ItemsScreenControllerImpl.ItemTypes.AllTraining.id -> R.drawable.baseline_arrow_up_24
|
||||
6 -> R.drawable.baseline_timer_24
|
||||
7 -> R.drawable.baseline_rank_24
|
||||
8 -> R.drawable.baseline_vitals_24
|
||||
else -> R.drawable.baseline_question_mark_24
|
||||
}
|
||||
}
|
||||
|
||||
fun getLengthResource(index: Int): Int {
|
||||
return when (index) {
|
||||
15 -> R.drawable.baseline_15_min_timer
|
||||
30 -> R.drawable.baseline_30_min_timer
|
||||
60 -> R.drawable.baseline_60_min_timer
|
||||
-60 -> R.drawable.baseline_60_min_timer
|
||||
300 -> R.drawable.baseline_5_hour_timer
|
||||
600 -> R.drawable.baseline_10_hour_timer
|
||||
-720 -> R.drawable.baseline_12_hour_timer
|
||||
-1440 -> R.drawable.baseline_24_hour_timer
|
||||
6000 -> R.drawable.baseline_reset_24
|
||||
1000 -> R.drawable.baseline_single_arrow_up
|
||||
2500 -> R.drawable.baseline_double_arrow_up
|
||||
5000 -> R.drawable.baseline_triple_arrow_up
|
||||
9999 -> R.drawable.baseline_health_24
|
||||
-500 -> R.drawable.baseline_single_arrow_down
|
||||
-1000 -> R.drawable.baseline_double_arrow_down
|
||||
-2500 -> R.drawable.baseline_triple_arrow_down
|
||||
-9999 -> R.drawable.baseline_reset_24
|
||||
else -> R.drawable.baseline_question_mark_24
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true)
|
||||
fun PreviewItemDialog() {
|
||||
VBHelperTheme {
|
||||
ItemDialog(
|
||||
name = "AP Training x3 (60 min)",
|
||||
description = "Boosts AP during training (for 60 minutes)",
|
||||
itemIcon = R.drawable.baseline_attack_24,
|
||||
lengthIcon = R.drawable.baseline_60_min_timer,
|
||||
onClickUse = { },
|
||||
onClickCancel = { },
|
||||
amount = 19
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||
|
||||
import com.github.nacabaro.vbhelper.R
|
||||
|
||||
fun getIconResource(index: Int): Int {
|
||||
return when (index) {
|
||||
ItemsScreenControllerImpl.ItemTypes.PPTraining.id -> R.drawable.baseline_agility_24
|
||||
ItemsScreenControllerImpl.ItemTypes.APTraining.id -> R.drawable.baseline_attack_24
|
||||
ItemsScreenControllerImpl.ItemTypes.HPTraining.id -> R.drawable.baseline_shield_24
|
||||
ItemsScreenControllerImpl.ItemTypes.BPTraining.id -> R.drawable.baseline_trophy_24
|
||||
ItemsScreenControllerImpl.ItemTypes.AllTraining.id -> R.drawable.baseline_arrow_up_24
|
||||
6 -> R.drawable.baseline_timer_24
|
||||
7 -> R.drawable.baseline_rank_24
|
||||
8 -> R.drawable.baseline_vitals_24
|
||||
else -> R.drawable.baseline_question_mark_24
|
||||
}
|
||||
}
|
||||
|
||||
fun getLengthResource(index: Int): Int {
|
||||
return when (index) {
|
||||
15 -> R.drawable.baseline_15_min_timer
|
||||
30 -> R.drawable.baseline_30_min_timer
|
||||
60 -> R.drawable.baseline_60_min_timer
|
||||
-60 -> R.drawable.baseline_60_min_timer
|
||||
300 -> R.drawable.baseline_5_hour_timer
|
||||
600 -> R.drawable.baseline_10_hour_timer
|
||||
-720 -> R.drawable.baseline_12_hour_timer
|
||||
-1440 -> R.drawable.baseline_24_hour_timer
|
||||
6000 -> R.drawable.baseline_reset_24
|
||||
1000 -> R.drawable.baseline_single_arrow_up
|
||||
2500 -> R.drawable.baseline_double_arrow_up
|
||||
5000 -> R.drawable.baseline_triple_arrow_up
|
||||
9999 -> R.drawable.baseline_health_24
|
||||
-500 -> R.drawable.baseline_single_arrow_down
|
||||
-1000 -> R.drawable.baseline_double_arrow_down
|
||||
-2500 -> R.drawable.baseline_triple_arrow_down
|
||||
-9999 -> R.drawable.baseline_reset_24
|
||||
else -> R.drawable.baseline_question_mark_24
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,35 @@
|
||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Text
|
||||
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.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.source.CurrencyRepository
|
||||
import com.github.nacabaro.vbhelper.source.ItemsRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun ItemsStore(
|
||||
@@ -27,45 +37,98 @@ fun ItemsStore(
|
||||
) {
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val itemsRepository = ItemsRepository(application.container.db)
|
||||
val myItems = remember { mutableStateOf(emptyList<ItemDtos.ItemsWithQuantities>()) }
|
||||
val myItems by itemsRepository.getAllItems().collectAsState(emptyList())
|
||||
|
||||
var selectedElementIndex by remember { mutableStateOf<Int?>(null) }
|
||||
|
||||
LaunchedEffect(itemsRepository) {
|
||||
withContext(Dispatchers.IO) {
|
||||
myItems.value = itemsRepository.getAllItems()
|
||||
}
|
||||
}
|
||||
val currencyRepository = application.container.currencyRepository
|
||||
val currentCurrency = currencyRepository.currencyValue.collectAsState(0)
|
||||
|
||||
if (myItems.value.isEmpty()) {
|
||||
Text("No items")
|
||||
} else {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(3),
|
||||
modifier = Modifier
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
if (myItems.isEmpty()) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
items(myItems.value) { index ->
|
||||
ItemElement(
|
||||
itemIcon = getIconResource(index.itemIcon),
|
||||
lengthIcon = getLengthResource(index.itemLength),
|
||||
Text("No items")
|
||||
}
|
||||
} else {
|
||||
Column() {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = "${currentCurrency.value} credits",
|
||||
modifier = Modifier
|
||||
.padding(8.dp),
|
||||
onClick = {
|
||||
selectedElementIndex = myItems.value.indexOf(index)
|
||||
}
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedElementIndex != null) {
|
||||
ItemDialog(
|
||||
name = myItems.value[selectedElementIndex!!].name,
|
||||
description = myItems.value[selectedElementIndex!!].description,
|
||||
itemIcon = getIconResource(myItems.value[selectedElementIndex!!].itemIcon),
|
||||
lengthIcon = getLengthResource(myItems.value[selectedElementIndex!!].itemLength),
|
||||
amount = myItems.value[selectedElementIndex!!].quantity,
|
||||
onClickUse = { },
|
||||
onClickCancel = { selectedElementIndex = null }
|
||||
)
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(3),
|
||||
modifier = Modifier
|
||||
) {
|
||||
items(myItems) { index ->
|
||||
ItemElement(
|
||||
item = index,
|
||||
modifier = Modifier
|
||||
.padding(8.dp),
|
||||
onClick = {
|
||||
selectedElementIndex = myItems.indexOf(index)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (selectedElementIndex != null) {
|
||||
ItemDialog(
|
||||
item = myItems[selectedElementIndex!!],
|
||||
onClickPurchase = {
|
||||
scope.launch {
|
||||
Toast.makeText(
|
||||
application.applicationContext,
|
||||
purchaseItem(
|
||||
application.container.db,
|
||||
myItems[selectedElementIndex!!],
|
||||
currencyRepository
|
||||
),
|
||||
Toast.LENGTH_SHORT
|
||||
).show(
|
||||
)
|
||||
}
|
||||
},
|
||||
onClickCancel = { selectedElementIndex = null }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun purchaseItem(
|
||||
db: AppDatabase,
|
||||
item: ItemDtos.ItemsWithQuantities,
|
||||
currencyRepository: CurrencyRepository
|
||||
): String {
|
||||
if (currencyRepository.currencyValue.first() < item.price) {
|
||||
return "Not enough credits"
|
||||
} else {
|
||||
db
|
||||
.itemDao()
|
||||
.purchaseItem(
|
||||
item.id,
|
||||
1
|
||||
)
|
||||
|
||||
currencyRepository
|
||||
.setCurrencyValue(
|
||||
currencyRepository.currencyValue.first() - item.price
|
||||
)
|
||||
|
||||
return "Purchase successful!"
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material3.Text
|
||||
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
|
||||
@@ -20,11 +20,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.source.ItemsRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@Composable
|
||||
fun MyItems(
|
||||
@@ -32,16 +29,11 @@ fun MyItems(
|
||||
) {
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val itemsRepository = ItemsRepository(application.container.db)
|
||||
val myItems = remember { mutableStateOf(emptyList<ItemDtos.ItemsWithQuantities>()) }
|
||||
val myItems by itemsRepository.getUserItems().collectAsState(emptyList())
|
||||
|
||||
var selectedElementIndex by remember { mutableStateOf<Int?>(null) }
|
||||
|
||||
LaunchedEffect(itemsRepository) {
|
||||
withContext(Dispatchers.IO) {
|
||||
myItems.value = itemsRepository.getUserItems()
|
||||
}
|
||||
}
|
||||
|
||||
if (myItems.value.isEmpty()) {
|
||||
if (myItems.isEmpty()) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
@@ -54,14 +46,13 @@ fun MyItems(
|
||||
columns = GridCells.Fixed(3),
|
||||
modifier = Modifier
|
||||
) {
|
||||
items(myItems.value) { index ->
|
||||
items(myItems) { index ->
|
||||
ItemElement(
|
||||
itemIcon = getIconResource(index.itemIcon),
|
||||
lengthIcon = getLengthResource(index.itemLength),
|
||||
item = index,
|
||||
modifier = Modifier
|
||||
.padding(8.dp),
|
||||
onClick = {
|
||||
selectedElementIndex = myItems.value.indexOf(index)
|
||||
selectedElementIndex = myItems.indexOf(index)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -69,11 +60,7 @@ fun MyItems(
|
||||
|
||||
if (selectedElementIndex != null) {
|
||||
ItemDialog(
|
||||
name = myItems.value[selectedElementIndex!!].name,
|
||||
description = myItems.value[selectedElementIndex!!].description,
|
||||
itemIcon = getIconResource(myItems.value[selectedElementIndex!!].itemIcon),
|
||||
lengthIcon = getLengthResource(myItems.value[selectedElementIndex!!].itemLength),
|
||||
amount = myItems.value[selectedElementIndex!!].quantity,
|
||||
item = myItems[selectedElementIndex!!],
|
||||
onClickUse = {
|
||||
navController
|
||||
.navigate(
|
||||
@@ -81,7 +68,7 @@ fun MyItems(
|
||||
.ApplyItem.route
|
||||
.replace(
|
||||
"{itemId}",
|
||||
myItems.value[selectedElementIndex!!].id.toString()
|
||||
myItems[selectedElementIndex!!].id.toString()
|
||||
)
|
||||
)
|
||||
selectedElementIndex = null
|
||||
|
||||
+5
-7
@@ -152,15 +152,13 @@ class FromNfcConverter (
|
||||
nfcCharacter: NfcCharacter,
|
||||
cardData: Card
|
||||
) {
|
||||
val currentCardProgress = CardProgress(
|
||||
cardId = cardData.id,
|
||||
currentStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
||||
unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount
|
||||
)
|
||||
|
||||
database
|
||||
.cardProgressDao()
|
||||
.updateDimProgress(currentCardProgress)
|
||||
.updateCardProgress(
|
||||
currentStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
||||
cardId = cardData.id,
|
||||
unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-10
@@ -38,14 +38,10 @@ class ToNfcConverter(
|
||||
.characterDao()
|
||||
.getCharacterInfo(userCharacter.charId)
|
||||
|
||||
val currentCardStage = database
|
||||
.cardProgressDao()
|
||||
.getCardProgress(characterInfo.cardId)
|
||||
|
||||
return if (userCharacter.characterType == DeviceType.BEDevice)
|
||||
nfcToBENfc(characterId, characterInfo, currentCardStage, userCharacter)
|
||||
nfcToBENfc(characterId, characterInfo, userCharacter)
|
||||
else
|
||||
nfcToVBNfc(characterId, characterInfo, currentCardStage, userCharacter)
|
||||
nfcToVBNfc(characterId, characterInfo, userCharacter)
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +49,6 @@ class ToNfcConverter(
|
||||
private suspend fun nfcToVBNfc(
|
||||
characterId: Long,
|
||||
characterInfo: CharacterDtos.CardCharacterInfo,
|
||||
currentCardStage: Int,
|
||||
userCharacter: UserCharacter
|
||||
): VBNfcCharacter {
|
||||
val vbData = database
|
||||
@@ -70,7 +65,7 @@ class ToNfcConverter(
|
||||
stage = characterInfo.stage.toByte(),
|
||||
attribute = characterInfo.attribute,
|
||||
ageInDays = userCharacter.ageInDays.toByte(),
|
||||
nextAdventureMissionStage = currentCardStage.toByte(),
|
||||
nextAdventureMissionStage = characterInfo.currentStage.toByte(),
|
||||
mood = userCharacter.mood.toByte(),
|
||||
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
||||
transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(),
|
||||
@@ -173,7 +168,6 @@ class ToNfcConverter(
|
||||
private suspend fun nfcToBENfc(
|
||||
characterId: Long,
|
||||
characterInfo: CharacterDtos.CardCharacterInfo,
|
||||
currentCardStage: Int,
|
||||
userCharacter: UserCharacter
|
||||
): BENfcCharacter {
|
||||
val beData = database
|
||||
@@ -188,7 +182,7 @@ class ToNfcConverter(
|
||||
stage = characterInfo.stage.toByte(),
|
||||
attribute = characterInfo.attribute,
|
||||
ageInDays = userCharacter.ageInDays.toByte(),
|
||||
nextAdventureMissionStage = currentCardStage.toByte(),
|
||||
nextAdventureMissionStage = characterInfo.currentStage.toByte(),
|
||||
mood = userCharacter.mood.toByte(),
|
||||
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
||||
itemEffectMentalStateValue = beData.itemEffectMentalStateValue.toByte(),
|
||||
|
||||
+7
-7
@@ -336,15 +336,15 @@ class SettingsScreenControllerImpl(
|
||||
private fun updateCardProgress(
|
||||
cardId: Long,
|
||||
) {
|
||||
val cardProgress = CardProgress(
|
||||
cardId = cardId,
|
||||
currentStage = 0,
|
||||
unlocked = false
|
||||
)
|
||||
|
||||
database
|
||||
.cardProgressDao()
|
||||
.updateDimProgress(cardProgress)
|
||||
.insertCardProgress(
|
||||
CardProgress(
|
||||
cardId = cardId,
|
||||
currentStage = 1,
|
||||
unlocked = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun importCard(uri: Uri) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.github.nacabaro.vbhelper.source
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class CurrencyRepository (
|
||||
private val dataStore: DataStore<Preferences>
|
||||
) {
|
||||
|
||||
private companion object {
|
||||
val CURRENCY_VALUE = intPreferencesKey("currency_value")
|
||||
}
|
||||
|
||||
val currencyValue: Flow<Int> = dataStore.data
|
||||
.map { preferences ->
|
||||
preferences[CURRENCY_VALUE] ?: 10000
|
||||
}
|
||||
|
||||
suspend fun setCurrencyValue(newValue: Int) {
|
||||
dataStore.edit { preferences ->
|
||||
preferences[CURRENCY_VALUE] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
package com.github.nacabaro.vbhelper.source
|
||||
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.domain.items.Items
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class ItemsRepository(
|
||||
private val db: AppDatabase
|
||||
) {
|
||||
suspend fun getAllItems(): List<ItemDtos.ItemsWithQuantities> {
|
||||
fun getAllItems(): Flow<List<ItemDtos.ItemsWithQuantities>> {
|
||||
return db.itemDao().getAllItems()
|
||||
}
|
||||
|
||||
suspend fun getUserItems(): List<ItemDtos.ItemsWithQuantities> {
|
||||
fun getUserItems(): Flow<List<ItemDtos.ItemsWithQuantities>> {
|
||||
return db.itemDao().getAllUserItems()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "8.12.2"
|
||||
agp = "8.13.1"
|
||||
datastore = "1.1.2"
|
||||
kotlin = "2.0.0"
|
||||
coreKtx = "1.15.0"
|
||||
|
||||
Reference in New Issue
Block a user