mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-01-28 00:15: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 androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.domain.Character
|
import com.github.nacabaro.vbhelper.domain.Character
|
||||||
import com.github.nacabaro.vbhelper.domain.Sprites
|
import com.github.nacabaro.vbhelper.domain.Sprites
|
||||||
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface CharacterDao {
|
interface CharacterDao {
|
||||||
@ -25,4 +26,15 @@ interface CharacterDao {
|
|||||||
|
|
||||||
@Query("SELECT * FROM Sprites")
|
@Query("SELECT * FROM Sprites")
|
||||||
suspend fun getAllSprites(): List<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)
|
fun insertTransformationHistory(vararg transformationHistory: TransformationHistory)
|
||||||
|
|
||||||
@Query("SELECT * FROM TransformationHistory WHERE monId = :monId")
|
@Query("SELECT * FROM TransformationHistory WHERE monId = :monId")
|
||||||
fun getTransformationHistory(monId: Int): List<TransformationHistory>
|
fun getTransformationHistory(monId: Long): List<TransformationHistory>
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
SELECT
|
||||||
@ -36,4 +36,7 @@ interface UserCharacterDao {
|
|||||||
|
|
||||||
@Query("SELECT * FROM UserCharacter WHERE id = :id")
|
@Query("SELECT * FROM UserCharacter WHERE id = :id")
|
||||||
suspend fun getCharacter(id: Long): UserCharacter
|
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
|
package com.github.nacabaro.vbhelper.dtos
|
||||||
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
import com.github.nacabaro.vbhelper.domain.DeviceType
|
import com.github.nacabaro.vbhelper.domain.DeviceType
|
||||||
|
|
||||||
@ -29,4 +28,9 @@ object CharacterDtos {
|
|||||||
val spriteWidth: Int,
|
val spriteWidth: Int,
|
||||||
val spriteHeight: Int
|
val spriteHeight: Int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class DiMInfo(
|
||||||
|
val cardId: Int,
|
||||||
|
val charId: Int
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@ -35,45 +35,51 @@ fun AppNavigation(
|
|||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
startDestination = BottomNavItem.Home.route,
|
startDestination = NavigationItems.Home.route,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(contentPadding)
|
.padding(contentPadding)
|
||||||
) {
|
) {
|
||||||
composable(BottomNavItem.Battles.route) {
|
composable(NavigationItems.Battles.route) {
|
||||||
BattlesScreen()
|
BattlesScreen()
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.Home.route) {
|
composable(NavigationItems.Home.route) {
|
||||||
HomeScreen(
|
HomeScreen(
|
||||||
navController = navController
|
navController = navController
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.Storage.route) {
|
composable(NavigationItems.Storage.route) {
|
||||||
StorageScreen()
|
StorageScreen(
|
||||||
|
navController = navController
|
||||||
|
)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.Scan.route) {
|
composable(NavigationItems.Scan.route) {
|
||||||
|
val characterIdString = it.arguments?.getString("characterId")
|
||||||
|
val characterId = characterIdString?.toLongOrNull()
|
||||||
|
|
||||||
ScanScreen(
|
ScanScreen(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
scanScreenController = applicationNavigationHandlers.scanScreenController,
|
scanScreenController = applicationNavigationHandlers.scanScreenController,
|
||||||
|
characterId = characterId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.Dex.route) {
|
composable(NavigationItems.Dex.route) {
|
||||||
DexScreen(
|
DexScreen(
|
||||||
navController = navController
|
navController = navController
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.Settings.route) {
|
composable(NavigationItems.Settings.route) {
|
||||||
SettingsScreen(
|
SettingsScreen(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
settingsScreenController = applicationNavigationHandlers.settingsScreenController,
|
settingsScreenController = applicationNavigationHandlers.settingsScreenController,
|
||||||
onClickImportCard = onClickImportCard
|
onClickImportCard = onClickImportCard
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.Viewer.route) {
|
composable(NavigationItems.Viewer.route) {
|
||||||
SpriteViewer(
|
SpriteViewer(
|
||||||
navController = navController
|
navController = navController
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.CardView.route) {
|
composable(NavigationItems.CardView.route) {
|
||||||
val dimId = it.arguments?.getString("dimId")
|
val dimId = it.arguments?.getString("dimId")
|
||||||
Log.d("dimId", dimId.toString())
|
Log.d("dimId", dimId.toString())
|
||||||
if (dimId != null) {
|
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
|
@Composable
|
||||||
fun BottomNavigationBar(navController: NavController) {
|
fun BottomNavigationBar(navController: NavController) {
|
||||||
val items = listOf(
|
val items = listOf(
|
||||||
BottomNavItem.Scan,
|
NavigationItems.Scan,
|
||||||
BottomNavItem.Battles,
|
NavigationItems.Battles,
|
||||||
BottomNavItem.Home,
|
NavigationItems.Home,
|
||||||
BottomNavItem.Dex,
|
NavigationItems.Dex,
|
||||||
BottomNavItem.Storage,
|
NavigationItems.Storage,
|
||||||
)
|
)
|
||||||
NavigationBar {
|
NavigationBar {
|
||||||
val currentBackStackEntry = navController.currentBackStackEntryAsState()
|
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.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.domain.Dim
|
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 com.github.nacabaro.vbhelper.source.DexRepository
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ fun DexScreen(
|
|||||||
TopBanner(
|
TopBanner(
|
||||||
text = "Discovered Digimon",
|
text = "Discovered Digimon",
|
||||||
onGearClick = {
|
onGearClick = {
|
||||||
navController.navigate(BottomNavItem.Viewer.route)
|
navController.navigate(NavigationItems.Viewer.route)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ fun DexScreen(
|
|||||||
onClick = {
|
onClick = {
|
||||||
navController
|
navController
|
||||||
.navigate(
|
.navigate(
|
||||||
BottomNavItem
|
NavigationItems
|
||||||
.CardView.route
|
.CardView.route
|
||||||
.replace("{dimId}", "${it.id}")
|
.replace("{dimId}", "${it.id}")
|
||||||
)
|
)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.navigation.BottomNavItem
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(
|
fun HomeScreen(
|
||||||
@ -19,7 +19,7 @@ fun HomeScreen(
|
|||||||
TopBanner(
|
TopBanner(
|
||||||
text = "VB Helper",
|
text = "VB Helper",
|
||||||
onGearClick = {
|
onGearClick = {
|
||||||
navController.navigate(BottomNavItem.Settings.route)
|
navController.navigate(NavigationItems.Settings.route)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens
|
package com.github.nacabaro.vbhelper.screens
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
import androidx.compose.foundation.gestures.scrollable
|
import androidx.compose.foundation.gestures.scrollable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
@ -21,11 +21,9 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@ -34,18 +32,22 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
|
import androidx.navigation.NavController
|
||||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun StorageScreen() {
|
fun StorageScreen(
|
||||||
|
navController: NavController
|
||||||
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
val storageRepository = StorageRepository(application.container.db)
|
val storageRepository = StorageRepository(application.container.db)
|
||||||
@ -96,14 +98,24 @@ fun StorageScreen() {
|
|||||||
),
|
),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.size(96.dp)
|
.size(96.dp),
|
||||||
|
onClick = {
|
||||||
|
selectedCharacter = index.id
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (selectedCharacter != null) {
|
if (selectedCharacter != null) {
|
||||||
StorageDialog(
|
StorageDialog(
|
||||||
characterId = selectedCharacter!!,
|
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
|
@Composable
|
||||||
fun StorageDialog(
|
fun StorageDialog(
|
||||||
characterId: Long,
|
characterId: Long,
|
||||||
onDismissRequest: () -> Unit
|
onDismissRequest: () -> Unit,
|
||||||
|
onSendToBracelet: () -> Unit
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val application = LocalContext.current.applicationContext as VBHelper
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
@ -149,10 +162,17 @@ fun StorageDialog(
|
|||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Button(
|
Row {
|
||||||
onClick = onDismissRequest
|
Button(
|
||||||
) {
|
onClick = onSendToBracelet
|
||||||
Text(text = "Close")
|
) {
|
||||||
|
Text(text = "Send to bracelet")
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = onDismissRequest
|
||||||
|
) {
|
||||||
|
Text(text = "Close")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,11 +15,12 @@ import com.github.nacabaro.vbhelper.components.TopBanner
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ReadingCharacterScreen(
|
fun ReadingCharacterScreen(
|
||||||
|
topBannerText: String,
|
||||||
onClickCancel: () -> Unit,
|
onClickCancel: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner("Reading Character")
|
TopBanner(topBannerText)
|
||||||
}
|
}
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Column (
|
Column (
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import androidx.compose.material3.Scaffold
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -25,25 +26,48 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.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.isMissingSecrets
|
||||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
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.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
const val SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER = "SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER"
|
const val SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER = "SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER"
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ScanScreen(
|
fun ScanScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
|
characterId: Long?,
|
||||||
scanScreenController: ScanScreenController,
|
scanScreenController: ScanScreenController,
|
||||||
) {
|
) {
|
||||||
val secrets by scanScreenController.secretsFlow.collectAsState(null)
|
val secrets by scanScreenController.secretsFlow.collectAsState(null)
|
||||||
var readingScreen by remember { mutableStateOf(false) }
|
var readingScreen by remember { mutableStateOf(false) }
|
||||||
|
var writingScreen by remember { mutableStateOf(false) }
|
||||||
var isDoneReadingCharacter 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) {
|
if(readingScreen) {
|
||||||
scanScreenController.registerActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, object: ActivityLifecycleListener {
|
scanScreenController.registerActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, object: ActivityLifecycleListener {
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
@ -60,9 +84,39 @@ fun ScanScreen(
|
|||||||
scanScreenController.onClickRead(secrets!!) {
|
scanScreenController.onClickRead(secrets!!) {
|
||||||
isDoneReadingCharacter = true
|
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 {
|
onDispose {
|
||||||
if(readingScreen) {
|
if(readingScreen || writingScreen) {
|
||||||
scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER)
|
scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER)
|
||||||
scanScreenController.cancelRead()
|
scanScreenController.cancelRead()
|
||||||
}
|
}
|
||||||
@ -71,33 +125,68 @@ fun ScanScreen(
|
|||||||
|
|
||||||
if (isDoneReadingCharacter) {
|
if (isDoneReadingCharacter) {
|
||||||
readingScreen = false
|
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) {
|
if (readingScreen) {
|
||||||
ReadingCharacterScreen {
|
ReadingCharacterScreen("Reading character") {
|
||||||
readingScreen = false
|
readingScreen = false
|
||||||
scanScreenController.cancelRead()
|
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 {
|
} else {
|
||||||
val context = LocalContext.current
|
|
||||||
ChooseConnectOption(
|
ChooseConnectOption(
|
||||||
onClickRead = {
|
onClickRead = when {
|
||||||
if(secrets == null) {
|
characterId != null -> null
|
||||||
Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
|
else -> {
|
||||||
} else if(secrets?.isMissingSecrets() == true) {
|
{
|
||||||
Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
|
if(secrets == null) {
|
||||||
} else {
|
Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
|
||||||
readingScreen = true // kicks off nfc adapter in DisposableEffect
|
} 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
|
@Composable
|
||||||
private fun ChooseConnectOption(
|
fun ChooseConnectOption(
|
||||||
onClickRead: () -> Unit,
|
onClickRead: (() -> Unit)? = null,
|
||||||
|
onClickWrite: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { TopBanner(text = "Scan a Vital Bracelet") }
|
topBar = { TopBanner(text = "Scan a Vital Bracelet") }
|
||||||
@ -111,12 +200,14 @@ private fun ChooseConnectOption(
|
|||||||
) {
|
) {
|
||||||
ScanButton(
|
ScanButton(
|
||||||
text = "Vital Bracelet to App",
|
text = "Vital Bracelet to App",
|
||||||
onClick = onClickRead,
|
disabled = onClickRead == null,
|
||||||
|
onClick = onClickRead?: { },
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
ScanButton(
|
ScanButton(
|
||||||
text = "App to Vital Bracelet",
|
text = "App to Vital Bracelet",
|
||||||
onClick = {}
|
disabled = onClickWrite == null,
|
||||||
|
onClick = onClickWrite?: { },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,11 +218,13 @@ private fun ChooseConnectOption(
|
|||||||
fun ScanButton(
|
fun ScanButton(
|
||||||
text: String,
|
text: String,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier,
|
||||||
|
disabled: Boolean = false,
|
||||||
) {
|
) {
|
||||||
Button(
|
Button(
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
modifier = modifier
|
modifier = modifier,
|
||||||
|
enabled = !disabled,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = text,
|
text = text,
|
||||||
@ -157,7 +250,10 @@ fun ScanScreenPreview() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) {}
|
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() {}
|
override fun cancelRead() {}
|
||||||
}
|
},
|
||||||
|
characterId = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen
|
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.ActivityLifecycleListener
|
||||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -7,6 +8,9 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
interface ScanScreenController {
|
interface ScanScreenController {
|
||||||
val secretsFlow: Flow<Secrets>
|
val secretsFlow: Flow<Secrets>
|
||||||
fun onClickRead(secrets: Secrets, onComplete: ()->Unit)
|
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 cancelRead()
|
||||||
|
|
||||||
fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener)
|
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
|
// EXTRACTED DIRECTLY FROM EXAMPLE APP
|
||||||
private fun showWirelessSettings() {
|
private fun showWirelessSettings() {
|
||||||
Toast.makeText(context, "NFC must be enabled", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "NFC must be enabled", Toast.LENGTH_SHORT).show()
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package com.github.nacabaro.vbhelper.source
|
package com.github.nacabaro.vbhelper.source
|
||||||
|
|
||||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||||
|
import com.github.nacabaro.vbhelper.domain.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.domain.device_data.UserCharacter
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
|
|
||||||
@ -14,4 +16,16 @@ class StorageRepository (
|
|||||||
suspend fun getSingleCharacter(id: Long): UserCharacter {
|
suspend fun getSingleCharacter(id: Long): UserCharacter {
|
||||||
return db.userCharacterDao().getCharacter(id)
|
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