mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-01-27 16:05:32 +00:00
A few things, again...
- Added ability to write character (incomplete) - Renamed BottomNavItem.kt to NavigationItems.kt, as it covers the entire application navigation, not just the bottom navigation bar - Modified the ScanScreenController and the Impl to accomodate writing characters on the BE (need to do the VB later on) - Modified repositories to fetch data from the database and additional information needed to convert back to NfcCharacter - Function to convert to NfcCharacter Originally this was also going to cover the home screen, since my idea was to have marked as active (the one shown in the home screen) be the one sent to the watch, but for testing I have added a "send to bracelet" button on the pop-up on the storage screen.
This commit is contained in:
parent
7f22650601
commit
cac5198488
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
)
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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")
|
||||
}
|
||||
@ -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()
|
||||
|
||||
@ -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")
|
||||
}
|
||||
@ -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}")
|
||||
)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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
|
||||
)
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user