mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-01-28 00:15:32 +00:00
Compare commits
No commits in common. "main" and "v0.6-pre" have entirely different histories.
101
README.md
101
README.md
@ -1,69 +1,38 @@
|
|||||||
# VBHelper
|
# VBHelper
|
||||||
|
|
||||||
Application to interact with the Vital series, VB, VH, VBC and VBBE.
|
## Developer Setup
|
||||||
|
|
||||||
## Current state of the project
|
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.
|
||||||
Right now the project is still under development, and until further notice, any database updates will result in having to erase application data.
|
3. Clone vb-dim-reader (https://github.com/cfogrady/vb-dim-reader)
|
||||||
|
4. Run publishToMavenLocal gradle task in the vb-dim-reader project.
|
||||||
This document will be updated once the application does not need any more database resets.
|
5. Create res/values/keys.xml within the app module.
|
||||||
|
6. Populate with:
|
||||||
## Features
|
```
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
As of now, the project allows you to read characters, view characters stats, and send them back to your watch.
|
<resources>
|
||||||
|
<string name="password1">beHmacKey1</string>
|
||||||
You can also apply items to the characters read, such as special missions, or change timers, and store characters in the storage section.
|
<string name="password2">beHmacKey2</string>
|
||||||
|
<string name="decryptionKey">aesKey</string>
|
||||||
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.
|
<integer-array name="substitutionArray">
|
||||||
|
<item>0</item>
|
||||||
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.
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
## How to set up
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
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:
|
<item>5</item>
|
||||||
|
<item>6</item>
|
||||||
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.
|
<item>7</item>
|
||||||
|
<item>8</item>
|
||||||
2. Once the files are extracted, look for an APK called `com.bandai.vitalbraceletarena.apk`. Copy it somewhere else, you will need it.
|
<item>9</item>
|
||||||
|
<item>10</item>
|
||||||
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.
|
<item>11</item>
|
||||||
|
<item>12</item>
|
||||||
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.
|
<item>13</item>
|
||||||
|
<item>14</item>
|
||||||
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`.
|
<item>15</item>
|
||||||
|
</integer-array>
|
||||||
You will be prompted to choose a file. Choose the APK file that was previously obtained.
|
</resources>
|
||||||
|
```
|
||||||
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.
|
7. Replace the values in the keys.xml file with those extracted from the original app.
|
||||||
|
8. Run
|
||||||
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.
|
|
||||||
@ -15,7 +15,7 @@ android {
|
|||||||
minSdk = 28
|
minSdk = 28
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "Alpha 0.6.3"
|
versionName = "Alpha 0.6"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@ -91,5 +91,4 @@ dependencies {
|
|||||||
implementation("com.google.android.material:material:1.2.0")
|
implementation("com.google.android.material:material:1.2.0")
|
||||||
implementation(libs.protobuf.javalite)
|
implementation(libs.protobuf.javalite)
|
||||||
implementation("androidx.compose.material:material")
|
implementation("androidx.compose.material:material")
|
||||||
implementation("androidx.datastore:datastore-preferences:1.1.7")
|
|
||||||
}
|
}
|
||||||
@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardColors
|
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@ -36,27 +35,20 @@ import com.github.cfogrady.vbnfc.vb.SpecialMission
|
|||||||
import com.github.nacabaro.vbhelper.R
|
import com.github.nacabaro.vbhelper.R
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||||
import com.github.nacabaro.vbhelper.utils.getObscuredBitmap
|
import com.github.nacabaro.vbhelper.utils.getObscuredBitmap
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CharacterEntry(
|
fun CharacterEntry(
|
||||||
icon: BitmapData,
|
icon: BitmapData,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
cardIcon: BitmapData? = null,
|
|
||||||
obscure: Boolean = false,
|
obscure: Boolean = false,
|
||||||
disabled: Boolean = false,
|
disabled: Boolean = false,
|
||||||
shape: Shape = MaterialTheme.shapes.medium,
|
shape: Shape = MaterialTheme.shapes.medium,
|
||||||
multiplier: Int = 4,
|
multiplier: Int = 4,
|
||||||
cardColors: CardColors = CardDefaults.cardColors(
|
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceContainerHighest
|
|
||||||
),
|
|
||||||
onClick: () -> Unit = { }
|
onClick: () -> Unit = { }
|
||||||
) {
|
) {
|
||||||
val bitmap = remember (icon.bitmap) {
|
val bitmap = remember (icon.bitmap) {
|
||||||
if(obscure) icon.getObscuredBitmap() else icon.getBitmap()
|
if(obscure) icon.getObscuredBitmap() else icon.getBitmap()
|
||||||
}
|
}
|
||||||
val iconSizeMultiplier = 3
|
|
||||||
val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
||||||
val density: Float = LocalContext.current.resources.displayMetrics.density
|
val density: Float = LocalContext.current.resources.displayMetrics.density
|
||||||
val dpSize = (icon.width * multiplier / density).dp
|
val dpSize = (icon.width * multiplier / density).dp
|
||||||
@ -69,8 +61,7 @@ fun CharacterEntry(
|
|||||||
},
|
},
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
.padding(8.dp),
|
.padding(8.dp)
|
||||||
colors = cardColors
|
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.BottomCenter,
|
contentAlignment = Alignment.BottomCenter,
|
||||||
@ -88,24 +79,7 @@ fun CharacterEntry(
|
|||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(dpSize)
|
.size(dpSize)
|
||||||
.align(Alignment.BottomCenter)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (cardIcon != null) {
|
|
||||||
val bitmap = remember (icon.bitmap) { cardIcon.getBitmap() }
|
|
||||||
val iconBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
|
||||||
val dpSize = (icon.width * iconSizeMultiplier /density).dp
|
|
||||||
|
|
||||||
Image(
|
|
||||||
bitmap = iconBitmap,
|
|
||||||
contentDescription = "Card icon",
|
|
||||||
filterQuality = FilterQuality.None,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(dpSize)
|
|
||||||
.align(Alignment.BottomEnd)
|
|
||||||
.padding(8.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,27 +126,14 @@ fun ItemDisplay(
|
|||||||
fun SpecialMissionsEntry(
|
fun SpecialMissionsEntry(
|
||||||
specialMission: SpecialMissions,
|
specialMission: SpecialMissions,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onClickMission: (Long) -> Unit = { },
|
onClickCard: () -> Unit = { },
|
||||||
onClickCollect: (Long) -> Unit = { }
|
|
||||||
) {
|
) {
|
||||||
val textValue = when (specialMission.missionType) {
|
val textValue = when (specialMission.missionType) {
|
||||||
SpecialMission.Type.NONE -> stringResource(R.string.special_mission_none)
|
SpecialMission.Type.NONE -> "No mission selected"
|
||||||
SpecialMission.Type.STEPS -> stringResource(
|
SpecialMission.Type.STEPS -> "Walk ${specialMission.goal} steps"
|
||||||
R.string.special_mission_steps,
|
SpecialMission.Type.BATTLES -> "Battle ${specialMission.goal} times"
|
||||||
specialMission.goal
|
SpecialMission.Type.WINS -> "Win ${specialMission.goal} battles"
|
||||||
)
|
SpecialMission.Type.VITALS -> "Earn ${specialMission.goal} vitals"
|
||||||
SpecialMission.Type.BATTLES -> stringResource(
|
|
||||||
R.string.special_mission_battles,
|
|
||||||
specialMission.goal
|
|
||||||
)
|
|
||||||
SpecialMission.Type.WINS -> stringResource(
|
|
||||||
R.string.special_mission_wins,
|
|
||||||
specialMission.goal
|
|
||||||
)
|
|
||||||
SpecialMission.Type.VITALS -> stringResource(
|
|
||||||
R.string.special_mission_vitals,
|
|
||||||
specialMission.goal
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val progress = if (specialMission.status == SpecialMission.Status.COMPLETED) {
|
val progress = if (specialMission.status == SpecialMission.Status.COMPLETED) {
|
||||||
@ -183,22 +144,10 @@ fun SpecialMissionsEntry(
|
|||||||
|
|
||||||
val completion = when (specialMission.missionType) {
|
val completion = when (specialMission.missionType) {
|
||||||
SpecialMission.Type.NONE -> ""
|
SpecialMission.Type.NONE -> ""
|
||||||
SpecialMission.Type.STEPS -> stringResource(
|
SpecialMission.Type.STEPS -> "Walked $progress steps"
|
||||||
R.string.special_mission_steps_progress,
|
SpecialMission.Type.BATTLES -> "Battled $progress times"
|
||||||
progress
|
SpecialMission.Type.WINS -> "Won $progress battles"
|
||||||
)
|
SpecialMission.Type.VITALS -> "Earned $progress vitals"
|
||||||
SpecialMission.Type.BATTLES -> stringResource(
|
|
||||||
R.string.special_mission_battles_progress,
|
|
||||||
progress
|
|
||||||
)
|
|
||||||
SpecialMission.Type.WINS -> stringResource(
|
|
||||||
R.string.special_mission_wins_progress,
|
|
||||||
progress
|
|
||||||
)
|
|
||||||
SpecialMission.Type.VITALS -> stringResource(
|
|
||||||
R.string.special_mission_vitals_progress,
|
|
||||||
progress
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val icon = when (specialMission.missionType) {
|
val icon = when (specialMission.missionType) {
|
||||||
@ -220,12 +169,10 @@ fun SpecialMissionsEntry(
|
|||||||
Card(
|
Card(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
||||||
onClick = if (specialMission.status == SpecialMission.Status.COMPLETED) {
|
onClick = if (specialMission.status == SpecialMission.Status.COMPLETED || specialMission.status == SpecialMission.Status.FAILED) {
|
||||||
{ onClickCollect(specialMission.id) }
|
onClickCard
|
||||||
} else if (specialMission.status == SpecialMission.Status.UNAVAILABLE) {
|
|
||||||
{ }
|
|
||||||
} else {
|
} else {
|
||||||
{ onClickMission(specialMission.id) }
|
{ }
|
||||||
},
|
},
|
||||||
colors = CardDefaults.cardColors(
|
colors = CardDefaults.cardColors(
|
||||||
containerColor = color
|
containerColor = color
|
||||||
@ -241,7 +188,7 @@ fun SpecialMissionsEntry(
|
|||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(icon),
|
painter = painterResource(icon),
|
||||||
contentDescription = stringResource(R.string.special_mission_icon_content_description),
|
contentDescription = "Vitals",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package com.github.nacabaro.vbhelper.daos
|
|||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -32,13 +31,13 @@ interface AdventureDao {
|
|||||||
a.finishesAdventure AS finishesAdventure,
|
a.finishesAdventure AS finishesAdventure,
|
||||||
a.originalDuration AS originalTimeInMinutes
|
a.originalDuration AS originalTimeInMinutes
|
||||||
FROM UserCharacter uc
|
FROM UserCharacter uc
|
||||||
JOIN CardCharacter c ON uc.charId = c.id
|
JOIN CharacterData c ON uc.charId = c.id
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
JOIN Card d ON c.cardId = d.id
|
JOIN Card d ON c.cardId = d.id
|
||||||
JOIN Adventure a ON uc.id = a.characterId
|
JOIN Adventure a ON uc.id = a.characterId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getAdventureCharacters(): Flow<List<CharacterDtos.AdventureCharacterWithSprites>>
|
suspend fun getAdventureCharacters(): List<CharacterDtos.AdventureCharacterWithSprites>
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
DELETE FROM Adventure
|
DELETE FROM Adventure
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
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 {
|
|
||||||
@Query("""
|
|
||||||
INSERT INTO
|
|
||||||
CardAdventure (cardId, characterId, steps, bossAp, bossHp, bossDp, bossBp)
|
|
||||||
SELECT
|
|
||||||
:cardId,
|
|
||||||
cc.id,
|
|
||||||
:steps,
|
|
||||||
:bossAp,
|
|
||||||
:bossHp,
|
|
||||||
:bossDp,
|
|
||||||
:bossBp
|
|
||||||
FROM
|
|
||||||
CardCharacter cc
|
|
||||||
WHERE
|
|
||||||
cc.charaIndex = :characterId AND
|
|
||||||
cc.cardId = :cardId
|
|
||||||
""")
|
|
||||||
suspend fun insertNewAdventure(
|
|
||||||
cardId: Long,
|
|
||||||
characterId: Int,
|
|
||||||
steps: Int,
|
|
||||||
bossAp: Int,
|
|
||||||
bossHp: Int,
|
|
||||||
bossDp: Int,
|
|
||||||
bossBp: Int?
|
|
||||||
)
|
|
||||||
|
|
||||||
@Query("""
|
|
||||||
SELECT
|
|
||||||
cc.nameSprite as characterName,
|
|
||||||
cc.nameWidth as characterNameWidth,
|
|
||||||
cc.nameHeight as characterNameHeight,
|
|
||||||
s.spriteIdle1 as characterIdleSprite,
|
|
||||||
s.width as characterIdleSpriteWidth,
|
|
||||||
s.height as characterIdleSpriteHeight,
|
|
||||||
ca.bossAp as characterAp,
|
|
||||||
ca.bossBp as characterBp,
|
|
||||||
ca.bossDp as characterDp,
|
|
||||||
ca.bossHp as characterHp,
|
|
||||||
ca.steps as steps
|
|
||||||
FROM CardCharacter cc
|
|
||||||
JOIN Sprite s ON cc.spriteId = s.id
|
|
||||||
JOIN CardAdventure ca ON cc.id = ca.characterId
|
|
||||||
WHERE
|
|
||||||
cc.cardId = :cardId
|
|
||||||
""")
|
|
||||||
fun getAdventureForCard(
|
|
||||||
cardId: Long
|
|
||||||
): Flow<List<CardDtos.CardAdventureWithSprites>>
|
|
||||||
}
|
|
||||||
@ -5,8 +5,6 @@ import androidx.room.Insert
|
|||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface CardDao {
|
interface CardDao {
|
||||||
@ -23,27 +21,16 @@ interface CardDao {
|
|||||||
"""
|
"""
|
||||||
SELECT ca.*
|
SELECT ca.*
|
||||||
FROM Card ca
|
FROM Card ca
|
||||||
JOIN CardCharacter ch ON ca.id = ch.cardId
|
JOIN CharacterData ch ON ca.id = ch.cardId
|
||||||
JOIN UserCharacter uc ON ch.id = uc.charId
|
JOIN UserCharacter uc ON ch.id = uc.charId
|
||||||
WHERE uc.id = :id
|
WHERE uc.id = :id
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getCardByCharacterId(id: Long): Flow<Card>
|
suspend fun getCardByCharacterId(id: Long): Card
|
||||||
|
|
||||||
@Query("UPDATE Card SET name = :newName WHERE id = :id")
|
@Query("UPDATE Card SET name = :newName WHERE id = :id")
|
||||||
suspend fun renameCard(id: Int, newName: String)
|
suspend fun renameCard(id: Int, newName: String)
|
||||||
|
|
||||||
@Query("DELETE FROM Card WHERE id = :id")
|
@Query("DELETE FROM Card WHERE id = :id")
|
||||||
suspend fun deleteCard(id: Long)
|
suspend fun deleteCard(id: Long)
|
||||||
|
|
||||||
@Query("""
|
|
||||||
SELECT
|
|
||||||
c.logo as cardIcon,
|
|
||||||
c.logoWidth as cardIconWidth,
|
|
||||||
c.logoHeight as cardIconHeight
|
|
||||||
FROM Card c
|
|
||||||
JOIN CardCharacter cc ON cc.cardId = c.id
|
|
||||||
WHERE cc.id = :charaId
|
|
||||||
""")
|
|
||||||
fun getCardIconByCharaId(charaId: Long): Flow<CardDtos.CardIcon>
|
|
||||||
}
|
}
|
||||||
@ -1,48 +0,0 @@
|
|||||||
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 {
|
|
||||||
@Query("""
|
|
||||||
INSERT INTO
|
|
||||||
CardFusions (
|
|
||||||
fromCharaId,
|
|
||||||
attribute,
|
|
||||||
toCharaId
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :fromCharaId),
|
|
||||||
:attribute,
|
|
||||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaId)
|
|
||||||
""")
|
|
||||||
suspend fun insertNewFusion(
|
|
||||||
cardId: Long,
|
|
||||||
fromCharaId: 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>>
|
|
||||||
}
|
|
||||||
@ -1,29 +1,17 @@
|
|||||||
package com.github.nacabaro.vbhelper.daos
|
package com.github.nacabaro.vbhelper.daos
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import androidx.room.Upsert
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface CardProgressDao {
|
interface CardProgressDao {
|
||||||
@Query("""
|
@Upsert
|
||||||
UPDATE CardProgress
|
fun updateDimProgress(vararg cardProgresses: CardProgress)
|
||||||
SET
|
|
||||||
currentStage = :currentStage,
|
|
||||||
unlocked = :unlocked
|
|
||||||
WHERE cardId = :cardId AND
|
|
||||||
currentStage < :currentStage
|
|
||||||
""")
|
|
||||||
fun updateCardProgress(currentStage: Int, cardId: Long, unlocked: Boolean)
|
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT currentStage FROM CardProgress WHERE cardId = :cardId"
|
"SELECT currentStage FROM CardProgress WHERE cardId = :cardId"
|
||||||
)
|
)
|
||||||
fun getCardProgress(cardId: Long): Flow<Int>
|
fun getCardProgress(cardId: Int): Int
|
||||||
|
|
||||||
@Insert
|
|
||||||
fun insertCardProgress(cardProgress: CardProgress)
|
|
||||||
}
|
}
|
||||||
@ -3,18 +3,17 @@ package com.github.nacabaro.vbhelper.daos
|
|||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
import com.github.nacabaro.vbhelper.domain.card.CharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface CharacterDao {
|
interface CharacterDao {
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insertCharacter(vararg characterData: CardCharacter)
|
suspend fun insertCharacter(vararg characterData: CharacterData)
|
||||||
|
|
||||||
@Query("SELECT * FROM CardCharacter WHERE charaIndex = :monIndex AND cardId = :dimId LIMIT 1")
|
@Query("SELECT * FROM CharacterData WHERE charaIndex = :monIndex AND cardId = :dimId LIMIT 1")
|
||||||
fun getCharacterByMonIndex(monIndex: Int, dimId: Long): CardCharacter
|
fun getCharacterByMonIndex(monIndex: Int, dimId: Long): CharacterData
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insertSprite(vararg sprite: Sprite)
|
suspend fun insertSprite(vararg sprite: Sprite)
|
||||||
@ -25,12 +24,10 @@ interface CharacterDao {
|
|||||||
d.cardId as cardId,
|
d.cardId as cardId,
|
||||||
c.charaIndex as charId,
|
c.charaIndex as charId,
|
||||||
c.stage as stage,
|
c.stage as stage,
|
||||||
c.attribute as attribute,
|
c.attribute as attribute
|
||||||
cp.currentStage as currentStage
|
FROM CharacterData c
|
||||||
FROM CardCharacter c
|
|
||||||
JOIN UserCharacter uc ON c.id = uc.charId
|
JOIN UserCharacter uc ON c.id = uc.charId
|
||||||
JOIN Card d ON c.cardId = d.id
|
JOIN Card d ON c.cardId = d.id
|
||||||
JOIN CardProgress cp ON d.id = cp.cardId
|
|
||||||
WHERE c.id = :charId
|
WHERE c.id = :charId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@ -40,14 +37,14 @@ interface CharacterDao {
|
|||||||
"""
|
"""
|
||||||
INSERT INTO PossibleTransformations (charaId, requiredVitals, requiredTrophies, requiredBattles, requiredWinRate, changeTimerHours, requiredAdventureLevelCompleted, toCharaId)
|
INSERT INTO PossibleTransformations (charaId, requiredVitals, requiredTrophies, requiredBattles, requiredWinRate, changeTimerHours, requiredAdventureLevelCompleted, toCharaId)
|
||||||
SELECT
|
SELECT
|
||||||
(SELECT id FROM CardCharacter WHERE charaIndex = :fromChraraIndex AND cardId = :cardId),
|
(SELECT id FROM CharacterData WHERE charaIndex = :fromChraraIndex AND cardId = :cardId),
|
||||||
:requiredVitals,
|
:requiredVitals,
|
||||||
:requiredTrophies,
|
:requiredTrophies,
|
||||||
:requiredBattles,
|
:requiredBattles,
|
||||||
:requiredWinRate,
|
:requiredWinRate,
|
||||||
:changeTimerHours,
|
:changeTimerHours,
|
||||||
:requiredAdventureLevelCompleted,
|
:requiredAdventureLevelCompleted,
|
||||||
(SELECT id FROM CardCharacter WHERE charaIndex = :toChraraIndex AND cardId = :cardId)
|
(SELECT id FROM CharacterData WHERE charaIndex = :toChraraIndex AND cardId = :cardId)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
suspend fun insertPossibleTransformation(
|
suspend fun insertPossibleTransformation(
|
||||||
@ -79,12 +76,12 @@ interface CharacterDao {
|
|||||||
pt.requiredAdventureLevelCompleted as requiredAdventureLevelCompleted
|
pt.requiredAdventureLevelCompleted as requiredAdventureLevelCompleted
|
||||||
FROM
|
FROM
|
||||||
PossibleTransformations pt
|
PossibleTransformations pt
|
||||||
JOIN CardCharacter c on pt.toCharaId = c.id
|
JOIN CharacterData c on pt.toCharaId = c.id
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
LEFT JOIN Dex d ON d.id = pt.toCharaId
|
LEFT JOIN Dex d ON d.id = pt.toCharaId
|
||||||
WHERE
|
WHERE
|
||||||
pt.charaId = :characterId
|
c.cardId = :cardId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getEvolutionRequirementsForCard(characterId: Long): Flow<List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>>
|
suspend fun getEvolutionRequirementsForCard(cardId: Long): List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>
|
||||||
}
|
}
|
||||||
@ -4,7 +4,6 @@ import androidx.room.Dao
|
|||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface DexDao {
|
interface DexDao {
|
||||||
@ -12,7 +11,7 @@ interface DexDao {
|
|||||||
"""
|
"""
|
||||||
INSERT OR IGNORE INTO Dex(id, discoveredOn)
|
INSERT OR IGNORE INTO Dex(id, discoveredOn)
|
||||||
VALUES (
|
VALUES (
|
||||||
(SELECT id FROM CardCharacter WHERE charaIndex = :charIndex AND cardId = :cardId),
|
(SELECT id FROM CharacterData WHERE charaIndex = :charIndex AND cardId = :cardId),
|
||||||
:discoveredOn
|
:discoveredOn
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
@ -35,13 +34,13 @@ interface DexDao {
|
|||||||
c.baseAp as baseAp,
|
c.baseAp as baseAp,
|
||||||
c.stage as stage,
|
c.stage as stage,
|
||||||
c.attribute as attribute
|
c.attribute as attribute
|
||||||
FROM CardCharacter c
|
FROM CharacterData c
|
||||||
JOIN Sprite s ON c.spriteId = s.id
|
JOIN Sprite s ON c.spriteId = s.id
|
||||||
LEFT JOIN dex d ON c.id = d.id
|
LEFT JOIN dex d ON c.id = d.id
|
||||||
WHERE c.cardId = :cardId
|
WHERE c.cardId = :cardId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getSingleCardProgress(cardId: Long): Flow<List<CharacterDtos.CardCharaProgress>>
|
suspend fun getSingleCardProgress(cardId: Long): List<CharacterDtos.CardCharaProgress>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
@ -51,10 +50,10 @@ interface DexDao {
|
|||||||
c.logo as cardLogo,
|
c.logo as cardLogo,
|
||||||
c.logoWidth as logoWidth,
|
c.logoWidth as logoWidth,
|
||||||
c.logoHeight as logoHeight,
|
c.logoHeight as logoHeight,
|
||||||
(SELECT COUNT(*) FROM CardCharacter cc WHERE cc.cardId = c.id) AS totalCharacters,
|
(SELECT COUNT(*) FROM CharacterData cc WHERE cc.cardId = c.id) AS totalCharacters,
|
||||||
(SELECT COUNT(*) FROM Dex d JOIN CardCharacter cc ON d.id = cc.id WHERE cc.cardId = c.id AND d.discoveredOn IS NOT NULL) AS obtainedCharacters
|
(SELECT COUNT(*) FROM Dex d JOIN CharacterData cc ON d.id = cc.id WHERE cc.cardId = c.id AND d.discoveredOn IS NOT NULL) AS obtainedCharacters
|
||||||
FROM Card c
|
FROM Card c
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getCardsWithProgress(): Flow<List<CardDtos.CardProgress>>
|
suspend fun getCardsWithProgress(): List<CardDtos.CardProgress>
|
||||||
}
|
}
|
||||||
@ -3,7 +3,6 @@ package com.github.nacabaro.vbhelper.daos
|
|||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface ItemDao {
|
interface ItemDao {
|
||||||
@ -14,7 +13,7 @@ interface ItemDao {
|
|||||||
ORDER BY Items.itemIcon ASC
|
ORDER BY Items.itemIcon ASC
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getAllItems(): Flow<List<ItemDtos.ItemsWithQuantities>>
|
suspend fun getAllItems(): List<ItemDtos.ItemsWithQuantities>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
@ -23,7 +22,7 @@ interface ItemDao {
|
|||||||
WHERE quantity > 0
|
WHERE quantity > 0
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getAllUserItems(): Flow<List<ItemDtos.ItemsWithQuantities>>
|
suspend fun getAllUserItems(): List<ItemDtos.ItemsWithQuantities>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -2,8 +2,6 @@ package com.github.nacabaro.vbhelper.daos
|
|||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface SpecialMissionDao {
|
interface SpecialMissionDao {
|
||||||
@ -14,11 +12,4 @@ interface SpecialMissionDao {
|
|||||||
WHERE id = :id
|
WHERE id = :id
|
||||||
""")
|
""")
|
||||||
suspend fun clearSpecialMission(id: Long)
|
suspend fun clearSpecialMission(id: Long)
|
||||||
|
|
||||||
@Query("""
|
|
||||||
SELECT *
|
|
||||||
FROM SpecialMissions
|
|
||||||
WHERE id = :id
|
|
||||||
""")
|
|
||||||
fun getSpecialMission(id: Long): Flow<SpecialMissions>
|
|
||||||
}
|
}
|
||||||
@ -5,7 +5,7 @@ import androidx.room.Insert
|
|||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Upsert
|
import androidx.room.Upsert
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
import com.github.nacabaro.vbhelper.domain.card.CharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||||
@ -13,7 +13,6 @@ import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory
|
|||||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory
|
import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface UserCharacterDao {
|
interface UserCharacterDao {
|
||||||
@ -48,12 +47,12 @@ interface UserCharacterDao {
|
|||||||
c.charaIndex AS monIndex,
|
c.charaIndex AS monIndex,
|
||||||
t.transformationDate AS transformationDate
|
t.transformationDate AS transformationDate
|
||||||
FROM TransformationHistory t
|
FROM TransformationHistory t
|
||||||
JOIN CardCharacter c ON c.id = t.stageId
|
JOIN CharacterData c ON c.id = t.stageId
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
WHERE monId = :monId
|
WHERE monId = :monId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getTransformationHistory(monId: Long): Flow<List<CharacterDtos.TransformationHistory>>
|
suspend fun getTransformationHistory(monId: Long): List<CharacterDtos.TransformationHistory>?
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
@ -69,16 +68,15 @@ interface UserCharacterDao {
|
|||||||
c.nameWidth as nameSpriteWidth,
|
c.nameWidth as nameSpriteWidth,
|
||||||
c.nameHeight as nameSpriteHeight,
|
c.nameHeight as nameSpriteHeight,
|
||||||
d.isBEm as isBemCard,
|
d.isBEm as isBemCard,
|
||||||
a.characterId = uc.id as isInAdventure,
|
a.characterId = uc.id as isInAdventure
|
||||||
uc.isActive as active
|
|
||||||
FROM UserCharacter uc
|
FROM UserCharacter uc
|
||||||
JOIN CardCharacter c ON uc.charId = c.id
|
JOIN CharacterData c ON uc.charId = c.id
|
||||||
JOIN Card d ON d.id = c.cardId
|
JOIN Card d ON d.id = c.cardId
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
LEFT JOIN Adventure a ON a.characterId = uc.id
|
LEFT JOIN Adventure a ON a.characterId = uc.id
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getAllCharacters(): Flow<List<CharacterDtos.CharacterWithSprites>>
|
suspend fun getAllCharacters(): List<CharacterDtos.CharacterWithSprites>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
@ -94,10 +92,9 @@ interface UserCharacterDao {
|
|||||||
c.nameWidth as nameSpriteWidth,
|
c.nameWidth as nameSpriteWidth,
|
||||||
c.nameHeight as nameSpriteHeight,
|
c.nameHeight as nameSpriteHeight,
|
||||||
d.isBEm as isBemCard,
|
d.isBEm as isBemCard,
|
||||||
a.characterId = uc.id as isInAdventure,
|
a.characterId = uc.id as isInAdventure
|
||||||
uc.isActive as active
|
|
||||||
FROM UserCharacter uc
|
FROM UserCharacter uc
|
||||||
JOIN CardCharacter c ON uc.charId = c.id
|
JOIN CharacterData c ON uc.charId = c.id
|
||||||
JOIN Card d ON c.cardId = d.id
|
JOIN Card d ON c.cardId = d.id
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
LEFT JOIN Adventure a ON a.characterId = uc.id
|
LEFT JOIN Adventure a ON a.characterId = uc.id
|
||||||
@ -110,13 +107,13 @@ interface UserCharacterDao {
|
|||||||
suspend fun getCharacter(id: Long): UserCharacter
|
suspend fun getCharacter(id: Long): UserCharacter
|
||||||
|
|
||||||
@Query("SELECT * FROM BECharacterData WHERE id = :id")
|
@Query("SELECT * FROM BECharacterData WHERE id = :id")
|
||||||
fun getBeData(id: Long): Flow<BECharacterData>
|
suspend fun getBeData(id: Long): BECharacterData
|
||||||
|
|
||||||
@Query("SELECT * FROM VBCharacterData WHERE id = :id")
|
@Query("SELECT * FROM VBCharacterData WHERE id = :id")
|
||||||
fun getVbData(id: Long): Flow<VBCharacterData>
|
suspend fun getVbData(id: Long): VBCharacterData
|
||||||
|
|
||||||
@Query("SELECT * FROM SpecialMissions WHERE characterId = :id")
|
@Query("SELECT * FROM SpecialMissions WHERE characterId = :id")
|
||||||
fun getSpecialMissions(id: Long): Flow<List<SpecialMissions>>
|
suspend fun getSpecialMissions(id: Long): List<SpecialMissions>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
@ -132,10 +129,9 @@ interface UserCharacterDao {
|
|||||||
c.nameWidth as nameSpriteWidth,
|
c.nameWidth as nameSpriteWidth,
|
||||||
c.nameHeight as nameSpriteHeight,
|
c.nameHeight as nameSpriteHeight,
|
||||||
d.isBEm as isBemCard,
|
d.isBEm as isBemCard,
|
||||||
a.characterId as isInAdventure,
|
a.characterId as isInAdventure
|
||||||
uc.isActive as active
|
|
||||||
FROM UserCharacter uc
|
FROM UserCharacter uc
|
||||||
JOIN CardCharacter c ON uc.charId = c.id
|
JOIN CharacterData c ON uc.charId = c.id
|
||||||
JOIN Card d ON c.cardId = d.id
|
JOIN Card d ON c.cardId = d.id
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
LEFT JOIN Adventure a ON a.characterId = uc.id
|
LEFT JOIN Adventure a ON a.characterId = uc.id
|
||||||
@ -143,7 +139,7 @@ interface UserCharacterDao {
|
|||||||
LIMIT 1
|
LIMIT 1
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun getActiveCharacter(): Flow<CharacterDtos.CharacterWithSprites?>
|
suspend fun getActiveCharacter(): CharacterDtos.CharacterWithSprites?
|
||||||
|
|
||||||
@Query("DELETE FROM UserCharacter WHERE id = :id")
|
@Query("DELETE FROM UserCharacter WHERE id = :id")
|
||||||
fun deleteCharacterById(id: Long)
|
fun deleteCharacterById(id: Long)
|
||||||
@ -157,13 +153,13 @@ interface UserCharacterDao {
|
|||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
SELECT c.*
|
SELECT c.*
|
||||||
FROM CardCharacter c
|
FROM CharacterData c
|
||||||
join UserCharacter uc on c.id = uc.charId
|
join UserCharacter uc on c.id = uc.charId
|
||||||
where uc.id = :charId
|
where uc.id = :charId
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
suspend fun getCharacterInfo(charId: Long): CardCharacter
|
suspend fun getCharacterInfo(charId: Long): CharacterData
|
||||||
|
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
@ -171,7 +167,7 @@ interface UserCharacterDao {
|
|||||||
INSERT INTO TransformationHistory(monId, stageId, transformationDate)
|
INSERT INTO TransformationHistory(monId, stageId, transformationDate)
|
||||||
VALUES
|
VALUES
|
||||||
(:monId,
|
(:monId,
|
||||||
(SELECT id FROM CardCharacter WHERE charaIndex = :stage AND cardId = :dimId),
|
(SELECT id FROM CharacterData WHERE charaIndex = :stage AND cardId = :dimId),
|
||||||
:transformationDate)
|
:transformationDate)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@ -197,10 +193,9 @@ interface UserCharacterDao {
|
|||||||
c.nameWidth as nameSpriteWidth,
|
c.nameWidth as nameSpriteWidth,
|
||||||
c.nameHeight as nameSpriteHeight,
|
c.nameHeight as nameSpriteHeight,
|
||||||
d.isBEm as isBemCard,
|
d.isBEm as isBemCard,
|
||||||
a.characterId = uc.id as isInAdventure,
|
a.characterId = uc.id as isInAdventure
|
||||||
uc.isActive as active
|
|
||||||
FROM UserCharacter uc
|
FROM UserCharacter uc
|
||||||
JOIN CardCharacter c ON uc.charId = c.id
|
JOIN CharacterData c ON uc.charId = c.id
|
||||||
JOIN Card d ON d.id = c.cardId
|
JOIN Card d ON d.id = c.cardId
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
LEFT JOIN Adventure a ON a.characterId = uc.id
|
LEFT JOIN Adventure a ON a.characterId = uc.id
|
||||||
@ -223,10 +218,9 @@ interface UserCharacterDao {
|
|||||||
c.nameWidth as nameSpriteWidth,
|
c.nameWidth as nameSpriteWidth,
|
||||||
c.nameHeight as nameSpriteHeight,
|
c.nameHeight as nameSpriteHeight,
|
||||||
d.isBEm as isBemCard,
|
d.isBEm as isBemCard,
|
||||||
a.characterId = uc.id as isInAdventure,
|
a.characterId = uc.id as isInAdventure
|
||||||
uc.isActive as active
|
|
||||||
FROM UserCharacter uc
|
FROM UserCharacter uc
|
||||||
JOIN CardCharacter c ON uc.charId = c.id
|
JOIN CharacterData c ON uc.charId = c.id
|
||||||
JOIN Card d ON d.id = c.cardId
|
JOIN Card d ON d.id = c.cardId
|
||||||
JOIN Sprite s ON s.id = c.spriteId
|
JOIN Sprite s ON s.id = c.spriteId
|
||||||
LEFT JOIN Adventure a ON a.characterId = uc.id
|
LEFT JOIN Adventure a ON a.characterId = uc.id
|
||||||
|
|||||||
@ -3,21 +3,17 @@ package com.github.nacabaro.vbhelper.database
|
|||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import com.github.nacabaro.vbhelper.daos.AdventureDao
|
import com.github.nacabaro.vbhelper.daos.AdventureDao
|
||||||
import com.github.nacabaro.vbhelper.daos.CardAdventureDao
|
|
||||||
import com.github.nacabaro.vbhelper.daos.CharacterDao
|
import com.github.nacabaro.vbhelper.daos.CharacterDao
|
||||||
import com.github.nacabaro.vbhelper.daos.DexDao
|
import com.github.nacabaro.vbhelper.daos.DexDao
|
||||||
import com.github.nacabaro.vbhelper.daos.CardDao
|
import com.github.nacabaro.vbhelper.daos.CardDao
|
||||||
import com.github.nacabaro.vbhelper.daos.CardFusionsDao
|
|
||||||
import com.github.nacabaro.vbhelper.daos.CardProgressDao
|
import com.github.nacabaro.vbhelper.daos.CardProgressDao
|
||||||
import com.github.nacabaro.vbhelper.daos.ItemDao
|
import com.github.nacabaro.vbhelper.daos.ItemDao
|
||||||
import com.github.nacabaro.vbhelper.daos.SpecialMissionDao
|
import com.github.nacabaro.vbhelper.daos.SpecialMissionDao
|
||||||
import com.github.nacabaro.vbhelper.daos.SpriteDao
|
import com.github.nacabaro.vbhelper.daos.SpriteDao
|
||||||
import com.github.nacabaro.vbhelper.daos.UserCharacterDao
|
import com.github.nacabaro.vbhelper.daos.UserCharacterDao
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Background
|
import com.github.nacabaro.vbhelper.domain.card.Background
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
import com.github.nacabaro.vbhelper.domain.card.CharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardAdventure
|
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardFusions
|
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||||
import com.github.nacabaro.vbhelper.domain.card.PossibleTransformations
|
import com.github.nacabaro.vbhelper.domain.card.PossibleTransformations
|
||||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||||
@ -36,9 +32,7 @@ import com.github.nacabaro.vbhelper.domain.items.Items
|
|||||||
entities = [
|
entities = [
|
||||||
Card::class,
|
Card::class,
|
||||||
CardProgress::class,
|
CardProgress::class,
|
||||||
CardCharacter::class,
|
CharacterData::class,
|
||||||
CardAdventure::class,
|
|
||||||
CardFusions::class,
|
|
||||||
Sprite::class,
|
Sprite::class,
|
||||||
UserCharacter::class,
|
UserCharacter::class,
|
||||||
BECharacterData::class,
|
BECharacterData::class,
|
||||||
@ -63,6 +57,4 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
abstract fun adventureDao(): AdventureDao
|
abstract fun adventureDao(): AdventureDao
|
||||||
abstract fun spriteDao(): SpriteDao
|
abstract fun spriteDao(): SpriteDao
|
||||||
abstract fun specialMissionDao(): SpecialMissionDao
|
abstract fun specialMissionDao(): SpecialMissionDao
|
||||||
abstract fun cardAdventureDao(): CardAdventureDao
|
|
||||||
abstract fun cardFusionsDao(): CardFusionsDao
|
|
||||||
}
|
}
|
||||||
@ -1,11 +1,9 @@
|
|||||||
package com.github.nacabaro.vbhelper.di
|
package com.github.nacabaro.vbhelper.di
|
||||||
|
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||||
import com.github.nacabaro.vbhelper.source.CurrencyRepository
|
|
||||||
import com.github.nacabaro.vbhelper.source.DataStoreSecretsRepository
|
import com.github.nacabaro.vbhelper.source.DataStoreSecretsRepository
|
||||||
|
|
||||||
interface AppContainer {
|
interface AppContainer {
|
||||||
val db: AppDatabase
|
val db: AppDatabase
|
||||||
val dataStoreSecretsRepository: DataStoreSecretsRepository
|
val dataStoreSecretsRepository: DataStoreSecretsRepository
|
||||||
val currencyRepository: CurrencyRepository
|
|
||||||
}
|
}
|
||||||
@ -1,27 +1,20 @@
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.datastore.core.DataStore
|
import androidx.datastore.core.DataStore
|
||||||
import androidx.datastore.dataStore
|
import androidx.datastore.dataStore
|
||||||
import androidx.datastore.preferences.core.Preferences
|
|
||||||
import androidx.datastore.preferences.preferencesDataStore
|
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||||
import com.github.nacabaro.vbhelper.di.AppContainer
|
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.DataStoreSecretsRepository
|
||||||
import com.github.nacabaro.vbhelper.source.SecretsSerializer
|
import com.github.nacabaro.vbhelper.source.SecretsSerializer
|
||||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||||
|
|
||||||
private const val SECRETS_DATA_STORE_NAME = "secrets.pb"
|
private const val SECRETS_DATA_STORE_NAME = "secrets.pb"
|
||||||
private const val USER_PREFERENCES_NAME = "user_preferences"
|
|
||||||
val Context.secretsStore: DataStore<Secrets> by dataStore(
|
val Context.secretsStore: DataStore<Secrets> by dataStore(
|
||||||
fileName = SECRETS_DATA_STORE_NAME,
|
fileName = SECRETS_DATA_STORE_NAME,
|
||||||
serializer = SecretsSerializer
|
serializer = SecretsSerializer
|
||||||
)
|
)
|
||||||
|
|
||||||
val Context.currencyStore: DataStore<Preferences> by preferencesDataStore(
|
|
||||||
name = USER_PREFERENCES_NAME
|
|
||||||
)
|
|
||||||
|
|
||||||
class DefaultAppContainer(private val context: Context) : AppContainer {
|
class DefaultAppContainer(private val context: Context) : AppContainer {
|
||||||
|
|
||||||
override val db: AppDatabase by lazy {
|
override val db: AppDatabase by lazy {
|
||||||
@ -36,6 +29,5 @@ class DefaultAppContainer(private val context: Context) : AppContainer {
|
|||||||
|
|
||||||
override val dataStoreSecretsRepository = DataStoreSecretsRepository(context.secretsStore)
|
override val dataStoreSecretsRepository = DataStoreSecretsRepository(context.secretsStore)
|
||||||
|
|
||||||
override val currencyRepository = CurrencyRepository(context.currencyStore)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.domain.card
|
|
||||||
|
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.ForeignKey
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
|
|
||||||
@Entity(
|
|
||||||
foreignKeys = [
|
|
||||||
ForeignKey(
|
|
||||||
entity = CardCharacter::class,
|
|
||||||
parentColumns = ["id"],
|
|
||||||
childColumns = ["characterId"],
|
|
||||||
onDelete = ForeignKey.CASCADE
|
|
||||||
),
|
|
||||||
ForeignKey(
|
|
||||||
entity = Card::class,
|
|
||||||
parentColumns = ["id"],
|
|
||||||
childColumns = ["cardId"],
|
|
||||||
onDelete = ForeignKey.CASCADE
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
data class CardAdventure(
|
|
||||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
|
||||||
val cardId: Long,
|
|
||||||
val characterId: Long,
|
|
||||||
val steps: Int,
|
|
||||||
val bossHp: Int,
|
|
||||||
val bossAp: Int,
|
|
||||||
val bossDp: Int,
|
|
||||||
val bossBp: Int?
|
|
||||||
)
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
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 = [
|
|
||||||
ForeignKey(
|
|
||||||
entity = CardCharacter::class,
|
|
||||||
parentColumns = ["id"],
|
|
||||||
childColumns = ["fromCharaId"],
|
|
||||||
onDelete = ForeignKey.CASCADE
|
|
||||||
),
|
|
||||||
ForeignKey(
|
|
||||||
entity = CardCharacter::class,
|
|
||||||
parentColumns = ["id"],
|
|
||||||
childColumns = ["toCharaId"],
|
|
||||||
onDelete = ForeignKey.CASCADE
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
data class CardFusions(
|
|
||||||
@PrimaryKey(autoGenerate = true) val id: Long,
|
|
||||||
val fromCharaId: Long,
|
|
||||||
val attribute: NfcCharacter.Attribute,
|
|
||||||
val toCharaId: Long
|
|
||||||
)
|
|
||||||
@ -28,7 +28,7 @@ import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
|||||||
* and monIndex.
|
* and monIndex.
|
||||||
* TODO: Customs will mean this should be unique per cardName and monIndex
|
* TODO: Customs will mean this should be unique per cardName and monIndex
|
||||||
*/
|
*/
|
||||||
data class CardCharacter (
|
data class CharacterData (
|
||||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||||
val cardId: Long,
|
val cardId: Long,
|
||||||
val spriteId: Long,
|
val spriteId: Long,
|
||||||
@ -7,13 +7,13 @@ import androidx.room.PrimaryKey
|
|||||||
@Entity(
|
@Entity(
|
||||||
foreignKeys = [
|
foreignKeys = [
|
||||||
ForeignKey(
|
ForeignKey(
|
||||||
entity = CardCharacter::class,
|
entity = CharacterData::class,
|
||||||
parentColumns = ["id"],
|
parentColumns = ["id"],
|
||||||
childColumns = ["charaId"],
|
childColumns = ["charaId"],
|
||||||
onDelete = ForeignKey.CASCADE
|
onDelete = ForeignKey.CASCADE
|
||||||
),
|
),
|
||||||
ForeignKey(
|
ForeignKey(
|
||||||
entity = CardCharacter::class,
|
entity = CharacterData::class,
|
||||||
parentColumns = ["id"],
|
parentColumns = ["id"],
|
||||||
childColumns = ["toCharaId"],
|
childColumns = ["toCharaId"],
|
||||||
onDelete = ForeignKey.CASCADE
|
onDelete = ForeignKey.CASCADE
|
||||||
|
|||||||
@ -3,12 +3,12 @@ package com.github.nacabaro.vbhelper.domain.characters
|
|||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
import com.github.nacabaro.vbhelper.domain.card.CharacterData
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
foreignKeys = [
|
foreignKeys = [
|
||||||
ForeignKey(
|
ForeignKey(
|
||||||
entity = CardCharacter::class,
|
entity = CharacterData::class,
|
||||||
parentColumns = ["id"],
|
parentColumns = ["id"],
|
||||||
childColumns = ["id"],
|
childColumns = ["id"],
|
||||||
onDelete = ForeignKey.CASCADE
|
onDelete = ForeignKey.CASCADE
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package com.github.nacabaro.vbhelper.domain.device_data
|
|||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
import com.github.nacabaro.vbhelper.domain.card.CharacterData
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
foreignKeys = [
|
foreignKeys = [
|
||||||
@ -14,7 +14,7 @@ import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
|||||||
onDelete = ForeignKey.CASCADE
|
onDelete = ForeignKey.CASCADE
|
||||||
),
|
),
|
||||||
ForeignKey(
|
ForeignKey(
|
||||||
entity = CardCharacter::class,
|
entity = CharacterData::class,
|
||||||
parentColumns = ["id"],
|
parentColumns = ["id"],
|
||||||
childColumns = ["stageId"],
|
childColumns = ["stageId"],
|
||||||
onDelete = ForeignKey.CASCADE
|
onDelete = ForeignKey.CASCADE
|
||||||
|
|||||||
@ -5,12 +5,12 @@ import androidx.room.ForeignKey
|
|||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
import com.github.nacabaro.vbhelper.domain.card.CharacterData
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
foreignKeys = [
|
foreignKeys = [
|
||||||
ForeignKey(
|
ForeignKey(
|
||||||
entity = CardCharacter::class,
|
entity = CharacterData::class,
|
||||||
parentColumns = ["id"],
|
parentColumns = ["id"],
|
||||||
childColumns = ["charId"],
|
childColumns = ["charId"],
|
||||||
onDelete = ForeignKey.CASCADE
|
onDelete = ForeignKey.CASCADE
|
||||||
|
|||||||
@ -10,24 +10,4 @@ object CardDtos {
|
|||||||
val totalCharacters: Int,
|
val totalCharacters: Int,
|
||||||
val obtainedCharacters: Int,
|
val obtainedCharacters: Int,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class CardAdventureWithSprites (
|
|
||||||
val characterName: ByteArray,
|
|
||||||
val characterNameWidth: Int,
|
|
||||||
val characterNameHeight: Int,
|
|
||||||
val characterIdleSprite: ByteArray,
|
|
||||||
val characterIdleSpriteWidth: Int,
|
|
||||||
val characterIdleSpriteHeight: Int,
|
|
||||||
val characterAp: Int,
|
|
||||||
val characterBp: Int?,
|
|
||||||
val characterDp: Int,
|
|
||||||
val characterHp: Int,
|
|
||||||
val steps: Int,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class CardIcon (
|
|
||||||
val cardIcon: ByteArray,
|
|
||||||
val cardIconWidth: Int,
|
|
||||||
val cardIconHeight: Int
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
@ -31,16 +31,14 @@ object CharacterDtos {
|
|||||||
val nameSpriteWidth: Int,
|
val nameSpriteWidth: Int,
|
||||||
val nameSpriteHeight: Int,
|
val nameSpriteHeight: Int,
|
||||||
val isBemCard: Boolean,
|
val isBemCard: Boolean,
|
||||||
val isInAdventure: Boolean,
|
val isInAdventure: Boolean
|
||||||
val active: Boolean
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class CardCharacterInfo(
|
data class CardCharacterInfo(
|
||||||
val cardId: Long,
|
val cardId: Int,
|
||||||
val charId: Int,
|
val charId: Int,
|
||||||
val stage: Int,
|
val stage: Int,
|
||||||
val attribute: NfcCharacter.Attribute,
|
val attribute: NfcCharacter.Attribute
|
||||||
val currentStage: Int
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class TransformationHistory(
|
data class TransformationHistory(
|
||||||
@ -115,14 +113,4 @@ object CharacterDtos {
|
|||||||
val changeTimerHours: Int,
|
val changeTimerHours: Int,
|
||||||
val requiredAdventureLevelCompleted: 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
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
@ -1,12 +1,13 @@
|
|||||||
package com.github.nacabaro.vbhelper.navigation
|
package com.github.nacabaro.vbhelper.navigation
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -33,7 +34,6 @@ import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImp
|
|||||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
|
||||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreen
|
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreen
|
||||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
||||||
import com.github.nacabaro.vbhelper.screens.cardScreen.CardAdventureScreen
|
|
||||||
import com.github.nacabaro.vbhelper.screens.cardScreen.CardScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.cardScreen.CardScreenControllerImpl
|
||||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.CreditsScreen
|
import com.github.nacabaro.vbhelper.screens.settingsScreen.CreditsScreen
|
||||||
import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewerControllerImpl
|
import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewerControllerImpl
|
||||||
@ -98,14 +98,20 @@ fun AppNavigation(
|
|||||||
composable(NavigationItems.Scan.route) {
|
composable(NavigationItems.Scan.route) {
|
||||||
val characterIdString = it.arguments?.getString("characterId")
|
val characterIdString = it.arguments?.getString("characterId")
|
||||||
var characterId by remember { mutableStateOf(characterIdString?.toLongOrNull()) }
|
var characterId by remember { mutableStateOf(characterIdString?.toLongOrNull()) }
|
||||||
|
Log.d("ScanScreen", "characterId: $characterId")
|
||||||
val launchedFromHomeScreen = (characterIdString?.toLongOrNull() == null)
|
val launchedFromHomeScreen = (characterIdString?.toLongOrNull() == null)
|
||||||
|
|
||||||
if (characterId == null) {
|
if (characterId == null) {
|
||||||
val context = LocalContext.current.applicationContext as VBHelper
|
val context = LocalContext.current.applicationContext as VBHelper
|
||||||
val storageRepository = StorageRepository(context.container.db)
|
val storageRepository = StorageRepository(context.container.db)
|
||||||
val characterData by storageRepository.getActiveCharacter().collectAsState(null)
|
|
||||||
|
LaunchedEffect(characterId) {
|
||||||
|
if (characterId == null) {
|
||||||
|
val characterData = storageRepository.getActiveCharacter()
|
||||||
if (characterData != null) {
|
if (characterData != null) {
|
||||||
characterId = characterData!!.id
|
characterId = characterData.id
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +145,7 @@ fun AppNavigation(
|
|||||||
if (cardId != null) {
|
if (cardId != null) {
|
||||||
CardViewScreen(
|
CardViewScreen(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
cardId = cardId.toLong()
|
dimId = cardId.toLong()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,17 +177,6 @@ fun AppNavigation(
|
|||||||
navController = navController
|
navController = navController
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(NavigationItems.CardAdventure.route) {
|
|
||||||
val cardId = it.arguments?.getString("cardId")
|
|
||||||
if (cardId != null) {
|
|
||||||
CardAdventureScreen(
|
|
||||||
navController = navController,
|
|
||||||
cardId = cardId.toLong(),
|
|
||||||
cardScreenController = applicationNavigationHandlers
|
|
||||||
.cardScreenController
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNavigationBar(navController: NavController) {
|
fun BottomNavigationBar(navController: NavController) {
|
||||||
@ -26,8 +26,8 @@ fun BottomNavigationBar(navController: NavController) {
|
|||||||
|
|
||||||
items.forEach { item ->
|
items.forEach { item ->
|
||||||
NavigationBarItem (
|
NavigationBarItem (
|
||||||
icon = { Icon(painter = painterResource(item.icon), contentDescription = stringResource(item.label)) },
|
icon = { Icon(painter = painterResource(item.icon), contentDescription = item.label) },
|
||||||
label = { Text(text = stringResource(item.label)) },
|
label = { Text(item.label) },
|
||||||
selected = currentRoute == item.route,
|
selected = currentRoute == item.route,
|
||||||
onClick = {
|
onClick = {
|
||||||
navController.navigate(item.route) {
|
navController.navigate(item.route) {
|
||||||
|
|||||||
@ -1,101 +1,24 @@
|
|||||||
package com.github.nacabaro.vbhelper.navigation
|
package com.github.nacabaro.vbhelper.navigation
|
||||||
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
import com.github.nacabaro.vbhelper.R
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
|
|
||||||
sealed class NavigationItems (
|
sealed class NavigationItems (
|
||||||
val route: String,
|
var route: String,
|
||||||
@DrawableRes val icon: Int,
|
var icon: Int,
|
||||||
@StringRes val label: Int
|
var label: String
|
||||||
) {
|
) {
|
||||||
object Scan : NavigationItems(
|
object Scan : NavigationItems("Scan/{characterId}", R.drawable.baseline_nfc_24, "Scan")
|
||||||
"Scan/{characterId}",
|
object Battles : NavigationItems("Battle", R.drawable.baseline_swords_24, "Battle")
|
||||||
R.drawable.baseline_nfc_24,
|
object Home : NavigationItems("Home", R.drawable.baseline_cottage_24, "Home")
|
||||||
R.string.nav_scan
|
object Dex : NavigationItems("Dex", R.drawable.baseline_menu_book_24, "Dex")
|
||||||
)
|
object Storage : NavigationItems("Storage", R.drawable.baseline_catching_pokemon_24, "Storage")
|
||||||
|
object Settings : NavigationItems("Settings", R.drawable.baseline_settings_24, "Settings")
|
||||||
object Battles : NavigationItems(
|
object Viewer : NavigationItems("Viewer", R.drawable.baseline_image_24, "Viewer")
|
||||||
"Battle",
|
object CardView : NavigationItems("Card/{cardId}", R.drawable.baseline_image_24, "Card")
|
||||||
R.drawable.baseline_swords_24,
|
object Items : NavigationItems("Items", R.drawable.baseline_data_24, "Items")
|
||||||
R.string.nav_battle
|
object MyItems : NavigationItems("MyItems", R.drawable.baseline_data_24, "My items")
|
||||||
)
|
object ItemsStore : NavigationItems("ItemsStore", R.drawable.baseline_data_24, "Items store")
|
||||||
|
object ApplyItem : NavigationItems("ApplyItem/{itemId}", R.drawable.baseline_data_24, "Apply item")
|
||||||
object Home : NavigationItems(
|
object Adventure : NavigationItems("Adventure", R.drawable.baseline_fort_24, "Adventure")
|
||||||
"Home",
|
object Credits : NavigationItems("Credits", R.drawable.baseline_data_24, "Credits")
|
||||||
R.drawable.baseline_cottage_24,
|
|
||||||
R.string.nav_home
|
|
||||||
)
|
|
||||||
|
|
||||||
object Dex : NavigationItems(
|
|
||||||
"Dex",
|
|
||||||
R.drawable.baseline_menu_book_24,
|
|
||||||
R.string.nav_dex
|
|
||||||
)
|
|
||||||
|
|
||||||
object CardAdventure : NavigationItems(
|
|
||||||
"CardAdventure/{cardId}",
|
|
||||||
R.drawable.baseline_fort_24,
|
|
||||||
R.string.nav_card_adventure
|
|
||||||
)
|
|
||||||
|
|
||||||
object Storage : NavigationItems(
|
|
||||||
"Storage",
|
|
||||||
R.drawable.baseline_catching_pokemon_24,
|
|
||||||
R.string.nav_storage
|
|
||||||
)
|
|
||||||
|
|
||||||
object Settings : NavigationItems(
|
|
||||||
"Settings",
|
|
||||||
R.drawable.baseline_settings_24,
|
|
||||||
R.string.nav_settings
|
|
||||||
)
|
|
||||||
|
|
||||||
object Viewer : NavigationItems(
|
|
||||||
"Viewer",
|
|
||||||
R.drawable.baseline_image_24,
|
|
||||||
R.string.nav_viewer
|
|
||||||
)
|
|
||||||
|
|
||||||
object CardView : NavigationItems(
|
|
||||||
"Card/{cardId}",
|
|
||||||
R.drawable.baseline_image_24,
|
|
||||||
R.string.nav_card
|
|
||||||
)
|
|
||||||
|
|
||||||
object Items : NavigationItems(
|
|
||||||
"Items",
|
|
||||||
R.drawable.baseline_data_24,
|
|
||||||
R.string.nav_items
|
|
||||||
)
|
|
||||||
|
|
||||||
object MyItems : NavigationItems(
|
|
||||||
"MyItems",
|
|
||||||
R.drawable.baseline_data_24,
|
|
||||||
R.string.nav_my_items
|
|
||||||
)
|
|
||||||
|
|
||||||
object ItemsStore : NavigationItems(
|
|
||||||
"ItemsStore",
|
|
||||||
R.drawable.baseline_data_24,
|
|
||||||
R.string.nav_items_store
|
|
||||||
)
|
|
||||||
|
|
||||||
object ApplyItem : NavigationItems(
|
|
||||||
"ApplyItem/{itemId}",
|
|
||||||
R.drawable.baseline_data_24,
|
|
||||||
R.string.nav_apply_item
|
|
||||||
)
|
|
||||||
|
|
||||||
object Adventure : NavigationItems(
|
|
||||||
"Adventure",
|
|
||||||
R.drawable.baseline_fort_24,
|
|
||||||
R.string.nav_adventure
|
|
||||||
)
|
|
||||||
|
|
||||||
object Credits : NavigationItems(
|
|
||||||
"Credits",
|
|
||||||
R.drawable.baseline_data_24,
|
|
||||||
R.string.nav_credits
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
@ -10,16 +10,13 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BattlesScreen() {
|
fun BattlesScreen() {
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.battles_online_title)
|
text = "Online battles"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
@ -30,7 +27,7 @@ fun BattlesScreen() {
|
|||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.battles_coming_soon))
|
Text("Coming soon")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,16 +9,16 @@ import androidx.compose.foundation.lazy.items
|
|||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.produceState
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ObtainedItemDialog
|
import com.github.nacabaro.vbhelper.screens.itemsScreen.ObtainedItemDialog
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
@ -29,25 +29,24 @@ import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
|||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AdventureScreen(
|
fun AdventureScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
storageScreenController: AdventureScreenControllerImpl
|
storageScreenController: AdventureScreenControllerImpl
|
||||||
) {
|
) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val database = application.container.db
|
val database = application.container.db
|
||||||
val storageRepository = StorageRepository(database)
|
val storageRepository = StorageRepository(database)
|
||||||
val characterList by storageRepository.getAdventureCharacters().collectAsState(emptyList())
|
val characterList = remember {
|
||||||
|
mutableStateOf<List<CharacterDtos.AdventureCharacterWithSprites>>(emptyList())
|
||||||
|
}
|
||||||
var obtainedItem by remember {
|
var obtainedItem by remember {
|
||||||
mutableStateOf<ItemDtos.PurchasedItem?>(null)
|
mutableStateOf<ItemDtos.PurchasedItem?>(null)
|
||||||
}
|
}
|
||||||
var obtainedCurrency by remember {
|
|
||||||
mutableStateOf(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
val currentTime by produceState(initialValue = Instant.now().epochSecond) {
|
val currentTime by produceState(initialValue = Instant.now().epochSecond) {
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -60,17 +59,24 @@ fun AdventureScreen(
|
|||||||
mutableStateOf<CharacterDtos.AdventureCharacterWithSprites?>(null)
|
mutableStateOf<CharacterDtos.AdventureCharacterWithSprites?>(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(storageRepository) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
characterList.value = storageRepository
|
||||||
|
.getAdventureCharacters()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.adventure_title),
|
text = "Adventure",
|
||||||
onBackClick = {
|
onBackClick = {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
if (characterList.isEmpty()) {
|
if (characterList.value.isEmpty()) {
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
@ -78,14 +84,14 @@ fun AdventureScreen(
|
|||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.adventure_empty_state))
|
Text(text = "Nothing to see here")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
) {
|
) {
|
||||||
items(characterList) {
|
items(characterList.value) {
|
||||||
AdventureEntry(
|
AdventureEntry(
|
||||||
icon = BitmapData(
|
icon = BitmapData(
|
||||||
bitmap = it.spriteIdle,
|
bitmap = it.spriteIdle,
|
||||||
@ -96,9 +102,8 @@ fun AdventureScreen(
|
|||||||
onClick = {
|
onClick = {
|
||||||
if (it.finishesAdventure < currentTime) {
|
if (it.finishesAdventure < currentTime) {
|
||||||
storageScreenController
|
storageScreenController
|
||||||
.getItemFromAdventure(it.id) { adventureResult, generatedCurrency ->
|
.getItemFromAdventure(it.id) { adventureResult ->
|
||||||
obtainedItem = adventureResult
|
obtainedItem = adventureResult
|
||||||
obtainedCurrency = generatedCurrency
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cancelAdventureDialog = it
|
cancelAdventureDialog = it
|
||||||
@ -113,7 +118,6 @@ fun AdventureScreen(
|
|||||||
if (obtainedItem != null) {
|
if (obtainedItem != null) {
|
||||||
ObtainedItemDialog(
|
ObtainedItemDialog(
|
||||||
obtainedItem = obtainedItem!!,
|
obtainedItem = obtainedItem!!,
|
||||||
obtainedCurrency = obtainedCurrency,
|
|
||||||
onClickDismiss = {
|
onClickDismiss = {
|
||||||
obtainedItem = null
|
obtainedItem = null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,6 @@ import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
|||||||
|
|
||||||
interface AdventureScreenController {
|
interface AdventureScreenController {
|
||||||
fun sendCharacterToAdventure(characterId: Long, timeInMinutes: Long)
|
fun sendCharacterToAdventure(characterId: Long, timeInMinutes: Long)
|
||||||
fun getItemFromAdventure(characterId: Long, onResult: (ItemDtos.PurchasedItem, Int) -> Unit)
|
fun getItemFromAdventure(characterId: Long, onResult: (ItemDtos.PurchasedItem) -> Unit)
|
||||||
fun cancelAdventure(characterId: Long, onResult: () -> Unit)
|
fun cancelAdventure(characterId: Long, onResult: () -> Unit)
|
||||||
}
|
}
|
||||||
@ -6,7 +6,6 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -38,29 +37,19 @@ class AdventureScreenControllerImpl(
|
|||||||
|
|
||||||
override fun getItemFromAdventure(
|
override fun getItemFromAdventure(
|
||||||
characterId: Long,
|
characterId: Long,
|
||||||
onResult: (ItemDtos.PurchasedItem, Int) -> Unit
|
onResult: (ItemDtos.PurchasedItem) -> Unit
|
||||||
) {
|
) {
|
||||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
database
|
database
|
||||||
.adventureDao()
|
.adventureDao()
|
||||||
.deleteAdventure(characterId)
|
.deleteAdventure(characterId)
|
||||||
|
|
||||||
val generatedCurrency = generateRandomCurrency()
|
|
||||||
|
|
||||||
val generatedItem = generateItem(characterId)
|
val generatedItem = generateItem(characterId)
|
||||||
|
|
||||||
onResult(generatedItem, generatedCurrency)
|
onResult(generatedItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun generateRandomCurrency(): Int {
|
|
||||||
val currentValue = application.container.currencyRepository.currencyValue.first()
|
|
||||||
val random = (2..6).random() * 1000
|
|
||||||
application.container.currencyRepository.setCurrencyValue(currentValue + random)
|
|
||||||
|
|
||||||
return random
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun cancelAdventure(characterId: Long, onResult: () -> Unit) {
|
override fun cancelAdventure(characterId: Long, onResult: () -> Unit) {
|
||||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
database
|
database
|
||||||
@ -88,7 +77,6 @@ class AdventureScreenControllerImpl(
|
|||||||
val randomItem = database
|
val randomItem = database
|
||||||
.itemDao()
|
.itemDao()
|
||||||
.getAllItems()
|
.getAllItems()
|
||||||
.first()
|
|
||||||
.random()
|
.random()
|
||||||
|
|
||||||
val random = ((Random.nextFloat() * character.stage) + 3).roundToInt()
|
val random = ((Random.nextFloat() * character.stage) + 3).roundToInt()
|
||||||
|
|||||||
@ -1,122 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
|
||||||
|
|
||||||
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.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 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 com.github.nacabaro.vbhelper.dtos.CardDtos
|
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
|
||||||
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun CardAdventureEntry(
|
|
||||||
cardAdventureEntry: CardDtos.CardAdventureWithSprites,
|
|
||||||
obscure: Boolean
|
|
||||||
) {
|
|
||||||
val charaImageBitmapData = BitmapData(
|
|
||||||
bitmap = cardAdventureEntry.characterIdleSprite,
|
|
||||||
width = cardAdventureEntry.characterIdleSpriteWidth,
|
|
||||||
height = cardAdventureEntry.characterIdleSpriteHeight
|
|
||||||
).getImageBitmap(
|
|
||||||
context = LocalContext.current,
|
|
||||||
multiplier = 4,
|
|
||||||
obscure = obscure
|
|
||||||
)
|
|
||||||
|
|
||||||
val nameImageBitmapData = BitmapData(
|
|
||||||
bitmap = cardAdventureEntry.characterName,
|
|
||||||
width = cardAdventureEntry.characterNameWidth,
|
|
||||||
height = cardAdventureEntry.characterNameHeight
|
|
||||||
).getImageBitmap(
|
|
||||||
context = LocalContext.current,
|
|
||||||
multiplier = 3,
|
|
||||||
obscure = obscure
|
|
||||||
)
|
|
||||||
|
|
||||||
Card (
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
Row (
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
){
|
|
||||||
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(8.dp))
|
|
||||||
|
|
||||||
Column {
|
|
||||||
if (!obscure) {
|
|
||||||
Image(
|
|
||||||
bitmap = nameImageBitmapData.imageBitmap,
|
|
||||||
contentDescription = "Icon",
|
|
||||||
modifier = Modifier
|
|
||||||
.width(nameImageBitmapData.dpWidth)
|
|
||||||
.height(nameImageBitmapData.dpHeight),
|
|
||||||
filterQuality = FilterQuality.None
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.padding(4.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "HP: ${cardAdventureEntry.characterHp}, DP: ${cardAdventureEntry.characterDp}, AP: ${cardAdventureEntry.characterAp}"
|
|
||||||
)
|
|
||||||
if (cardAdventureEntry.characterBp != null) {
|
|
||||||
Text(text = "BP: ${cardAdventureEntry.characterBp}")
|
|
||||||
}
|
|
||||||
Text(text = "Steps: ${cardAdventureEntry.steps}")
|
|
||||||
} else {
|
|
||||||
Text(text = "????????????????")
|
|
||||||
Text(
|
|
||||||
text = "HP: -, BP: -, AP: -"
|
|
||||||
)
|
|
||||||
if (cardAdventureEntry.characterBp != null) {
|
|
||||||
Text(text = "DP: -")
|
|
||||||
}
|
|
||||||
Text(text = "Steps: -")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun CardAdventureScreen(
|
|
||||||
navController: NavController,
|
|
||||||
cardScreenController: CardScreenControllerImpl,
|
|
||||||
cardId: Long
|
|
||||||
) {
|
|
||||||
val cardAdventureMissions by cardScreenController
|
|
||||||
.getCardAdventureMissions(cardId)
|
|
||||||
.collectAsState(emptyList())
|
|
||||||
val currentCardAdventure by cardScreenController
|
|
||||||
.getCardProgress(cardId)
|
|
||||||
.collectAsState(0)
|
|
||||||
|
|
||||||
Scaffold (
|
|
||||||
topBar = {
|
|
||||||
TopBanner(
|
|
||||||
text = stringResource(R.string.card_adventure_missions_title),
|
|
||||||
onBackClick = {
|
|
||||||
navController.popBackStack()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { contentPadding ->
|
|
||||||
Column (
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
|
||||||
.verticalScroll(state = rememberScrollState())
|
|
||||||
) {
|
|
||||||
cardAdventureMissions.mapIndexed { index, it ->
|
|
||||||
CardAdventureEntry(
|
|
||||||
cardAdventureEntry = it,
|
|
||||||
obscure = index > currentCardAdventure - 1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -24,9 +24,6 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import com.github.nacabaro.vbhelper.utils.getBitmap
|
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CardEntry(
|
fun CardEntry(
|
||||||
@ -78,11 +75,7 @@ fun CardEntry(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(
|
text = "$obtainedCharacters of $totalCharacters characters obtained",
|
||||||
R.string.card_entry_characters_obtained,
|
|
||||||
obtainedCharacters,
|
|
||||||
totalCharacters
|
|
||||||
),
|
|
||||||
fontFamily = MaterialTheme.typography.labelSmall.fontFamily,
|
fontFamily = MaterialTheme.typography.labelSmall.fontFamily,
|
||||||
fontSize = MaterialTheme.typography.labelSmall.fontSize,
|
fontSize = MaterialTheme.typography.labelSmall.fontSize,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -98,7 +91,7 @@ fun CardEntry(
|
|||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Edit,
|
imageVector = Icons.Default.Edit,
|
||||||
contentDescription = stringResource(R.string.card_entry_edit)
|
contentDescription = "Edit"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(
|
IconButton(
|
||||||
@ -106,7 +99,7 @@ fun CardEntry(
|
|||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Delete,
|
imageVector = Icons.Default.Delete,
|
||||||
contentDescription = stringResource(R.string.card_entry_delete)
|
contentDescription = "Delete"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,6 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
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 {
|
interface CardScreenController {
|
||||||
fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit)
|
fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit)
|
||||||
fun deleteCard(cardId: Long, onDeleted: () -> Unit)
|
fun deleteCard(cardId: Long, onDeleted: () -> Unit)
|
||||||
fun getCardAdventureMissions(cardId: Long): Flow<List<CardDtos.CardAdventureWithSprites>>
|
|
||||||
fun getCardProgress(cardId: Long): Flow<Int>
|
|
||||||
fun getFusionsForCharacters(characterId: Long): Flow<List<CharacterDtos.FusionsWithSpritesAndObtained>>
|
|
||||||
}
|
}
|
||||||
@ -3,9 +3,6 @@ package com.github.nacabaro.vbhelper.screens.cardScreen
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
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
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class CardScreenControllerImpl(
|
class CardScreenControllerImpl(
|
||||||
@ -14,6 +11,7 @@ class CardScreenControllerImpl(
|
|||||||
private val application = componentActivity.applicationContext as VBHelper
|
private val application = componentActivity.applicationContext as VBHelper
|
||||||
private val database = application.container.db
|
private val database = application.container.db
|
||||||
|
|
||||||
|
|
||||||
override fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit) {
|
override fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit) {
|
||||||
componentActivity.lifecycleScope.launch {
|
componentActivity.lifecycleScope.launch {
|
||||||
database
|
database
|
||||||
@ -33,23 +31,4 @@ class CardScreenControllerImpl(
|
|||||||
onDeleted()
|
onDeleted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCardAdventureMissions(cardId: Long): Flow<List<CardDtos.CardAdventureWithSprites>> {
|
|
||||||
return database
|
|
||||||
.cardAdventureDao()
|
|
||||||
.getAdventureForCard(cardId)
|
|
||||||
}
|
|
||||||
|
|
||||||
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,53 +5,51 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
|||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
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.screens.cardScreen.dialogs.DexCharaDetailsDialog
|
||||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
import com.github.nacabaro.vbhelper.source.DexRepository
|
||||||
import com.github.nacabaro.vbhelper.R
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CardViewScreen(
|
fun CardViewScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
cardId: Long
|
dimId: Long
|
||||||
) {
|
) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val dexRepository = DexRepository(application.container.db)
|
val dexRepository = DexRepository(application.container.db)
|
||||||
|
|
||||||
val characterList by dexRepository.getCharactersByCardId(cardId).collectAsState(emptyList())
|
val characterList = remember { mutableStateOf<List<CharacterDtos.CardCharaProgress>>(emptyList()) }
|
||||||
|
val cardPossibleTransformations = remember { mutableStateOf<List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>>(emptyList()) }
|
||||||
|
|
||||||
val selectedCharacter = remember { mutableStateOf<CharacterDtos.CardCharaProgress?>(null) }
|
val selectedCharacter = remember { mutableStateOf<CharacterDtos.CardCharaProgress?>(null) }
|
||||||
|
|
||||||
|
LaunchedEffect(dexRepository) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
val newCharacterList = dexRepository.getCharactersByCardId(dimId)
|
||||||
|
characterList.value = newCharacterList
|
||||||
|
|
||||||
|
val newCardPossibleTransformations = dexRepository.getCardPossibleTransformations(dimId)
|
||||||
|
cardPossibleTransformations.value = newCardPossibleTransformations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.card_view_discovered_characters),
|
text = "Discovered characters",
|
||||||
onBackClick = {
|
onBackClick = {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
},
|
|
||||||
onAdventureClick = {
|
|
||||||
navController
|
|
||||||
.navigate(route = NavigationItems
|
|
||||||
.CardAdventure
|
|
||||||
.route
|
|
||||||
.replace(
|
|
||||||
"{cardId}",
|
|
||||||
cardId.toString()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -60,7 +58,7 @@ fun CardViewScreen(
|
|||||||
columns = GridCells.Fixed(3),
|
columns = GridCells.Fixed(3),
|
||||||
contentPadding = contentPadding
|
contentPadding = contentPadding
|
||||||
) {
|
) {
|
||||||
items(characterList) { character ->
|
items(characterList.value) { character ->
|
||||||
CharacterEntry(
|
CharacterEntry(
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedCharacter.value = character
|
selectedCharacter.value = character
|
||||||
@ -78,6 +76,7 @@ fun CardViewScreen(
|
|||||||
if (selectedCharacter.value != null) {
|
if (selectedCharacter.value != null) {
|
||||||
DexCharaDetailsDialog(
|
DexCharaDetailsDialog(
|
||||||
currentChara = selectedCharacter.value!!,
|
currentChara = selectedCharacter.value!!,
|
||||||
|
possibleTransformations = cardPossibleTransformations.value,
|
||||||
obscure = selectedCharacter.value!!.discoveredOn == null,
|
obscure = selectedCharacter.value!!.discoveredOn == null,
|
||||||
onClickClose = {
|
onClickClose = {
|
||||||
selectedCharacter.value = null
|
selectedCharacter.value = null
|
||||||
|
|||||||
@ -7,10 +7,11 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
@ -24,17 +25,17 @@ import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
|||||||
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardDeleteDialog
|
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardDeleteDialog
|
||||||
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardRenameDialog
|
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardRenameDialog
|
||||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
import com.github.nacabaro.vbhelper.source.DexRepository
|
||||||
import androidx.compose.ui.res.stringResource
|
import kotlinx.coroutines.launch
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CardsScreen(
|
fun CardsScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
cardScreenController: CardScreenControllerImpl
|
cardScreenController: CardScreenControllerImpl
|
||||||
) {
|
) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val dexRepository = DexRepository(application.container.db)
|
val dexRepository = DexRepository(application.container.db)
|
||||||
val cardList by dexRepository.getAllDims().collectAsState(emptyList())
|
val cardList = remember { mutableStateOf<List<CardDtos.CardProgress>>(emptyList()) }
|
||||||
|
|
||||||
val selectedCard = remember { mutableStateOf<CardDtos.CardProgress?>(null) }
|
val selectedCard = remember { mutableStateOf<CardDtos.CardProgress?>(null) }
|
||||||
var clickedDelete by remember { mutableStateOf(false) }
|
var clickedDelete by remember { mutableStateOf(false) }
|
||||||
@ -42,10 +43,17 @@ fun CardsScreen(
|
|||||||
|
|
||||||
var modifyCards by remember { mutableStateOf(false) }
|
var modifyCards by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
LaunchedEffect(dexRepository) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
val newDimList = dexRepository.getAllDims()
|
||||||
|
cardList.value = newDimList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.cards_my_cards_title),
|
text = "My cards",
|
||||||
onModifyClick = {
|
onModifyClick = {
|
||||||
modifyCards = !modifyCards
|
modifyCards = !modifyCards
|
||||||
}
|
}
|
||||||
@ -56,7 +64,7 @@ fun CardsScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
) {
|
) {
|
||||||
items(cardList) {
|
items(cardList.value) {
|
||||||
CardEntry(
|
CardEntry(
|
||||||
name = it.cardName,
|
name = it.cardName,
|
||||||
logo = BitmapData(
|
logo = BitmapData(
|
||||||
|
|||||||
@ -16,11 +16,6 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.contentColorFor
|
import androidx.compose.material3.contentColorFor
|
||||||
import androidx.compose.runtime.Composable
|
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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
@ -28,36 +23,22 @@ import androidx.compose.ui.graphics.FilterQuality
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
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.dtos.CharacterDtos
|
||||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DexCharaDetailsDialog(
|
fun DexCharaDetailsDialog(
|
||||||
currentChara: CharacterDtos.CardCharaProgress,
|
currentChara: CharacterDtos.CardCharaProgress,
|
||||||
|
possibleTransformations: List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>,
|
||||||
obscure: Boolean,
|
obscure: Boolean,
|
||||||
onClickClose: () -> Unit
|
onClickClose: () -> Unit
|
||||||
) {
|
) {
|
||||||
val nameMultiplier = 3
|
val nameMultiplier = 3
|
||||||
val charaMultiplier = 4
|
val charaMultiplier = 4
|
||||||
|
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val currentCharaPossibleTransformations = possibleTransformations.filter { it.fromCharaId == currentChara.id }
|
||||||
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) {
|
val romanNumeralsStage = when (currentChara.stage) {
|
||||||
1 -> "II"
|
1 -> "II"
|
||||||
@ -120,7 +101,7 @@ fun DexCharaDetailsDialog(
|
|||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
bitmap = charaImageBitmapData.imageBitmap,
|
bitmap = charaImageBitmapData.imageBitmap,
|
||||||
contentDescription = stringResource(R.string.dex_chara_icon_description),
|
contentDescription = "Icon",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(charaImageBitmapData.dpWidth)
|
.size(charaImageBitmapData.dpWidth)
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
@ -139,7 +120,7 @@ fun DexCharaDetailsDialog(
|
|||||||
Column {
|
Column {
|
||||||
Image(
|
Image(
|
||||||
bitmap = nameImageBitmapData.imageBitmap,
|
bitmap = nameImageBitmapData.imageBitmap,
|
||||||
contentDescription = stringResource(R.string.dex_chara_name_icon_description),
|
contentDescription = "Icon",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(nameImageBitmapData.dpWidth)
|
.width(nameImageBitmapData.dpWidth)
|
||||||
.height(nameImageBitmapData.dpHeight),
|
.height(nameImageBitmapData.dpHeight),
|
||||||
@ -148,28 +129,17 @@ fun DexCharaDetailsDialog(
|
|||||||
Spacer(modifier = Modifier.padding(4.dp))
|
Spacer(modifier = Modifier.padding(4.dp))
|
||||||
if (currentChara.baseHp != 65535) {
|
if (currentChara.baseHp != 65535) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(
|
text = "HP: ${currentChara.baseHp}, BP: ${currentChara.baseBp}, AP: ${currentChara.baseAp}"
|
||||||
R.string.dex_chara_stats,
|
|
||||||
currentChara.baseHp,
|
|
||||||
currentChara.baseBp,
|
|
||||||
currentChara.baseAp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = stringResource(
|
|
||||||
R.string.dex_chara_stage_attribute,
|
|
||||||
romanNumeralsStage,
|
|
||||||
currentChara.attribute.toString().substring(0, 2)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
Text(text = "Stg: ${romanNumeralsStage}, Atr: ${currentChara.attribute.toString().substring(0, 2)}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Column {
|
Column {
|
||||||
Text(stringResource(R.string.dex_chara_unknown_name))
|
Text(text = "????????????????")
|
||||||
Spacer(modifier = Modifier.padding(4.dp))
|
Spacer(modifier = Modifier.padding(4.dp))
|
||||||
Text(stringResource(R.string.dex_chara_stage_attribute_unknown))
|
Text(text = "Stg: -, Atr: -")
|
||||||
Text(stringResource(R.string.dex_chara_stats_unknown))
|
Text(text = "HP: -, BP: -, AP: -")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +180,7 @@ fun DexCharaDetailsDialog(
|
|||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
bitmap = selectedCharaImageBitmap.imageBitmap,
|
bitmap = selectedCharaImageBitmap.imageBitmap,
|
||||||
contentDescription = stringResource(R.string.dex_chara_icon_description),
|
contentDescription = "Icon",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(selectedCharaImageBitmap.dpWidth)
|
.size(selectedCharaImageBitmap.dpWidth)
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
@ -226,62 +196,20 @@ fun DexCharaDetailsDialog(
|
|||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
)
|
)
|
||||||
Column {
|
Column {
|
||||||
Text(
|
Text("Tr: ${it.requiredTrophies}; Bt: ${it.requiredBattles}; Vr: ${it.requiredVitals}; Wr: ${it.requiredWinRate}%; Ct: ${it.changeTimerHours}h")
|
||||||
text = stringResource(
|
Text("AdvLvl ${it.requiredAdventureLevelCompleted + 1}")
|
||||||
R.string.dex_chara_requirements,
|
|
||||||
it.requiredTrophies,
|
|
||||||
it.requiredBattles,
|
|
||||||
it.requiredVitals,
|
|
||||||
it.requiredWinRate,
|
|
||||||
it.changeTimerHours
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = stringResource(
|
|
||||||
R.string.dex_chara_adventure_level,
|
|
||||||
it.requiredAdventureLevelCompleted + 1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
|
||||||
if (currentCharaPossibleFusions.isNotEmpty()) {
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
showFusions = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.dex_chara_fusions_button))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = onClickClose
|
onClick = onClickClose
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.dex_chara_close_button))
|
Text("Close")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showFusions) {
|
|
||||||
DexCharaFusionsDialog(
|
|
||||||
currentChara = currentChara,
|
|
||||||
currentCharaPossibleFusions = currentCharaPossibleFusions,
|
|
||||||
onClickDismiss = {
|
|
||||||
showFusions = false
|
|
||||||
},
|
|
||||||
obscure = obscure
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -8,10 +8,8 @@ import androidx.compose.material3.Card
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BetaWarning(
|
fun BetaWarning(
|
||||||
@ -26,21 +24,21 @@ fun BetaWarning(
|
|||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.beta_warning_message_main)
|
text = "This application is currently in alpha and it is not complete. Do not use to store important characters for you, as any future updates might delete all your characters. Sorry for the inconvenience!"
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.padding(8.dp))
|
Spacer(modifier = Modifier.padding(8.dp))
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.beta_warning_message_compatibility)
|
text = "Application should work now with the original VB and the VH."
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.padding(8.dp))
|
Spacer(modifier = Modifier.padding(8.dp))
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.beta_warning_message_thanks)
|
text = "Thank you for your understanding and patience. Sincerely, the dev team."
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.padding(8.dp))
|
Spacer(modifier = Modifier.padding(8.dp))
|
||||||
Button(
|
Button(
|
||||||
onClick = onDismissRequest
|
onClick = onDismissRequest
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.beta_warning_button_dismiss))
|
Text(text = "Dismiss")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@ -11,7 +12,6 @@ import androidx.compose.material3.Scaffold
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -20,7 +20,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
@ -29,7 +28,9 @@ import com.github.nacabaro.vbhelper.components.TopBanner
|
|||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||||
|
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||||
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.screens.homeScreens.screens.BEBEmHomeScreen
|
import com.github.nacabaro.vbhelper.screens.homeScreens.screens.BEBEmHomeScreen
|
||||||
@ -37,12 +38,8 @@ import com.github.nacabaro.vbhelper.screens.homeScreens.screens.BEDiMHomeScreen
|
|||||||
import com.github.nacabaro.vbhelper.screens.homeScreens.screens.VBDiMHomeScreen
|
import com.github.nacabaro.vbhelper.screens.homeScreens.screens.VBDiMHomeScreen
|
||||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ObtainedItemDialog
|
import com.github.nacabaro.vbhelper.screens.itemsScreen.ObtainedItemDialog
|
||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||||
import com.github.nacabaro.vbhelper.R
|
import kotlinx.coroutines.Dispatchers
|
||||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
import kotlinx.coroutines.withContext
|
||||||
import com.github.nacabaro.vbhelper.source.CardRepository
|
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
|
||||||
import kotlinx.coroutines.flow.flowOf
|
|
||||||
import kotlin.collections.emptyList
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(
|
fun HomeScreen(
|
||||||
@ -51,59 +48,28 @@ fun HomeScreen(
|
|||||||
) {
|
) {
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val storageRepository = StorageRepository(application.container.db)
|
val storageRepository = StorageRepository(application.container.db)
|
||||||
val cardRepository = CardRepository(application.container.db)
|
val activeMon = remember { mutableStateOf<CharacterDtos.CharacterWithSprites?>(null) }
|
||||||
|
val transformationHistory = remember { mutableStateOf<List<CharacterDtos.TransformationHistory>?>(null) }
|
||||||
val activeMon by storageRepository
|
val beData = remember { mutableStateOf<BECharacterData?>(null) }
|
||||||
.getActiveCharacter()
|
val vbData = remember { mutableStateOf<VBCharacterData?>(null) }
|
||||||
.collectAsState(initial = null)
|
val vbSpecialMissions = remember { mutableStateOf<List<SpecialMissions>>(emptyList()) }
|
||||||
|
|
||||||
val cardIconData by (
|
|
||||||
activeMon
|
|
||||||
?.let { chara ->
|
|
||||||
cardRepository.getCardIconByCharaId(chara.charId)
|
|
||||||
}
|
|
||||||
?: flowOf<CardDtos.CardIcon?>(null)
|
|
||||||
).collectAsState(initial = null)
|
|
||||||
|
|
||||||
val transformationHistory by (
|
|
||||||
activeMon
|
|
||||||
?.let { chara ->
|
|
||||||
storageRepository.getTransformationHistory(chara.id)
|
|
||||||
}
|
|
||||||
?: flowOf(emptyList())
|
|
||||||
).collectAsState(initial = emptyList())
|
|
||||||
|
|
||||||
val vbSpecialMissions by (
|
|
||||||
activeMon
|
|
||||||
?.takeIf { it.characterType == DeviceType.VBDevice }
|
|
||||||
?.let { chara ->
|
|
||||||
storageRepository.getSpecialMissions(chara.id)
|
|
||||||
}
|
|
||||||
?: flowOf(emptyList())
|
|
||||||
).collectAsState(initial = emptyList())
|
|
||||||
|
|
||||||
val vbData by (
|
|
||||||
activeMon
|
|
||||||
?.takeIf { it.characterType == DeviceType.VBDevice }
|
|
||||||
?.let { chara ->
|
|
||||||
storageRepository.getCharacterVbData(chara.id)
|
|
||||||
}
|
|
||||||
?: flowOf<VBCharacterData?>(null)
|
|
||||||
).collectAsState(initial = null)
|
|
||||||
|
|
||||||
val beData by (
|
|
||||||
activeMon
|
|
||||||
?.takeIf { it.characterType == DeviceType.BEDevice }
|
|
||||||
?.let { chara ->
|
|
||||||
storageRepository.getCharacterBeData(chara.id)
|
|
||||||
}
|
|
||||||
?: flowOf<BECharacterData?>(null)
|
|
||||||
).collectAsState(initial = null)
|
|
||||||
|
|
||||||
var adventureMissionsFinished by rememberSaveable { mutableStateOf(false) }
|
var adventureMissionsFinished by rememberSaveable { mutableStateOf(false) }
|
||||||
var betaWarning by rememberSaveable { mutableStateOf(true) }
|
var betaWarning by rememberSaveable { mutableStateOf(true) }
|
||||||
var collectedItem by remember { mutableStateOf<ItemDtos.PurchasedItem?>(null) }
|
var collectedItem by remember { mutableStateOf<ItemDtos.PurchasedItem?>(null) }
|
||||||
var collectedCurrency by remember { mutableStateOf<Int?>(null) }
|
|
||||||
|
LaunchedEffect(storageRepository, activeMon, collectedItem) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
activeMon.value = storageRepository.getActiveCharacter()
|
||||||
|
if (activeMon.value != null && activeMon.value!!.characterType == DeviceType.BEDevice) {
|
||||||
|
beData.value = storageRepository.getCharacterBeData(activeMon.value!!.id)
|
||||||
|
transformationHistory.value = storageRepository.getTransformationHistory(activeMon.value!!.id)
|
||||||
|
} else if (activeMon.value != null && activeMon.value!!.characterType == DeviceType.VBDevice) {
|
||||||
|
vbData.value = storageRepository.getCharacterVbData(activeMon.value!!.id)
|
||||||
|
vbSpecialMissions.value = storageRepository.getSpecialMissions(activeMon.value!!.id)
|
||||||
|
transformationHistory.value = storageRepository.getTransformationHistory(activeMon.value!!.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(true) {
|
LaunchedEffect(true) {
|
||||||
homeScreenController
|
homeScreenController
|
||||||
@ -115,7 +81,7 @@ fun HomeScreen(
|
|||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.home_title),
|
text = "VB Helper",
|
||||||
onScanClick = {
|
onScanClick = {
|
||||||
navController.navigate(NavigationItems.Scan.route)
|
navController.navigate(NavigationItems.Scan.route)
|
||||||
},
|
},
|
||||||
@ -125,7 +91,8 @@ fun HomeScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
if (activeMon == null || (beData == null && vbData == null) || cardIconData == null || transformationHistory.isEmpty()) {
|
if (activeMon.value == null || (beData.value == null && vbData.value == null) || transformationHistory.value == null) {
|
||||||
|
Log.d("TetTet", "Something is null")
|
||||||
Column (
|
Column (
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
@ -133,44 +100,35 @@ fun HomeScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.adventure_empty_state))
|
Text(text = "Nothing to see here")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val cardIcon = BitmapData(
|
Log.d("TetTet", "Something is not null")
|
||||||
bitmap = cardIconData!!.cardIcon,
|
if (activeMon.value!!.isBemCard) {
|
||||||
width = cardIconData!!.cardIconWidth,
|
|
||||||
height = cardIconData!!.cardIconHeight
|
|
||||||
)
|
|
||||||
|
|
||||||
if (activeMon!!.isBemCard && beData != null) {
|
|
||||||
BEBEmHomeScreen(
|
BEBEmHomeScreen(
|
||||||
activeMon = activeMon!!,
|
activeMon = activeMon.value!!,
|
||||||
beData = beData!!,
|
beData = beData.value!!,
|
||||||
transformationHistory = transformationHistory,
|
transformationHistory = transformationHistory.value!!,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding
|
||||||
cardIcon = cardIcon
|
|
||||||
)
|
)
|
||||||
} else if (!activeMon!!.isBemCard && activeMon!!.characterType == DeviceType.BEDevice && beData != null) {
|
} else if (!activeMon.value!!.isBemCard && activeMon.value!!.characterType == DeviceType.BEDevice) {
|
||||||
BEDiMHomeScreen(
|
BEDiMHomeScreen(
|
||||||
activeMon = activeMon!!,
|
activeMon = activeMon.value!!,
|
||||||
beData = beData!!,
|
beData = beData.value!!,
|
||||||
transformationHistory = transformationHistory,
|
transformationHistory = transformationHistory.value!!,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding
|
||||||
cardIcon = cardIcon
|
|
||||||
)
|
)
|
||||||
} else if (vbData != null) {
|
} else {
|
||||||
VBDiMHomeScreen(
|
VBDiMHomeScreen(
|
||||||
activeMon = activeMon!!,
|
activeMon = activeMon.value!!,
|
||||||
vbData = vbData!!,
|
vbData = vbData.value!!,
|
||||||
transformationHistory = transformationHistory,
|
transformationHistory = transformationHistory.value!!,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
specialMissions = vbSpecialMissions,
|
specialMissions = vbSpecialMissions.value,
|
||||||
homeScreenController = homeScreenController,
|
homeScreenController = homeScreenController,
|
||||||
onClickCollect = { item, currency ->
|
onClickCollect = { item ->
|
||||||
collectedItem = item
|
collectedItem = item
|
||||||
collectedCurrency = currency
|
}
|
||||||
},
|
|
||||||
cardIcon = cardIcon
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,10 +137,8 @@ fun HomeScreen(
|
|||||||
if (collectedItem != null) {
|
if (collectedItem != null) {
|
||||||
ObtainedItemDialog(
|
ObtainedItemDialog(
|
||||||
obtainedItem = collectedItem!!,
|
obtainedItem = collectedItem!!,
|
||||||
obtainedCurrency = collectedCurrency!!,
|
|
||||||
onClickDismiss = {
|
onClickDismiss = {
|
||||||
collectedItem = null
|
collectedItem = null
|
||||||
collectedCurrency = null
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -197,7 +153,7 @@ fun HomeScreen(
|
|||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.home_adventure_mission_finished),
|
text = "One of your characters has finished their adventure mission!",
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
Button(
|
Button(
|
||||||
@ -208,7 +164,7 @@ fun HomeScreen(
|
|||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.beta_warning_button_dismiss))
|
Text(text = "Dismiss")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||||
|
|
||||||
|
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
|
|
||||||
interface HomeScreenController {
|
interface HomeScreenController {
|
||||||
fun didAdventureMissionsFinish(onCompletion: (Boolean) -> Unit)
|
fun didAdventureMissionsFinish(onCompletion: (Boolean) -> Unit)
|
||||||
fun clearSpecialMission(missionId: Long, onCleared: (ItemDtos.PurchasedItem?, Int?) -> Unit)
|
fun clearSpecialMission(missionId: Long, missionCompletion: SpecialMission.Status, onCleared: (ItemDtos.PurchasedItem?) -> Unit)
|
||||||
}
|
}
|
||||||
@ -5,7 +5,6 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -23,7 +22,6 @@ class HomeScreenControllerImpl(
|
|||||||
val adventureCharacters = database
|
val adventureCharacters = database
|
||||||
.adventureDao()
|
.adventureDao()
|
||||||
.getAdventureCharacters()
|
.getAdventureCharacters()
|
||||||
.first()
|
|
||||||
|
|
||||||
val finishedAdventureCharacters = adventureCharacters.filter { character ->
|
val finishedAdventureCharacters = adventureCharacters.filter { character ->
|
||||||
character.finishesAdventure <= currentTime
|
character.finishesAdventure <= currentTime
|
||||||
@ -33,22 +31,16 @@ class HomeScreenControllerImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearSpecialMission(missionId: Long, onCleared: (ItemDtos.PurchasedItem?, Int?) -> Unit) {
|
override fun clearSpecialMission(missionId: Long, missionCompletion: SpecialMission.Status, onCleared: (ItemDtos.PurchasedItem?) -> Unit) {
|
||||||
componentActivity.lifecycleScope.launch {
|
componentActivity.lifecycleScope.launch {
|
||||||
val missionStatus = database
|
|
||||||
.specialMissionDao()
|
|
||||||
.getSpecialMission(missionId)
|
|
||||||
.first()
|
|
||||||
|
|
||||||
database
|
database
|
||||||
.specialMissionDao()
|
.specialMissionDao()
|
||||||
.clearSpecialMission(missionId)
|
.clearSpecialMission(missionId)
|
||||||
|
|
||||||
if (missionStatus.status == SpecialMission.Status.COMPLETED) {
|
if (missionCompletion == SpecialMission.Status.COMPLETED) {
|
||||||
val randomItem = database
|
val randomItem = database
|
||||||
.itemDao()
|
.itemDao()
|
||||||
.getAllItems()
|
.getAllItems()
|
||||||
.first()
|
|
||||||
.random()
|
.random()
|
||||||
|
|
||||||
val randomItemAmount = (Random.nextFloat() * 5).roundToInt()
|
val randomItemAmount = (Random.nextFloat() * 5).roundToInt()
|
||||||
@ -70,14 +62,11 @@ class HomeScreenControllerImpl(
|
|||||||
itemType = randomItem.itemType
|
itemType = randomItem.itemType
|
||||||
)
|
)
|
||||||
|
|
||||||
val randomAmount = (2..6).random() * 1000
|
onCleared(purchasedItem)
|
||||||
val currentCurrency = application.container.currencyRepository.currencyValue.first()
|
|
||||||
application.container.currencyRepository.setCurrencyValue(currentCurrency + randomAmount)
|
|
||||||
|
|
||||||
onCleared(purchasedItem, randomAmount)
|
|
||||||
} else {
|
} else {
|
||||||
onCleared(null, null)
|
onCleared(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,56 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.homeScreens.dialogs
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.window.Dialog
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun DeleteSpecialMissionDialog(
|
|
||||||
onClickDismiss: () -> Unit,
|
|
||||||
onClickDelete: () -> Unit
|
|
||||||
) {
|
|
||||||
Dialog(
|
|
||||||
onDismissRequest = onClickDismiss
|
|
||||||
) {
|
|
||||||
Card {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(16.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.home_special_mission_delete_main),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.padding(8.dp))
|
|
||||||
Row {
|
|
||||||
Button(
|
|
||||||
onClick = onClickDismiss,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
Text(text = stringResource(R.string.home_special_mission_delete_dismiss))
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = onClickDelete,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
Text(text = stringResource(R.string.home_special_mission_delete_remove))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -26,7 +26,6 @@ import java.util.Locale
|
|||||||
fun BEBEmHomeScreen(
|
fun BEBEmHomeScreen(
|
||||||
activeMon: CharacterDtos.CharacterWithSprites,
|
activeMon: CharacterDtos.CharacterWithSprites,
|
||||||
beData: BECharacterData,
|
beData: BECharacterData,
|
||||||
cardIcon: BitmapData,
|
|
||||||
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
||||||
contentPadding: PaddingValues
|
contentPadding: PaddingValues
|
||||||
) {
|
) {
|
||||||
@ -47,7 +46,6 @@ fun BEBEmHomeScreen(
|
|||||||
),
|
),
|
||||||
multiplier = 8,
|
multiplier = 8,
|
||||||
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
||||||
cardIcon = cardIcon,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
|
|||||||
@ -26,7 +26,6 @@ import kotlin.text.format
|
|||||||
@Composable
|
@Composable
|
||||||
fun BEDiMHomeScreen(
|
fun BEDiMHomeScreen(
|
||||||
activeMon: CharacterDtos.CharacterWithSprites,
|
activeMon: CharacterDtos.CharacterWithSprites,
|
||||||
cardIcon: BitmapData,
|
|
||||||
beData: BECharacterData,
|
beData: BECharacterData,
|
||||||
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
||||||
contentPadding: PaddingValues
|
contentPadding: PaddingValues
|
||||||
@ -46,7 +45,6 @@ fun BEDiMHomeScreen(
|
|||||||
width = activeMon.spriteWidth,
|
width = activeMon.spriteWidth,
|
||||||
height = activeMon.spriteHeight
|
height = activeMon.spriteHeight
|
||||||
),
|
),
|
||||||
cardIcon = cardIcon,
|
|
||||||
multiplier = 8,
|
multiplier = 8,
|
||||||
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@ -10,10 +10,6 @@ import androidx.compose.foundation.rememberScrollState
|
|||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@ -29,23 +25,17 @@ import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
|||||||
import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreenControllerImpl
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.screens.homeScreens.dialogs.DeleteSpecialMissionDialog
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun VBDiMHomeScreen(
|
fun VBDiMHomeScreen(
|
||||||
activeMon: CharacterDtos.CharacterWithSprites,
|
activeMon: CharacterDtos.CharacterWithSprites,
|
||||||
cardIcon: BitmapData,
|
|
||||||
vbData: VBCharacterData,
|
vbData: VBCharacterData,
|
||||||
specialMissions: List<SpecialMissions>,
|
specialMissions: List<SpecialMissions>,
|
||||||
homeScreenController: HomeScreenControllerImpl,
|
homeScreenController: HomeScreenControllerImpl,
|
||||||
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
onClickCollect: (ItemDtos.PurchasedItem?, Int?) -> Unit
|
onClickCollect: (ItemDtos.PurchasedItem?) -> Unit
|
||||||
) {
|
) {
|
||||||
var selectedSpecialMissionId by remember { mutableStateOf<Long>(-1) }
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
@ -61,7 +51,6 @@ fun VBDiMHomeScreen(
|
|||||||
width = activeMon.spriteWidth,
|
width = activeMon.spriteWidth,
|
||||||
height = activeMon.spriteHeight
|
height = activeMon.spriteHeight
|
||||||
),
|
),
|
||||||
cardIcon = cardIcon,
|
|
||||||
multiplier = 8,
|
multiplier = 8,
|
||||||
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -76,7 +65,7 @@ fun VBDiMHomeScreen(
|
|||||||
ItemDisplay(
|
ItemDisplay(
|
||||||
icon = R.drawable.baseline_vitals_24,
|
icon = R.drawable.baseline_vitals_24,
|
||||||
textValue = activeMon.vitalPoints.toString(),
|
textValue = activeMon.vitalPoints.toString(),
|
||||||
definition = stringResource(R.string.home_vbdim_vitals),
|
definition = "Vitals",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(0.5f)
|
.weight(0.5f)
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
@ -85,7 +74,7 @@ fun VBDiMHomeScreen(
|
|||||||
ItemDisplay(
|
ItemDisplay(
|
||||||
icon = R.drawable.baseline_trophy_24,
|
icon = R.drawable.baseline_trophy_24,
|
||||||
textValue = activeMon.trophies.toString(),
|
textValue = activeMon.trophies.toString(),
|
||||||
definition = stringResource(R.string.home_vbdim_trophies),
|
definition = "Trophies",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(0.5f)
|
.weight(0.5f)
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
@ -100,7 +89,7 @@ fun VBDiMHomeScreen(
|
|||||||
ItemDisplay(
|
ItemDisplay(
|
||||||
icon = R.drawable.baseline_mood_24,
|
icon = R.drawable.baseline_mood_24,
|
||||||
textValue = activeMon.mood.toString(),
|
textValue = activeMon.mood.toString(),
|
||||||
definition = stringResource(R.string.home_vbdim_mood),
|
definition = "Mood",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
@ -113,7 +102,7 @@ fun VBDiMHomeScreen(
|
|||||||
0 -> "${activeMon.transformationCountdown} m"
|
0 -> "${activeMon.transformationCountdown} m"
|
||||||
else -> "$transformationCountdownInHours h"
|
else -> "$transformationCountdownInHours h"
|
||||||
},
|
},
|
||||||
definition = stringResource(R.string.home_vbdim_next_timer),
|
definition = "Next timer",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
@ -133,7 +122,7 @@ fun VBDiMHomeScreen(
|
|||||||
) + " %" // Specify locale
|
) + " %" // Specify locale
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
definition = stringResource(R.string.home_vbdim_total_battle_win),
|
definition = "Total battle win %",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
@ -153,7 +142,7 @@ fun VBDiMHomeScreen(
|
|||||||
) + " %" // Specify locale
|
) + " %" // Specify locale
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
definition = stringResource(R.string.home_vbdim_current_phase_win),
|
definition = "Current phase win %",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
@ -176,7 +165,7 @@ fun VBDiMHomeScreen(
|
|||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.home_vbdim_special_missions),
|
text = "Special missions",
|
||||||
fontSize = 24.sp
|
fontSize = 24.sp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -190,28 +179,11 @@ fun VBDiMHomeScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
onClickMission = { missionId ->
|
) {
|
||||||
selectedSpecialMissionId = missionId
|
|
||||||
},
|
|
||||||
onClickCollect = {
|
|
||||||
homeScreenController
|
homeScreenController
|
||||||
.clearSpecialMission(selectedSpecialMissionId, onClickCollect)
|
.clearSpecialMission(mission.id, mission.status, onClickCollect)
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedSpecialMissionId.toInt() != -1) {
|
|
||||||
DeleteSpecialMissionDialog(
|
|
||||||
onClickDismiss = {
|
|
||||||
selectedSpecialMissionId = -1
|
|
||||||
},
|
|
||||||
onClickDelete = {
|
|
||||||
homeScreenController
|
|
||||||
.clearSpecialMission(selectedSpecialMissionId, onClickCollect)
|
|
||||||
selectedSpecialMissionId = -1
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,7 +15,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
@ -25,9 +24,8 @@ import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
|||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChooseCharacterScreen(
|
fun ChooseCharacterScreen(
|
||||||
@ -37,7 +35,7 @@ fun ChooseCharacterScreen(
|
|||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val storageRepository = StorageRepository(application.container.db, )
|
val storageRepository = StorageRepository(application.container.db)
|
||||||
val characterList = remember {
|
val characterList = remember {
|
||||||
mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList())
|
mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList())
|
||||||
}
|
}
|
||||||
@ -59,7 +57,7 @@ fun ChooseCharacterScreen(
|
|||||||
characterList.value = storageRepository.getVBCharacters()
|
characterList.value = storageRepository.getVBCharacters()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
characterList.value = storageRepository.getAllCharacters().first()
|
characterList.value = storageRepository.getAllCharacters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +68,7 @@ fun ChooseCharacterScreen(
|
|||||||
itemsScreenController.applyItem(itemId, selectedCharacter!!) {
|
itemsScreenController.applyItem(itemId, selectedCharacter!!) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
application.applicationContext,
|
application.applicationContext,
|
||||||
application.getString(R.string.choose_character_item_applied),
|
"Item applied!",
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
@ -81,7 +79,7 @@ fun ChooseCharacterScreen(
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.choose_character_title),
|
text = "Choose character",
|
||||||
onBackClick = {
|
onBackClick = {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,173 +0,0 @@
|
|||||||
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.res.stringResource
|
|
||||||
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 = stringResource(
|
|
||||||
R.string.item_dialog_costs_credits,
|
|
||||||
item.price
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Text(
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
|
||||||
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
|
||||||
text = stringResource(
|
|
||||||
R.string.item_dialog_you_have_quantity,
|
|
||||||
item.quantity
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
|
||||||
|
|
||||||
Row (
|
|
||||||
horizontalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
if (onClickUse != null) {
|
|
||||||
Button(
|
|
||||||
onClick = onClickUse
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.item_dialog_use))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onClickPurchase != null) {
|
|
||||||
Button(
|
|
||||||
onClick = onClickPurchase
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.item_dialog_purchase))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.size(8.dp))
|
|
||||||
Button(
|
|
||||||
onClick = onClickCancel
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.item_dialog_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,24 +1,36 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
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.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
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.unit.dp
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import com.github.nacabaro.vbhelper.R
|
import com.github.nacabaro.vbhelper.R
|
||||||
|
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ItemElement(
|
fun ItemElement(
|
||||||
item: ItemDtos.ItemsWithQuantities,
|
itemIcon: Int,
|
||||||
|
lengthIcon: Int,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onClick: (() -> Unit) = { }
|
onClick: (() -> Unit) = { }
|
||||||
) {
|
) {
|
||||||
@ -29,7 +41,7 @@ fun ItemElement(
|
|||||||
) {
|
) {
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = getIconResource(item.itemIcon)),
|
painter = painterResource(id = itemIcon),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(96.dp)
|
.size(96.dp)
|
||||||
@ -37,14 +49,164 @@ fun ItemElement(
|
|||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
)
|
)
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = getLengthResource(item.itemLength)),
|
painter = painterResource(id = lengthIcon),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = MaterialTheme.colorScheme.surfaceTint,
|
tint = MaterialTheme.colorScheme.surfaceTint,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(48.dp)
|
.size(48.dp) // Set the size of the overlay image
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart) // Align to the top end (top-right corner)
|
||||||
.padding(8.dp)
|
.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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,40 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -17,9 +17,6 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ItemsScreen(
|
fun ItemsScreen(
|
||||||
@ -33,14 +30,14 @@ fun ItemsScreen(
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
Column {
|
Column {
|
||||||
TopBanner(text = stringResource(R.string.items_title))
|
TopBanner("Items")
|
||||||
TabRow(
|
TabRow(
|
||||||
selectedTabIndex = selectedTabItem,
|
selectedTabIndex = selectedTabItem,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
) {
|
) {
|
||||||
items.forEachIndexed { index, item ->
|
items.forEachIndexed { index, item ->
|
||||||
Tab(
|
Tab(
|
||||||
text = { Text(text = stringResource(item.label)) },
|
text = { Text(item.label) },
|
||||||
selected = selectedTabItem == index,
|
selected = selectedTabItem == index,
|
||||||
onClick = { selectedTabItem = index }
|
onClick = { selectedTabItem = index }
|
||||||
)
|
)
|
||||||
|
|||||||
@ -11,8 +11,6 @@ import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
|||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@ -54,16 +52,9 @@ class ItemsScreenControllerImpl (
|
|||||||
var vbCharacterData: VBCharacterData? = null
|
var vbCharacterData: VBCharacterData? = null
|
||||||
|
|
||||||
if (characterData.characterType == DeviceType.BEDevice) {
|
if (characterData.characterType == DeviceType.BEDevice) {
|
||||||
beCharacterData = database
|
beCharacterData = database.userCharacterDao().getBeData(characterId)
|
||||||
.userCharacterDao()
|
|
||||||
.getBeData(characterId)
|
|
||||||
.firstOrNull()
|
|
||||||
|
|
||||||
} else if (characterData.characterType == DeviceType.VBDevice) {
|
} else if (characterData.characterType == DeviceType.VBDevice) {
|
||||||
vbCharacterData = database
|
vbCharacterData = database.userCharacterDao().getVbData(characterId)
|
||||||
.userCharacterDao()
|
|
||||||
.getVbData(characterId)
|
|
||||||
.firstOrNull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -163,34 +154,32 @@ class ItemsScreenControllerImpl (
|
|||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val specialMissionSlot = when (itemIcon) {
|
|
||||||
ItemTypes.Step8k.id -> 0
|
|
||||||
ItemTypes.Step4k.id -> 0
|
|
||||||
ItemTypes.Vitals1000.id -> 1
|
|
||||||
ItemTypes.Vitals250.id -> 1
|
|
||||||
ItemTypes.Battle20.id -> 2
|
|
||||||
ItemTypes.Battle5.id -> 2
|
|
||||||
ItemTypes.Win10.id -> 3
|
|
||||||
ItemTypes.Win4.id -> 3
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val availableSpecialMissions = database
|
val availableSpecialMissions = database
|
||||||
.userCharacterDao()
|
.userCharacterDao()
|
||||||
.getSpecialMissions(characterId)
|
.getSpecialMissions(characterId)
|
||||||
.first()
|
|
||||||
|
|
||||||
var newSpecialMission = availableSpecialMissions[specialMissionSlot]
|
var firstUnavailableMissionSlot: Long = 0
|
||||||
newSpecialMission = SpecialMissions(
|
var watchId = 0
|
||||||
id = newSpecialMission.id,
|
|
||||||
characterId = newSpecialMission.characterId,
|
for ((index, mission) in availableSpecialMissions.withIndex()) {
|
||||||
|
if (
|
||||||
|
mission.status == SpecialMission.Status.UNAVAILABLE
|
||||||
|
) {
|
||||||
|
firstUnavailableMissionSlot = mission.id
|
||||||
|
watchId = index + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newSpecialMission = SpecialMissions(
|
||||||
|
id = firstUnavailableMissionSlot,
|
||||||
|
characterId = characterId,
|
||||||
|
missionType = specialMissionType,
|
||||||
goal = specialMissionGoal,
|
goal = specialMissionGoal,
|
||||||
watchId = newSpecialMission.watchId,
|
|
||||||
progress = 0,
|
|
||||||
status = SpecialMission.Status.AVAILABLE,
|
|
||||||
timeElapsedInMinutes = 0,
|
|
||||||
timeLimitInMinutes = itemLength,
|
timeLimitInMinutes = itemLength,
|
||||||
missionType = specialMissionType
|
watchId = watchId,
|
||||||
|
status = SpecialMission.Status.AVAILABLE,
|
||||||
|
progress = 0,
|
||||||
|
timeElapsedInMinutes = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
database
|
database
|
||||||
|
|||||||
@ -1,37 +1,25 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
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.layout.padding
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import com.github.nacabaro.vbhelper.source.CurrencyRepository
|
|
||||||
import com.github.nacabaro.vbhelper.source.ItemsRepository
|
import com.github.nacabaro.vbhelper.source.ItemsRepository
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.withContext
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ItemsStore(
|
fun ItemsStore(
|
||||||
@ -39,102 +27,45 @@ fun ItemsStore(
|
|||||||
) {
|
) {
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val itemsRepository = ItemsRepository(application.container.db)
|
val itemsRepository = ItemsRepository(application.container.db)
|
||||||
val myItems by itemsRepository.getAllItems().collectAsState(emptyList())
|
val myItems = remember { mutableStateOf(emptyList<ItemDtos.ItemsWithQuantities>()) }
|
||||||
|
|
||||||
var selectedElementIndex by remember { mutableStateOf<Int?>(null) }
|
var selectedElementIndex by remember { mutableStateOf<Int?>(null) }
|
||||||
|
|
||||||
val currencyRepository = application.container.currencyRepository
|
LaunchedEffect(itemsRepository) {
|
||||||
val currentCurrency = currencyRepository.currencyValue.collectAsState(0)
|
withContext(Dispatchers.IO) {
|
||||||
|
myItems.value = itemsRepository.getAllItems()
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
if (myItems.isEmpty()) {
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.items_no_items))
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myItems.value.isEmpty()) {
|
||||||
|
Text("No items")
|
||||||
} else {
|
} else {
|
||||||
Column() {
|
|
||||||
Card(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(
|
|
||||||
R.string.items_store_credits,
|
|
||||||
currentCurrency.value
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(3),
|
columns = GridCells.Fixed(3),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
) {
|
) {
|
||||||
items(myItems) { index ->
|
items(myItems.value) { index ->
|
||||||
ItemElement(
|
ItemElement(
|
||||||
item = index,
|
itemIcon = getIconResource(index.itemIcon),
|
||||||
|
lengthIcon = getLengthResource(index.itemLength),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedElementIndex = myItems.indexOf(index)
|
selectedElementIndex = myItems.value.indexOf(index)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (selectedElementIndex != null) {
|
if (selectedElementIndex != null) {
|
||||||
ItemDialog(
|
ItemDialog(
|
||||||
item = myItems[selectedElementIndex!!],
|
name = myItems.value[selectedElementIndex!!].name,
|
||||||
onClickPurchase = {
|
description = myItems.value[selectedElementIndex!!].description,
|
||||||
scope.launch {
|
itemIcon = getIconResource(myItems.value[selectedElementIndex!!].itemIcon),
|
||||||
Toast.makeText(
|
lengthIcon = getLengthResource(myItems.value[selectedElementIndex!!].itemLength),
|
||||||
application.applicationContext,
|
amount = myItems.value[selectedElementIndex!!].quantity,
|
||||||
application.getString(
|
onClickUse = { },
|
||||||
purchaseItem(
|
|
||||||
application.container.db,
|
|
||||||
myItems[selectedElementIndex!!],
|
|
||||||
currencyRepository
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onClickCancel = { selectedElementIndex = null }
|
onClickCancel = { selectedElementIndex = null }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun purchaseItem(
|
|
||||||
db: AppDatabase,
|
|
||||||
item: ItemDtos.ItemsWithQuantities,
|
|
||||||
currencyRepository: CurrencyRepository
|
|
||||||
): Int {
|
|
||||||
return if (currencyRepository.currencyValue.first() < item.price) {
|
|
||||||
R.string.items_not_enough_credits
|
|
||||||
} else {
|
|
||||||
db
|
|
||||||
.itemDao()
|
|
||||||
.purchaseItem(
|
|
||||||
item.id,
|
|
||||||
1
|
|
||||||
)
|
|
||||||
|
|
||||||
currencyRepository
|
|
||||||
.setCurrencyValue(
|
|
||||||
currencyRepository.currencyValue.first() - item.price
|
|
||||||
)
|
|
||||||
|
|
||||||
R.string.items_purchase_success
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
|||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -17,14 +17,14 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
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.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.source.ItemsRepository
|
import com.github.nacabaro.vbhelper.source.ItemsRepository
|
||||||
import com.github.nacabaro.vbhelper.R
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MyItems(
|
fun MyItems(
|
||||||
@ -32,30 +32,36 @@ fun MyItems(
|
|||||||
) {
|
) {
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val itemsRepository = ItemsRepository(application.container.db)
|
val itemsRepository = ItemsRepository(application.container.db)
|
||||||
val myItems by itemsRepository.getUserItems().collectAsState(emptyList())
|
val myItems = remember { mutableStateOf(emptyList<ItemDtos.ItemsWithQuantities>()) }
|
||||||
|
|
||||||
var selectedElementIndex by remember { mutableStateOf<Int?>(null) }
|
var selectedElementIndex by remember { mutableStateOf<Int?>(null) }
|
||||||
|
|
||||||
if (myItems.isEmpty()) {
|
LaunchedEffect(itemsRepository) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
myItems.value = itemsRepository.getUserItems()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myItems.value.isEmpty()) {
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.items_no_items))
|
Text("No items")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(3),
|
columns = GridCells.Fixed(3),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
) {
|
) {
|
||||||
items(myItems) { index ->
|
items(myItems.value) { index ->
|
||||||
ItemElement(
|
ItemElement(
|
||||||
item = index,
|
itemIcon = getIconResource(index.itemIcon),
|
||||||
|
lengthIcon = getLengthResource(index.itemLength),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedElementIndex = myItems.indexOf(index)
|
selectedElementIndex = myItems.value.indexOf(index)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -63,7 +69,11 @@ fun MyItems(
|
|||||||
|
|
||||||
if (selectedElementIndex != null) {
|
if (selectedElementIndex != null) {
|
||||||
ItemDialog(
|
ItemDialog(
|
||||||
item = myItems[selectedElementIndex!!],
|
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 = {
|
onClickUse = {
|
||||||
navController
|
navController
|
||||||
.navigate(
|
.navigate(
|
||||||
@ -71,7 +81,7 @@ fun MyItems(
|
|||||||
.ApplyItem.route
|
.ApplyItem.route
|
||||||
.replace(
|
.replace(
|
||||||
"{itemId}",
|
"{itemId}",
|
||||||
myItems[selectedElementIndex!!].id.toString()
|
myItems.value[selectedElementIndex!!].id.toString()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
selectedElementIndex = null
|
selectedElementIndex = null
|
||||||
|
|||||||
@ -19,13 +19,10 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ObtainedItemDialog(
|
fun ObtainedItemDialog(
|
||||||
obtainedItem: ItemDtos.PurchasedItem,
|
obtainedItem: ItemDtos.PurchasedItem,
|
||||||
obtainedCurrency: Int,
|
|
||||||
onClickDismiss: () -> Unit
|
onClickDismiss: () -> Unit
|
||||||
) {
|
) {
|
||||||
Dialog(
|
Dialog(
|
||||||
@ -84,32 +81,17 @@ fun ObtainedItemDialog(
|
|||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
||||||
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
||||||
text = stringResource(
|
text = "You have obtained ${obtainedItem.itemAmount} of this item",
|
||||||
R.string.obtained_item_you_have,
|
|
||||||
obtainedItem.itemAmount
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(top = 4.dp)
|
.padding(5.dp)
|
||||||
)
|
|
||||||
Text(
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
|
||||||
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
|
||||||
text = stringResource(
|
|
||||||
R.string.obtained_item_you_also_got_credits,
|
|
||||||
obtainedCurrency
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 4.dp)
|
|
||||||
)
|
)
|
||||||
Button(
|
Button(
|
||||||
onClick = onClickDismiss,
|
onClick = onClickDismiss,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.obtained_item_dismiss))
|
Text(text = "Dismiss")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,80 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
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.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ChooseConnectOption(
|
|
||||||
onClickRead: (() -> Unit)? = null,
|
|
||||||
onClickWrite: (() -> Unit)? = null,
|
|
||||||
navController: NavController
|
|
||||||
) {
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBanner(
|
|
||||||
text = stringResource(R.string.scan_title),
|
|
||||||
onBackClick = {
|
|
||||||
navController.popBackStack()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { contentPadding ->
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(contentPadding)
|
|
||||||
) {
|
|
||||||
ScanButton(
|
|
||||||
text = stringResource(R.string.scan_vb_to_app),
|
|
||||||
disabled = onClickRead == null,
|
|
||||||
onClick = onClickRead?: { },
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
ScanButton(
|
|
||||||
text = stringResource(R.string.scan_app_to_vb),
|
|
||||||
disabled = onClickWrite == null,
|
|
||||||
onClick = onClickWrite?: { },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ScanButton(
|
|
||||||
text: String,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
disabled: Boolean = false,
|
|
||||||
) {
|
|
||||||
Button(
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = modifier,
|
|
||||||
enabled = !disabled,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = text,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
package com.github.nacabaro.vbhelper.screens.scanScreen
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -10,22 +10,17 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ActionScreen(
|
fun ReadingCharacterScreen(
|
||||||
topBannerText: String,
|
topBannerText: String,
|
||||||
onClickCancel: () -> Unit,
|
onClickCancel: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(topBannerText)
|
||||||
text = topBannerText,
|
|
||||||
onBackClick = onClickCancel
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Column (
|
Column (
|
||||||
@ -35,12 +30,12 @@ fun ActionScreen(
|
|||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.action_place_near_reader))
|
Text("Place your Vital Bracelet near the reader...")
|
||||||
Button(
|
Button(
|
||||||
onClick = onClickCancel,
|
onClick = onClickCancel,
|
||||||
modifier = Modifier.padding(16.dp)
|
modifier = Modifier.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.action_cancel))
|
Text("Cancel")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,31 +1,44 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen
|
package com.github.nacabaro.vbhelper.screens.scanScreen
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
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.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
||||||
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.screens.scanScreen.screens.ReadingScreen
|
import com.github.nacabaro.vbhelper.screens.cardScreen.ChooseCard
|
||||||
import com.github.nacabaro.vbhelper.screens.scanScreen.screens.WritingScreen
|
|
||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||||
import com.github.nacabaro.vbhelper.source.isMissingSecrets
|
import com.github.nacabaro.vbhelper.source.isMissingSecrets
|
||||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
const val SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER = "SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER"
|
const val SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER = "SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER"
|
||||||
|
|
||||||
@ -42,6 +55,8 @@ fun ScanScreen(
|
|||||||
val storageRepository = StorageRepository(application.container.db)
|
val storageRepository = StorageRepository(application.container.db)
|
||||||
var nfcCharacter by remember { mutableStateOf<NfcCharacter?>(null) }
|
var nfcCharacter by remember { mutableStateOf<NfcCharacter?>(null) }
|
||||||
|
|
||||||
|
var cardsRead by remember { mutableStateOf<List<Card>?>(null) }
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
LaunchedEffect(storageRepository) {
|
LaunchedEffect(storageRepository) {
|
||||||
@ -58,33 +73,143 @@ fun ScanScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var writingScreen by remember { mutableStateOf(false) }
|
|
||||||
var readingScreen by remember { mutableStateOf(false) }
|
var readingScreen by remember { mutableStateOf(false) }
|
||||||
|
var writingScreen by remember { mutableStateOf(false) }
|
||||||
|
var cardSelectScreen by remember { mutableStateOf(false) }
|
||||||
|
var isDoneReadingCharacter by remember { mutableStateOf(false) }
|
||||||
|
var isDoneSendingCard by remember { mutableStateOf(false) }
|
||||||
|
var isDoneWritingCharacter by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
if (writingScreen && nfcCharacter != null && characterId != null) {
|
DisposableEffect(readingScreen) {
|
||||||
WritingScreen(
|
if(readingScreen) {
|
||||||
scanScreenController = scanScreenController,
|
scanScreenController.registerActivityLifecycleListener(
|
||||||
nfcCharacter = nfcCharacter!!,
|
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
||||||
characterId = characterId,
|
object: ActivityLifecycleListener {
|
||||||
|
override fun onPause() {
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
scanScreenController.onClickRead(
|
||||||
|
secrets = secrets!!,
|
||||||
onComplete = {
|
onComplete = {
|
||||||
writingScreen = false
|
isDoneReadingCharacter = true
|
||||||
navController.navigate(NavigationItems.Home.route)
|
|
||||||
},
|
},
|
||||||
onCancel = {
|
onMultipleCards = { cards ->
|
||||||
writingScreen = false
|
cardsRead = cards
|
||||||
navController.navigate(NavigationItems.Home.route)
|
readingScreen = false
|
||||||
|
cardSelectScreen = true
|
||||||
|
isDoneReadingCharacter = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else if (readingScreen) {
|
}
|
||||||
ReadingScreen(
|
}
|
||||||
scanScreenController = scanScreenController,
|
)
|
||||||
onCancel = {
|
scanScreenController.onClickRead(
|
||||||
readingScreen = false
|
secrets = secrets!!,
|
||||||
navController.navigate(NavigationItems.Home.route)
|
|
||||||
},
|
|
||||||
onComplete = {
|
onComplete = {
|
||||||
|
isDoneReadingCharacter = true
|
||||||
|
},
|
||||||
|
onMultipleCards = { cards ->
|
||||||
|
cardsRead = cards
|
||||||
|
readingScreen = false
|
||||||
|
cardSelectScreen = true
|
||||||
|
isDoneReadingCharacter = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
onDispose {
|
||||||
|
if(readingScreen) {
|
||||||
|
scanScreenController.unregisterActivityLifecycleListener(
|
||||||
|
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
||||||
|
)
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DisposableEffect(writingScreen, isDoneSendingCard) {
|
||||||
|
if (writingScreen) {
|
||||||
|
scanScreenController.registerActivityLifecycleListener(
|
||||||
|
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
||||||
|
object : ActivityLifecycleListener {
|
||||||
|
override fun onPause() {
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
if (!isDoneSendingCard) {
|
||||||
|
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) {
|
||||||
|
isDoneSendingCard = true
|
||||||
|
}
|
||||||
|
} else if (!isDoneWritingCharacter) {
|
||||||
|
scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) {
|
||||||
|
isDoneWritingCharacter = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secrets != null && nfcCharacter != null) {
|
||||||
|
if (!isDoneSendingCard) {
|
||||||
|
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) {
|
||||||
|
isDoneSendingCard = true
|
||||||
|
}
|
||||||
|
} else if (!isDoneWritingCharacter) {
|
||||||
|
scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) {
|
||||||
|
isDoneWritingCharacter = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDispose {
|
||||||
|
if(writingScreen) {
|
||||||
|
scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER)
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDoneReadingCharacter && !cardSelectScreen) {
|
||||||
readingScreen = false
|
readingScreen = false
|
||||||
navController.navigate(NavigationItems.Home.route)
|
navController.navigate(NavigationItems.Home.route)
|
||||||
|
} else if (isDoneSendingCard && isDoneWritingCharacter) {
|
||||||
|
writingScreen = false
|
||||||
|
navController.navigate(NavigationItems.Home.route)
|
||||||
|
LaunchedEffect(storageRepository) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
storageRepository
|
||||||
|
.deleteCharacter(characterId!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readingScreen) {
|
||||||
|
ReadingCharacterScreen("Reading character") {
|
||||||
|
readingScreen = false
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
} else if (writingScreen) {
|
||||||
|
if (!isDoneSendingCard) {
|
||||||
|
ReadingCharacterScreen("Sending card") {
|
||||||
|
writingScreen = false
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
} else if (!isDoneWritingCharacter) {
|
||||||
|
ReadingCharacterScreen("Writing character") {
|
||||||
|
isDoneSendingCard = false
|
||||||
|
writingScreen = false
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (cardSelectScreen) {
|
||||||
|
ChooseCard(
|
||||||
|
cards = cardsRead!!,
|
||||||
|
onCardSelected = { card ->
|
||||||
|
cardSelectScreen = false
|
||||||
|
scanScreenController.flushCharacter(card.id)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -94,9 +219,9 @@ fun ScanScreen(
|
|||||||
else -> {
|
else -> {
|
||||||
{
|
{
|
||||||
if(secrets == null) {
|
if(secrets == null) {
|
||||||
Toast.makeText(context, context.getString(R.string.scan_secrets_not_initialized), Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
|
||||||
} else if(secrets?.isMissingSecrets() == true) {
|
} else if(secrets?.isMissingSecrets() == true) {
|
||||||
Toast.makeText(context, context.getString(R.string.scan_secrets_not_imported), Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
readingScreen = true // kicks off nfc adapter in DisposableEffect
|
readingScreen = true // kicks off nfc adapter in DisposableEffect
|
||||||
}
|
}
|
||||||
@ -108,9 +233,9 @@ fun ScanScreen(
|
|||||||
else -> {
|
else -> {
|
||||||
{
|
{
|
||||||
if(secrets == null) {
|
if(secrets == null) {
|
||||||
Toast.makeText(context, context.getString(R.string.scan_secrets_not_initialized), Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
|
||||||
} else if(secrets?.isMissingSecrets() == true) {
|
} else if(secrets?.isMissingSecrets() == true) {
|
||||||
Toast.makeText(context, context.getString(R.string.scan_secrets_not_imported), Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
writingScreen = true // kicks off nfc adapter in DisposableEffect
|
writingScreen = true // kicks off nfc adapter in DisposableEffect
|
||||||
}
|
}
|
||||||
@ -122,8 +247,66 @@ fun ScanScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ChooseConnectOption(
|
||||||
|
onClickRead: (() -> Unit)? = null,
|
||||||
|
onClickWrite: (() -> Unit)? = null,
|
||||||
|
navController: NavController
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopBanner(
|
||||||
|
text = "Scan a Vital Bracelet",
|
||||||
|
onBackClick = {
|
||||||
|
navController.popBackStack()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { contentPadding ->
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(contentPadding)
|
||||||
|
) {
|
||||||
|
ScanButton(
|
||||||
|
text = "Vital Bracelet to App",
|
||||||
|
disabled = onClickRead == null,
|
||||||
|
onClick = onClickRead?: { },
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
ScanButton(
|
||||||
|
text = "App to Vital Bracelet",
|
||||||
|
disabled = onClickWrite == null,
|
||||||
|
onClick = onClickWrite?: { },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ScanButton(
|
||||||
|
text: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
disabled: Boolean = false,
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = modifier,
|
||||||
|
enabled = !disabled,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(4.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
@Preview(showBackground = true)
|
||||||
@Composable
|
@Composable
|
||||||
fun ScanScreenPreview() {
|
fun ScanScreenPreview() {
|
||||||
|
|||||||
@ -25,7 +25,6 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
class ScanScreenControllerImpl(
|
class ScanScreenControllerImpl(
|
||||||
override val secretsFlow: Flow<Secrets>,
|
override val secretsFlow: Flow<Secrets>,
|
||||||
@ -39,7 +38,7 @@ class ScanScreenControllerImpl(
|
|||||||
init {
|
init {
|
||||||
val maybeNfcAdapter = NfcAdapter.getDefaultAdapter(componentActivity)
|
val maybeNfcAdapter = NfcAdapter.getDefaultAdapter(componentActivity)
|
||||||
if (maybeNfcAdapter == null) {
|
if (maybeNfcAdapter == null) {
|
||||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_no_nfc_on_device), Toast.LENGTH_SHORT).show()
|
Toast.makeText(componentActivity, "No NFC on device!", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
nfcAdapter = maybeNfcAdapter
|
nfcAdapter = maybeNfcAdapter
|
||||||
checkSecrets()
|
checkSecrets()
|
||||||
@ -95,7 +94,7 @@ class ScanScreenControllerImpl(
|
|||||||
val nfcData = NfcA.get(tag)
|
val nfcData = NfcA.get(tag)
|
||||||
if (nfcData == null) {
|
if (nfcData == null) {
|
||||||
componentActivity.runOnUiThread {
|
componentActivity.runOnUiThread {
|
||||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_tag_not_vb), Toast.LENGTH_SHORT).show()
|
Toast.makeText(componentActivity, "Tag detected is not VB", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nfcData.connect()
|
nfcData.connect()
|
||||||
@ -113,7 +112,7 @@ class ScanScreenControllerImpl(
|
|||||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
if(secretsFlow.stateIn(componentActivity.lifecycleScope).value.isMissingSecrets()) {
|
if(secretsFlow.stateIn(componentActivity.lifecycleScope).value.isMissingSecrets()) {
|
||||||
componentActivity.runOnUiThread {
|
componentActivity.runOnUiThread {
|
||||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_missing_secrets), Toast.LENGTH_SHORT).show()
|
Toast.makeText(componentActivity, "Missing Secrets. Go to settings and import Vital Arena APK", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,10 +135,10 @@ class ScanScreenControllerImpl(
|
|||||||
tagCommunicator.sendCharacter(castNfcCharacter)
|
tagCommunicator.sendCharacter(castNfcCharacter)
|
||||||
}
|
}
|
||||||
onComplete.invoke()
|
onComplete.invoke()
|
||||||
componentActivity.getString(R.string.scan_sent_character_success)
|
"Sent character successfully!"
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Log.e("TAG", e.stackTraceToString())
|
Log.e("TAG", e.stackTraceToString())
|
||||||
componentActivity.getString(R.string.scan_error_generic)
|
"Whoops"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,13 +151,13 @@ class ScanScreenControllerImpl(
|
|||||||
handleTag(secrets) { tagCommunicator ->
|
handleTag(secrets) { tagCommunicator ->
|
||||||
tagCommunicator.prepareDIMForCharacter(nfcCharacter.dimId)
|
tagCommunicator.prepareDIMForCharacter(nfcCharacter.dimId)
|
||||||
onComplete.invoke()
|
onComplete.invoke()
|
||||||
componentActivity.getString(R.string.scan_sent_dim_success)
|
"Sent DIM successfully!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXTRACTED DIRECTLY FROM EXAMPLE APP
|
// EXTRACTED DIRECTLY FROM EXAMPLE APP
|
||||||
private fun showWirelessSettings() {
|
private fun showWirelessSettings() {
|
||||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_nfc_must_be_enabled), Toast.LENGTH_SHORT).show()
|
Toast.makeText(componentActivity, "NFC must be enabled", Toast.LENGTH_SHORT).show()
|
||||||
componentActivity.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS))
|
componentActivity.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.converters
|
package com.github.nacabaro.vbhelper.screens.scanScreen.converters
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
||||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
import com.github.cfogrady.vbnfc.vb.VBNfcCharacter
|
import com.github.cfogrady.vbnfc.vb.VBNfcCharacter
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
|
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||||
@ -150,13 +152,15 @@ class FromNfcConverter (
|
|||||||
nfcCharacter: NfcCharacter,
|
nfcCharacter: NfcCharacter,
|
||||||
cardData: Card
|
cardData: Card
|
||||||
) {
|
) {
|
||||||
|
val currentCardProgress = CardProgress(
|
||||||
|
cardId = cardData.id,
|
||||||
|
currentStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
||||||
|
unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount
|
||||||
|
)
|
||||||
|
|
||||||
database
|
database
|
||||||
.cardProgressDao()
|
.cardProgressDao()
|
||||||
.updateCardProgress(
|
.updateDimProgress(currentCardProgress)
|
||||||
currentStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
|
||||||
cardId = cardData.id,
|
|
||||||
unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -248,11 +252,10 @@ class FromNfcConverter (
|
|||||||
) {
|
) {
|
||||||
val vitalsHistoryWatch = nfcCharacter.vitalHistory
|
val vitalsHistoryWatch = nfcCharacter.vitalHistory
|
||||||
val vitalsHistory = vitalsHistoryWatch.map { historyElement ->
|
val vitalsHistory = vitalsHistoryWatch.map { historyElement ->
|
||||||
val year = if (historyElement.year.toInt() !in 2021 .. 2035) 0 else historyElement.year.toInt()
|
Log.d("VitalsHistory", "${historyElement.year.toInt()} ${historyElement.month.toInt()} ${historyElement.day.toInt()}")
|
||||||
|
|
||||||
VitalsHistory(
|
VitalsHistory(
|
||||||
charId = characterId,
|
charId = characterId,
|
||||||
year = year,
|
year = historyElement.year.toInt(),
|
||||||
month = historyElement.month.toInt(),
|
month = historyElement.month.toInt(),
|
||||||
day = historyElement.day.toInt(),
|
day = historyElement.day.toInt(),
|
||||||
vitalPoints = historyElement.vitalsGained.toInt()
|
vitalPoints = historyElement.vitalsGained.toInt()
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import com.github.nacabaro.vbhelper.di.VBHelper
|
|||||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
class ToNfcConverter(
|
class ToNfcConverter(
|
||||||
@ -39,10 +38,14 @@ class ToNfcConverter(
|
|||||||
.characterDao()
|
.characterDao()
|
||||||
.getCharacterInfo(userCharacter.charId)
|
.getCharacterInfo(userCharacter.charId)
|
||||||
|
|
||||||
|
val currentCardStage = database
|
||||||
|
.cardProgressDao()
|
||||||
|
.getCardProgress(characterInfo.cardId)
|
||||||
|
|
||||||
return if (userCharacter.characterType == DeviceType.BEDevice)
|
return if (userCharacter.characterType == DeviceType.BEDevice)
|
||||||
nfcToBENfc(characterId, characterInfo, userCharacter)
|
nfcToBENfc(characterId, characterInfo, currentCardStage, userCharacter)
|
||||||
else
|
else
|
||||||
nfcToVBNfc(characterId, characterInfo, userCharacter)
|
nfcToVBNfc(characterId, characterInfo, currentCardStage, userCharacter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -50,12 +53,12 @@ class ToNfcConverter(
|
|||||||
private suspend fun nfcToVBNfc(
|
private suspend fun nfcToVBNfc(
|
||||||
characterId: Long,
|
characterId: Long,
|
||||||
characterInfo: CharacterDtos.CardCharacterInfo,
|
characterInfo: CharacterDtos.CardCharacterInfo,
|
||||||
|
currentCardStage: Int,
|
||||||
userCharacter: UserCharacter
|
userCharacter: UserCharacter
|
||||||
): VBNfcCharacter {
|
): VBNfcCharacter {
|
||||||
val vbData = database
|
val vbData = database
|
||||||
.userCharacterDao()
|
.userCharacterDao()
|
||||||
.getVbData(characterId)
|
.getVbData(characterId)
|
||||||
.first()
|
|
||||||
|
|
||||||
val paddedTransformationArray = generateTransformationHistory(characterId, 9)
|
val paddedTransformationArray = generateTransformationHistory(characterId, 9)
|
||||||
|
|
||||||
@ -67,7 +70,7 @@ class ToNfcConverter(
|
|||||||
stage = characterInfo.stage.toByte(),
|
stage = characterInfo.stage.toByte(),
|
||||||
attribute = characterInfo.attribute,
|
attribute = characterInfo.attribute,
|
||||||
ageInDays = userCharacter.ageInDays.toByte(),
|
ageInDays = userCharacter.ageInDays.toByte(),
|
||||||
nextAdventureMissionStage = characterInfo.currentStage.toByte(),
|
nextAdventureMissionStage = currentCardStage.toByte(),
|
||||||
mood = userCharacter.mood.toByte(),
|
mood = userCharacter.mood.toByte(),
|
||||||
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
||||||
transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(),
|
transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(),
|
||||||
@ -98,7 +101,6 @@ class ToNfcConverter(
|
|||||||
val cardData = database
|
val cardData = database
|
||||||
.cardDao()
|
.cardDao()
|
||||||
.getCardByCharacterId(userCharacter.id)
|
.getCardByCharacterId(userCharacter.id)
|
||||||
.first()
|
|
||||||
|
|
||||||
val appReserved = Array<UShort>(3) {
|
val appReserved = Array<UShort>(3) {
|
||||||
0u
|
0u
|
||||||
@ -117,7 +119,6 @@ class ToNfcConverter(
|
|||||||
val specialMissions = database
|
val specialMissions = database
|
||||||
.userCharacterDao()
|
.userCharacterDao()
|
||||||
.getSpecialMissions(characterId)
|
.getSpecialMissions(characterId)
|
||||||
.first()
|
|
||||||
|
|
||||||
val watchSpecialMissions = specialMissions.map {
|
val watchSpecialMissions = specialMissions.map {
|
||||||
SpecialMission(
|
SpecialMission(
|
||||||
@ -172,12 +173,12 @@ class ToNfcConverter(
|
|||||||
private suspend fun nfcToBENfc(
|
private suspend fun nfcToBENfc(
|
||||||
characterId: Long,
|
characterId: Long,
|
||||||
characterInfo: CharacterDtos.CardCharacterInfo,
|
characterInfo: CharacterDtos.CardCharacterInfo,
|
||||||
|
currentCardStage: Int,
|
||||||
userCharacter: UserCharacter
|
userCharacter: UserCharacter
|
||||||
): BENfcCharacter {
|
): BENfcCharacter {
|
||||||
val beData = database
|
val beData = database
|
||||||
.userCharacterDao()
|
.userCharacterDao()
|
||||||
.getBeData(characterId)
|
.getBeData(characterId)
|
||||||
.first()
|
|
||||||
|
|
||||||
val paddedTransformationArray = generateTransformationHistory(characterId)
|
val paddedTransformationArray = generateTransformationHistory(characterId)
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ class ToNfcConverter(
|
|||||||
stage = characterInfo.stage.toByte(),
|
stage = characterInfo.stage.toByte(),
|
||||||
attribute = characterInfo.attribute,
|
attribute = characterInfo.attribute,
|
||||||
ageInDays = userCharacter.ageInDays.toByte(),
|
ageInDays = userCharacter.ageInDays.toByte(),
|
||||||
nextAdventureMissionStage = characterInfo.currentStage.toByte(),
|
nextAdventureMissionStage = currentCardStage.toByte(),
|
||||||
mood = userCharacter.mood.toByte(),
|
mood = userCharacter.mood.toByte(),
|
||||||
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
||||||
itemEffectMentalStateValue = beData.itemEffectMentalStateValue.toByte(),
|
itemEffectMentalStateValue = beData.itemEffectMentalStateValue.toByte(),
|
||||||
@ -240,8 +241,7 @@ class ToNfcConverter(
|
|||||||
): Array<NfcCharacter.Transformation> {
|
): Array<NfcCharacter.Transformation> {
|
||||||
val transformationHistory = database
|
val transformationHistory = database
|
||||||
.userCharacterDao()
|
.userCharacterDao()
|
||||||
.getTransformationHistory(characterId)
|
.getTransformationHistory(characterId)!!
|
||||||
.first()
|
|
||||||
.map {
|
.map {
|
||||||
val date = Date(it.transformationDate)
|
val date = Date(it.transformationDate)
|
||||||
val calendar = android.icu.util.GregorianCalendar(TimeZone.getTimeZone("UTC"))
|
val calendar = android.icu.util.GregorianCalendar(TimeZone.getTimeZone("UTC"))
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
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.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ReadCharacterScreen(
|
|
||||||
onClickCancel: () -> Unit,
|
|
||||||
onClickConfirm: () -> Unit
|
|
||||||
) {
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBanner(
|
|
||||||
text = stringResource(R.string.read_character_title),
|
|
||||||
onBackClick = onClickCancel
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { innerPadding ->
|
|
||||||
Column(
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(innerPadding)
|
|
||||||
.fillMaxSize()
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.read_character_prepare_device),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.read_character_go_to_connect),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(
|
|
||||||
modifier = Modifier.padding(8.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = onClickConfirm,
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.read_character_confirm))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
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.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
|
||||||
import com.github.nacabaro.vbhelper.screens.cardScreen.ChooseCard
|
|
||||||
import com.github.nacabaro.vbhelper.screens.scanScreen.SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
|
||||||
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenController
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ReadingScreen(
|
|
||||||
scanScreenController: ScanScreenController,
|
|
||||||
onCancel: () -> Unit,
|
|
||||||
onComplete: () -> Unit
|
|
||||||
) {
|
|
||||||
val secrets by scanScreenController.secretsFlow.collectAsState(null)
|
|
||||||
|
|
||||||
var cardsRead by remember { mutableStateOf<List<Card>?>(null) }
|
|
||||||
|
|
||||||
var readingScreen by remember { mutableStateOf(false) }
|
|
||||||
var isDoneReadingCharacter by remember { mutableStateOf(false) }
|
|
||||||
var cardSelectScreen by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
DisposableEffect(readingScreen) {
|
|
||||||
if(readingScreen) {
|
|
||||||
scanScreenController.registerActivityLifecycleListener(
|
|
||||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
|
||||||
object: ActivityLifecycleListener {
|
|
||||||
override fun onPause() {
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
scanScreenController.onClickRead(
|
|
||||||
secrets = secrets!!,
|
|
||||||
onComplete = {
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
},
|
|
||||||
onMultipleCards = { cards ->
|
|
||||||
cardsRead = cards
|
|
||||||
readingScreen = false
|
|
||||||
cardSelectScreen = true
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
scanScreenController.onClickRead(
|
|
||||||
secrets = secrets!!,
|
|
||||||
onComplete = {
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
},
|
|
||||||
onMultipleCards = { cards ->
|
|
||||||
cardsRead = cards
|
|
||||||
readingScreen = false
|
|
||||||
cardSelectScreen = true
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
onDispose {
|
|
||||||
if(readingScreen) {
|
|
||||||
scanScreenController.unregisterActivityLifecycleListener(
|
|
||||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
|
||||||
)
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDoneReadingCharacter && !cardSelectScreen) {
|
|
||||||
readingScreen = false
|
|
||||||
onComplete()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!readingScreen) {
|
|
||||||
ReadCharacterScreen(
|
|
||||||
onClickConfirm = {
|
|
||||||
readingScreen = true
|
|
||||||
},
|
|
||||||
onClickCancel = {
|
|
||||||
onCancel()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readingScreen) {
|
|
||||||
ActionScreen(topBannerText = stringResource(R.string.reading_character_title),) {
|
|
||||||
readingScreen = false
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
onCancel()
|
|
||||||
}
|
|
||||||
} else if (cardSelectScreen) {
|
|
||||||
ChooseCard(
|
|
||||||
cards = cardsRead!!,
|
|
||||||
onCardSelected = { card ->
|
|
||||||
cardSelectScreen = false
|
|
||||||
scanScreenController.flushCharacter(card.id)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
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.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.Scaffold
|
|
||||||
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.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.FilterQuality
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
|
||||||
import com.github.nacabaro.vbhelper.source.ScanRepository
|
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
|
||||||
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun WriteCardScreen(
|
|
||||||
characterId: Long,
|
|
||||||
onClickCancel: () -> Unit,
|
|
||||||
onClickConfirm: () -> Unit
|
|
||||||
) {
|
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
|
||||||
val database = application.container.db
|
|
||||||
val scanRepository = ScanRepository(database)
|
|
||||||
val cardDetails by scanRepository.getCardDetails(characterId).collectAsState(Card(
|
|
||||||
id = 0,
|
|
||||||
cardId = 0,
|
|
||||||
name = "",
|
|
||||||
logo = byteArrayOf(),
|
|
||||||
logoHeight = 0,
|
|
||||||
logoWidth = 0,
|
|
||||||
stageCount = 0,
|
|
||||||
isBEm = false
|
|
||||||
))
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBanner(
|
|
||||||
text = stringResource(R.string.write_card_title),
|
|
||||||
onBackClick = onClickCancel
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { innerPadding ->
|
|
||||||
Column(
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(innerPadding)
|
|
||||||
.fillMaxSize()
|
|
||||||
) {
|
|
||||||
Card (
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
Row (
|
|
||||||
modifier = Modifier.padding(16.dp),
|
|
||||||
){
|
|
||||||
if (cardDetails.logoHeight > 0 && cardDetails.logoWidth > 0) {
|
|
||||||
val charaBitmapData = BitmapData(
|
|
||||||
bitmap = cardDetails.logo,
|
|
||||||
width = cardDetails.logoWidth,
|
|
||||||
height = cardDetails.logoHeight
|
|
||||||
)
|
|
||||||
val charaImageBitmapData = charaBitmapData.getImageBitmap(
|
|
||||||
context = LocalContext.current,
|
|
||||||
multiplier = 4,
|
|
||||||
obscure = false
|
|
||||||
)
|
|
||||||
|
|
||||||
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 = stringResource(
|
|
||||||
R.string.write_card_icon_description
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.size(charaImageBitmapData.dpWidth)
|
|
||||||
.padding(8.dp),
|
|
||||||
filterQuality = FilterQuality.None
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(
|
|
||||||
modifier = Modifier.width(8.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Column {
|
|
||||||
Text(stringResource(R.string.write_card_device_ready))
|
|
||||||
Text(
|
|
||||||
stringResource(
|
|
||||||
R.string.write_card_required_card,
|
|
||||||
cardDetails.name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = onClickConfirm,
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.write_card_confirm))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,138 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
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.Scaffold
|
|
||||||
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.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.FilterQuality
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
|
||||||
import com.github.nacabaro.vbhelper.source.ScanRepository
|
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
|
||||||
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun WriteCharacterScreen(
|
|
||||||
characterId: Long,
|
|
||||||
onClickCancel: () -> Unit,
|
|
||||||
onClickConfirm: () -> Unit
|
|
||||||
) {
|
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
|
||||||
val database = application.container.db
|
|
||||||
val scanRepository = ScanRepository(database)
|
|
||||||
val cardDetails by scanRepository.getCardDetails(characterId).collectAsState(Card(
|
|
||||||
id = 0,
|
|
||||||
cardId = 0,
|
|
||||||
name = "",
|
|
||||||
logo = byteArrayOf(),
|
|
||||||
logoHeight = 0,
|
|
||||||
logoWidth = 0,
|
|
||||||
stageCount = 0,
|
|
||||||
isBEm = false
|
|
||||||
))
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBanner(
|
|
||||||
text = stringResource(R.string.write_character_title),
|
|
||||||
onBackClick = onClickCancel
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { innerPadding ->
|
|
||||||
Column(
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(innerPadding)
|
|
||||||
.fillMaxSize()
|
|
||||||
) {
|
|
||||||
Card (
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
Row (
|
|
||||||
modifier = Modifier.padding(16.dp),
|
|
||||||
){
|
|
||||||
if (cardDetails.logoHeight > 0 && cardDetails.logoWidth > 0) {
|
|
||||||
val charaBitmapData = BitmapData(
|
|
||||||
bitmap = cardDetails.logo,
|
|
||||||
width = cardDetails.logoWidth,
|
|
||||||
height = cardDetails.logoHeight
|
|
||||||
)
|
|
||||||
val charaImageBitmapData = charaBitmapData.getImageBitmap(
|
|
||||||
context = LocalContext.current,
|
|
||||||
multiplier = 4,
|
|
||||||
obscure = false
|
|
||||||
)
|
|
||||||
|
|
||||||
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 = stringResource(R.string.write_character_icon_description),
|
|
||||||
modifier = Modifier
|
|
||||||
.size(charaImageBitmapData.dpWidth)
|
|
||||||
.padding(8.dp),
|
|
||||||
filterQuality = FilterQuality.None
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(
|
|
||||||
modifier = Modifier.width(8.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Column {
|
|
||||||
Text(stringResource(R.string.write_character_success))
|
|
||||||
Text(stringResource(R.string.write_character_wait_ready))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = onClickConfirm,
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.write_character_confirm))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
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.setValue
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
|
||||||
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
|
||||||
import com.github.nacabaro.vbhelper.screens.scanScreen.SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
|
||||||
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenController
|
|
||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun WritingScreen(
|
|
||||||
scanScreenController: ScanScreenController,
|
|
||||||
characterId: Long,
|
|
||||||
nfcCharacter: NfcCharacter,
|
|
||||||
onComplete: () -> Unit,
|
|
||||||
onCancel: () -> Unit,
|
|
||||||
) {
|
|
||||||
val secrets by scanScreenController.secretsFlow.collectAsState(null)
|
|
||||||
|
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
|
||||||
val storageRepository = StorageRepository(application.container.db)
|
|
||||||
|
|
||||||
var writing by remember { mutableStateOf(false) }
|
|
||||||
var writingScreen by remember { mutableStateOf(false) }
|
|
||||||
var writingConfirmScreen by remember { mutableStateOf(false) }
|
|
||||||
var isDoneSendingCard by remember { mutableStateOf(false) }
|
|
||||||
var isDoneWritingCharacter by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
DisposableEffect(writing) {
|
|
||||||
if (writing) {
|
|
||||||
scanScreenController.registerActivityLifecycleListener(
|
|
||||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
|
||||||
object : ActivityLifecycleListener {
|
|
||||||
override fun onPause() {
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
if (!isDoneSendingCard) {
|
|
||||||
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter) {
|
|
||||||
isDoneSendingCard = true
|
|
||||||
}
|
|
||||||
} else if (!isDoneWritingCharacter) {
|
|
||||||
scanScreenController.onClickWrite(secrets!!, nfcCharacter) {
|
|
||||||
isDoneWritingCharacter = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (secrets != null) {
|
|
||||||
if (!isDoneSendingCard) {
|
|
||||||
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter) {
|
|
||||||
isDoneSendingCard = true
|
|
||||||
}
|
|
||||||
} else if (!isDoneWritingCharacter) {
|
|
||||||
scanScreenController.onClickWrite(secrets!!, nfcCharacter) {
|
|
||||||
isDoneWritingCharacter = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onDispose {
|
|
||||||
if (writing) {
|
|
||||||
scanScreenController.unregisterActivityLifecycleListener(
|
|
||||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
|
||||||
)
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!writingScreen) {
|
|
||||||
writing = false
|
|
||||||
WriteCardScreen (
|
|
||||||
characterId = characterId,
|
|
||||||
onClickCancel = {
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
onCancel()
|
|
||||||
},
|
|
||||||
onClickConfirm = {
|
|
||||||
writingScreen = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else if (!isDoneSendingCard) {
|
|
||||||
writing = true
|
|
||||||
ActionScreen( topBannerText = stringResource(R.string.sending_card_title)) {
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
onCancel()
|
|
||||||
}
|
|
||||||
} else if (!writingConfirmScreen) {
|
|
||||||
writing = false
|
|
||||||
WriteCharacterScreen (
|
|
||||||
characterId = characterId,
|
|
||||||
onClickCancel = {
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
onCancel()
|
|
||||||
},
|
|
||||||
onClickConfirm = {
|
|
||||||
writingConfirmScreen = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else if (!isDoneWritingCharacter) {
|
|
||||||
writing = true
|
|
||||||
ActionScreen(topBannerText = stringResource(R.string.writing_character_action_title)) {
|
|
||||||
isDoneSendingCard = false
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
onCancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var completedWriting by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
LaunchedEffect(isDoneSendingCard, isDoneWritingCharacter) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
if (isDoneSendingCard && isDoneWritingCharacter) {
|
|
||||||
storageRepository
|
|
||||||
.deleteCharacter(characterId)
|
|
||||||
completedWriting = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (completedWriting) {
|
|
||||||
onComplete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -6,10 +6,8 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CreditsScreen(
|
fun CreditsScreen(
|
||||||
@ -18,7 +16,7 @@ fun CreditsScreen(
|
|||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.credits_title),
|
text = "Credits",
|
||||||
onBackClick = {
|
onBackClick = {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
@ -31,13 +29,13 @@ fun CreditsScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
) {
|
) {
|
||||||
SettingsSection(stringResource(R.string.credits_section_reverse_engineering))
|
SettingsSection("Reverse engineering")
|
||||||
SettingsEntry(title = "cyanic", description = stringResource(R.string.credits_cyanic_description)) { }
|
SettingsEntry(title = "cyanic", description = "Reversed the firmware and helped us during development.") { }
|
||||||
SettingsSection(stringResource(R.string.credits_section_app_development))
|
SettingsSection("Application development")
|
||||||
SettingsEntry(title = "cfogrady", description = stringResource(R.string.credits_cfogrady_description)) { }
|
SettingsEntry(title = "cfogrady", description = "Developed vb-lib-nfc and part of this application.") { }
|
||||||
SettingsEntry(title = "nacabaro", description = stringResource(R.string.credits_nacabaro_description)) { }
|
SettingsEntry(title = "nacabaro", description = "Developed this application.") { }
|
||||||
SettingsEntry(title = "lightheel", description = stringResource(R.string.credits_lightheel_description)) { }
|
SettingsEntry(title = "lightheel", description = "Developing the battling part for this application, including server. Still in the works.") { }
|
||||||
SettingsEntry(title = "shvstrz", description = stringResource(R.string.credits_shvstrz_description)) { }
|
SettingsEntry(title = "shvstrz", description = "Designing the app icon in SVG.") { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.settingsScreen
|
package com.github.nacabaro.vbhelper.screens.settingsScreen
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -15,28 +13,22 @@ import androidx.compose.material3.Scaffold
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsScreen(
|
fun SettingsScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
settingsScreenController: SettingsScreenControllerImpl,
|
settingsScreenController: SettingsScreenControllerImpl,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.settings_title),
|
text = "Settings",
|
||||||
onBackClick = {
|
onBackClick = {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
@ -51,51 +43,25 @@ fun SettingsScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
SettingsSection(title = stringResource(R.string.settings_section_nfc))
|
SettingsSection("NFC Communication")
|
||||||
SettingsEntry(
|
SettingsEntry(title = "Import APK", description = "Import Secrets From Vital Arean 2.1.0 APK") {
|
||||||
title = stringResource(R.string.settings_import_apk_title),
|
|
||||||
description = stringResource(R.string.settings_import_apk_desc)
|
|
||||||
) {
|
|
||||||
settingsScreenController.onClickImportApk()
|
settingsScreenController.onClickImportApk()
|
||||||
}
|
}
|
||||||
|
SettingsSection("DiM/BEm management")
|
||||||
SettingsSection(title = stringResource(R.string.settings_section_dim_bem))
|
SettingsEntry(title = "Import card", description = "Import DiM/BEm card file") {
|
||||||
SettingsEntry(
|
|
||||||
title = stringResource(R.string.settings_import_card_title),
|
|
||||||
description = stringResource(R.string.settings_import_card_desc)
|
|
||||||
) {
|
|
||||||
settingsScreenController.onClickImportCard()
|
settingsScreenController.onClickImportCard()
|
||||||
}
|
}
|
||||||
|
SettingsEntry(title = "Rename DiM/BEm", description = "Set card name") { }
|
||||||
SettingsSection(title = stringResource(R.string.settings_section_about))
|
SettingsSection("About and credits")
|
||||||
SettingsEntry(
|
SettingsEntry(title = "Credits", description = "Credits") {
|
||||||
title = stringResource(R.string.settings_credits_title),
|
|
||||||
description = stringResource(R.string.settings_credits_desc)
|
|
||||||
) {
|
|
||||||
navController.navigate(NavigationItems.Credits.route)
|
navController.navigate(NavigationItems.Credits.route)
|
||||||
}
|
}
|
||||||
SettingsEntry(
|
SettingsEntry(title = "About", description = "About") { }
|
||||||
title = stringResource(R.string.settings_about_title),
|
SettingsSection("Data management")
|
||||||
description = stringResource(R.string.settings_about_desc)
|
SettingsEntry(title = "Export data", description = "Export application database") {
|
||||||
) {
|
|
||||||
val browserIntent = Intent(
|
|
||||||
Intent.ACTION_VIEW,
|
|
||||||
Uri.parse("https://github.com/nacabaro/vbhelper/")
|
|
||||||
)
|
|
||||||
context.startActivity(browserIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsSection(title = stringResource(R.string.settings_section_data))
|
|
||||||
SettingsEntry(
|
|
||||||
title = stringResource(R.string.settings_export_data_title),
|
|
||||||
description = stringResource(R.string.settings_export_data_desc)
|
|
||||||
) {
|
|
||||||
settingsScreenController.onClickOpenDirectory()
|
settingsScreenController.onClickOpenDirectory()
|
||||||
}
|
}
|
||||||
SettingsEntry(
|
SettingsEntry(title = "Import data", description = "Import application database") {
|
||||||
title = stringResource(R.string.settings_import_data_title),
|
|
||||||
description = stringResource(R.string.settings_import_data_desc)
|
|
||||||
) {
|
|
||||||
settingsScreenController.onClickImportDatabase()
|
settingsScreenController.onClickImportDatabase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +95,7 @@ fun SettingsSection(
|
|||||||
) {
|
) {
|
||||||
Box (
|
Box (
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(start = 16.dp, top = 16.dp, bottom = 4.dp)
|
.padding(start = 16.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
|
|||||||
@ -3,24 +3,36 @@ package com.github.nacabaro.vbhelper.screens.settingsScreen
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.provider.OpenableColumns
|
||||||
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
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.database.AppDatabase
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.controllers.CardImportController
|
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.controllers.DatabaseManagementController
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
|
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||||
|
import com.github.nacabaro.vbhelper.domain.card.CharacterData
|
||||||
import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
|
import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
|
||||||
import com.github.nacabaro.vbhelper.source.SecretsImporter
|
import com.github.nacabaro.vbhelper.source.SecretsImporter
|
||||||
import com.github.nacabaro.vbhelper.source.SecretsRepository
|
import com.github.nacabaro.vbhelper.source.SecretsRepository
|
||||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
|
||||||
class SettingsScreenControllerImpl(
|
class SettingsScreenControllerImpl(
|
||||||
private val context: ComponentActivity,
|
private val context: ComponentActivity,
|
||||||
): SettingsScreenController {
|
): SettingsScreenController {
|
||||||
|
private val roomDbName = "internalDb"
|
||||||
private val filePickerLauncher: ActivityResultLauncher<String>
|
private val filePickerLauncher: ActivityResultLauncher<String>
|
||||||
private val filePickerOpenerLauncher: ActivityResultLauncher<Array<String>>
|
private val filePickerOpenerLauncher: ActivityResultLauncher<Array<String>>
|
||||||
private val filePickerApk: ActivityResultLauncher<Array<String>>
|
private val filePickerApk: ActivityResultLauncher<Array<String>>
|
||||||
@ -29,17 +41,13 @@ class SettingsScreenControllerImpl(
|
|||||||
private val application = context.applicationContext as VBHelper
|
private val application = context.applicationContext as VBHelper
|
||||||
private val secretsRepository: SecretsRepository = application.container.dataStoreSecretsRepository
|
private val secretsRepository: SecretsRepository = application.container.dataStoreSecretsRepository
|
||||||
private val database: AppDatabase = application.container.db
|
private val database: AppDatabase = application.container.db
|
||||||
private val databaseManagementController = DatabaseManagementController(
|
|
||||||
componentActivity = context,
|
|
||||||
application = application
|
|
||||||
)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
filePickerLauncher = context.registerForActivityResult(
|
filePickerLauncher = context.registerForActivityResult(
|
||||||
ActivityResultContracts.CreateDocument("application/octet-stream")
|
ActivityResultContracts.CreateDocument("application/octet-stream")
|
||||||
) { uri ->
|
) { uri ->
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
databaseManagementController.exportDatabase(uri)
|
exportDatabase(uri)
|
||||||
} else {
|
} else {
|
||||||
context.runOnUiThread {
|
context.runOnUiThread {
|
||||||
Toast.makeText(context, "No destination selected", Toast.LENGTH_SHORT)
|
Toast.makeText(context, "No destination selected", Toast.LENGTH_SHORT)
|
||||||
@ -52,7 +60,7 @@ class SettingsScreenControllerImpl(
|
|||||||
ActivityResultContracts.OpenDocument()
|
ActivityResultContracts.OpenDocument()
|
||||||
) { uri ->
|
) { uri ->
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
databaseManagementController.importDatabase(uri)
|
importDatabase(uri)
|
||||||
} else {
|
} else {
|
||||||
context.runOnUiThread {
|
context.runOnUiThread {
|
||||||
Toast.makeText(context, "No source selected", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "No source selected", Toast.LENGTH_SHORT).show()
|
||||||
@ -101,14 +109,212 @@ class SettingsScreenControllerImpl(
|
|||||||
filePickerCard.launch(arrayOf("*/*"))
|
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<CharacterData>()
|
||||||
|
|
||||||
|
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(
|
||||||
|
CharacterData(
|
||||||
|
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 fun updateCardProgress(
|
||||||
|
cardId: Long,
|
||||||
|
) {
|
||||||
|
val cardProgress = CardProgress(
|
||||||
|
cardId = cardId,
|
||||||
|
currentStage = 0,
|
||||||
|
unlocked = false
|
||||||
|
)
|
||||||
|
|
||||||
|
database
|
||||||
|
.cardProgressDao()
|
||||||
|
.updateDimProgress(cardProgress)
|
||||||
|
}
|
||||||
|
|
||||||
private fun importCard(uri: Uri) {
|
private fun importCard(uri: Uri) {
|
||||||
context.lifecycleScope.launch(Dispatchers.IO) {
|
context.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val contentResolver = context.contentResolver
|
val contentResolver = context.contentResolver
|
||||||
val inputStream = contentResolver.openInputStream(uri)
|
val inputStream = contentResolver.openInputStream(uri)
|
||||||
|
|
||||||
inputStream.use { fileReader ->
|
inputStream.use { fileReader ->
|
||||||
val cardImportController = CardImportController(database)
|
val dimReader = DimReader()
|
||||||
cardImportController.importCard(fileReader)
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
inputStream?.close()
|
inputStream?.close()
|
||||||
@ -118,6 +324,100 @@ 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) {
|
private fun importApk(uri: Uri) {
|
||||||
context.lifecycleScope.launch(Dispatchers.IO) {
|
context.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
context.contentResolver.openInputStream(uri).use {
|
context.contentResolver.openInputStream(uri).use {
|
||||||
|
|||||||
@ -1,320 +0,0 @@
|
|||||||
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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -33,15 +33,11 @@ import com.github.nacabaro.vbhelper.source.StorageRepository
|
|||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import com.github.nacabaro.vbhelper.utils.getBitmap
|
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun StorageDialog(
|
fun StorageDialog(
|
||||||
characterId: Long,
|
characterId: Long,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onClickDelete: () -> Unit,
|
|
||||||
onSendToBracelet: () -> Unit,
|
onSendToBracelet: () -> Unit,
|
||||||
onClickSetActive: () -> Unit,
|
onClickSetActive: () -> Unit,
|
||||||
onClickSendToAdventure: (time: Long) -> Unit
|
onClickSendToAdventure: (time: Long) -> Unit
|
||||||
@ -97,7 +93,7 @@ fun StorageDialog(
|
|||||||
val dpSize = (characterSprite.value!!.width * 4 / density).dp
|
val dpSize = (characterSprite.value!!.width * 4 / density).dp
|
||||||
Image(
|
Image(
|
||||||
bitmap = imageBitmap,
|
bitmap = imageBitmap,
|
||||||
contentDescription = stringResource(R.string.storage_character_image_description),
|
contentDescription = "Character image",
|
||||||
filterQuality = FilterQuality.None,
|
filterQuality = FilterQuality.None,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(dpSize)
|
.size(dpSize)
|
||||||
@ -107,7 +103,7 @@ fun StorageDialog(
|
|||||||
val nameDpSize = (characterName.value!!.width * 4 / density).dp
|
val nameDpSize = (characterName.value!!.width * 4 / density).dp
|
||||||
Image(
|
Image(
|
||||||
bitmap = nameImageBitmap,
|
bitmap = nameImageBitmap,
|
||||||
contentDescription = stringResource(R.string.storage_character_image_description),
|
contentDescription = "Character image",
|
||||||
filterQuality = FilterQuality.None,
|
filterQuality = FilterQuality.None,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(nameDpSize)
|
.size(nameDpSize)
|
||||||
@ -124,7 +120,7 @@ fun StorageDialog(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.storage_send_to_watch))
|
Text(text = "Send to watch")
|
||||||
}
|
}
|
||||||
Spacer(
|
Spacer(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -133,7 +129,7 @@ fun StorageDialog(
|
|||||||
Button(
|
Button(
|
||||||
onClick = onClickSetActive,
|
onClick = onClickSetActive,
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.storage_set_active))
|
Text(text = "Set active")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button(
|
Button(
|
||||||
@ -143,21 +139,14 @@ fun StorageDialog(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.storage_send_on_adventure))
|
Text(text = "Send on adventure")
|
||||||
}
|
|
||||||
Button(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth(),
|
|
||||||
onClick = onClickDelete
|
|
||||||
) {
|
|
||||||
Text(text = stringResource(R.string.storage_delete_character))
|
|
||||||
}
|
}
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
onClick = onDismissRequest
|
onClick = onDismissRequest
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.storage_close))
|
Text(text = "Close")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.storageScreen
|
package com.github.nacabaro.vbhelper.screens.storageScreen
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
import androidx.compose.foundation.gestures.scrollable
|
import androidx.compose.foundation.gestures.scrollable
|
||||||
@ -12,15 +11,14 @@ import androidx.compose.foundation.lazy.grid.GridCells
|
|||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.material3.CardDefaults
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@ -30,12 +28,12 @@ import androidx.navigation.NavController
|
|||||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import androidx.compose.ui.res.stringResource
|
import kotlinx.coroutines.launch
|
||||||
import com.github.nacabaro.vbhelper.R
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -44,23 +42,30 @@ fun StorageScreen(
|
|||||||
storageScreenController: StorageScreenControllerImpl,
|
storageScreenController: StorageScreenControllerImpl,
|
||||||
adventureScreenController: AdventureScreenControllerImpl
|
adventureScreenController: AdventureScreenControllerImpl
|
||||||
) {
|
) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val storageRepository = StorageRepository(application.container.db)
|
val storageRepository = StorageRepository(application.container.db)
|
||||||
val characterList by storageRepository.getAllCharacters().collectAsState(initial = emptyList())
|
val monList = remember { mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList()) }
|
||||||
|
|
||||||
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
|
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
|
||||||
|
|
||||||
|
LaunchedEffect(storageRepository, selectedCharacter) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
val characterList = storageRepository.getAllCharacters()
|
||||||
|
monList.value = characterList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(
|
TopBanner(
|
||||||
text = stringResource(R.string.storage_my_characters_title),
|
text = "My characters",
|
||||||
onAdventureClick = {
|
onAdventureClick = {
|
||||||
navController.navigate(NavigationItems.Adventure.route)
|
navController.navigate(NavigationItems.Adventure.route)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
if (characterList.isEmpty()) {
|
if (monList.value.isEmpty()) {
|
||||||
Column (
|
Column (
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
@ -69,7 +74,7 @@ fun StorageScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.storage_nothing_to_see_here),
|
text = "Nothing to see here",
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
)
|
)
|
||||||
@ -81,7 +86,7 @@ fun StorageScreen(
|
|||||||
.scrollable(state = rememberScrollState(), orientation = Orientation.Vertical)
|
.scrollable(state = rememberScrollState(), orientation = Orientation.Vertical)
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
) {
|
) {
|
||||||
items(characterList) { index ->
|
items(monList.value) { index ->
|
||||||
CharacterEntry(
|
CharacterEntry(
|
||||||
icon = BitmapData(
|
icon = BitmapData(
|
||||||
bitmap = index.spriteIdle,
|
bitmap = index.spriteIdle,
|
||||||
@ -94,7 +99,7 @@ fun StorageScreen(
|
|||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
application,
|
application,
|
||||||
application.getString(R.string.storage_in_adventure_toast),
|
"This character is in an adventure",
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.navigate(
|
navController.navigate(
|
||||||
@ -102,16 +107,6 @@ fun StorageScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cardColors = if (index.active) {
|
|
||||||
CardDefaults.cardColors(
|
|
||||||
containerColor = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
CardDefaults.cardColors(
|
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceContainerHighest
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,16 +138,6 @@ fun StorageScreen(
|
|||||||
timeInMinutes = time
|
timeInMinutes = time
|
||||||
)
|
)
|
||||||
selectedCharacter = null
|
selectedCharacter = null
|
||||||
},
|
|
||||||
onClickDelete = {
|
|
||||||
storageScreenController
|
|
||||||
.deleteCharacter(
|
|
||||||
characterId = selectedCharacter!!,
|
|
||||||
onCompletion = {
|
|
||||||
Log.d("StorageScreen", "Character deleted")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
selectedCharacter = null
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,5 +2,4 @@ package com.github.nacabaro.vbhelper.screens.storageScreen
|
|||||||
|
|
||||||
interface StorageScreenController {
|
interface StorageScreenController {
|
||||||
fun setActive(characterId: Long, onCompletion: () -> Unit)
|
fun setActive(characterId: Long, onCompletion: () -> Unit)
|
||||||
fun deleteCharacter(characterId: Long, onCompletion: () -> Unit)
|
|
||||||
}
|
}
|
||||||
@ -28,21 +28,4 @@ class StorageScreenControllerImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deleteCharacter(characterId: Long, onCompletion: () -> Unit) {
|
|
||||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
database
|
|
||||||
.userCharacterDao()
|
|
||||||
.deleteCharacterById(characterId)
|
|
||||||
|
|
||||||
componentActivity.runOnUiThread {
|
|
||||||
Toast.makeText(
|
|
||||||
componentActivity,
|
|
||||||
"Character deleted!",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
onCompletion()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.source
|
|
||||||
|
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
|
||||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
class CardRepository (
|
|
||||||
private val db: AppDatabase
|
|
||||||
) {
|
|
||||||
fun getCardIconByCharaId(charaId: Long): Flow<CardDtos.CardIcon> {
|
|
||||||
return db
|
|
||||||
.cardDao()
|
|
||||||
.getCardIconByCharaId(charaId = charaId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,24 +3,19 @@ package com.github.nacabaro.vbhelper.source
|
|||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
class DexRepository (
|
class DexRepository (
|
||||||
private val db: AppDatabase
|
private val db: AppDatabase
|
||||||
) {
|
) {
|
||||||
fun getAllDims(): Flow<List<CardDtos.CardProgress>> {
|
suspend fun getAllDims(): List<CardDtos.CardProgress> {
|
||||||
return db.dexDao().getCardsWithProgress()
|
return db.dexDao().getCardsWithProgress()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCharactersByCardId(cardId: Long): Flow<List<CharacterDtos.CardCharaProgress>> {
|
suspend fun getCharactersByCardId(cardId: Long): List<CharacterDtos.CardCharaProgress> {
|
||||||
return db.dexDao().getSingleCardProgress(cardId)
|
return db.dexDao().getSingleCardProgress(cardId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCharacterPossibleTransformations(characterId: Long): Flow<List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>> {
|
suspend fun getCardPossibleTransformations(cardId: Long): List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained> {
|
||||||
return db.characterDao().getEvolutionRequirementsForCard(characterId)
|
return db.characterDao().getEvolutionRequirementsForCard(cardId)
|
||||||
}
|
|
||||||
|
|
||||||
fun getCharacterPossibleFusions(characterId: Long): Flow<List<CharacterDtos.FusionsWithSpritesAndObtained>> {
|
|
||||||
return db.cardFusionsDao().getFusionsForCharacter(characterId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,17 +1,17 @@
|
|||||||
package com.github.nacabaro.vbhelper.source
|
package com.github.nacabaro.vbhelper.source
|
||||||
|
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||||
|
import com.github.nacabaro.vbhelper.domain.items.Items
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
class ItemsRepository(
|
class ItemsRepository(
|
||||||
private val db: AppDatabase
|
private val db: AppDatabase
|
||||||
) {
|
) {
|
||||||
fun getAllItems(): Flow<List<ItemDtos.ItemsWithQuantities>> {
|
suspend fun getAllItems(): List<ItemDtos.ItemsWithQuantities> {
|
||||||
return db.itemDao().getAllItems()
|
return db.itemDao().getAllItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUserItems(): Flow<List<ItemDtos.ItemsWithQuantities>> {
|
suspend fun getUserItems(): List<ItemDtos.ItemsWithQuantities> {
|
||||||
return db.itemDao().getAllUserItems()
|
return db.itemDao().getAllUserItems()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.github.nacabaro.vbhelper.source
|
|
||||||
|
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
class ScanRepository(
|
|
||||||
val database: AppDatabase
|
|
||||||
) {
|
|
||||||
fun getCardDetails(characterId: Long): Flow<Card> {
|
|
||||||
return database.cardDao().getCardByCharacterId(characterId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -6,12 +6,11 @@ import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
|||||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
class StorageRepository (
|
class StorageRepository (
|
||||||
private val db: AppDatabase
|
private val db: AppDatabase
|
||||||
) {
|
) {
|
||||||
fun getAllCharacters(): Flow<List<CharacterDtos.CharacterWithSprites>> {
|
suspend fun getAllCharacters(): List<CharacterDtos.CharacterWithSprites> {
|
||||||
return db.userCharacterDao().getAllCharacters()
|
return db.userCharacterDao().getAllCharacters()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,19 +18,19 @@ class StorageRepository (
|
|||||||
return db.userCharacterDao().getCharacterWithSprites(id)
|
return db.userCharacterDao().getCharacterWithSprites(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCharacterBeData(id: Long): Flow<BECharacterData> {
|
suspend fun getCharacterBeData(id: Long): BECharacterData {
|
||||||
return db.userCharacterDao().getBeData(id)
|
return db.userCharacterDao().getBeData(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTransformationHistory(characterId: Long): Flow<List<CharacterDtos.TransformationHistory>> {
|
suspend fun getTransformationHistory(characterId: Long): List<CharacterDtos.TransformationHistory>? {
|
||||||
return db.userCharacterDao().getTransformationHistory(characterId)
|
return db.userCharacterDao().getTransformationHistory(characterId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCharacterVbData(id: Long): Flow<VBCharacterData> {
|
suspend fun getCharacterVbData(id: Long): VBCharacterData {
|
||||||
return db.userCharacterDao().getVbData(id)
|
return db.userCharacterDao().getVbData(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSpecialMissions(id: Long): Flow<List<SpecialMissions>> {
|
suspend fun getSpecialMissions(id: Long): List<SpecialMissions> {
|
||||||
return db.userCharacterDao().getSpecialMissions(id)
|
return db.userCharacterDao().getSpecialMissions(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ class StorageRepository (
|
|||||||
return db.itemDao().getItem(id)
|
return db.itemDao().getItem(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getActiveCharacter(): Flow<CharacterDtos.CharacterWithSprites?> {
|
suspend fun getActiveCharacter(): CharacterDtos.CharacterWithSprites? {
|
||||||
return db.userCharacterDao().getActiveCharacter()
|
return db.userCharacterDao().getActiveCharacter()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ class StorageRepository (
|
|||||||
return db.userCharacterDao().deleteCharacterById(id)
|
return db.userCharacterDao().deleteCharacterById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAdventureCharacters(): Flow<List<CharacterDtos.AdventureCharacterWithSprites>> {
|
suspend fun getAdventureCharacters(): List<CharacterDtos.AdventureCharacterWithSprites> {
|
||||||
return db.adventureDao().getAdventureCharacters()
|
return db.adventureDao().getAdventureCharacters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,220 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<string name="app_name">VBHelper</string>
|
|
||||||
<string name="beta_warning_message_main">
|
|
||||||
Este aplicativo ainda está em versão alfa e não está completo. Não o use para armazenar personagens importantes para você, pois futuras atualizações podem apagar todos os seus personagens. Desculpe pelo transtorno!
|
|
||||||
</string>
|
|
||||||
<string name="beta_warning_message_compatibility">
|
|
||||||
O aplicativo agora deve funcionar com o VB original e com o VH.
|
|
||||||
</string>
|
|
||||||
<string name="beta_warning_message_thanks">
|
|
||||||
Obrigado pela compreensão e pela paciência. Atenciosamente, a equipe de desenvolvimento.
|
|
||||||
</string>
|
|
||||||
<string name="beta_warning_button_dismiss">Fechar</string>
|
|
||||||
|
|
||||||
|
|
||||||
<string name="nav_scan">Escanear</string>
|
|
||||||
<string name="nav_battle">Batalhas</string>
|
|
||||||
<string name="nav_home">Início</string>
|
|
||||||
<string name="nav_dex">Dex</string>
|
|
||||||
<string name="nav_card_adventure">Aventura do card</string>
|
|
||||||
<string name="nav_storage">Armazenamento</string>
|
|
||||||
<string name="nav_settings">Configurações</string>
|
|
||||||
<string name="nav_viewer">Visualizador</string>
|
|
||||||
<string name="nav_card">Card</string>
|
|
||||||
<string name="nav_items">Itens</string>
|
|
||||||
<string name="nav_my_items">Meus itens</string>
|
|
||||||
<string name="nav_items_store">Loja de itens</string>
|
|
||||||
<string name="nav_apply_item">Aplicar item</string>
|
|
||||||
<string name="nav_adventure">Aventura</string>
|
|
||||||
<string name="nav_credits">Créditos</string>
|
|
||||||
|
|
||||||
<string name="adventure_title">Aventura</string>
|
|
||||||
<string name="adventure_empty_state">Nada para ver aqui</string>
|
|
||||||
|
|
||||||
<string name="home_title">VB Helper</string>
|
|
||||||
<string name="home_adventure_mission_finished">
|
|
||||||
Um dos seus personagens terminou a missão de aventura!
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="scan_secrets_not_initialized">
|
|
||||||
Os segredos ainda não foram inicializados. Tente novamente.
|
|
||||||
</string>
|
|
||||||
<string name="scan_secrets_not_imported">
|
|
||||||
Os segredos ainda não foram importados. Vá em Configurações e importe o APK.
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="scan_title">Escanear um Vital Bracelet</string>
|
|
||||||
<string name="scan_vb_to_app">Vital Bracelet para o app</string>
|
|
||||||
<string name="scan_app_to_vb">App para o Vital Bracelet</string>
|
|
||||||
|
|
||||||
<string name="scan_no_nfc_on_device">O dispositivo não possui NFC!</string>
|
|
||||||
<string name="scan_tag_not_vb">A tag detectada não é do Vital Bracelet.</string>
|
|
||||||
<string name="scan_missing_secrets">
|
|
||||||
Segredos ausentes. Vá em Configurações e importe o APK do Vital Arena.
|
|
||||||
</string>
|
|
||||||
<string name="scan_sent_character_success">Personagem enviado com sucesso!</string>
|
|
||||||
<string name="scan_error_generic">Ops!</string>
|
|
||||||
<string name="scan_sent_dim_success">DIM enviado com sucesso!</string>
|
|
||||||
<string name="scan_nfc_must_be_enabled">O NFC precisa estar ativado.</string>
|
|
||||||
|
|
||||||
<string name="settings_title">Configurações</string>
|
|
||||||
|
|
||||||
<string name="settings_section_nfc">Comunicação NFC</string>
|
|
||||||
<string name="settings_section_dim_bem">Gerenciamento de DiM/BEm</string>
|
|
||||||
<string name="settings_section_about">Sobre e créditos</string>
|
|
||||||
<string name="settings_section_data">Gerenciamento de dados</string>
|
|
||||||
|
|
||||||
<string name="settings_import_apk_title">Importar APK</string>
|
|
||||||
<string name="settings_import_apk_desc">
|
|
||||||
Importar segredos do APK do Vital Arena 2.1.0
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="settings_import_card_title">Importar card</string>
|
|
||||||
<string name="settings_import_card_desc">
|
|
||||||
Importar arquivo de card DiM/BEm
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="settings_credits_title">Créditos</string>
|
|
||||||
<string name="settings_credits_desc">Créditos</string>
|
|
||||||
|
|
||||||
<string name="settings_about_title">Sobre</string>
|
|
||||||
<string name="settings_about_desc">Sobre</string>
|
|
||||||
|
|
||||||
<string name="settings_export_data_title">Exportar dados</string>
|
|
||||||
<string name="settings_export_data_desc">
|
|
||||||
Exportar banco de dados do aplicativo
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="settings_import_data_title">Importar dados</string>
|
|
||||||
<string name="settings_import_data_desc">
|
|
||||||
Importar banco de dados do aplicativo
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="credits_title">Créditos</string>
|
|
||||||
<string name="credits_section_reverse_engineering">Engenharia reversa</string>
|
|
||||||
<string name="credits_section_app_development">Desenvolvimento do aplicativo</string>
|
|
||||||
|
|
||||||
<string name="credits_cyanic_description">
|
|
||||||
Reverteu o firmware e nos ajudou durante o desenvolvimento.
|
|
||||||
</string>
|
|
||||||
<string name="credits_cfogrady_description">
|
|
||||||
Desenvolveu vb-lib-nfc e parte deste aplicativo.
|
|
||||||
</string>
|
|
||||||
<string name="credits_nacabaro_description">
|
|
||||||
Desenvolveu este aplicativo.
|
|
||||||
</string>
|
|
||||||
<string name="credits_lightheel_description">
|
|
||||||
Está desenvolvendo a parte de batalhas deste aplicativo, incluindo o servidor. Ainda em desenvolvimento.
|
|
||||||
</string>
|
|
||||||
<string name="credits_shvstrz_description">
|
|
||||||
Responsável pelo design do ícone do aplicativo em SVG.
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="action_place_near_reader">Aproxime o seu Vital Bracelet do leitor...</string>
|
|
||||||
<string name="action_cancel">Cancelar</string>
|
|
||||||
|
|
||||||
<string name="read_character_title">Ler personagem</string>
|
|
||||||
<string name="read_character_prepare_device">Prepare seu dispositivo!</string>
|
|
||||||
<string name="read_character_go_to_connect">Vá em conectar e, quando estiver pronto, pressione confirmar!</string>
|
|
||||||
<string name="read_character_confirm">Confirmar</string>
|
|
||||||
|
|
||||||
<string name="reading_character_title">Lendo personagem</string>
|
|
||||||
|
|
||||||
<string name="write_card_title">Escrevendo detalhes do cartão</string>
|
|
||||||
<string name="write_card_icon_description">Ícone do cartão</string>
|
|
||||||
<string name="write_card_device_ready">Prepare o seu dispositivo!</string>
|
|
||||||
<string name="write_card_required_card">Você vai precisar do cartão %1$s!</string>
|
|
||||||
<string name="write_card_confirm">Confirmar</string>
|
|
||||||
|
|
||||||
<string name="write_character_title">Escrevendo personagem</string>
|
|
||||||
<string name="write_character_icon_description">Ícone do personagem</string>
|
|
||||||
<string name="write_character_success">
|
|
||||||
Cartão instalado com sucesso!!
|
|
||||||
</string>
|
|
||||||
<string name="write_character_wait_ready">
|
|
||||||
Aguarde até que seu dispositivo esteja pronto e então toque em Confirmar
|
|
||||||
</string>
|
|
||||||
<string name="write_character_confirm">Confirmar</string>
|
|
||||||
|
|
||||||
<string name="sending_card_title">Enviando cartão</string>
|
|
||||||
<string name="writing_character_action_title">Escrevendo personagem</string>
|
|
||||||
|
|
||||||
<string name="items_title">Itens</string>
|
|
||||||
<string name="items_no_items">Nenhum item</string>
|
|
||||||
|
|
||||||
<string name="items_store_credits">%1$d créditos</string>
|
|
||||||
<string name="items_not_enough_credits">Créditos insuficientes</string>
|
|
||||||
<string name="items_purchase_success">Compra realizada com sucesso!</string>
|
|
||||||
|
|
||||||
<string name="obtained_item_you_have">Você obteve %1$d deste item</string>
|
|
||||||
<string name="obtained_item_you_also_got_credits">Você também recebeu %1$d créditos</string>
|
|
||||||
<string name="obtained_item_dismiss">Fechar</string>
|
|
||||||
|
|
||||||
<string name="choose_character_title">Escolher personagem</string>
|
|
||||||
<string name="choose_character_item_applied">Item aplicado!</string>
|
|
||||||
|
|
||||||
<string name="item_dialog_costs_credits">Custa %1$d créditos</string>
|
|
||||||
<string name="item_dialog_you_have_quantity">Você tem %1$d deste item</string>
|
|
||||||
<string name="item_dialog_use">Usar item</string>
|
|
||||||
<string name="item_dialog_purchase">Comprar</string>
|
|
||||||
<string name="item_dialog_cancel">Cancelar</string>
|
|
||||||
|
|
||||||
<string name="battles_online_title">Batalhas online</string>
|
|
||||||
<string name="battles_coming_soon">Em breve</string>
|
|
||||||
|
|
||||||
<string name="cards_my_cards_title">Meus cards</string>
|
|
||||||
|
|
||||||
<string name="card_view_discovered_characters">Personagens descobertos</string>
|
|
||||||
|
|
||||||
<string name="dex_chara_icon_description">Ícone do personagem</string>
|
|
||||||
<string name="dex_chara_name_icon_description">Nome do personagem</string>
|
|
||||||
<string name="dex_chara_stats">HP: %1$d, BP: %2$d, AP: %3$d</string>
|
|
||||||
<string name="dex_chara_stage_attribute">Stg: %1$s, Atr: %2$s</string>
|
|
||||||
<string name="dex_chara_unknown_name">\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?</string>
|
|
||||||
<string name="dex_chara_stage_attribute_unknown">Stg: -, Atr: -</string>
|
|
||||||
<string name="dex_chara_stats_unknown">HP: -, BP: -, AP: -</string>
|
|
||||||
<string name="dex_chara_requirements">
|
|
||||||
Tr: %1$d; Bt: %2$d; Vr: %3$d; Wr: %4$d%%; Ct: %5$dh
|
|
||||||
</string>
|
|
||||||
<string name="dex_chara_adventure_level">AdvLvl %1$d</string>
|
|
||||||
<string name="dex_chara_fusions_button">Fusões</string>
|
|
||||||
<string name="dex_chara_close_button">Fechar</string>
|
|
||||||
|
|
||||||
<string name="card_adventure_missions_title">Missões de aventura</string>
|
|
||||||
|
|
||||||
<string name="card_entry_characters_obtained">%1$d de %2$d personagens obtidos</string>
|
|
||||||
<string name="card_entry_edit">Editar card</string>
|
|
||||||
<string name="card_entry_delete">Excluir card</string>
|
|
||||||
|
|
||||||
<string name="storage_my_characters_title">Meus personagens</string>
|
|
||||||
<string name="storage_nothing_to_see_here">Nada para ver aqui</string>
|
|
||||||
<string name="storage_in_adventure_toast">Este personagem está em uma aventura</string>
|
|
||||||
|
|
||||||
<string name="storage_character_image_description">Imagem do personagem</string>
|
|
||||||
<string name="storage_send_to_watch">Enviar para o relógio</string>
|
|
||||||
<string name="storage_set_active">Definir como ativo</string>
|
|
||||||
<string name="storage_send_on_adventure">Enviar para aventura</string>
|
|
||||||
<string name="storage_delete_character">Excluir personagem</string>
|
|
||||||
<string name="storage_close">Fechar</string>
|
|
||||||
|
|
||||||
<string name="home_vbdim_vitals">Vitais</string>
|
|
||||||
<string name="home_vbdim_trophies">Troféus</string>
|
|
||||||
<string name="home_vbdim_mood">Humor</string>
|
|
||||||
<string name="home_vbdim_next_timer">Próximo timer</string>
|
|
||||||
<string name="home_vbdim_total_battle_win">% vitórias totais</string>
|
|
||||||
<string name="home_vbdim_current_phase_win">% vitórias fase atual</string>
|
|
||||||
<string name="home_vbdim_special_missions">Missões especiais</string>
|
|
||||||
|
|
||||||
<string name="special_mission_none">Nenhuma missão selecionada</string>
|
|
||||||
<string name="special_mission_steps">Ande %1$d passos</string>
|
|
||||||
<string name="special_mission_battles">Lute %1$d vezes</string>
|
|
||||||
<string name="special_mission_wins">Vença %1$d batalhas</string>
|
|
||||||
<string name="special_mission_vitals">Ganhe %1$d vitals</string>
|
|
||||||
<string name="special_mission_steps_progress">Andou %1$d passos</string>
|
|
||||||
<string name="special_mission_battles_progress">Lutou %1$d vezes</string>
|
|
||||||
<string name="special_mission_wins_progress">Venceu %1$d batalhas</string>
|
|
||||||
<string name="special_mission_vitals_progress">Ganhou %1$d vitals</string>
|
|
||||||
<string name="special_mission_icon_content_description">Ícone de missão especial</string>
|
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
|
||||||
@ -1,229 +1,3 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">VBHelper</string>
|
<string name="app_name">VBHelper</string>
|
||||||
<string name="beta_warning_message_main">
|
|
||||||
This application is currently in alpha and it is not complete. Do not use it to store important characters for you, as any future updates might delete all your characters. Sorry for the inconvenience!
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="beta_warning_message_compatibility">
|
|
||||||
The application should now work with the original VB and the VH.
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="beta_warning_message_thanks">
|
|
||||||
Thank you for your understanding and patience. Sincerely, the dev team.
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="beta_warning_button_dismiss">
|
|
||||||
Dismiss
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="nav_scan">Scan</string>
|
|
||||||
<string name="nav_battle">Battle</string>
|
|
||||||
<string name="nav_home">Home</string>
|
|
||||||
<string name="nav_dex">Dex</string>
|
|
||||||
<string name="nav_card_adventure">Card adventure</string>
|
|
||||||
<string name="nav_storage">Storage</string>
|
|
||||||
<string name="nav_settings">Settings</string>
|
|
||||||
<string name="nav_viewer">Viewer</string>
|
|
||||||
<string name="nav_card">Card</string>
|
|
||||||
<string name="nav_items">Items</string>
|
|
||||||
<string name="nav_my_items">My items</string>
|
|
||||||
<string name="nav_items_store">Items store</string>
|
|
||||||
<string name="nav_apply_item">Apply item</string>
|
|
||||||
<string name="nav_adventure">Adventure</string>
|
|
||||||
<string name="nav_credits">Credits</string>
|
|
||||||
|
|
||||||
<string name="adventure_title">Adventure</string>
|
|
||||||
<string name="adventure_empty_state">Nothing to see here</string>
|
|
||||||
|
|
||||||
<string name="home_title">VB Helper</string>
|
|
||||||
<string name="home_adventure_mission_finished">
|
|
||||||
One of your characters has finished their adventure mission!
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="scan_secrets_not_initialized">
|
|
||||||
Secrets is not yet initialized. Try again.
|
|
||||||
</string>
|
|
||||||
<string name="scan_secrets_not_imported">
|
|
||||||
Secrets not yet imported. Go to Settings and Import APK.
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="scan_title">Scan a Vital Bracelet</string>
|
|
||||||
<string name="scan_vb_to_app">Vital Bracelet to App</string>
|
|
||||||
<string name="scan_app_to_vb">App to Vital Bracelet</string>
|
|
||||||
|
|
||||||
<string name="scan_no_nfc_on_device">No NFC on device!</string>
|
|
||||||
<string name="scan_tag_not_vb">Tag detected is not VB</string>
|
|
||||||
<string name="scan_missing_secrets">
|
|
||||||
Missing Secrets. Go to settings and import Vital Arena APK.
|
|
||||||
</string>
|
|
||||||
<string name="scan_sent_character_success">Sent character successfully!</string>
|
|
||||||
<string name="scan_error_generic">Whoops</string>
|
|
||||||
<string name="scan_sent_dim_success">Sent DIM successfully!</string>
|
|
||||||
<string name="scan_nfc_must_be_enabled">NFC must be enabled</string>
|
|
||||||
|
|
||||||
|
|
||||||
<string name="settings_title">Settings</string>
|
|
||||||
|
|
||||||
<string name="settings_section_nfc">NFC Communication</string>
|
|
||||||
<string name="settings_section_dim_bem">DiM/BEm management</string>
|
|
||||||
<string name="settings_section_about">About and credits</string>
|
|
||||||
<string name="settings_section_data">Data management</string>
|
|
||||||
|
|
||||||
<string name="settings_import_apk_title">Import APK</string>
|
|
||||||
<string name="settings_import_apk_desc">
|
|
||||||
Import Secrets From Vital Arena 2.1.0 APK
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="settings_import_card_title">Import card</string>
|
|
||||||
<string name="settings_import_card_desc">
|
|
||||||
Import DiM/BEm card file
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="settings_credits_title">Credits</string>
|
|
||||||
<string name="settings_credits_desc">Credits</string>
|
|
||||||
|
|
||||||
<string name="settings_about_title">About</string>
|
|
||||||
<string name="settings_about_desc">About</string>
|
|
||||||
|
|
||||||
<string name="settings_export_data_title">Export data</string>
|
|
||||||
<string name="settings_export_data_desc">
|
|
||||||
Export application database
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="settings_import_data_title">Import data</string>
|
|
||||||
<string name="settings_import_data_desc">
|
|
||||||
Import application database
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="credits_title">Credits</string>
|
|
||||||
<string name="credits_section_reverse_engineering">Reverse engineering</string>
|
|
||||||
<string name="credits_section_app_development">Application development</string>
|
|
||||||
|
|
||||||
<string name="credits_cyanic_description">
|
|
||||||
Reversed the firmware and helped us during development.
|
|
||||||
</string>
|
|
||||||
<string name="credits_cfogrady_description">
|
|
||||||
Developed vb-lib-nfc and part of this application.
|
|
||||||
</string>
|
|
||||||
<string name="credits_nacabaro_description">
|
|
||||||
Developed this application.
|
|
||||||
</string>
|
|
||||||
<string name="credits_lightheel_description">
|
|
||||||
Developing the battling part for this application, including server. Still in the works.
|
|
||||||
</string>
|
|
||||||
<string name="credits_shvstrz_description">
|
|
||||||
Designing the app icon in SVG.
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="action_place_near_reader">Place your Vital Bracelet near the reader...</string>
|
|
||||||
<string name="action_cancel">Cancel</string>
|
|
||||||
|
|
||||||
<string name="read_character_title">Read character</string>
|
|
||||||
<string name="read_character_prepare_device">Prepare your device!</string>
|
|
||||||
<string name="read_character_go_to_connect">Go to connect and when ready press confirm!</string>
|
|
||||||
<string name="read_character_confirm">Confirm</string>
|
|
||||||
|
|
||||||
<string name="reading_character_title">Reading character</string>
|
|
||||||
|
|
||||||
<string name="write_card_title">Writing card details</string>
|
|
||||||
<string name="write_card_icon_description">Card icon</string>
|
|
||||||
<string name="write_card_device_ready">Get your device ready!</string>
|
|
||||||
<string name="write_card_required_card">You will need %1$s card!</string>
|
|
||||||
<string name="write_card_confirm">Confirm</string>
|
|
||||||
|
|
||||||
|
|
||||||
<string name="write_character_title">Writing character</string>
|
|
||||||
<string name="write_character_icon_description">Character icon</string>
|
|
||||||
<string name="write_character_success">
|
|
||||||
Card installed successfully!!
|
|
||||||
</string>
|
|
||||||
<string name="write_character_wait_ready">
|
|
||||||
Wait until your device is ready, then tap Confirm
|
|
||||||
</string>
|
|
||||||
<string name="write_character_confirm">Confirm</string>
|
|
||||||
|
|
||||||
<string name="sending_card_title">Sending card</string>
|
|
||||||
<string name="writing_character_action_title">Writing character</string>
|
|
||||||
|
|
||||||
<string name="items_title">Items</string>
|
|
||||||
<string name="items_no_items">No items</string>
|
|
||||||
|
|
||||||
<string name="items_store_credits">%1$d credits</string>
|
|
||||||
<string name="items_not_enough_credits">Not enough credits</string>
|
|
||||||
<string name="items_purchase_success">Purchase successful!</string>
|
|
||||||
|
|
||||||
<string name="obtained_item_you_have">You have obtained %1$d of this item</string>
|
|
||||||
<string name="obtained_item_you_also_got_credits">You also got %1$d credits</string>
|
|
||||||
<string name="obtained_item_dismiss">Dismiss</string>
|
|
||||||
|
|
||||||
<string name="choose_character_title">Choose character</string>
|
|
||||||
<string name="choose_character_item_applied">Item applied!</string>
|
|
||||||
|
|
||||||
<string name="item_dialog_costs_credits">Costs %1$d credits</string>
|
|
||||||
<string name="item_dialog_you_have_quantity">You have %1$d of this item</string>
|
|
||||||
<string name="item_dialog_use">Use item</string>
|
|
||||||
<string name="item_dialog_purchase">Purchase</string>
|
|
||||||
<string name="item_dialog_cancel">Cancel</string>
|
|
||||||
|
|
||||||
<string name="battles_online_title">Online battles</string>
|
|
||||||
<string name="battles_coming_soon">Coming soon</string>
|
|
||||||
|
|
||||||
<string name="cards_my_cards_title">My cards</string>
|
|
||||||
|
|
||||||
<string name="card_view_discovered_characters">Discovered characters</string>
|
|
||||||
|
|
||||||
|
|
||||||
<string name="dex_chara_icon_description">Character icon</string>
|
|
||||||
<string name="dex_chara_name_icon_description">Character name</string>
|
|
||||||
<string name="dex_chara_stats">HP: %1$d, BP: %2$d, AP: %3$d</string>
|
|
||||||
<string name="dex_chara_stage_attribute">Stg: %1$s, Atr: %2$s</string>
|
|
||||||
<string name="dex_chara_unknown_name">\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?</string>
|
|
||||||
<string name="dex_chara_stage_attribute_unknown">Stg: -, Atr: -</string>
|
|
||||||
<string name="dex_chara_stats_unknown">HP: -, BP: -, AP: -</string>
|
|
||||||
<string name="dex_chara_requirements">
|
|
||||||
Tr: %1$d; Bt: %2$d; Vr: %3$d; Wr: %4$d%%; Ct: %5$dh
|
|
||||||
</string>
|
|
||||||
<string name="dex_chara_adventure_level">AdvLvl %1$d</string>
|
|
||||||
<string name="dex_chara_fusions_button">Fusions</string>
|
|
||||||
<string name="dex_chara_close_button">Close</string>
|
|
||||||
|
|
||||||
<string name="card_adventure_missions_title">Adventure missions</string>
|
|
||||||
|
|
||||||
<string name="card_entry_characters_obtained">%1$d of %2$d characters obtained</string>
|
|
||||||
<string name="card_entry_edit">Edit card</string>
|
|
||||||
<string name="card_entry_delete">Delete card</string>
|
|
||||||
|
|
||||||
<string name="storage_my_characters_title">My characters</string>
|
|
||||||
<string name="storage_nothing_to_see_here">Nothing to see here</string>
|
|
||||||
<string name="storage_in_adventure_toast">This character is in an adventure</string>
|
|
||||||
|
|
||||||
<string name="storage_character_image_description">Character image</string>
|
|
||||||
<string name="storage_send_to_watch">Send to watch</string>
|
|
||||||
<string name="storage_set_active">Set active</string>
|
|
||||||
<string name="storage_send_on_adventure">Send on adventure</string>
|
|
||||||
<string name="storage_delete_character">Delete character</string>
|
|
||||||
<string name="storage_close">Close</string>
|
|
||||||
|
|
||||||
<string name="home_vbdim_vitals">Vitals</string>
|
|
||||||
<string name="home_vbdim_trophies">Trophies</string>
|
|
||||||
<string name="home_vbdim_mood">Mood</string>
|
|
||||||
<string name="home_vbdim_next_timer">Next timer</string>
|
|
||||||
<string name="home_vbdim_total_battle_win">Total battle win %</string>
|
|
||||||
<string name="home_vbdim_current_phase_win">Current phase win %</string>
|
|
||||||
<string name="home_vbdim_special_missions">Special missions</string>
|
|
||||||
|
|
||||||
<string name="special_mission_none">No mission selected</string>
|
|
||||||
<string name="special_mission_steps">Walk %1$d steps</string>
|
|
||||||
<string name="special_mission_battles">Battle %1$d times</string>
|
|
||||||
<string name="special_mission_wins">Win %1$d battles</string>
|
|
||||||
<string name="special_mission_vitals">Earn %1$d vitals</string>
|
|
||||||
<string name="special_mission_steps_progress">Walked %1$d steps</string>
|
|
||||||
<string name="special_mission_battles_progress">Battled %1$d times</string>
|
|
||||||
<string name="special_mission_wins_progress">Won %1$d battles</string>
|
|
||||||
<string name="special_mission_vitals_progress">Earned %1$d vitals</string>
|
|
||||||
<string name="special_mission_icon_content_description">Special mission icon</string>
|
|
||||||
<string name="home_special_mission_delete_main">Are you sure you want to delete this special mission with this progress?</string>
|
|
||||||
<string name="home_special_mission_delete_dismiss">Dismiss</string>
|
|
||||||
<string name="home_special_mission_delete_remove">Remove</string>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.13.2"
|
agp = "8.12.2"
|
||||||
datastore = "1.1.2"
|
datastore = "1.1.2"
|
||||||
kotlin = "2.0.0"
|
kotlin = "2.0.0"
|
||||||
coreKtx = "1.15.0"
|
coreKtx = "1.15.0"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user