mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-01-27 16:05:32 +00:00
Other few things
- I changed more things to flows from the database - Cleaned up the logic coming from the scan screen - Added a delete button to a character. CAREFUL, IT HAS NO CONFIRMATION YET! - Fixed a few things, now scanning is more stable and will fix the second whoops thing. - Quick patch, should improve stability when writing to the watch
This commit is contained in:
parent
cf272e8030
commit
dce186737d
@ -5,6 +5,7 @@ import androidx.room.Insert
|
|||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface CardDao {
|
interface CardDao {
|
||||||
@ -26,7 +27,7 @@ interface CardDao {
|
|||||||
WHERE uc.id = :id
|
WHERE uc.id = :id
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
suspend fun getCardByCharacterId(id: Long): Card
|
fun getCardByCharacterId(id: Long): Flow<Card>
|
||||||
|
|
||||||
@Query("UPDATE Card SET name = :newName WHERE id = :id")
|
@Query("UPDATE Card SET name = :newName WHERE id = :id")
|
||||||
suspend fun renameCard(id: Int, newName: String)
|
suspend fun renameCard(id: Int, newName: String)
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory
|
|||||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory
|
import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface UserCharacterDao {
|
interface UserCharacterDao {
|
||||||
@ -76,7 +77,7 @@ interface UserCharacterDao {
|
|||||||
LEFT JOIN Adventure a ON a.characterId = uc.id
|
LEFT JOIN Adventure a ON a.characterId = uc.id
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
suspend fun getAllCharacters(): List<CharacterDtos.CharacterWithSprites>
|
fun getAllCharacters(): Flow<List<CharacterDtos.CharacterWithSprites>>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
|||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
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.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ fun ChooseCharacterScreen(
|
|||||||
) {
|
) {
|
||||||
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, )
|
||||||
val characterList = remember {
|
val characterList = remember {
|
||||||
mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList())
|
mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList())
|
||||||
}
|
}
|
||||||
@ -57,7 +58,7 @@ fun ChooseCharacterScreen(
|
|||||||
characterList.value = storageRepository.getVBCharacters()
|
characterList.value = storageRepository.getVBCharacters()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
characterList.value = storageRepository.getAllCharacters()
|
characterList.value = storageRepository.getAllCharacters().first()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,78 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.scanScreen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ChooseConnectOption(
|
||||||
|
onClickRead: (() -> Unit)? = null,
|
||||||
|
onClickWrite: (() -> Unit)? = null,
|
||||||
|
navController: NavController
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopBanner(
|
||||||
|
text = "Scan a Vital Bracelet",
|
||||||
|
onBackClick = {
|
||||||
|
navController.popBackStack()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { contentPadding ->
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(contentPadding)
|
||||||
|
) {
|
||||||
|
ScanButton(
|
||||||
|
text = "Vital Bracelet to App",
|
||||||
|
disabled = onClickRead == null,
|
||||||
|
onClick = onClickRead?: { },
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
ScanButton(
|
||||||
|
text = "App to Vital Bracelet",
|
||||||
|
disabled = onClickWrite == null,
|
||||||
|
onClick = onClickWrite?: { },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ScanButton(
|
||||||
|
text: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
disabled: Boolean = false,
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = modifier,
|
||||||
|
enabled = !disabled,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(4.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,38 +1,24 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen
|
package com.github.nacabaro.vbhelper.screens.scanScreen
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
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
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
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.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.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.screens.cardScreen.ChooseCard
|
import com.github.nacabaro.vbhelper.screens.scanScreen.screens.ReadingScreen
|
||||||
|
import com.github.nacabaro.vbhelper.screens.scanScreen.screens.WritingScreen
|
||||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
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
|
||||||
@ -55,8 +41,6 @@ fun ScanScreen(
|
|||||||
val storageRepository = StorageRepository(application.container.db)
|
val storageRepository = StorageRepository(application.container.db)
|
||||||
var nfcCharacter by remember { mutableStateOf<NfcCharacter?>(null) }
|
var nfcCharacter by remember { mutableStateOf<NfcCharacter?>(null) }
|
||||||
|
|
||||||
var cardsRead by remember { mutableStateOf<List<Card>?>(null) }
|
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
LaunchedEffect(storageRepository) {
|
LaunchedEffect(storageRepository) {
|
||||||
@ -73,143 +57,33 @@ fun ScanScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var readingScreen by remember { mutableStateOf(false) }
|
|
||||||
var writingScreen by remember { mutableStateOf(false) }
|
var writingScreen by remember { mutableStateOf(false) }
|
||||||
var cardSelectScreen by remember { mutableStateOf(false) }
|
var readingScreen by remember { mutableStateOf(false) }
|
||||||
var isDoneReadingCharacter by remember { mutableStateOf(false) }
|
|
||||||
var isDoneSendingCard by remember { mutableStateOf(false) }
|
|
||||||
var isDoneWritingCharacter by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
DisposableEffect(readingScreen) {
|
if (writingScreen && nfcCharacter != null && characterId != null) {
|
||||||
if(readingScreen) {
|
WritingScreen(
|
||||||
scanScreenController.registerActivityLifecycleListener(
|
scanScreenController = scanScreenController,
|
||||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
nfcCharacter = nfcCharacter!!,
|
||||||
object: ActivityLifecycleListener {
|
characterId = characterId,
|
||||||
override fun onPause() {
|
onComplete = {
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
scanScreenController.onClickRead(
|
|
||||||
secrets = secrets!!,
|
|
||||||
onComplete = {
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
},
|
|
||||||
onMultipleCards = { cards ->
|
|
||||||
cardsRead = cards
|
|
||||||
readingScreen = false
|
|
||||||
cardSelectScreen = true
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
scanScreenController.onClickRead(
|
|
||||||
secrets = secrets!!,
|
|
||||||
onComplete = {
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
},
|
|
||||||
onMultipleCards = { cards ->
|
|
||||||
cardsRead = cards
|
|
||||||
readingScreen = false
|
|
||||||
cardSelectScreen = true
|
|
||||||
isDoneReadingCharacter = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
onDispose {
|
|
||||||
if(readingScreen) {
|
|
||||||
scanScreenController.unregisterActivityLifecycleListener(
|
|
||||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
|
||||||
)
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DisposableEffect(writingScreen, isDoneSendingCard) {
|
|
||||||
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 (secrets != null && nfcCharacter != null) {
|
|
||||||
if (!isDoneSendingCard) {
|
|
||||||
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) {
|
|
||||||
isDoneSendingCard = true
|
|
||||||
}
|
|
||||||
} else if (!isDoneWritingCharacter) {
|
|
||||||
scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) {
|
|
||||||
isDoneWritingCharacter = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onDispose {
|
|
||||||
if(writingScreen) {
|
|
||||||
scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER)
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDoneReadingCharacter && !cardSelectScreen) {
|
|
||||||
readingScreen = false
|
|
||||||
navController.navigate(NavigationItems.Home.route)
|
|
||||||
} else if (isDoneSendingCard && isDoneWritingCharacter) {
|
|
||||||
writingScreen = false
|
|
||||||
navController.navigate(NavigationItems.Home.route)
|
|
||||||
LaunchedEffect(storageRepository) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
storageRepository
|
|
||||||
.deleteCharacter(characterId!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readingScreen) {
|
|
||||||
ReadingCharacterScreen("Reading character") {
|
|
||||||
readingScreen = false
|
|
||||||
scanScreenController.cancelRead()
|
|
||||||
}
|
|
||||||
} else if (writingScreen) {
|
|
||||||
if (!isDoneSendingCard) {
|
|
||||||
ReadingCharacterScreen("Sending card") {
|
|
||||||
writingScreen = false
|
writingScreen = false
|
||||||
scanScreenController.cancelRead()
|
navController.navigate(NavigationItems.Home.route)
|
||||||
}
|
},
|
||||||
} else if (!isDoneWritingCharacter) {
|
onCancel = {
|
||||||
ReadingCharacterScreen("Writing character") {
|
|
||||||
isDoneSendingCard = false
|
|
||||||
writingScreen = false
|
writingScreen = false
|
||||||
scanScreenController.cancelRead()
|
navController.navigate(NavigationItems.Home.route)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
} else if (cardSelectScreen) {
|
} else if (readingScreen) {
|
||||||
ChooseCard(
|
ReadingScreen(
|
||||||
cards = cardsRead!!,
|
scanScreenController = scanScreenController,
|
||||||
onCardSelected = { card ->
|
onCancel = {
|
||||||
cardSelectScreen = false
|
readingScreen = false
|
||||||
scanScreenController.flushCharacter(card.id)
|
navController.navigate(NavigationItems.Home.route)
|
||||||
|
},
|
||||||
|
onComplete = {
|
||||||
|
readingScreen = false
|
||||||
|
navController.navigate(NavigationItems.Home.route)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -247,66 +121,8 @@ fun ScanScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ChooseConnectOption(
|
|
||||||
onClickRead: (() -> Unit)? = null,
|
|
||||||
onClickWrite: (() -> Unit)? = null,
|
|
||||||
navController: NavController
|
|
||||||
) {
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBanner(
|
|
||||||
text = "Scan a Vital Bracelet",
|
|
||||||
onBackClick = {
|
|
||||||
navController.popBackStack()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { contentPadding ->
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(contentPadding)
|
|
||||||
) {
|
|
||||||
ScanButton(
|
|
||||||
text = "Vital Bracelet to App",
|
|
||||||
disabled = onClickRead == null,
|
|
||||||
onClick = onClickRead?: { },
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
ScanButton(
|
|
||||||
text = "App to Vital Bracelet",
|
|
||||||
disabled = onClickWrite == null,
|
|
||||||
onClick = onClickWrite?: { },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ScanButton(
|
|
||||||
text: String,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
disabled: Boolean = false,
|
|
||||||
) {
|
|
||||||
Button(
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = modifier,
|
|
||||||
enabled = !disabled,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = text,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
@Preview(showBackground = true)
|
||||||
@Composable
|
@Composable
|
||||||
fun ScanScreenPreview() {
|
fun ScanScreenPreview() {
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen.converters
|
package com.github.nacabaro.vbhelper.screens.scanScreen.converters
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
||||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
import com.github.cfogrady.vbnfc.vb.VBNfcCharacter
|
import com.github.cfogrady.vbnfc.vb.VBNfcCharacter
|
||||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||||
@ -250,10 +248,11 @@ class FromNfcConverter (
|
|||||||
) {
|
) {
|
||||||
val vitalsHistoryWatch = nfcCharacter.vitalHistory
|
val vitalsHistoryWatch = nfcCharacter.vitalHistory
|
||||||
val vitalsHistory = vitalsHistoryWatch.map { historyElement ->
|
val vitalsHistory = vitalsHistoryWatch.map { historyElement ->
|
||||||
Log.d("VitalsHistory", "${historyElement.year.toInt()} ${historyElement.month.toInt()} ${historyElement.day.toInt()}")
|
val year = if (historyElement.year.toInt() !in 2021 .. 2035) 0 else historyElement.year.toInt()
|
||||||
|
|
||||||
VitalsHistory(
|
VitalsHistory(
|
||||||
charId = characterId,
|
charId = characterId,
|
||||||
year = historyElement.year.toInt(),
|
year = year,
|
||||||
month = historyElement.month.toInt(),
|
month = historyElement.month.toInt(),
|
||||||
day = historyElement.day.toInt(),
|
day = historyElement.day.toInt(),
|
||||||
vitalPoints = historyElement.vitalsGained.toInt()
|
vitalPoints = historyElement.vitalsGained.toInt()
|
||||||
|
|||||||
@ -14,6 +14,7 @@ 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.utils.DeviceType
|
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
class ToNfcConverter(
|
class ToNfcConverter(
|
||||||
@ -96,6 +97,7 @@ class ToNfcConverter(
|
|||||||
val cardData = database
|
val cardData = database
|
||||||
.cardDao()
|
.cardDao()
|
||||||
.getCardByCharacterId(userCharacter.id)
|
.getCardByCharacterId(userCharacter.id)
|
||||||
|
.first()
|
||||||
|
|
||||||
val appReserved = Array<UShort>(3) {
|
val appReserved = Array<UShort>(3) {
|
||||||
0u
|
0u
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.scanScreen
|
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -14,13 +14,16 @@ import androidx.compose.ui.unit.dp
|
|||||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ReadingCharacterScreen(
|
fun ActionScreen(
|
||||||
topBannerText: String,
|
topBannerText: String,
|
||||||
onClickCancel: () -> Unit,
|
onClickCancel: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBanner(topBannerText)
|
TopBanner(
|
||||||
|
text = topBannerText,
|
||||||
|
onBackClick = onClickCancel
|
||||||
|
)
|
||||||
}
|
}
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Column (
|
Column (
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReadCharacterScreen(
|
||||||
|
onClickCancel: () -> Unit,
|
||||||
|
onClickConfirm: () -> Unit
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopBanner(
|
||||||
|
text = "Read character",
|
||||||
|
onBackClick = onClickCancel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { innerPadding ->
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(innerPadding)
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Prepare your device!",
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Go to connect and when ready press confirm!",
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier.padding(8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = onClickConfirm,
|
||||||
|
) {
|
||||||
|
Text("Confirm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
||||||
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
|
import com.github.nacabaro.vbhelper.screens.cardScreen.ChooseCard
|
||||||
|
import com.github.nacabaro.vbhelper.screens.scanScreen.SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
||||||
|
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenController
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReadingScreen(
|
||||||
|
scanScreenController: ScanScreenController,
|
||||||
|
onCancel: () -> Unit,
|
||||||
|
onComplete: () -> Unit
|
||||||
|
) {
|
||||||
|
val secrets by scanScreenController.secretsFlow.collectAsState(null)
|
||||||
|
|
||||||
|
var cardsRead by remember { mutableStateOf<List<Card>?>(null) }
|
||||||
|
|
||||||
|
var readingScreen by remember { mutableStateOf(false) }
|
||||||
|
var isDoneReadingCharacter by remember { mutableStateOf(false) }
|
||||||
|
var cardSelectScreen by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
DisposableEffect(readingScreen) {
|
||||||
|
if(readingScreen) {
|
||||||
|
scanScreenController.registerActivityLifecycleListener(
|
||||||
|
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
||||||
|
object: ActivityLifecycleListener {
|
||||||
|
override fun onPause() {
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
scanScreenController.onClickRead(
|
||||||
|
secrets = secrets!!,
|
||||||
|
onComplete = {
|
||||||
|
isDoneReadingCharacter = true
|
||||||
|
},
|
||||||
|
onMultipleCards = { cards ->
|
||||||
|
cardsRead = cards
|
||||||
|
readingScreen = false
|
||||||
|
cardSelectScreen = true
|
||||||
|
isDoneReadingCharacter = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
scanScreenController.onClickRead(
|
||||||
|
secrets = secrets!!,
|
||||||
|
onComplete = {
|
||||||
|
isDoneReadingCharacter = true
|
||||||
|
},
|
||||||
|
onMultipleCards = { cards ->
|
||||||
|
cardsRead = cards
|
||||||
|
readingScreen = false
|
||||||
|
cardSelectScreen = true
|
||||||
|
isDoneReadingCharacter = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
onDispose {
|
||||||
|
if(readingScreen) {
|
||||||
|
scanScreenController.unregisterActivityLifecycleListener(
|
||||||
|
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
||||||
|
)
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDoneReadingCharacter && !cardSelectScreen) {
|
||||||
|
readingScreen = false
|
||||||
|
onComplete()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readingScreen) {
|
||||||
|
ReadCharacterScreen(
|
||||||
|
onClickConfirm = {
|
||||||
|
readingScreen = true
|
||||||
|
},
|
||||||
|
onClickCancel = {
|
||||||
|
onCancel()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readingScreen) {
|
||||||
|
ActionScreen("Reading character") {
|
||||||
|
readingScreen = false
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
onCancel()
|
||||||
|
}
|
||||||
|
} else if (cardSelectScreen) {
|
||||||
|
ChooseCard(
|
||||||
|
cards = cardsRead!!,
|
||||||
|
onCardSelected = { card ->
|
||||||
|
cardSelectScreen = false
|
||||||
|
scanScreenController.flushCharacter(card.id)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardColors
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.contentColorFor
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.FilterQuality
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
|
import com.github.nacabaro.vbhelper.source.ScanRepository
|
||||||
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
|
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun WriteCardScreen(
|
||||||
|
characterId: Long,
|
||||||
|
onClickCancel: () -> Unit,
|
||||||
|
onClickConfirm: () -> Unit
|
||||||
|
) {
|
||||||
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
|
val database = application.container.db
|
||||||
|
val scanRepository = ScanRepository(database)
|
||||||
|
val cardDetails by scanRepository.getCardDetails(characterId).collectAsState(Card(
|
||||||
|
id = 0,
|
||||||
|
cardId = 0,
|
||||||
|
name = "",
|
||||||
|
logo = byteArrayOf(),
|
||||||
|
logoHeight = 0,
|
||||||
|
logoWidth = 0,
|
||||||
|
stageCount = 0,
|
||||||
|
isBEm = false
|
||||||
|
))
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopBanner(
|
||||||
|
text = "Writing card details",
|
||||||
|
onBackClick = onClickCancel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { innerPadding ->
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(innerPadding)
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
Card (
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
|
Row (
|
||||||
|
modifier = Modifier.padding(16.dp),
|
||||||
|
){
|
||||||
|
if (cardDetails.logoHeight > 0 && cardDetails.logoWidth > 0) {
|
||||||
|
val charaBitmapData = BitmapData(
|
||||||
|
bitmap = cardDetails.logo,
|
||||||
|
width = cardDetails.logoWidth,
|
||||||
|
height = cardDetails.logoHeight
|
||||||
|
)
|
||||||
|
val charaImageBitmapData = charaBitmapData.getImageBitmap(
|
||||||
|
context = LocalContext.current,
|
||||||
|
multiplier = 4,
|
||||||
|
obscure = false
|
||||||
|
)
|
||||||
|
|
||||||
|
Card (
|
||||||
|
colors = CardColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
contentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
),
|
||||||
|
disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
disabledContentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
bitmap = charaImageBitmapData.imageBitmap,
|
||||||
|
contentDescription = "Icon",
|
||||||
|
modifier = Modifier
|
||||||
|
.size(charaImageBitmapData.dpWidth)
|
||||||
|
.padding(8.dp),
|
||||||
|
filterQuality = FilterQuality.None
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier.width(8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Text("Get your device Ready!")
|
||||||
|
Text("You will need ${cardDetails.name} card!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = onClickConfirm,
|
||||||
|
) {
|
||||||
|
Text("Confirm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,135 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardColors
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.contentColorFor
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.FilterQuality
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||||
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
|
import com.github.nacabaro.vbhelper.source.ScanRepository
|
||||||
|
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||||
|
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun WriteCharacterScreen(
|
||||||
|
characterId: Long,
|
||||||
|
onClickCancel: () -> Unit,
|
||||||
|
onClickConfirm: () -> Unit
|
||||||
|
) {
|
||||||
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
|
val database = application.container.db
|
||||||
|
val scanRepository = ScanRepository(database)
|
||||||
|
val cardDetails by scanRepository.getCardDetails(characterId).collectAsState(Card(
|
||||||
|
id = 0,
|
||||||
|
cardId = 0,
|
||||||
|
name = "",
|
||||||
|
logo = byteArrayOf(),
|
||||||
|
logoHeight = 0,
|
||||||
|
logoWidth = 0,
|
||||||
|
stageCount = 0,
|
||||||
|
isBEm = false
|
||||||
|
))
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopBanner(
|
||||||
|
text = "Writing character",
|
||||||
|
onBackClick = onClickCancel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { innerPadding ->
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(innerPadding)
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
Card (
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
|
Row (
|
||||||
|
modifier = Modifier.padding(16.dp),
|
||||||
|
){
|
||||||
|
if (cardDetails.logoHeight > 0 && cardDetails.logoWidth > 0) {
|
||||||
|
val charaBitmapData = BitmapData(
|
||||||
|
bitmap = cardDetails.logo,
|
||||||
|
width = cardDetails.logoWidth,
|
||||||
|
height = cardDetails.logoHeight
|
||||||
|
)
|
||||||
|
val charaImageBitmapData = charaBitmapData.getImageBitmap(
|
||||||
|
context = LocalContext.current,
|
||||||
|
multiplier = 4,
|
||||||
|
obscure = false
|
||||||
|
)
|
||||||
|
|
||||||
|
Card (
|
||||||
|
colors = CardColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
contentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
),
|
||||||
|
disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
disabledContentColor = MaterialTheme.colorScheme.contentColorFor(
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
bitmap = charaImageBitmapData.imageBitmap,
|
||||||
|
contentDescription = "Icon",
|
||||||
|
modifier = Modifier
|
||||||
|
.size(charaImageBitmapData.dpWidth)
|
||||||
|
.padding(8.dp),
|
||||||
|
filterQuality = FilterQuality.None
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(
|
||||||
|
modifier = Modifier.width(8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Text("Card installed successfully!!")
|
||||||
|
Text("Wait until your device is ready, then tap 'Confirm'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = onClickConfirm,
|
||||||
|
) {
|
||||||
|
Text("Confirm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.screens.scanScreen.screens
|
||||||
|
|
||||||
|
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
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||||
|
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
||||||
|
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||||
|
import com.github.nacabaro.vbhelper.screens.scanScreen.SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
||||||
|
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenController
|
||||||
|
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun WritingScreen(
|
||||||
|
scanScreenController: ScanScreenController,
|
||||||
|
characterId: Long,
|
||||||
|
nfcCharacter: NfcCharacter,
|
||||||
|
onComplete: () -> Unit,
|
||||||
|
onCancel: () -> Unit,
|
||||||
|
) {
|
||||||
|
val secrets by scanScreenController.secretsFlow.collectAsState(null)
|
||||||
|
|
||||||
|
val application = LocalContext.current.applicationContext as VBHelper
|
||||||
|
val storageRepository = StorageRepository(application.container.db)
|
||||||
|
|
||||||
|
var writing by remember { mutableStateOf(false) }
|
||||||
|
var writingScreen by remember { mutableStateOf(false) }
|
||||||
|
var writingConfirmScreen by remember { mutableStateOf(false) }
|
||||||
|
var isDoneSendingCard by remember { mutableStateOf(false) }
|
||||||
|
var isDoneWritingCharacter by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
DisposableEffect(writing) {
|
||||||
|
if (writing) {
|
||||||
|
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 (secrets != null) {
|
||||||
|
if (!isDoneSendingCard) {
|
||||||
|
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter) {
|
||||||
|
isDoneSendingCard = true
|
||||||
|
}
|
||||||
|
} else if (!isDoneWritingCharacter) {
|
||||||
|
scanScreenController.onClickWrite(secrets!!, nfcCharacter) {
|
||||||
|
isDoneWritingCharacter = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDispose {
|
||||||
|
if (writing) {
|
||||||
|
scanScreenController.unregisterActivityLifecycleListener(
|
||||||
|
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
||||||
|
)
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!writingScreen) {
|
||||||
|
writing = false
|
||||||
|
WriteCardScreen (
|
||||||
|
characterId = characterId,
|
||||||
|
onClickCancel = {
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
onCancel()
|
||||||
|
},
|
||||||
|
onClickConfirm = {
|
||||||
|
writingScreen = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else if (!isDoneSendingCard) {
|
||||||
|
writing = true
|
||||||
|
ActionScreen("Sending card") {
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
onCancel()
|
||||||
|
}
|
||||||
|
} else if (!writingConfirmScreen) {
|
||||||
|
writing = false
|
||||||
|
WriteCharacterScreen (
|
||||||
|
characterId = characterId,
|
||||||
|
onClickCancel = {
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
onCancel()
|
||||||
|
},
|
||||||
|
onClickConfirm = {
|
||||||
|
writingConfirmScreen = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else if (!isDoneWritingCharacter) {
|
||||||
|
writing = true
|
||||||
|
ActionScreen("Writing character") {
|
||||||
|
isDoneSendingCard = false
|
||||||
|
scanScreenController.cancelRead()
|
||||||
|
onCancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var completedWriting by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
LaunchedEffect(isDoneSendingCard, isDoneWritingCharacter) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (isDoneSendingCard && isDoneWritingCharacter) {
|
||||||
|
storageRepository
|
||||||
|
.deleteCharacter(characterId)
|
||||||
|
completedWriting = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completedWriting) {
|
||||||
|
onComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -38,6 +38,7 @@ import kotlinx.coroutines.launch
|
|||||||
fun StorageDialog(
|
fun StorageDialog(
|
||||||
characterId: Long,
|
characterId: Long,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
|
onClickDelete: () -> Unit,
|
||||||
onSendToBracelet: () -> Unit,
|
onSendToBracelet: () -> Unit,
|
||||||
onClickSetActive: () -> Unit,
|
onClickSetActive: () -> Unit,
|
||||||
onClickSendToAdventure: (time: Long) -> Unit
|
onClickSendToAdventure: (time: Long) -> Unit
|
||||||
@ -141,6 +142,13 @@ fun StorageDialog(
|
|||||||
) {
|
) {
|
||||||
Text(text = "Send on adventure")
|
Text(text = "Send on adventure")
|
||||||
}
|
}
|
||||||
|
Button(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(),
|
||||||
|
onClick = onClickDelete
|
||||||
|
) {
|
||||||
|
Text(text = "Delete character")
|
||||||
|
}
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.github.nacabaro.vbhelper.screens.storageScreen
|
package com.github.nacabaro.vbhelper.screens.storageScreen
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
import androidx.compose.foundation.gestures.scrollable
|
import androidx.compose.foundation.gestures.scrollable
|
||||||
@ -14,11 +15,10 @@ import androidx.compose.foundation.rememberScrollState
|
|||||||
import androidx.compose.material3.Scaffold
|
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.LaunchedEffect
|
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
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
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
|
||||||
@ -28,12 +28,10 @@ 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.dtos.CharacterDtos
|
|
||||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -42,18 +40,11 @@ fun StorageScreen(
|
|||||||
storageScreenController: StorageScreenControllerImpl,
|
storageScreenController: StorageScreenControllerImpl,
|
||||||
adventureScreenController: AdventureScreenControllerImpl
|
adventureScreenController: AdventureScreenControllerImpl
|
||||||
) {
|
) {
|
||||||
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)
|
||||||
val monList = remember { mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList()) }
|
val characterList by storageRepository.getAllCharacters().collectAsState(initial = emptyList())
|
||||||
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
|
|
||||||
|
|
||||||
LaunchedEffect(storageRepository, selectedCharacter) {
|
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
|
||||||
coroutineScope.launch {
|
|
||||||
val characterList = storageRepository.getAllCharacters()
|
|
||||||
monList.value = characterList
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Scaffold (
|
Scaffold (
|
||||||
topBar = {
|
topBar = {
|
||||||
@ -65,7 +56,7 @@ fun StorageScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
if (monList.value.isEmpty()) {
|
if (characterList.isEmpty()) {
|
||||||
Column (
|
Column (
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
@ -86,7 +77,7 @@ fun StorageScreen(
|
|||||||
.scrollable(state = rememberScrollState(), orientation = Orientation.Vertical)
|
.scrollable(state = rememberScrollState(), orientation = Orientation.Vertical)
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
.padding(top = contentPadding.calculateTopPadding())
|
||||||
) {
|
) {
|
||||||
items(monList.value) { index ->
|
items(characterList) { index ->
|
||||||
CharacterEntry(
|
CharacterEntry(
|
||||||
icon = BitmapData(
|
icon = BitmapData(
|
||||||
bitmap = index.spriteIdle,
|
bitmap = index.spriteIdle,
|
||||||
@ -138,6 +129,16 @@ fun StorageScreen(
|
|||||||
timeInMinutes = time
|
timeInMinutes = time
|
||||||
)
|
)
|
||||||
selectedCharacter = null
|
selectedCharacter = null
|
||||||
|
},
|
||||||
|
onClickDelete = {
|
||||||
|
storageScreenController
|
||||||
|
.deleteCharacter(
|
||||||
|
characterId = selectedCharacter!!,
|
||||||
|
onCompletion = {
|
||||||
|
Log.d("StorageScreen", "Character deleted")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
selectedCharacter = null
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,4 +2,5 @@ package com.github.nacabaro.vbhelper.screens.storageScreen
|
|||||||
|
|
||||||
interface StorageScreenController {
|
interface StorageScreenController {
|
||||||
fun setActive(characterId: Long, onCompletion: () -> Unit)
|
fun setActive(characterId: Long, onCompletion: () -> Unit)
|
||||||
|
fun deleteCharacter(characterId: Long, onCompletion: () -> Unit)
|
||||||
}
|
}
|
||||||
@ -28,4 +28,21 @@ class StorageScreenControllerImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun deleteCharacter(characterId: Long, onCompletion: () -> Unit) {
|
||||||
|
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
database
|
||||||
|
.userCharacterDao()
|
||||||
|
.deleteCharacterById(characterId)
|
||||||
|
|
||||||
|
componentActivity.runOnUiThread {
|
||||||
|
Toast.makeText(
|
||||||
|
componentActivity,
|
||||||
|
"Character deleted!",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
onCompletion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.github.nacabaro.vbhelper.source
|
||||||
|
|
||||||
|
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||||
|
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class ScanRepository(
|
||||||
|
val database: AppDatabase
|
||||||
|
) {
|
||||||
|
fun getCardDetails(characterId: Long): Flow<Card> {
|
||||||
|
return database.cardDao().getCardByCharacterId(characterId)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,11 +6,12 @@ import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
|||||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class StorageRepository (
|
class StorageRepository (
|
||||||
private val db: AppDatabase
|
private val db: AppDatabase
|
||||||
) {
|
) {
|
||||||
suspend fun getAllCharacters(): List<CharacterDtos.CharacterWithSprites> {
|
fun getAllCharacters(): Flow<List<CharacterDtos.CharacterWithSprites>> {
|
||||||
return db.userCharacterDao().getAllCharacters()
|
return db.userCharacterDao().getAllCharacters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user