Few things, again!

- From "Battles" to "Battle"
- Added a settings screen, to import keys and cards
- Added a way to access the settings from home
- Get character details
This commit is contained in:
Nacho 2025-01-05 01:58:08 +01:00
parent 59033e6459
commit e8f441ba2b
10 changed files with 278 additions and 16 deletions

View File

@ -1,25 +1,63 @@
package com.github.nacabaro.vbhelper.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.github.nacabaro.vbhelper.R
@Composable
fun TopBanner(
text: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
onGearClick: (() -> Unit)? = null,
onBackClick: (() -> Unit)? = null
) {
Text(
text = text,
textAlign = TextAlign.Center,
fontSize = 24.sp,
Box( // Use Box to overlay elements
modifier = modifier
.fillMaxWidth()
.padding(16.dp)
)
) {
Text(
text = text,
textAlign = TextAlign.Center,
fontSize = 24.sp,
modifier = Modifier
.align(Alignment.Center) // Center the text
)
if (onGearClick != null) {
IconButton(
onClick = onGearClick,
modifier = Modifier
.align(Alignment.CenterEnd) // Place gear icon at the end
) {
Icon(
painter = painterResource(R.drawable.baseline_settings_24), // Use a gear icon
contentDescription = "Settings"
)
}
}
if (onBackClick != null) {
IconButton(
onClick = onBackClick,
modifier = Modifier
.align(Alignment.CenterStart) // Place gear icon at the end
) {
Icon(
painter = painterResource(R.drawable.baseline_arrow_back_24), // Use a gear icon
contentDescription = "Settings"
)
}
}
}
}

View File

@ -11,6 +11,7 @@ import com.github.nacabaro.vbhelper.screens.BattlesScreen
import com.github.nacabaro.vbhelper.screens.DexScreen
import com.github.nacabaro.vbhelper.screens.HomeScreen
import com.github.nacabaro.vbhelper.screens.ScanScreen
import com.github.nacabaro.vbhelper.screens.SettingsScreen
import com.github.nacabaro.vbhelper.screens.StorageScreen
@Composable
@ -36,7 +37,9 @@ fun AppNavigation(
BattlesScreen()
}
composable(BottomNavItem.Home.route) {
HomeScreen()
HomeScreen(
navController = navController
)
}
composable(BottomNavItem.Storage.route) {
StorageScreen()
@ -52,6 +55,11 @@ fun AppNavigation(
composable(BottomNavItem.Dex.route) {
DexScreen()
}
composable(BottomNavItem.Settings.route) {
SettingsScreen(
navController = navController
)
}
}
}
}

View File

@ -8,8 +8,9 @@ sealed class BottomNavItem (
var label: String
) {
object Scan : BottomNavItem("Scan", R.drawable.baseline_nfc_24, "Scan")
object Battles : BottomNavItem("Battles", R.drawable.baseline_swords_24, "Battles")
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")
}

View File

@ -1,9 +1,34 @@
package com.github.nacabaro.vbhelper.screens
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
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
@Composable
fun HomeScreen() {
Text("Home Screen")
fun HomeScreen(
navController: NavController
) {
Scaffold (
topBar = {
TopBanner(
text = "VB Helper",
onGearClick = {
navController.navigate(BottomNavItem.Settings.route)
}
)
}
) { contentPadding ->
Box (
modifier = Modifier
.padding(top = contentPadding.calculateTopPadding())
) {
Text("Home Screen")
}
}
}

View File

@ -0,0 +1,96 @@
package com.github.nacabaro.vbhelper.screens
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
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 SettingsScreen(
navController: NavController
) {
Scaffold (
topBar = {
TopBanner(
text = "Settings",
onBackClick = {
navController.popBackStack()
}
)
},
modifier = Modifier
.fillMaxSize()
) { contentPadding ->
Column (
modifier = Modifier
.padding(top = contentPadding.calculateTopPadding())
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
SettingsSection("General")
SettingsEntry(title = "Import VB key", description = "Import standard vital bracelet keys") { }
SettingsEntry(title = "Import VB Characters key", description = "Import standard vital bracelet keys") { }
SettingsEntry(title = "Import VB BE key", description = "Import standard vital bracelet keys") { }
SettingsEntry(title = "Import transform functions", description = "Import standard vital bracelet keys") { }
SettingsEntry(title = "Import decryption key", description = "Import standard vital bracelet keys") { }
SettingsSection("DiM/BEm management")
SettingsEntry(title = "Import DiM card", description = "Import DiM card file") { }
SettingsEntry(title = "Import BEm card", description = "Import BEm card file") { }
SettingsSection("About and credits")
SettingsEntry(title = "Credits", description = "Credits") { }
SettingsEntry(title = "About", description = "About") { }
}
}
}
@Composable
fun SettingsEntry(
title: String,
description: String,
onClick: () -> Unit
) {
Column(
modifier = Modifier
.fillMaxWidth()
.clickable { onClick() }
.padding(16.dp)
) {
Text(text = title)
Text(
text = description,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.outline
)
}
}
@Composable
fun SettingsSection(
title: String
) {
Box (
modifier = Modifier
.padding(start = 16.dp)
) {
Text(
text = title,
fontSize = 12.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)
}
}

View File

@ -4,6 +4,7 @@ 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.fillMaxSize
import androidx.compose.foundation.layout.padding
@ -12,7 +13,10 @@ import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardElevation
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
@ -23,12 +27,16 @@ 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
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
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 com.github.nacabaro.vbhelper.R
import com.github.nacabaro.vbhelper.components.TopBanner
import com.github.nacabaro.vbhelper.di.VBHelper
@ -45,6 +53,7 @@ fun StorageScreen() {
val storageRepository = StorageRepository(application.container.db)
val monList = remember { mutableStateListOf<TemporaryCharacterData>() }
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
LaunchedEffect(storageRepository) {
coroutineScope.launch {
@ -60,11 +69,19 @@ fun StorageScreen() {
topBar = { TopBanner(text = "My Digimon") }
) { contentPadding ->
if (monList.isEmpty()) {
Text(
text = "Nothing to see here",
Column (
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier
.padding(8.dp)
)
.padding(contentPadding)
.fillMaxSize()
) {
Text(
text = "Nothing to see here",
textAlign = TextAlign.Center,
modifier = Modifier
)
}
}
LazyVerticalGrid(
@ -74,12 +91,22 @@ fun StorageScreen() {
.padding(top = contentPadding.calculateTopPadding())
) {
items(monList) { index ->
var showDialog by rememberSaveable { mutableStateOf(false) }
StorageEntry(
name = index.dimId.toString() + " - " + index.charIndex.toString(),
icon = R.drawable.ic_launcher_foreground,
onClick = { selectedCharacter = index.id },
modifier = Modifier
.padding(8.dp)
)
if (selectedCharacter != null) {
StorageDialog(
characterId = selectedCharacter!!,
onDismissRequest = { selectedCharacter = null }
)
}
}
}
}
@ -89,14 +116,16 @@ fun StorageScreen() {
fun StorageEntry(
name: String,
icon: Int,
onClick: () -> Unit = {},
modifier: Modifier = Modifier
) {
Card (
Card(
shape = MaterialTheme.shapes.medium,
onClick = onClick,
modifier = modifier
.padding(8.dp)
) {
Column (
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
@ -116,4 +145,52 @@ fun StorageEntry(
)
}
}
}
@Composable
fun StorageDialog(
characterId: Long,
onDismissRequest: () -> Unit
) {
val coroutineScope = rememberCoroutineScope()
val application = LocalContext.current.applicationContext as VBHelper
val storageRepository = StorageRepository(application.container.db)
val character = remember { mutableStateOf<TemporaryCharacterData?>(null) }
LaunchedEffect(storageRepository) {
coroutineScope.launch {
character.value = storageRepository.getSingleCharacter(characterId)
}
}
Dialog(
onDismissRequest = onDismissRequest,
properties = DialogProperties(
dismissOnBackPress = true,
dismissOnClickOutside = true
)
) {
Card(
shape = RoundedCornerShape(16.dp)
) {
Column (
modifier = Modifier
.padding(16.dp)
) {
if (character.value != null) {
Text(
text = character.value?.toString() ?: "Loading...",
textAlign = TextAlign.Center,
modifier = Modifier
.padding(8.dp)
)
}
Button(
onClick = onDismissRequest
) {
Text(text = "Close")
}
}
}
}
}

View File

@ -9,4 +9,8 @@ class StorageRepository (
suspend fun getAllCharacters(): List<TemporaryCharacterData> {
return db.temporaryMonsterDao().getAllCharacters()
}
suspend fun getSingleCharacter(id: Long): TemporaryCharacterData {
return db.temporaryMonsterDao().getCharacter(id)
}
}

View File

@ -24,4 +24,7 @@ interface TemporaryMonsterDao {
@Query("SELECT * FROM TemporaryCharacterData")
suspend fun getAllCharacters(): List<TemporaryCharacterData>
@Query("SELECT * FROM TemporaryCharacterData WHERE id = :id")
suspend fun getCharacter(id: Long): TemporaryCharacterData
}

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
</vector>