~cytrogen/vbhelper

305b776b5207800a4b109bbfca1704d6ab2bb426 — Nacho 1 year, 3 months ago c0a67e3
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
M app/src/main/assets/items.db => app/src/main/assets/items.db +0 -0
M app/src/main/java/com/github/nacabaro/vbhelper/components/ItemElement.kt => app/src/main/java/com/github/nacabaro/vbhelper/components/ItemElement.kt +157 -23
@@ 1,20 1,37 @@
package com.github.nacabaro.vbhelper.components

import android.graphics.drawable.Icon
import android.util.EventLogTags.Description
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
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.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
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.di.VBHelper
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme

@Composable
fun ItemElement(


@@ 23,20 40,6 @@ fun ItemElement(
    modifier: Modifier = Modifier,
    onClick: (() -> 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),
            Icon(
                painter = painterResource(id = itemIcon),
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxSize()
                modifier = Modifier
                    .size(96.dp)
                    .align(Alignment.Center)
            )
            Image(
                painter = painterResource(id = lengthResource),
            Icon(
                painter = painterResource(id = lengthIcon),
                contentDescription = null,
                tint = MaterialTheme.colorScheme.surfaceTint,
                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(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

M app/src/main/java/com/github/nacabaro/vbhelper/daos/ItemDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/ItemDao.kt +6 -2
@@ 7,8 7,12 @@ import com.github.nacabaro.vbhelper.dtos.ItemDtos

@Dao
interface ItemDao {
    @Query("SELECT * FROM Items")
    suspend fun getAllItems(): List<Items>
    @Query("""
        SELECT Items.*, UserItems.quantity
        FROM Items
        LEFT JOIN UserItems ON Items.id = UserItems.itemId
    """)
    suspend fun getAllItems(): List<ItemDtos.ItemsWithQuantities>

    @Query("""
        SELECT Items.*, UserItems.quantity

M app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +1 -1
@@ 93,7 93,7 @@ fun AppNavigation(
                }
            }
            composable(NavigationItems.Items.route) {
                MyItems(
                ItemsScreen(
                    navController = navController
                )
            }

M app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt +2 -0
@@ 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

M app/src/main/java/com/github/nacabaro/vbhelper/screens/ItemsScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/ItemsScreen.kt +55 -2
@@ 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

M app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/StorageScreen.kt +1 -1
@@ 66,7 66,7 @@ fun StorageScreen(
    }

    Scaffold (
        topBar = { TopBanner(text = "My Digimon") }
        topBar = { TopBanner(text = "My characters") }
    ) { contentPadding ->
        if (monList.value.isEmpty()) {
            Column (

A app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsStore.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsStore.kt +77 -0
@@ 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<ItemDtos.ItemsWithQuantities>()) }
    var showDialog by remember { mutableStateOf(false) }
    var selectedElementIndex by remember { mutableStateOf<Int?>(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

M app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/MyItems.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/MyItems.kt +37 -17
@@ 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<ItemDtos.ItemsWithQuantities>()) }
    var showDialog by remember { mutableStateOf(false) }
    var selectedElementIndex by remember { mutableStateOf<Int?>(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 }
                    )
                }
            }

M app/src/main/java/com/github/nacabaro/vbhelper/source/ItemsRepository.kt => app/src/main/java/com/github/nacabaro/vbhelper/source/ItemsRepository.kt +1 -1
@@ 7,7 7,7 @@ import com.github.nacabaro.vbhelper.dtos.ItemDtos
class ItemsRepository(
    private val db: AppDatabase
) {
    suspend fun getAllItems(): List<Items> {
    suspend fun getAllItems(): List<ItemDtos.ItemsWithQuantities> {
        return db.itemDao().getAllItems()
    }


M app/src/main/res/drawable/baseline_shield_24.xml => app/src/main/res/drawable/baseline_shield_24.xml +4 -4
@@ 1,9 1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    android:viewportWidth="960"
    android:viewportHeight="960">
  <path
      android:fillColor="#FF000000"
      android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12V5l-9,-4z"/>
      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"/>
</vector>