M app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt => app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt +44 -6
@@ 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"
+ )
+ }
+ }
+ }
}
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +9 -1
@@ 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
+ )
+ }
}
}
}
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/BottomNavItem.kt +2 -1
@@ 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")
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/HomeScreen.kt +27 -2
@@ 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")
+ }
+ }
}
A app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/SettingsScreen.kt +96 -0
@@ 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
+ )
+ }
+}<
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt +83 -6
@@ 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")
+ }
+ }
+ }
+ }
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt => app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt +4 -0
@@ 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)
+ }
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/temporary_daos/TemporaryMonsterDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/temporary_daos/TemporaryMonsterDao.kt +3 -0
@@ 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
}=
\ No newline at end of file
A app/src/main/res/drawable/baseline_arrow_back_24.xml => app/src/main/res/drawable/baseline_arrow_back_24.xml +5 -0
@@ 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>
A app/src/main/res/drawable/baseline_settings_24.xml => app/src/main/res/drawable/baseline_settings_24.xml +5 -0
@@ 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>