M app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt +12 -0
@@ 5,6 5,7 @@ import androidx.room.Insert
import androidx.room.Query
import com.github.nacabaro.vbhelper.domain.Character
import com.github.nacabaro.vbhelper.domain.Sprites
+import com.github.nacabaro.vbhelper.dtos.CharacterDtos
@Dao
interface CharacterDao {
@@ 25,4 26,15 @@ interface CharacterDao {
@Query("SELECT * FROM Sprites")
suspend fun getAllSprites(): List<Sprites>
+
+ @Query("""
+ SELECT
+ d.dimId as cardId,
+ c.monIndex as charId
+ FROM Character c
+ JOIN UserCharacter uc ON c.id = uc.charId
+ JOIN Dim d ON c.dimId = d.id
+ WHERE uc.id = :charId
+ """)
+ suspend fun getCharacterInfo(charId: Long): CharacterDtos.DiMInfo
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt +4 -1
@@ 21,7 21,7 @@ interface UserCharacterDao {
fun insertTransformationHistory(vararg transformationHistory: TransformationHistory)
@Query("SELECT * FROM TransformationHistory WHERE monId = :monId")
- fun getTransformationHistory(monId: Int): List<TransformationHistory>
+ fun getTransformationHistory(monId: Long): List<TransformationHistory>
@Query("""
SELECT
@@ 36,4 36,7 @@ interface UserCharacterDao {
@Query("SELECT * FROM UserCharacter WHERE id = :id")
suspend fun getCharacter(id: Long): UserCharacter
+
+ @Query("SELECT * FROM BECharacterData WHERE id = :id")
+ suspend fun getBeData(id: Long): BECharacterData
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt => app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt +5 -1
@@ 1,6 1,5 @@
package com.github.nacabaro.vbhelper.dtos
-import androidx.room.PrimaryKey
import com.github.cfogrady.vbnfc.data.NfcCharacter
import com.github.nacabaro.vbhelper.domain.DeviceType
@@ 29,4 28,9 @@ object CharacterDtos {
val spriteWidth: Int,
val spriteHeight: Int
)
+
+ data class DiMInfo(
+ val cardId: Int,
+ val charId: Int
+ )
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +16 -10
@@ 35,45 35,51 @@ fun AppNavigation(
) { contentPadding ->
NavHost(
navController = navController,
- startDestination = BottomNavItem.Home.route,
+ startDestination = NavigationItems.Home.route,
modifier = Modifier
.padding(contentPadding)
) {
- composable(BottomNavItem.Battles.route) {
+ composable(NavigationItems.Battles.route) {
BattlesScreen()
}
- composable(BottomNavItem.Home.route) {
+ composable(NavigationItems.Home.route) {
HomeScreen(
navController = navController
)
}
- composable(BottomNavItem.Storage.route) {
- StorageScreen()
+ composable(NavigationItems.Storage.route) {
+ StorageScreen(
+ navController = navController
+ )
}
- composable(BottomNavItem.Scan.route) {
+ composable(NavigationItems.Scan.route) {
+ val characterIdString = it.arguments?.getString("characterId")
+ val characterId = characterIdString?.toLongOrNull()
+
ScanScreen(
navController = navController,
scanScreenController = applicationNavigationHandlers.scanScreenController,
+ characterId = characterId
)
}
- composable(BottomNavItem.Dex.route) {
+ composable(NavigationItems.Dex.route) {
DexScreen(
navController = navController
)
}
- composable(BottomNavItem.Settings.route) {
+ composable(NavigationItems.Settings.route) {
SettingsScreen(
navController = navController,
settingsScreenController = applicationNavigationHandlers.settingsScreenController,
onClickImportCard = onClickImportCard
)
}
- composable(BottomNavItem.Viewer.route) {
+ composable(NavigationItems.Viewer.route) {
SpriteViewer(
navController = navController
)
}
- composable(BottomNavItem.CardView.route) {
+ composable(NavigationItems.CardView.route) {
val dimId = it.arguments?.getString("dimId")
Log.d("dimId", dimId.toString())
if (dimId != null) {
D app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt +0 -18
@@ 1,18 0,0 @@
-package com.github.nacabaro.vbhelper.navigation
-
-import com.github.nacabaro.vbhelper.R
-
-sealed class BottomNavItem (
- var route: String,
- var icon: Int,
- var label: String
-) {
- object Scan : BottomNavItem("Scan", R.drawable.baseline_nfc_24, "Scan")
- object Battles : BottomNavItem("Battle", R.drawable.baseline_swords_24, "Battle")
- object Home : BottomNavItem("Home", R.drawable.baseline_cottage_24, "Home")
- object Dex : BottomNavItem("Dex", R.drawable.baseline_menu_book_24, "Dex")
- object Storage : BottomNavItem("Storage", R.drawable.baseline_catching_pokemon_24, "Storage")
- object Settings : BottomNavItem("Settings", R.drawable.baseline_settings_24, "Settings")
- object Viewer : BottomNavItem("Viewer", R.drawable.baseline_image_24, "Viewer")
- object CardView : BottomNavItem("Card/{dimId}", R.drawable.baseline_image_24, "Card")
-}>
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt +5 -5
@@ 13,11 13,11 @@ import androidx.navigation.compose.currentBackStackEntryAsState
@Composable
fun BottomNavigationBar(navController: NavController) {
val items = listOf(
- BottomNavItem.Scan,
- BottomNavItem.Battles,
- BottomNavItem.Home,
- BottomNavItem.Dex,
- BottomNavItem.Storage,
+ NavigationItems.Scan,
+ NavigationItems.Battles,
+ NavigationItems.Home,
+ NavigationItems.Dex,
+ NavigationItems.Storage,
)
NavigationBar {
val currentBackStackEntry = navController.currentBackStackEntryAsState()
A app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt +18 -0
@@ 0,0 1,18 @@
+package com.github.nacabaro.vbhelper.navigation
+
+import com.github.nacabaro.vbhelper.R
+
+sealed class NavigationItems (
+ var route: String,
+ var icon: Int,
+ var label: String
+) {
+ object Scan : NavigationItems("Scan/{characterId}", R.drawable.baseline_nfc_24, "Scan")
+ object Battles : NavigationItems("Battle", R.drawable.baseline_swords_24, "Battle")
+ object Home : NavigationItems("Home", R.drawable.baseline_cottage_24, "Home")
+ 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 Viewer : NavigationItems("Viewer", R.drawable.baseline_image_24, "Viewer")
+ object CardView : NavigationItems("Card/{dimId}", R.drawable.baseline_image_24, "Card")
+}<
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt +3 -3
@@ 19,7 19,7 @@ import com.github.nacabaro.vbhelper.components.DexDiMEntry
import com.github.nacabaro.vbhelper.components.TopBanner
import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.domain.Dim
-import com.github.nacabaro.vbhelper.navigation.BottomNavItem
+import com.github.nacabaro.vbhelper.navigation.NavigationItems
import com.github.nacabaro.vbhelper.source.DexRepository
import kotlinx.coroutines.launch
@@ 45,7 45,7 @@ fun DexScreen(
TopBanner(
text = "Discovered Digimon",
onGearClick = {
- navController.navigate(BottomNavItem.Viewer.route)
+ navController.navigate(NavigationItems.Viewer.route)
}
)
}
@@ 65,7 65,7 @@ fun DexScreen(
onClick = {
navController
.navigate(
- BottomNavItem
+ NavigationItems
.CardView.route
.replace("{dimId}", "${it.id}")
)
M app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt +2 -2
@@ 8,7 8,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavController
import com.github.nacabaro.vbhelper.components.TopBanner
-import com.github.nacabaro.vbhelper.navigation.BottomNavItem
+import com.github.nacabaro.vbhelper.navigation.NavigationItems
@Composable
fun HomeScreen(
@@ 19,7 19,7 @@ fun HomeScreen(
TopBanner(
text = "VB Helper",
onGearClick = {
- navController.navigate(BottomNavItem.Settings.route)
+ navController.navigate(NavigationItems.Settings.route)
}
)
}
M app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt +32 -12
@@ 1,11 1,11 @@
package com.github.nacabaro.vbhelper.screens
import android.util.Log
-import androidx.compose.foundation.Image
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ 21,11 21,9 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ 34,18 32,22 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
+import androidx.navigation.NavController
import com.github.nacabaro.vbhelper.components.CharacterEntry
import com.github.nacabaro.vbhelper.components.TopBanner
import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
+import com.github.nacabaro.vbhelper.navigation.NavigationItems
import com.github.nacabaro.vbhelper.source.StorageRepository
import com.github.nacabaro.vbhelper.utils.BitmapData
import kotlinx.coroutines.launch
@Composable
-fun StorageScreen() {
+fun StorageScreen(
+ navController: NavController
+) {
val coroutineScope = rememberCoroutineScope()
val application = LocalContext.current.applicationContext as VBHelper
val storageRepository = StorageRepository(application.container.db)
@@ 96,14 98,24 @@ fun StorageScreen() {
),
modifier = Modifier
.padding(8.dp)
- .size(96.dp)
-
+ .size(96.dp),
+ onClick = {
+ selectedCharacter = index.id
+ }
)
if (selectedCharacter != null) {
StorageDialog(
characterId = selectedCharacter!!,
- onDismissRequest = { selectedCharacter = null }
+ onDismissRequest = { selectedCharacter = null },
+ onSendToBracelet = {
+ navController.navigate(
+ NavigationItems.Scan.route.replace(
+ "{characterId}",
+ selectedCharacter.toString()
+ )
+ )
+ }
)
}
}
@@ 114,7 126,8 @@ fun StorageScreen() {
@Composable
fun StorageDialog(
characterId: Long,
- onDismissRequest: () -> Unit
+ onDismissRequest: () -> Unit,
+ onSendToBracelet: () -> Unit
) {
val coroutineScope = rememberCoroutineScope()
val application = LocalContext.current.applicationContext as VBHelper
@@ 149,10 162,17 @@ fun StorageDialog(
.padding(8.dp)
)
}
- Button(
- onClick = onDismissRequest
- ) {
- Text(text = "Close")
+ Row {
+ Button(
+ onClick = onSendToBracelet
+ ) {
+ Text(text = "Send to bracelet")
+ }
+ Button(
+ onClick = onDismissRequest
+ ) {
+ Text(text = "Close")
+ }
}
}
}
M app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ReadingCharacter.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ReadingCharacter.kt +2 -1
@@ 15,11 15,12 @@ import com.github.nacabaro.vbhelper.components.TopBanner
@Composable
fun ReadingCharacterScreen(
+ topBannerText: String,
onClickCancel: () -> Unit,
) {
Scaffold (
topBar = {
- TopBanner("Reading Character")
+ TopBanner(topBannerText)
}
) { innerPadding ->
Column (
M app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt +116 -20
@@ 12,6 12,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
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
@@ 25,25 26,48 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
+import com.github.cfogrady.vbnfc.data.NfcCharacter
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
import com.github.nacabaro.vbhelper.components.TopBanner
-import com.github.nacabaro.vbhelper.navigation.BottomNavItem
+import com.github.nacabaro.vbhelper.di.VBHelper
+import com.github.nacabaro.vbhelper.navigation.NavigationItems
+import com.github.nacabaro.vbhelper.source.StorageRepository
import com.github.nacabaro.vbhelper.source.isMissingSecrets
import com.github.nacabaro.vbhelper.source.proto.Secrets
+import com.github.nacabaro.vbhelper.utils.characterToNfc
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.withContext
const val SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER = "SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER"
@Composable
fun ScanScreen(
navController: NavController,
+ characterId: Long?,
scanScreenController: ScanScreenController,
) {
val secrets by scanScreenController.secretsFlow.collectAsState(null)
var readingScreen by remember { mutableStateOf(false) }
+ var writingScreen by remember { mutableStateOf(false) }
var isDoneReadingCharacter by remember { mutableStateOf(false) }
+ var isDoneSendingCard by remember { mutableStateOf(false) }
+ var isDoneWritingCharacter by remember { mutableStateOf(false) }
- DisposableEffect(readingScreen) {
+ val application = LocalContext.current.applicationContext as VBHelper
+ val storageRepository = StorageRepository(application.container.db)
+ var nfcCharacter by remember { mutableStateOf<NfcCharacter?>(null) }
+
+ val context = LocalContext.current
+ LaunchedEffect(storageRepository) {
+ withContext(Dispatchers.IO) {
+ if(characterId != null) {
+ nfcCharacter = characterToNfc(context, characterId)
+ }
+ }
+ }
+
+ DisposableEffect(readingScreen || writingScreen) {
if(readingScreen) {
scanScreenController.registerActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, object: ActivityLifecycleListener {
override fun onPause() {
@@ 60,9 84,39 @@ fun ScanScreen(
scanScreenController.onClickRead(secrets!!) {
isDoneReadingCharacter = true
}
+ } else 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 (!isDoneSendingCard) {
+ scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) {
+ isDoneSendingCard = true
+ }
+ } else if (!isDoneWritingCharacter) {
+ scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) {
+ isDoneWritingCharacter = true
+ }
+ }
}
onDispose {
- if(readingScreen) {
+ if(readingScreen || writingScreen) {
scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER)
scanScreenController.cancelRead()
}
@@ 71,33 125,68 @@ fun ScanScreen(
if (isDoneReadingCharacter) {
readingScreen = false
- navController.navigate(BottomNavItem.Home.route)
+ navController.navigate(NavigationItems.Home.route)
+ } else if (isDoneSendingCard && isDoneWritingCharacter) {
+ writingScreen = false
+ navController.navigate(NavigationItems.Home.route)
}
if (readingScreen) {
- ReadingCharacterScreen {
+ ReadingCharacterScreen("Reading character") {
readingScreen = false
scanScreenController.cancelRead()
}
+ } else if (writingScreen) {
+ if (!isDoneSendingCard) {
+ ReadingCharacterScreen("Sending card") {
+ isDoneSendingCard = true
+ scanScreenController.cancelRead()
+ }
+ } else if (!isDoneWritingCharacter) {
+ ReadingCharacterScreen("Writing character") {
+ isDoneWritingCharacter = true
+ writingScreen = false
+ scanScreenController.cancelRead()
+ }
+ }
} else {
- val context = LocalContext.current
ChooseConnectOption(
- onClickRead = {
- if(secrets == null) {
- Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
- } else if(secrets?.isMissingSecrets() == true) {
- Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
- } else {
- readingScreen = true // kicks off nfc adapter in DisposableEffect
+ onClickRead = when {
+ characterId != null -> null
+ else -> {
+ {
+ if(secrets == null) {
+ Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
+ } else if(secrets?.isMissingSecrets() == true) {
+ Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
+ } else {
+ readingScreen = true // kicks off nfc adapter in DisposableEffect
+ }
+ }
}
},
+ onClickWrite = when {
+ nfcCharacter == null -> null
+ else -> {
+ {
+ if(secrets == null) {
+ Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
+ } else if(secrets?.isMissingSecrets() == true) {
+ Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
+ } else {
+ writingScreen = true // kicks off nfc adapter in DisposableEffect
+ }
+ }
+ }
+ }
)
}
}
@Composable
-private fun ChooseConnectOption(
- onClickRead: () -> Unit,
+fun ChooseConnectOption(
+ onClickRead: (() -> Unit)? = null,
+ onClickWrite: (() -> Unit)? = null,
) {
Scaffold(
topBar = { TopBanner(text = "Scan a Vital Bracelet") }
@@ 111,12 200,14 @@ private fun ChooseConnectOption(
) {
ScanButton(
text = "Vital Bracelet to App",
- onClick = onClickRead,
+ disabled = onClickRead == null,
+ onClick = onClickRead?: { },
)
Spacer(modifier = Modifier.height(16.dp))
ScanButton(
text = "App to Vital Bracelet",
- onClick = {}
+ disabled = onClickWrite == null,
+ onClick = onClickWrite?: { },
)
}
}
@@ 127,11 218,13 @@ private fun ChooseConnectOption(
fun ScanButton(
text: String,
onClick: () -> Unit,
- modifier: Modifier = Modifier
+ modifier: Modifier = Modifier,
+ disabled: Boolean = false,
) {
Button(
onClick = onClick,
- modifier = modifier
+ modifier = modifier,
+ enabled = !disabled,
) {
Text(
text = text,
@@ 157,7 250,10 @@ fun ScanScreenPreview() {
}
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) {}
+ override fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {}
+ override fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {}
override fun cancelRead() {}
- }
+ },
+ characterId = null
)
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt +4 -0
@@ 1,5 1,6 @@
package com.github.nacabaro.vbhelper.screens.scanScreen
+import com.github.cfogrady.vbnfc.data.NfcCharacter
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
import com.github.nacabaro.vbhelper.source.proto.Secrets
import kotlinx.coroutines.flow.Flow
@@ 7,6 8,9 @@ import kotlinx.coroutines.flow.Flow
interface ScanScreenController {
val secretsFlow: Flow<Secrets>
fun onClickRead(secrets: Secrets, onComplete: ()->Unit)
+ fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit)
+ fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit)
+
fun cancelRead()
fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener)
M app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt +24 -0
@@ 109,6 109,30 @@ class ScanScreenControllerImpl(
}
}
+ override fun onClickWrite(
+ secrets: Secrets,
+ nfcCharacter: NfcCharacter,
+ onComplete: () -> Unit
+ ) {
+ handleTag(secrets) { tagCommunicator ->
+ tagCommunicator.sendCharacter(nfcCharacter)
+ onComplete.invoke()
+ "Sent character successfully!"
+ }
+ }
+
+ override fun onClickCheckCard(
+ secrets: Secrets,
+ nfcCharacter: NfcCharacter,
+ onComplete: () -> Unit
+ ) {
+ handleTag(secrets) { tagCommunicator ->
+ tagCommunicator.prepareDIMForCharacter(nfcCharacter.dimId)
+ onComplete.invoke()
+ "Sent DIM successfully!"
+ }
+ }
+
// EXTRACTED DIRECTLY FROM EXAMPLE APP
private fun showWirelessSettings() {
Toast.makeText(context, "NFC must be enabled", Toast.LENGTH_SHORT).show()
M app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt => app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt +14 -0
@@ 1,6 1,8 @@
package com.github.nacabaro.vbhelper.source
import com.github.nacabaro.vbhelper.database.AppDatabase
+import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
+import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
@@ 14,4 16,16 @@ class StorageRepository (
suspend fun getSingleCharacter(id: Long): UserCharacter {
return db.userCharacterDao().getCharacter(id)
}
+
+ suspend fun getCharacterBeData(id: Long): BECharacterData {
+ return db.userCharacterDao().getBeData(id)
+ }
+
+ fun getTransformationHistory(characterId: Long): List<TransformationHistory> {
+ return db.userCharacterDao().getTransformationHistory(characterId)
+ }
+
+ suspend fun getCharacterData(id: Long): CharacterDtos.DiMInfo {
+ return db.characterDao().getCharacterInfo(id)
+ }
}=
\ No newline at end of file
A app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt => app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt +86 -0
@@ 0,0 1,86 @@
+package com.github.nacabaro.vbhelper.utils
+
+import android.content.Context
+import com.github.cfogrady.vbnfc.be.BENfcCharacter
+import com.github.cfogrady.vbnfc.be.FirmwareVersion
+import com.github.cfogrady.vbnfc.data.NfcCharacter
+import com.github.nacabaro.vbhelper.di.VBHelper
+import com.github.nacabaro.vbhelper.domain.DeviceType
+import com.github.nacabaro.vbhelper.source.StorageRepository
+
+suspend fun characterToNfc(context: Context, characterId: Long): NfcCharacter? {
+ val app = context.applicationContext as VBHelper
+ val database = app.container.db
+ val storageRepository = StorageRepository(database)
+ val userCharacter = storageRepository.getSingleCharacter(characterId)
+ val characterInfo = storageRepository.getCharacterData(characterId)
+
+ if (userCharacter.characterType == DeviceType.BEDevice) {
+ val beData = storageRepository.getCharacterBeData(characterId)
+ val transformationHistory = storageRepository
+ .getTransformationHistory(characterId)
+ .map {
+ NfcCharacter.Transformation(
+ toCharIndex = it.toCharIndex.toUByte(),
+ year = it.year.toUShort(),
+ month = it.month.toUByte(),
+ day = it.day.toUByte()
+ )
+ }.toTypedArray()
+
+ // Maybe this is the issue?
+ val dummyVitalHistory = arrayOf<NfcCharacter.DailyVitals>()
+
+ val nfcData = BENfcCharacter(
+ dimId = characterInfo.cardId.toUShort(),
+ charIndex = characterInfo.charId.toUShort(),
+ stage = userCharacter.stage.toByte(),
+ attribute = userCharacter.attribute,
+ ageInDays = userCharacter.ageInDays.toByte(),
+ nextAdventureMissionStage = userCharacter.nextAdventureMissionStage.toByte(),
+ mood = userCharacter.mood.toByte(),
+ vitalPoints = userCharacter.vitalPoints.toUShort(),
+ itemEffectMentalStateValue = beData.itemEffectMentalStateValue.toByte(),
+ itemEffectMentalStateMinutesRemaining = beData.itemEffectMentalStateMinutesRemaining.toByte(),
+ itemEffectActivityLevelValue = beData.itemEffectActivityLevelValue.toByte(),
+ itemEffectActivityLevelMinutesRemaining = beData.itemEffectActivityLevelMinutesRemaining.toByte(),
+ itemEffectVitalPointsChangeValue = beData.itemEffectVitalPointsChangeValue.toByte(),
+ itemEffectVitalPointsChangeMinutesRemaining = beData.itemEffectVitalPointsChangeMinutesRemaining.toByte(),
+ transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(),
+ injuryStatus = userCharacter.injuryStatus,
+ trainingPp = userCharacter.trophies.toUShort(),
+ currentPhaseBattlesWon = userCharacter.currentPhaseBattlesWon.toUShort(),
+ currentPhaseBattlesLost = userCharacter.currentPhaseBattlesLost.toUShort(),
+ totalBattlesWon = userCharacter.totalBattlesWon.toUShort(),
+ totalBattlesLost = userCharacter.totalBattlesLost.toUShort(),
+ activityLevel = userCharacter.activityLevel.toByte(),
+ heartRateCurrent = userCharacter.heartRateCurrent.toUByte(),
+ transformationHistory = transformationHistory,
+ vitalHistory = arrayOf(),
+ appReserved1 = byteArrayOf(),
+ appReserved2 = Array(2, { 0u }),
+ trainingHp = beData.trainingHp.toUShort(),
+ trainingAp = beData.trainingAp.toUShort(),
+ trainingBp = beData.trainingBp.toUShort(),
+ remainingTrainingTimeInMinutes = beData.remainingTrainingTimeInMinutes.toUShort(),
+ abilityRarity = beData.abilityRarity,
+ abilityType = beData.abilityType.toUShort(),
+ abilityBranch = beData.abilityBranch.toUShort(),
+ abilityReset = beData.abilityReset.toByte(),
+ rank = beData.rank.toByte(),
+ itemType = beData.itemType.toByte(),
+ itemMultiplier = beData.itemMultiplier.toByte(),
+ itemRemainingTime = beData.itemRemainingTime.toByte(),
+ otp0 = byteArrayOf(8),
+ otp1 = byteArrayOf(8),
+ characterCreationFirmwareVersion = FirmwareVersion(
+ minorVersion = beData.minorVersion.toByte(),
+ majorVersion = beData.majorVersion.toByte()
+ )
+ )
+
+ return nfcData
+ }
+
+ return null
+}<
\ No newline at end of file