mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-01-27 16:05:32 +00:00
Merge pull request #15 from nacabaro/ui/home_screen
A few things, again...
This commit is contained in:
commit
dd893a08da
@ -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