diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt index 0931d87..7b0642f 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt @@ -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 + + @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 diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt index f6a4ed6..450cec9 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt @@ -21,7 +21,7 @@ interface UserCharacterDao { fun insertTransformationHistory(vararg transformationHistory: TransformationHistory) @Query("SELECT * FROM TransformationHistory WHERE monId = :monId") - fun getTransformationHistory(monId: Int): List + fun getTransformationHistory(monId: Long): List @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 diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt b/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt index 93df0a8..f7514cb 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt @@ -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 diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt index 727b5fc..24220ed 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt @@ -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) { diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt deleted file mode 100644 index cb93839..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt +++ /dev/null @@ -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 diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt index 24eb230..36aabc0 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavigationBar.kt @@ -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() diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt new file mode 100644 index 0000000..5e92c7c --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt @@ -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 diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt index 710d593..da9d9e6 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt @@ -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}") ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt index 03b6985..5491405 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt @@ -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) } ) } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt index 4801c9c..c237072 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt @@ -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") + } } } } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ReadingCharacter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ReadingCharacter.kt index 9c7a2dc..89ce2ed 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ReadingCharacter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ReadingCharacter.kt @@ -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 ( diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt index 9b545e9..ed2a6dc 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt @@ -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(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 diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt index 061e737..609ab50 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt @@ -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 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) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt index c31061b..849c742 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt @@ -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() diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt b/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt index 8aa03ae..8e1f753 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt @@ -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 { + return db.userCharacterDao().getTransformationHistory(characterId) + } + + suspend fun getCharacterData(id: Long): CharacterDtos.DiMInfo { + return db.characterDao().getCharacterInfo(id) + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt new file mode 100644 index 0000000..8d37cbf --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt @@ -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() + + 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