From 305b776b5207800a4b109bbfca1704d6ab2bb426 Mon Sep 17 00:00:00 2001 From: Nacho Date: Sun, 19 Jan 2025 13:41:50 +0100 Subject: [PATCH] Things - Added items store and a way to switch between the store and your items - Added an items dialog, click on it to see details of the item (description, amount) and use it - Added items store, it lists all the items available --- app/src/main/assets/items.db | Bin 16384 -> 16384 bytes .../vbhelper/components/ItemElement.kt | 184 +++++++++++++++--- .../github/nacabaro/vbhelper/daos/ItemDao.kt | 8 +- .../vbhelper/navigation/AppNavigation.kt | 2 +- .../vbhelper/navigation/NavigationItems.kt | 2 + .../nacabaro/vbhelper/screens/ItemsScreen.kt | 57 +++++- .../vbhelper/screens/StorageScreen.kt | 2 +- .../screens/itemsScreen/ItemsStore.kt | 77 ++++++++ .../vbhelper/screens/itemsScreen/MyItems.kt | 54 +++-- .../vbhelper/source/ItemsRepository.kt | 2 +- .../main/res/drawable/baseline_shield_24.xml | 8 +- 11 files changed, 343 insertions(+), 53 deletions(-) create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsStore.kt diff --git a/app/src/main/assets/items.db b/app/src/main/assets/items.db index 9064ecf8cdccc050f63d947f4e79964cbd469f11..37e07adc584bbff9ba83851f8d5b6f7e09a51b54 100644 GIT binary patch delta 744 zcmZo@U~Fh$oFL68Fj2;tQD9@jLVj(YJO&}Iy)67&_?q~oc@+6fc%Sk7<(yC~Wb*O!^$bx6at(G32}&(aEh$zgDN4-D z%gjqx$jQvjEKx{GOwLv)$yYEmFi^pr~Le4ps#?kDWydqZ-M+b`K^o?FAL)YZ!VB#PN3$=`{ZRA113L^ z5ueN_&&|uiFwL6Yp0B(+$RiQyODc?J#!ATZ};XE1aG zy1>shB18ca7P=7IgHlsUlY!v?mPx8qfQW(&U}k01@!^I!9b^N~F)=gz@?nMQcLcjIT26zL2_ypak0Z!GlcVJ%K)#7&VwlFC z$sh=FEF75g0mI%F&DDlRkg!L0H%y#`m05v-!J8Rsixb!uUa&2E-XNpV?BK^@hmi?( RJ7D6htSlQgZtLVihJRt8R<9gO^2_+|Lc^EL6A@IK?&!8?Q3Yh&X) z9xiWob_VN2PDUn=$rGeyC*PKrm~11<$HJe<;5xC;ZZH2EITSYA1a$x-q^VJ4`sBUm^Z XEX>W$#4wG4fx&BHqx Unit) = { } ) { - val iconResource = when (itemIcon) { - 1 -> R.drawable.baseline_agility_24 - 2 -> R.drawable.baseline_attack_24 - 3 -> R.drawable.baseline_shield_24 - else -> R.drawable.baseline_question_mark_24 - } - - val lengthResource = when (lengthIcon) { - 1 -> R.drawable.baseline_15_min_timer - 2 -> R.drawable.baseline_30_min_timer - 3 -> R.drawable.baseline_60_min_timer - else -> R.drawable.baseline_question_mark_24 - } - Card ( onClick = onClick, modifier = modifier @@ -44,20 +47,151 @@ fun ItemElement( ) { Box(modifier = Modifier.fillMaxSize()) { // Background image (full size) - Image( - painter = painterResource(id = iconResource), - contentDescription = null, - contentScale = ContentScale.Crop, - modifier = Modifier.fillMaxSize() - ) - Image( - painter = painterResource(id = lengthResource), + Icon( + painter = painterResource(id = itemIcon), contentDescription = null, modifier = Modifier - .size(100.dp) // Set the size of the overlay image - .align(Alignment.TopEnd) // Align to the top end (top-right corner) - .padding(16.dp) // Add some padding from the edges + .size(96.dp) + .align(Alignment.Center) + ) + Icon( + painter = painterResource(id = lengthIcon), + contentDescription = null, + tint = MaterialTheme.colorScheme.surfaceTint, + modifier = Modifier + .size(48.dp) // Set the size of the overlay image + .padding(4.dp + ) + .align(Alignment.TopStart) // Align to the top end (top-right corner) ) } } +} + +@Composable +fun ItemDialog( + name: String, + description: String, + itemIcon: Int, + lengthIcon: Int, + amount: Int, + onClickUse: () -> Unit, + onClickCancel: () -> Unit +) { + Dialog( + onDismissRequest = onClickCancel, + properties = DialogProperties( + dismissOnBackPress = true, + dismissOnClickOutside = true + ) + ) { + Card ( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Column ( + modifier = Modifier + .padding(16.dp) + ) { + Row { + Box(modifier = Modifier) { + // Background image (full size) + Icon( + painter = painterResource(id = itemIcon), + contentDescription = null, + modifier = Modifier + .size(96.dp) + .align(Alignment.Center) + ) + Icon( + painter = painterResource(id = lengthIcon), + contentDescription = null, + tint = MaterialTheme.colorScheme.outline, + modifier = Modifier + .size(64.dp) // Set the size of the overlay image + .align(Alignment.BottomEnd) // Align to the top end (top-right corner) + ) + } + Column ( + modifier = Modifier + .padding(16.dp) + ) { + Text( + fontSize = MaterialTheme.typography.titleLarge.fontSize, + text = name, + modifier = Modifier + .fillMaxWidth() + ) + } + } + Text( + textAlign = TextAlign.Center, + fontSize = MaterialTheme.typography.bodyMedium.fontSize, + fontFamily = MaterialTheme.typography.bodyMedium.fontFamily, + text = description + ) + Text( + textAlign = TextAlign.Center, + fontSize = MaterialTheme.typography.bodySmall.fontSize, + fontFamily = MaterialTheme.typography.bodySmall.fontFamily, + text = "You have $amount of this item", + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) + Row ( + horizontalArrangement = Arrangement.Center, + modifier = Modifier + .fillMaxWidth() + ) { + Button( + onClick = onClickUse + ) { + Text("Use item") + } + Spacer(modifier = Modifier.size(8.dp)) + Button( + onClick = onClickCancel + ) { + Text("Cancel") + } + } + } + } + } +} + +fun getIconResource(index: Int): Int { + return when (index) { + 1 -> R.drawable.baseline_agility_24 + 2 -> R.drawable.baseline_attack_24 + 3 -> R.drawable.baseline_shield_24 + else -> R.drawable.baseline_question_mark_24 + } +} + +fun getLengthResource(index: Int): Int { + return when (index) { + 1 -> R.drawable.baseline_15_min_timer + 2 -> R.drawable.baseline_30_min_timer + 3 -> R.drawable.baseline_60_min_timer + else -> R.drawable.baseline_question_mark_24 + } +} + +@Composable +@Preview(showBackground = true) +fun PreviewItemDialog() { + VBHelperTheme { + ItemDialog( + name = "AP Training x3 (60 min)", + description = "Boosts AP during training (for 60 minutes)", + itemIcon = R.drawable.baseline_attack_24, + lengthIcon = R.drawable.baseline_60_min_timer, + onClickUse = { }, + onClickCancel = { }, + amount = 19 + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/ItemDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/ItemDao.kt index 2c4cad0..db9c90e 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/ItemDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/ItemDao.kt @@ -7,8 +7,12 @@ import com.github.nacabaro.vbhelper.dtos.ItemDtos @Dao interface ItemDao { - @Query("SELECT * FROM Items") - suspend fun getAllItems(): List + @Query(""" + SELECT Items.*, UserItems.quantity + FROM Items + LEFT JOIN UserItems ON Items.id = UserItems.itemId + """) + suspend fun getAllItems(): List @Query(""" SELECT Items.*, UserItems.quantity diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt index be70f03..c0b044b 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt @@ -93,7 +93,7 @@ fun AppNavigation( } } composable(NavigationItems.Items.route) { - MyItems( + ItemsScreen( navController = navController ) } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt index bc0bd38..ee831b0 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt @@ -16,4 +16,6 @@ sealed class NavigationItems ( object Viewer : NavigationItems("Viewer", R.drawable.baseline_image_24, "Viewer") object CardView : NavigationItems("Card/{cardId}", R.drawable.baseline_image_24, "Card") object Items : NavigationItems("Items", R.drawable.baseline_data_24, "Items") + object MyItems : NavigationItems("MyItems", R.drawable.baseline_data_24, "My items") + object ItemsStore : NavigationItems("ItemsStore", R.drawable.baseline_data_24, "Items store") } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/ItemsScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/ItemsScreen.kt index 76b9532..2ef81b5 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/ItemsScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/ItemsScreen.kt @@ -1,12 +1,65 @@ package com.github.nacabaro.vbhelper.screens +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Tab +import androidx.compose.material3.TabRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import androidx.navigation.NavController +import com.github.nacabaro.vbhelper.components.TopBanner +import com.github.nacabaro.vbhelper.navigation.NavigationItems +import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsStore +import com.github.nacabaro.vbhelper.screens.itemsScreen.MyItems @Composable fun ItemsScreen( - navController: NavController + navController: NavController, ) { - Text(text = "Items") + var selectedTabItem by remember { mutableStateOf(0) } + val items = listOf( + NavigationItems.MyItems, + NavigationItems.ItemsStore + ) + Scaffold( + topBar = { + Column { + TopBanner("Items") + TabRow( + selectedTabIndex = selectedTabItem, + modifier = Modifier + ) { + items.forEachIndexed { index, item -> + Tab( + text = { Text(item.label) }, + selected = selectedTabItem == index, + onClick = { selectedTabItem = index } + ) + } + } + } + } + ) { contentPadding -> + Box( + modifier = Modifier + .fillMaxWidth() + .padding(top = contentPadding.calculateTopPadding()) + ) { + when (selectedTabItem) { + 0 -> MyItems(navController) + 1 -> ItemsStore(navController) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt index 597fca0..533b131 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt @@ -66,7 +66,7 @@ fun StorageScreen( } Scaffold ( - topBar = { TopBanner(text = "My Digimon") } + topBar = { TopBanner(text = "My characters") } ) { contentPadding -> if (monList.value.isEmpty()) { Column ( diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsStore.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsStore.kt new file mode 100644 index 0000000..d205f8f --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsStore.kt @@ -0,0 +1,77 @@ +package com.github.nacabaro.vbhelper.screens.itemsScreen + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.github.nacabaro.vbhelper.components.ItemDialog +import com.github.nacabaro.vbhelper.components.ItemElement +import com.github.nacabaro.vbhelper.components.getIconResource +import com.github.nacabaro.vbhelper.components.getLengthResource +import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.dtos.ItemDtos +import com.github.nacabaro.vbhelper.source.ItemsRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +@Composable +fun ItemsStore( + navController: NavController +) { + val application = LocalContext.current.applicationContext as VBHelper + val itemsRepository = ItemsRepository(application.container.db) + val myItems = remember { mutableStateOf(emptyList()) } + var showDialog by remember { mutableStateOf(false) } + var selectedElementIndex by remember { mutableStateOf(null) } + + LaunchedEffect(itemsRepository) { + withContext(Dispatchers.IO) { + myItems.value = itemsRepository.getAllItems() + } + } + + if (myItems.value.isEmpty()) { + Text("No items") + } else { + LazyVerticalGrid( + columns = GridCells.Fixed(3), + modifier = Modifier + ) { + items(myItems.value) { index -> + ItemElement( + itemIcon = getIconResource(index.itemIcon), + lengthIcon = getLengthResource(index.lengthIcon), + modifier = Modifier + .padding(8.dp), + onClick = { + showDialog = true + selectedElementIndex = myItems.value.indexOf(index) + } + ) + + if (showDialog && selectedElementIndex != null) { + ItemDialog( + name = myItems.value[selectedElementIndex!!].name, + description = myItems.value[selectedElementIndex!!].description, + itemIcon = getIconResource(myItems.value[selectedElementIndex!!].itemIcon), + lengthIcon = getLengthResource(myItems.value[selectedElementIndex!!].lengthIcon), + amount = myItems.value[selectedElementIndex!!].quantity, + onClickUse = { }, + onClickCancel = { showDialog = false } + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/MyItems.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/MyItems.kt index b3d0bad..2a6f0cb 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/MyItems.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/MyItems.kt @@ -1,5 +1,6 @@ package com.github.nacabaro.vbhelper.screens.itemsScreen +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid @@ -8,14 +9,20 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.navigation.NavController +import com.github.nacabaro.vbhelper.R +import com.github.nacabaro.vbhelper.components.ItemDialog import com.github.nacabaro.vbhelper.components.ItemElement import com.github.nacabaro.vbhelper.components.TopBanner +import com.github.nacabaro.vbhelper.components.getIconResource +import com.github.nacabaro.vbhelper.components.getLengthResource import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.dtos.ItemDtos import com.github.nacabaro.vbhelper.source.ItemsRepository @@ -29,6 +36,8 @@ fun MyItems( val application = LocalContext.current.applicationContext as VBHelper val itemsRepository = ItemsRepository(application.container.db) val myItems = remember { mutableStateOf(emptyList()) } + var showDialog by remember { mutableStateOf(false) } + var selectedElementIndex by remember { mutableStateOf(null) } LaunchedEffect(itemsRepository) { withContext(Dispatchers.IO) { @@ -36,23 +45,34 @@ fun MyItems( } } - Scaffold ( - topBar = { TopBanner("Available items") } - ) { contentPadding -> - if (myItems.value.isEmpty()) { - Text("No items") - } else { - LazyVerticalGrid( - columns = GridCells.Fixed(3), - contentPadding = contentPadding - ) { - items(myItems.value) { index -> - ItemElement( - itemIcon = index.itemIcon, - lengthIcon = index.lengthIcon, - modifier = Modifier - .padding(8.dp), - onClick = { } + if (myItems.value.isEmpty()) { + Text("No items") + } else { + LazyVerticalGrid( + columns = GridCells.Fixed(3), + modifier = Modifier + ) { + items(myItems.value) { index -> + ItemElement( + itemIcon = getIconResource(index.itemIcon), + lengthIcon = getLengthResource(index.lengthIcon), + modifier = Modifier + .padding(8.dp), + onClick = { + showDialog = true + selectedElementIndex = myItems.value.indexOf(index) + } + ) + + if (showDialog && selectedElementIndex != null) { + ItemDialog( + name = myItems.value[selectedElementIndex!!].name, + description = myItems.value[selectedElementIndex!!].description, + itemIcon = getIconResource(myItems.value[selectedElementIndex!!].itemIcon), + lengthIcon = getLengthResource(myItems.value[selectedElementIndex!!].lengthIcon), + amount = myItems.value[selectedElementIndex!!].quantity, + onClickUse = { }, + onClickCancel = { showDialog = false } ) } } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/source/ItemsRepository.kt b/app/src/main/java/com/github/nacabaro/vbhelper/source/ItemsRepository.kt index 553994c..8d6d705 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/source/ItemsRepository.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/source/ItemsRepository.kt @@ -7,7 +7,7 @@ import com.github.nacabaro.vbhelper.dtos.ItemDtos class ItemsRepository( private val db: AppDatabase ) { - suspend fun getAllItems(): List { + suspend fun getAllItems(): List { return db.itemDao().getAllItems() } diff --git a/app/src/main/res/drawable/baseline_shield_24.xml b/app/src/main/res/drawable/baseline_shield_24.xml index 4554dcb..8e3b2ca 100644 --- a/app/src/main/res/drawable/baseline_shield_24.xml +++ b/app/src/main/res/drawable/baseline_shield_24.xml @@ -1,9 +1,9 @@ + android:viewportWidth="960" + android:viewportHeight="960"> + android:pathData="M480,880q-139,-35 -229.5,-159.5T160,444v-244l320,-120 320,120v244q0,152 -90.5,276.5T480,880ZM480,796q104,-33 172,-132t68,-220v-189l-240,-90 -240,90v189q0,121 68,220t172,132ZM480,480Z" + android:fillColor="#000000"/>