diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 00f6931..42ba584 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -15,7 +15,7 @@ android { minSdk = 28 targetSdk = 35 versionCode = 1 - versionName = "Alpha 0.2" + versionName = "Alpha 0.5.1" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/assets/items.db b/app/src/main/assets/items.db index 80a883b..b67ef1d 100644 Binary files a/app/src/main/assets/items.db and b/app/src/main/assets/items.db differ diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..4a7f6e8 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt b/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt index cc8eff4..c8f358b 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt @@ -14,6 +14,7 @@ import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImp import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl +import com.github.nacabaro.vbhelper.screens.cardScreen.CardScreenControllerImpl import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewerControllerImpl import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreenControllerImpl import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme @@ -47,6 +48,7 @@ class MainActivity : ComponentActivity() { val storageScreenController = StorageScreenControllerImpl(this) val homeScreenController = HomeScreenControllerImpl(this) val spriteViewerController = SpriteViewerControllerImpl(this) + val cardScreenController = CardScreenControllerImpl(this) super.onCreate(savedInstanceState) @@ -61,7 +63,8 @@ class MainActivity : ComponentActivity() { adventureScreenController = adventureScreenController, homeScreenController = homeScreenController, storageScreenController = storageScreenController, - spriteViewerController = spriteViewerController + spriteViewerController = spriteViewerController, + cardScreenController = cardScreenController ) } } @@ -93,8 +96,9 @@ class MainActivity : ComponentActivity() { adventureScreenController: AdventureScreenControllerImpl, storageScreenController: StorageScreenControllerImpl, homeScreenController: HomeScreenControllerImpl, - spriteViewerController: SpriteViewerControllerImpl - ) { + spriteViewerController: SpriteViewerControllerImpl, + cardScreenController: CardScreenControllerImpl + ) { AppNavigation( applicationNavigationHandlers = AppNavigationHandlers( settingsScreenController, @@ -103,7 +107,8 @@ class MainActivity : ComponentActivity() { adventureScreenController, storageScreenController, homeScreenController, - spriteViewerController + spriteViewerController, + cardScreenController ) ) } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt b/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt index 114e946..16ae708 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/components/CharacterEntry.kt @@ -5,11 +5,14 @@ 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.aspectRatio +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -28,6 +31,9 @@ import com.github.nacabaro.vbhelper.utils.getBitmap import androidx.compose.ui.graphics.Shape import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight +import com.github.cfogrady.vbnfc.vb.SpecialMission +import com.github.nacabaro.vbhelper.R +import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.utils.getObscuredBitmap @Composable @@ -114,4 +120,90 @@ fun ItemDisplay( ) } } +} + +@Composable +fun SpecialMissionsEntry( + specialMission: SpecialMissions, + modifier: Modifier = Modifier, + onClickCard: () -> Unit = { }, +) { + val textValue = when (specialMission.missionType) { + SpecialMission.Type.NONE -> "No mission selected" + SpecialMission.Type.STEPS -> "Walk ${specialMission.goal} steps" + SpecialMission.Type.BATTLES -> "Battle ${specialMission.goal} times" + SpecialMission.Type.WINS -> "Win ${specialMission.goal} battles" + SpecialMission.Type.VITALS -> "Earn ${specialMission.goal} vitals" + } + + val progress = if (specialMission.status == SpecialMission.Status.COMPLETED) { + specialMission.goal + } else { + specialMission.progress + } + + val completion = when (specialMission.missionType) { + SpecialMission.Type.NONE -> "" + SpecialMission.Type.STEPS -> "Walked $progress steps" + SpecialMission.Type.BATTLES -> "Battled $progress times" + SpecialMission.Type.WINS -> "Won $progress battles" + SpecialMission.Type.VITALS -> "Earned $progress vitals" + } + + val icon = when (specialMission.missionType) { + SpecialMission.Type.NONE -> R.drawable.baseline_free_24 + SpecialMission.Type.STEPS -> R.drawable.baseline_agility_24 + SpecialMission.Type.BATTLES -> R.drawable.baseline_swords_24 + SpecialMission.Type.WINS -> R.drawable.baseline_trophy_24 + SpecialMission.Type.VITALS -> R.drawable.baseline_vitals_24 + } + + val color = when (specialMission.status) + { + SpecialMission.Status.IN_PROGRESS -> MaterialTheme.colorScheme.secondary + SpecialMission.Status.COMPLETED -> MaterialTheme.colorScheme.primary + SpecialMission.Status.FAILED -> MaterialTheme.colorScheme.error + else -> MaterialTheme.colorScheme.surfaceContainerHighest + } + + Card( + modifier = modifier, + shape = androidx.compose.material.MaterialTheme.shapes.small, + onClick = if (specialMission.status == SpecialMission.Status.COMPLETED) { + onClickCard + } else { + { } + }, + colors = CardDefaults.cardColors( + containerColor = color + ) + + ) { + Row ( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + Icon( + painter = painterResource(icon), + contentDescription = "Vitals", + modifier = Modifier + .fillMaxHeight() + .padding(16.dp) + ) + Column { + Text( + text = textValue, + fontFamily = MaterialTheme.typography.titleLarge.fontFamily, + fontWeight = FontWeight.Bold, + ) + Text( + text = completion, + fontFamily = MaterialTheme.typography.titleSmall.fontFamily, + ) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt b/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt index b184cee..79c1103 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/components/TopBanner.kt @@ -24,7 +24,8 @@ fun TopBanner( onGearClick: (() -> Unit)? = null, onBackClick: (() -> Unit)? = null, onScanClick: (() -> Unit)? = null, - onAdventureClick: (() -> Unit)? = null + onAdventureClick: (() -> Unit)? = null, + onModifyClick: (() -> Unit)? = null ) { Box( // Use Box to overlay elements modifier = modifier @@ -37,16 +38,16 @@ fun TopBanner( textAlign = TextAlign.Center, fontSize = 24.sp, modifier = Modifier - .align(Alignment.Center) // Center the text + .align(Alignment.Center) ) if (onGearClick != null) { IconButton( onClick = onGearClick, modifier = Modifier - .align(Alignment.CenterEnd) // Place gear icon at the end + .align(Alignment.CenterEnd) ) { Icon( - painter = painterResource(R.drawable.baseline_settings_24), // Use a gear icon + painter = painterResource(R.drawable.baseline_settings_24), contentDescription = "Settings" ) } @@ -54,23 +55,34 @@ fun TopBanner( IconButton( onClick = onAdventureClick, modifier = Modifier - .align(Alignment.CenterEnd) // Place gear icon at the end + .align(Alignment.CenterEnd) ) { Icon( - painter = painterResource(R.drawable.baseline_fort_24), // Use a gear icon + painter = painterResource(R.drawable.baseline_fort_24), contentDescription = "Adventure" ) } + } else if (onModifyClick != null) { + IconButton( + onClick = onModifyClick, + modifier = Modifier + .align(Alignment.CenterEnd) + ) { + Icon( + painter = painterResource(R.drawable.baseline_edit_24), + contentDescription = "Adventure" + ) + } } if (onScanClick != null) { IconButton( onClick = onScanClick, modifier = Modifier - .align(Alignment.CenterStart) // Place gear icon at the end + .align(Alignment.CenterStart) ) { Icon( - painter = painterResource(R.drawable.baseline_nfc_24), // Use a gear icon + painter = painterResource(R.drawable.baseline_nfc_24), contentDescription = "Scan" ) } @@ -78,10 +90,10 @@ fun TopBanner( IconButton( onClick = onBackClick, modifier = Modifier - .align(Alignment.CenterStart) // Place gear icon at the end + .align(Alignment.CenterStart) ) { Icon( - painter = painterResource(R.drawable.baseline_arrow_back_24), // Use a gear icon + painter = painterResource(R.drawable.baseline_arrow_back_24), contentDescription = "Settings" ) } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt index d9c1d3c..6fa7aec 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt @@ -9,8 +9,26 @@ import com.github.nacabaro.vbhelper.domain.card.Card @Dao interface CardDao { @Insert(onConflict = OnConflictStrategy.IGNORE) - suspend fun insertNewDim(card: Card): Long + suspend fun insertNewCard(card: Card): Long @Query("SELECT * FROM Card WHERE cardId = :id") - fun getDimById(id: Int): Card? + fun getCardByCardId(id: Int): List + + @Query("SELECT * FROM Card WHERE id = :id") + fun getCardById(id: Long): Card? + + @Query(""" + SELECT ca.* + FROM Card ca + JOIN Character ch ON ca.id = ch.dimId + JOIN UserCharacter uc ON ch.id = uc.charId + WHERE uc.id = :id + """) + suspend fun getCardByCharacterId(id: Long): Card + + @Query("UPDATE Card SET name = :newName WHERE id = :id") + suspend fun renameCard(id: Int, newName: String) + + @Query("DELETE FROM Card WHERE id = :id") + suspend fun deleteCard(id: Long) } \ 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 a655369..1164815 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 @@ -31,7 +31,7 @@ interface ItemDao { WHERE Items.id = :itemId """ ) - fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities + suspend fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities @Query( """ @@ -40,7 +40,7 @@ interface ItemDao { WHERE id = :itemId """ ) - fun useItem(itemId: Long) + suspend fun useItem(itemId: Long) @Query( """ diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/SpecialMissionDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/SpecialMissionDao.kt new file mode 100644 index 0000000..7dc5c74 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/SpecialMissionDao.kt @@ -0,0 +1,15 @@ +package com.github.nacabaro.vbhelper.daos + +import androidx.room.Dao +import androidx.room.Query + +@Dao +interface SpecialMissionDao { + @Query(""" + UPDATE SpecialMissions SET + missionType = "NONE", + status = "UNAVAILABLE" + WHERE id = :id + """) + suspend fun clearSpecialMission(id: Long) +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt index 39d43ee..3b08448 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt @@ -34,7 +34,7 @@ interface UserCharacterDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertTransformationHistory(vararg transformationHistory: TransformationHistory) - @Insert + @Upsert fun insertSpecialMissions(vararg specialMissions: SpecialMissions) @Query(""" @@ -172,4 +172,54 @@ interface UserCharacterDao { @Query("""SELECT * FROM VitalsHistory WHERE charId = :charId ORDER BY id ASC""") suspend fun getVitalsHistory(charId: Long): List + + @Query( + """ + SELECT + uc.*, + c.stage, + c.attribute, + s.spriteIdle1 AS spriteIdle, + s.spriteIdle2 AS spriteIdle2, + s.width AS spriteWidth, + s.height AS spriteHeight, + c.name as nameSprite, + c.nameWidth as nameSpriteWidth, + c.nameHeight as nameSpriteHeight, + d.isBEm as isBemCard, + a.characterId = uc.id as isInAdventure + FROM UserCharacter uc + JOIN Character c ON uc.charId = c.id + JOIN Card d ON d.id = c.dimId + JOIN Sprite s ON s.id = c.spriteId + LEFT JOIN Adventure a ON a.characterId = uc.id + WHERE uc.characterType = "BEDevice" + """ + ) + suspend fun getBECharacters(): List + + @Query( + """ + SELECT + uc.*, + c.stage, + c.attribute, + s.spriteIdle1 AS spriteIdle, + s.spriteIdle2 AS spriteIdle2, + s.width AS spriteWidth, + s.height AS spriteHeight, + c.name as nameSprite, + c.nameWidth as nameSpriteWidth, + c.nameHeight as nameSpriteHeight, + d.isBEm as isBemCard, + a.characterId = uc.id as isInAdventure + FROM UserCharacter uc + JOIN Character c ON uc.charId = c.id + JOIN Card d ON d.id = c.dimId + JOIN Sprite s ON s.id = c.spriteId + LEFT JOIN Adventure a ON a.characterId = uc.id + WHERE uc.characterType = "VBDevice" + """ + ) + suspend fun getVBDimCharacters(): List } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt index 1cd5dfe..0f963ce 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt @@ -8,6 +8,7 @@ import com.github.nacabaro.vbhelper.daos.DexDao import com.github.nacabaro.vbhelper.daos.CardDao import com.github.nacabaro.vbhelper.daos.CardProgressDao import com.github.nacabaro.vbhelper.daos.ItemDao +import com.github.nacabaro.vbhelper.daos.SpecialMissionDao import com.github.nacabaro.vbhelper.daos.SpriteDao import com.github.nacabaro.vbhelper.daos.UserCharacterDao import com.github.nacabaro.vbhelper.domain.characters.Character @@ -51,4 +52,5 @@ abstract class AppDatabase : RoomDatabase() { abstract fun itemDao(): ItemDao abstract fun adventureDao(): AdventureDao abstract fun spriteDao(): SpriteDao + abstract fun specialMissionDao(): SpecialMissionDao } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/items/Items.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/items/Items.kt index 18dfc68..3a7747e 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/items/Items.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/items/Items.kt @@ -3,6 +3,13 @@ package com.github.nacabaro.vbhelper.domain.items import androidx.room.Entity import androidx.room.PrimaryKey +enum class ItemType { + VBITEM, + BEITEM, + UNIVERSAL, + SPECIALMISSION +} + @Entity data class Items( @PrimaryKey val id: Long, @@ -11,5 +18,6 @@ data class Items( val itemIcon: Int, val itemLength: Int, val price: Int, - val quantity: Int + val quantity: Int, + val itemType: ItemType ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/dtos/ItemDtos.kt b/app/src/main/java/com/github/nacabaro/vbhelper/dtos/ItemDtos.kt index e2e7df6..4738280 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/dtos/ItemDtos.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/dtos/ItemDtos.kt @@ -1,5 +1,7 @@ package com.github.nacabaro.vbhelper.dtos +import com.github.nacabaro.vbhelper.domain.items.ItemType + object ItemDtos { data class ItemsWithQuantities( @@ -10,6 +12,7 @@ object ItemDtos { val itemLength: Int, val price: Int, val quantity: Int, + val itemType: ItemType ) data class PurchasedItem( @@ -18,6 +21,7 @@ object ItemDtos { val itemDescription: String, val itemIcon: Int, val itemLength: Int, - val itemAmount: Int + val itemAmount: Int, + val itemType: ItemType ) } \ No newline at end of file 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 ea20f0e..76d9009 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 @@ -19,8 +19,8 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.screens.BattlesScreen -import com.github.nacabaro.vbhelper.screens.DexScreen -import com.github.nacabaro.vbhelper.screens.DiMScreen +import com.github.nacabaro.vbhelper.screens.cardScreen.CardsScreen +import com.github.nacabaro.vbhelper.screens.cardScreen.CardViewScreen import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreen import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreen import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreen @@ -34,6 +34,7 @@ import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImp import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreen import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl +import com.github.nacabaro.vbhelper.screens.cardScreen.CardScreenControllerImpl import com.github.nacabaro.vbhelper.screens.settingsScreen.CreditsScreen import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewerControllerImpl import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreenControllerImpl @@ -46,7 +47,8 @@ data class AppNavigationHandlers( val adventureScreenController: AdventureScreenControllerImpl, val storageScreenController: StorageScreenControllerImpl, val homeScreenController: HomeScreenControllerImpl, - val spriteViewerController: SpriteViewerControllerImpl + val spriteViewerController: SpriteViewerControllerImpl, + val cardScreenController: CardScreenControllerImpl ) @Composable @@ -121,8 +123,9 @@ fun AppNavigation( ) } composable(NavigationItems.Dex.route) { - DexScreen( - navController = navController + CardsScreen( + navController = navController, + cardScreenController = applicationNavigationHandlers.cardScreenController ) } composable(NavigationItems.Settings.route) { @@ -140,7 +143,7 @@ fun AppNavigation( composable(NavigationItems.CardView.route) { val cardId = it.arguments?.getString("cardId") if (cardId != null) { - DiMScreen( + CardViewScreen( navController = navController, dimId = cardId.toLong() ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt deleted file mode 100644 index 6a99b4f..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt +++ /dev/null @@ -1,83 +0,0 @@ -package com.github.nacabaro.vbhelper.screens - -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material3.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -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.utils.BitmapData -import com.github.nacabaro.vbhelper.components.DexDiMEntry -import com.github.nacabaro.vbhelper.components.TopBanner -import com.github.nacabaro.vbhelper.di.VBHelper -import com.github.nacabaro.vbhelper.dtos.CardDtos -import com.github.nacabaro.vbhelper.navigation.NavigationItems -import com.github.nacabaro.vbhelper.source.DexRepository -import kotlinx.coroutines.launch - -@Composable -fun DexScreen( - navController: NavController -) { - val coroutineScope = rememberCoroutineScope() - val application = LocalContext.current.applicationContext as VBHelper - val dexRepository = DexRepository(application.container.db) - - val cardList = remember { mutableStateOf>(emptyList()) } - - LaunchedEffect(dexRepository) { - coroutineScope.launch { - val newDimList = dexRepository.getAllDims() - cardList.value = newDimList // Replace the entire list atomically - } - } - - Scaffold ( - topBar = { - TopBanner( - text = "Discovered characters", - onGearClick = { - navController.navigate(NavigationItems.Viewer.route) - } - ) - } - ) { contentPadding -> - LazyColumn ( - modifier = Modifier - .padding(top = contentPadding.calculateTopPadding()) - ) { - items(cardList.value) { - DexDiMEntry( - name = it.cardName, - logo = BitmapData( - bitmap = it.cardLogo, - width = it.logoWidth, - height = it.logoHeight - ), - onClick = { - navController - .navigate( - NavigationItems - .CardView.route - .replace("{cardId}", "${it.cardId}") - ) - }, - obtainedCharacters = it.obtainedCharacters, - totalCharacters = it.totalCharacters, - modifier = Modifier - .fillMaxWidth() - .padding(8.dp) - ) - } - } - } -} - diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/adventureScreen/AdventureScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/adventureScreen/AdventureScreenControllerImpl.kt index b775728..535d1f4 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/adventureScreen/AdventureScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/adventureScreen/AdventureScreenControllerImpl.kt @@ -94,7 +94,8 @@ class AdventureScreenControllerImpl( itemName = randomItem.name, itemIcon = randomItem.itemIcon, itemLength = randomItem.itemLength, - itemDescription = randomItem.description + itemDescription = randomItem.description, + itemType = randomItem.itemType ) } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardEntry.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardEntry.kt new file mode 100644 index 0000000..9d48d5a --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardEntry.kt @@ -0,0 +1,109 @@ +package com.github.nacabaro.vbhelper.screens.cardScreen + +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.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Edit +import androidx.compose.material3.Card +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.FilterQuality +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import com.github.nacabaro.vbhelper.utils.BitmapData +import com.github.nacabaro.vbhelper.utils.getBitmap + +@Composable +fun CardEntry( + name: String, + logo: BitmapData, + obtainedCharacters: Int, + totalCharacters: Int, + onClick: () -> Unit, + displayModify: Boolean, + onClickModify: () -> Unit, + onClickDelete: () -> Unit, + modifier: Modifier = Modifier +) { + val bitmap = remember (logo.bitmap) { logo.getBitmap() } + val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() } + val density: Float = LocalContext.current.resources.displayMetrics.density + val dpSize = (logo.width * 4 / density).dp + + Card ( + shape = MaterialTheme.shapes.medium, + modifier = modifier, + onClick = if (!displayModify) { + onClick + } else { + { } + } + ) { + Row ( + horizontalArrangement = Arrangement.Start, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(8.dp) + ) { + Image ( + bitmap = imageBitmap, + contentDescription = name, + filterQuality = FilterQuality.None, + modifier = Modifier + .padding(8.dp) + .size(dpSize) + ) + Column( + modifier = Modifier + .padding(8.dp) + .weight(1f) + ) { + Text( + text = name, + modifier = Modifier + ) + Text( + text = "$obtainedCharacters of $totalCharacters characters obtained", + fontFamily = MaterialTheme.typography.labelSmall.fontFamily, + fontSize = MaterialTheme.typography.labelSmall.fontSize, + modifier = Modifier + ) + } + if (displayModify) { + Row ( + modifier = Modifier, + horizontalArrangement = Arrangement.End, + ) { + IconButton( + onClick = onClickModify + ) { + Icon( + imageVector = Icons.Default.Edit, + contentDescription = "Edit" + ) + } + IconButton( + onClick = onClickDelete + ) { + Icon( + imageVector = Icons.Default.Delete, + contentDescription = "Delete" + ) + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenController.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenController.kt new file mode 100644 index 0000000..d47d888 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenController.kt @@ -0,0 +1,6 @@ +package com.github.nacabaro.vbhelper.screens.cardScreen + +interface CardScreenController { + fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit) + fun deleteCard(cardId: Long, onDeleted: () -> Unit) +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenControllerImpl.kt new file mode 100644 index 0000000..0e54d15 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenControllerImpl.kt @@ -0,0 +1,34 @@ +package com.github.nacabaro.vbhelper.screens.cardScreen + +import androidx.activity.ComponentActivity +import androidx.lifecycle.lifecycleScope +import com.github.nacabaro.vbhelper.di.VBHelper +import kotlinx.coroutines.launch + +class CardScreenControllerImpl( + private val componentActivity: ComponentActivity, +) : CardScreenController { + private val application = componentActivity.applicationContext as VBHelper + private val database = application.container.db + + + override fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit) { + componentActivity.lifecycleScope.launch { + database + .cardDao() + .renameCard(cardId.toInt(), newName) + + onRenamed(newName) + } + } + + override fun deleteCard(cardId: Long, onDeleted: () -> Unit) { + componentActivity.lifecycleScope.launch { + database + .cardDao() + .deleteCard(cardId) + + onDeleted() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardViewScreen.kt similarity index 94% rename from app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt rename to app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardViewScreen.kt index 609be95..d042eae 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DimScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardViewScreen.kt @@ -1,4 +1,4 @@ -package com.github.nacabaro.vbhelper.screens +package com.github.nacabaro.vbhelper.screens.cardScreen import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid @@ -14,14 +14,13 @@ import androidx.navigation.NavController import com.github.nacabaro.vbhelper.utils.BitmapData import com.github.nacabaro.vbhelper.components.CharacterEntry import com.github.nacabaro.vbhelper.components.TopBanner -import com.github.nacabaro.vbhelper.domain.characters.Character import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.dtos.CharacterDtos import com.github.nacabaro.vbhelper.source.DexRepository import kotlinx.coroutines.launch @Composable -fun DiMScreen( +fun CardViewScreen( navController: NavController, dimId: Long ) { diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardsScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardsScreen.kt new file mode 100644 index 0000000..e639444 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardsScreen.kt @@ -0,0 +1,145 @@ +package com.github.nacabaro.vbhelper.screens.cardScreen + +import android.util.Log +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Scaffold +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.rememberCoroutineScope +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.utils.BitmapData +import com.github.nacabaro.vbhelper.components.TopBanner +import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.dtos.CardDtos +import com.github.nacabaro.vbhelper.navigation.NavigationItems +import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardDeleteDialog +import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardRenameDialog +import com.github.nacabaro.vbhelper.source.DexRepository +import kotlinx.coroutines.launch + +@Composable +fun CardsScreen( + navController: NavController, + cardScreenController: CardScreenControllerImpl +) { + val coroutineScope = rememberCoroutineScope() + val application = LocalContext.current.applicationContext as VBHelper + val dexRepository = DexRepository(application.container.db) + val cardList = remember { mutableStateOf>(emptyList()) } + + val selectedCard = remember { mutableStateOf(null) } + var clickedDelete by remember { mutableStateOf(false) } + var clickedRename by remember { mutableStateOf(false) } + + var modifyCards by remember { mutableStateOf(false) } + + LaunchedEffect(dexRepository) { + coroutineScope.launch { + val newDimList = dexRepository.getAllDims() + cardList.value = newDimList + } + } + + Scaffold ( + topBar = { + TopBanner( + text = "My cards", + onModifyClick = { + modifyCards = !modifyCards + } + ) + } + ) { contentPadding -> + LazyColumn ( + modifier = Modifier + .padding(top = contentPadding.calculateTopPadding()) + ) { + items(cardList.value) { + CardEntry( + name = it.cardName, + logo = BitmapData( + bitmap = it.cardLogo, + width = it.logoWidth, + height = it.logoHeight + ), + onClick = { + navController + .navigate( + NavigationItems + .CardView.route + .replace("{cardId}", "${it.cardId}") + ) + }, + obtainedCharacters = it.obtainedCharacters, + totalCharacters = it.totalCharacters, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp), + displayModify = modifyCards, + onClickModify = { + selectedCard.value = it + clickedRename = true + }, + onClickDelete = { + selectedCard.value = it + clickedDelete = true + } + ) + } + } + } + + if (clickedRename) { + CardRenameDialog( + onDismiss = { + clickedRename = false + selectedCard.value = null + }, + onRename = { newName -> + Log.d("CardsScreen", "New name: $newName") + Log.d("CardsScreen", "Card: ${selectedCard.value.toString()}") + cardScreenController + .renameCard( + cardId = selectedCard.value!!.cardId, + newName = newName, + onRenamed = { + clickedRename = false + selectedCard.value = null + } + ) + }, + currentName = selectedCard.value!!.cardName + ) + } + + if (clickedDelete) { + CardDeleteDialog( + cardName = selectedCard.value!!.cardName, + onDismiss = { + clickedDelete = false + selectedCard.value = null + }, + onConfirm = { + cardScreenController + .deleteCard( + cardId = selectedCard.value!!.cardId, + onDeleted = { + clickedDelete = false + selectedCard.value = null + } + ) + } + ) + } +} + diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/dialogs/CardDeleteDialog.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/dialogs/CardDeleteDialog.kt new file mode 100644 index 0000000..42797da --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/dialogs/CardDeleteDialog.kt @@ -0,0 +1,51 @@ +package com.github.nacabaro.vbhelper.screens.cardScreen.dialogs + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog + +@Composable +fun CardDeleteDialog( + cardName: String, + onDismiss: () -> Unit, + onConfirm: () -> Unit +) { + Dialog( + onDismissRequest = onDismiss + + ) { + Card ( ) { + Column ( + modifier = Modifier + .padding(16.dp) + ) { + Text(text = "Are you sure you want to delete $cardName. This action will also delete all the characters raised from this card.") + Spacer(modifier = Modifier.padding(8.dp)) + Row { + Button( + onClick = { + onDismiss() + } + ) { + Text(text = "Confirm") + } + Button( + onClick = { + onConfirm() + } + ) { + Text(text = "Delete") + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/dialogs/CardRenameDialog.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/dialogs/CardRenameDialog.kt new file mode 100644 index 0000000..e3f9fe2 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/dialogs/CardRenameDialog.kt @@ -0,0 +1,52 @@ +package com.github.nacabaro.vbhelper.screens.cardScreen.dialogs + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +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.compose.ui.window.Dialog + +@Composable +fun CardRenameDialog( + onDismiss: () -> Unit, + onRename: (String) -> Unit, + currentName: String +) { + var cardName by remember { mutableStateOf(currentName) } + + Dialog( + onDismissRequest = onDismiss + + ) { + Card ( ) { + Column ( + modifier = Modifier + .padding(16.dp) + ) { + TextField( + value = cardName, + onValueChange = { cardName = it } + ) + Spacer(modifier = Modifier.padding(8.dp)) + Button( + onClick = { + onRename(cardName) + onDismiss() + } + ) { + Text(text = "Rename") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BetaWarning.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BetaWarning.kt index ff62f8e..fb9a567 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BetaWarning.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BetaWarning.kt @@ -28,7 +28,7 @@ fun BetaWarning( ) Spacer(modifier = Modifier.padding(8.dp)) Text( - text = "Also, this application does not work yet with the original VB." + text = "Application should work now with the original VB and the VH." ) Spacer(modifier = Modifier.padding(8.dp)) Text( diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreen.kt index 26931ad..4a5d3a0 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreen.kt @@ -1,5 +1,6 @@ package com.github.nacabaro.vbhelper.screens.homeScreens +import android.util.Log import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize @@ -27,9 +28,15 @@ import com.github.nacabaro.vbhelper.components.TopBanner import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.utils.DeviceType 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.VBCharacterData import com.github.nacabaro.vbhelper.dtos.CharacterDtos +import com.github.nacabaro.vbhelper.dtos.ItemDtos import com.github.nacabaro.vbhelper.navigation.NavigationItems +import com.github.nacabaro.vbhelper.screens.homeScreens.screens.BEBEmHomeScreen +import com.github.nacabaro.vbhelper.screens.homeScreens.screens.BEDiMHomeScreen +import com.github.nacabaro.vbhelper.screens.homeScreens.screens.VBDiMHomeScreen +import com.github.nacabaro.vbhelper.screens.itemsScreen.ObtainedItemDialog import com.github.nacabaro.vbhelper.source.StorageRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -45,15 +52,21 @@ fun HomeScreen( val transformationHistory = remember { mutableStateOf?>(null) } val beData = remember { mutableStateOf(null) } val vbData = remember { mutableStateOf(null) } + val vbSpecialMissions = remember { mutableStateOf>(emptyList()) } var adventureMissionsFinished by rememberSaveable { mutableStateOf(false) } var betaWarning by rememberSaveable { mutableStateOf(true) } + var collectedItem by remember { mutableStateOf(null) } - LaunchedEffect(storageRepository, activeMon) { + LaunchedEffect(storageRepository, activeMon, collectedItem) { withContext(Dispatchers.IO) { activeMon.value = storageRepository.getActiveCharacter() - if (activeMon.value != null) { + if (activeMon.value != null && activeMon.value!!.characterType == DeviceType.BEDevice) { beData.value = storageRepository.getCharacterBeData(activeMon.value!!.id) transformationHistory.value = storageRepository.getTransformationHistory(activeMon.value!!.id) + } else if (activeMon.value != null && activeMon.value!!.characterType == DeviceType.VBDevice) { + vbData.value = storageRepository.getCharacterVbData(activeMon.value!!.id) + vbSpecialMissions.value = storageRepository.getSpecialMissions(activeMon.value!!.id) + transformationHistory.value = storageRepository.getTransformationHistory(activeMon.value!!.id) } } } @@ -79,6 +92,7 @@ fun HomeScreen( } ) { contentPadding -> if (activeMon.value == null || (beData.value == null && vbData.value == null) || transformationHistory.value == null) { + Log.d("TetTet", "Something is null") Column ( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, @@ -89,6 +103,7 @@ fun HomeScreen( Text(text = "Nothing to see here") } } else { + Log.d("TetTet", "Something is not null") if (activeMon.value!!.isBemCard) { BEBEmHomeScreen( activeMon = activeMon.value!!, @@ -108,12 +123,26 @@ fun HomeScreen( activeMon = activeMon.value!!, vbData = vbData.value!!, transformationHistory = transformationHistory.value!!, - contentPadding = contentPadding + contentPadding = contentPadding, + specialMissions = vbSpecialMissions.value, + homeScreenController = homeScreenController, + onClickCollect = { item -> + collectedItem = item + } ) } } } + if (collectedItem != null) { + ObtainedItemDialog( + obtainedItem = collectedItem!!, + onClickDismiss = { + collectedItem = null + } + ) + } + if (adventureMissionsFinished) { Dialog( onDismissRequest = { adventureMissionsFinished = false }, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenController.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenController.kt index b524ba2..52572ce 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenController.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenController.kt @@ -1,5 +1,8 @@ package com.github.nacabaro.vbhelper.screens.homeScreens +import com.github.nacabaro.vbhelper.dtos.ItemDtos + interface HomeScreenController { fun didAdventureMissionsFinish(onCompletion: (Boolean) -> Unit) + fun clearSpecialMission(missionId: Long, onCleared: (ItemDtos.PurchasedItem) -> Unit) } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenControllerImpl.kt index a38bf0b..89fbdd0 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/HomeScreenControllerImpl.kt @@ -3,8 +3,11 @@ package com.github.nacabaro.vbhelper.screens.homeScreens import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.dtos.ItemDtos import kotlinx.coroutines.launch import java.time.Instant +import kotlin.math.roundToInt +import kotlin.random.Random class HomeScreenControllerImpl( private val componentActivity: ComponentActivity, @@ -26,4 +29,38 @@ class HomeScreenControllerImpl( onCompletion(finishedAdventureCharacters.isNotEmpty()) } } + + override fun clearSpecialMission(missionId: Long, onCleared: (ItemDtos.PurchasedItem) -> Unit) { + componentActivity.lifecycleScope.launch { + database + .specialMissionDao() + .clearSpecialMission(missionId) + + val randomItem = database + .itemDao() + .getAllItems() + .random() + + val randomItemAmount = (Random.nextFloat() * 5).roundToInt() + + database + .itemDao() + .purchaseItem( + itemId = randomItem.id, + itemAmount = randomItemAmount + ) + + val purchasedItem = ItemDtos.PurchasedItem( + itemId = randomItem.id, + itemName = randomItem.name, + itemDescription = randomItem.description, + itemIcon = randomItem.itemIcon, + itemLength = randomItem.itemLength, + itemAmount = randomItemAmount, + itemType = randomItem.itemType + ) + + onCleared(purchasedItem) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/VBDiMHomeScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/VBDiMHomeScreen.kt deleted file mode 100644 index 2670fa7..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/VBDiMHomeScreen.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.nacabaro.vbhelper.screens.homeScreens - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.runtime.Composable -import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData -import com.github.nacabaro.vbhelper.dtos.CharacterDtos - -@Composable -fun VBDiMHomeScreen( - activeMon: CharacterDtos.CharacterWithSprites, - vbData: VBCharacterData, - transformationHistory: List, - contentPadding: PaddingValues -) { - TODO("Not implemented yet") -} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BEBEmHomeScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/BEBEmHomeScreen.kt similarity index 99% rename from app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BEBEmHomeScreen.kt rename to app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/BEBEmHomeScreen.kt index 344ecc5..a35d577 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BEBEmHomeScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/BEBEmHomeScreen.kt @@ -1,4 +1,4 @@ -package com.github.nacabaro.vbhelper.screens.homeScreens +package com.github.nacabaro.vbhelper.screens.homeScreens.screens import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BEDiMHomeScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/BEDiMHomeScreen.kt similarity index 99% rename from app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BEDiMHomeScreen.kt rename to app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/BEDiMHomeScreen.kt index 05b250b..065b6c6 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/BEDiMHomeScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/BEDiMHomeScreen.kt @@ -1,4 +1,4 @@ -package com.github.nacabaro.vbhelper.screens.homeScreens +package com.github.nacabaro.vbhelper.screens.homeScreens.screens import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/VBDiMHomeScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/VBDiMHomeScreen.kt new file mode 100644 index 0000000..22e67b8 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/homeScreens/screens/VBDiMHomeScreen.kt @@ -0,0 +1,189 @@ +package com.github.nacabaro.vbhelper.screens.homeScreens.screens + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.aspectRatio +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.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.github.nacabaro.vbhelper.R +import com.github.nacabaro.vbhelper.components.CharacterEntry +import com.github.nacabaro.vbhelper.components.ItemDisplay +import com.github.nacabaro.vbhelper.components.SpecialMissionsEntry +import com.github.nacabaro.vbhelper.components.TransformationHistoryCard +import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions +import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData +import com.github.nacabaro.vbhelper.dtos.CharacterDtos +import com.github.nacabaro.vbhelper.dtos.ItemDtos +import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreenControllerImpl +import com.github.nacabaro.vbhelper.utils.BitmapData +import java.util.Locale + +@Composable +fun VBDiMHomeScreen( + activeMon: CharacterDtos.CharacterWithSprites, + vbData: VBCharacterData, + specialMissions: List, + homeScreenController: HomeScreenControllerImpl, + transformationHistory: List, + contentPadding: PaddingValues, + onClickCollect: (ItemDtos.PurchasedItem) -> Unit +) { + Column( + modifier = Modifier + .padding(top = contentPadding.calculateTopPadding()) + .verticalScroll(state = rememberScrollState()) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + ) { + CharacterEntry( + icon = BitmapData( + bitmap = activeMon.spriteIdle, + width = activeMon.spriteWidth, + height = activeMon.spriteHeight + ), + multiplier = 8, + shape = androidx.compose.material.MaterialTheme.shapes.small, + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + ) + Column( + modifier = Modifier + .weight(0.5f) + .aspectRatio(0.5f) + ) { + ItemDisplay( + icon = R.drawable.baseline_vitals_24, + textValue = activeMon.vitalPoints.toString(), + definition = "Vitals", + modifier = Modifier + .weight(0.5f) + .aspectRatio(1f) + .padding(8.dp) + ) + ItemDisplay( + icon = R.drawable.baseline_trophy_24, + textValue = activeMon.trophies.toString(), + definition = "Trophies", + modifier = Modifier + .weight(0.5f) + .aspectRatio(1f) + .padding(8.dp) + ) + } + } + Row( + modifier = Modifier + .fillMaxWidth() + ) { + ItemDisplay( + icon = R.drawable.baseline_mood_24, + textValue = activeMon.mood.toString(), + definition = "Mood", + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + .padding(8.dp) + ) + val transformationCountdownInHours = activeMon.transformationCountdown / 60 + ItemDisplay( + icon = R.drawable.baseline_next_24, + textValue = when (transformationCountdownInHours) { + 0 -> "${activeMon.transformationCountdown} m" + else -> "$transformationCountdownInHours h" + }, + definition = "Next timer", + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + .padding(8.dp) + ) + ItemDisplay( + icon = R.drawable.baseline_swords_24, + textValue = when { + activeMon.totalBattlesLost == 0 -> "0.00 %" + else -> { + val battleWinPercentage = + activeMon.totalBattlesWon.toFloat() / (activeMon.totalBattlesWon + activeMon.totalBattlesLost).toFloat() + String.format( + Locale.getDefault(), + "%.2f", + battleWinPercentage * 100 + ) + " %" // Specify locale + } + }, + definition = "Total battle win %", + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + .padding(8.dp) + ) + ItemDisplay( + icon = R.drawable.baseline_swords_24, + textValue = when { + activeMon.totalBattlesLost == 0 -> "0.00 %" + else -> { + val battleWinPercentage = + activeMon.currentPhaseBattlesWon.toFloat() / (activeMon.currentPhaseBattlesWon + activeMon.currentPhaseBattlesLost).toFloat() + String.format( + Locale.getDefault(), + "%.2f", + battleWinPercentage * 100 + ) + " %" // Specify locale + } + }, + definition = "Current phase win %", + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + .padding(8.dp) + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + ) { + TransformationHistoryCard( + transformationHistory = transformationHistory, + modifier = Modifier + .weight(1f) + .padding(8.dp) + ) + } + Row ( + modifier = Modifier + .padding(16.dp) + ) { + Text( + text = "Special missions", + fontSize = 24.sp + ) + } + for (mission in specialMissions) { + Row( + modifier = Modifier + .fillMaxWidth() + ) { + SpecialMissionsEntry( + specialMission = mission, + modifier = Modifier + .weight(1f) + .padding(8.dp), + ) { + homeScreenController + .clearSpecialMission(mission.id, onClickCollect) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ChooseCharacterScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ChooseCharacterScreen.kt index fe52df1..26be571 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ChooseCharacterScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ChooseCharacterScreen.kt @@ -19,7 +19,9 @@ import androidx.navigation.NavController import com.github.nacabaro.vbhelper.components.CharacterEntry import com.github.nacabaro.vbhelper.components.TopBanner import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.domain.items.ItemType import com.github.nacabaro.vbhelper.dtos.CharacterDtos +import com.github.nacabaro.vbhelper.dtos.ItemDtos import com.github.nacabaro.vbhelper.source.StorageRepository import com.github.nacabaro.vbhelper.utils.BitmapData import kotlinx.coroutines.launch @@ -39,10 +41,25 @@ fun ChooseCharacterScreen( } var selectedCharacter by remember { mutableStateOf(null) } + var selectedItem by remember { mutableStateOf(null) } LaunchedEffect(storageRepository) { coroutineScope.launch { - characterList.value = storageRepository.getAllCharacters() + selectedItem = storageRepository.getItem(itemId) + when (selectedItem?.itemType) { + ItemType.BEITEM -> { + characterList.value = storageRepository.getBECharacters() + } + ItemType.VBITEM -> { + characterList.value = storageRepository.getVBCharacters() + } + ItemType.SPECIALMISSION-> { + characterList.value = storageRepository.getVBCharacters() + } + else -> { + characterList.value = storageRepository.getAllCharacters() + } + } } } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsScreenControllerImpl.kt index f1a6716..db9194d 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/itemsScreen/ItemsScreenControllerImpl.kt @@ -2,9 +2,12 @@ package com.github.nacabaro.vbhelper.screens.itemsScreen import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope +import com.github.cfogrady.vbnfc.vb.SpecialMission +import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.database.AppDatabase import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData +import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData import com.github.nacabaro.vbhelper.dtos.ItemDtos import com.github.nacabaro.vbhelper.utils.DeviceType import kotlinx.coroutines.Dispatchers @@ -24,7 +27,15 @@ class ItemsScreenControllerImpl ( AllTraining(5), EvoTimer(6), LimitTimer(7), - Vitals(8) + Vitals(8), + Step8k(9), + Step4k(10), + Vitals1000(11), + Vitals250(12), + Battle20(13), + Battle5(14), + Win10(15), + Win4(16) } init { @@ -37,17 +48,20 @@ class ItemsScreenControllerImpl ( withContext(Dispatchers.IO) { val item = getItem(itemId) val characterData = database.userCharacterDao().getCharacter(characterId) - val beCharacterData: BECharacterData - //var vbCharacterData: VBCharacterData + var beCharacterData: BECharacterData? = null + var vbCharacterData: VBCharacterData? = null if (characterData.characterType == DeviceType.BEDevice) { beCharacterData = database.userCharacterDao().getBeData(characterId) - } else { - TODO("Not implemented") - //vbCharacterData = database.userCharacterDao().getVbData(characterId) + } else if (characterData.characterType == DeviceType.VBDevice) { + vbCharacterData = database.userCharacterDao().getVbData(characterId) } - if (item.itemIcon in 1 .. 5 && characterData.characterType == DeviceType.BEDevice) { + if ( + item.itemIcon in 1 .. 5 && + characterData.characterType == DeviceType.BEDevice && + beCharacterData != null + ) { beCharacterData.itemType = item.itemIcon beCharacterData.itemMultiplier = 3 beCharacterData.itemRemainingTime = item.itemLength @@ -72,7 +86,11 @@ class ItemsScreenControllerImpl ( .userCharacterDao() .updateCharacter(characterData) - } else if (item.itemIcon == ItemTypes.LimitTimer.id) { + } else if ( + item.itemIcon == ItemTypes.LimitTimer.id && + characterData.characterType == DeviceType.BEDevice && + beCharacterData != null + ) { beCharacterData.remainingTrainingTimeInMinutes += item.itemLength if (beCharacterData.remainingTrainingTimeInMinutes > 6000) { beCharacterData.remainingTrainingTimeInMinutes = 6000 @@ -93,6 +111,12 @@ class ItemsScreenControllerImpl ( database .userCharacterDao() .updateCharacter(characterData) + + } else if (item.itemIcon in ItemTypes.Step8k.id .. ItemTypes.Win4.id && + characterData.characterType == DeviceType.VBDevice && + vbCharacterData != null + ) { + applySpecialMission(item.itemIcon, item.itemLength, characterId) } consumeItem(item.id) @@ -104,13 +128,72 @@ class ItemsScreenControllerImpl ( } } - private fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities { + private suspend fun applySpecialMission(itemIcon: Int, itemLength: Int, characterId: Long) { + // Hello, it's me, naca! No! I don't like this, I'll see how I can improve it later on... + val specialMissionType = when (itemIcon) { + ItemTypes.Step8k.id -> SpecialMission.Type.STEPS + ItemTypes.Step4k.id -> SpecialMission.Type.STEPS + ItemTypes.Vitals1000.id -> SpecialMission.Type.VITALS + ItemTypes.Vitals250.id -> SpecialMission.Type.VITALS + ItemTypes.Battle20.id -> SpecialMission.Type.BATTLES + ItemTypes.Battle5.id -> SpecialMission.Type.BATTLES + ItemTypes.Win10.id -> SpecialMission.Type.WINS + ItemTypes.Win4.id -> SpecialMission.Type.WINS + else -> SpecialMission.Type.NONE + } + + val specialMissionGoal = when (itemIcon) { + ItemTypes.Step8k.id -> 8000 + ItemTypes.Step4k.id -> 4000 + ItemTypes.Vitals1000.id -> 1000 + ItemTypes.Vitals250.id -> 250 + ItemTypes.Battle20.id -> 20 + ItemTypes.Battle5.id -> 5 + ItemTypes.Win10.id -> 10 + ItemTypes.Win4.id -> 4 + else -> 0 + } + + val availableSpecialMissions = database + .userCharacterDao() + .getSpecialMissions(characterId) + + var firstUnavailableMissionSlot: Long = 0 + var watchId = 0 + + for ((index, mission) in availableSpecialMissions.withIndex()) { + if ( + mission.status == SpecialMission.Status.UNAVAILABLE + ) { + firstUnavailableMissionSlot = mission.id + watchId = index + 1 + } + } + + val newSpecialMission = SpecialMissions( + id = firstUnavailableMissionSlot, + characterId = characterId, + missionType = specialMissionType, + goal = specialMissionGoal, + timeLimitInMinutes = itemLength, + watchId = watchId, + status = SpecialMission.Status.AVAILABLE, + progress = 0, + timeElapsedInMinutes = 0 + ) + + database + .userCharacterDao() + .insertSpecialMissions(newSpecialMission) + } + + private suspend fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities { return database .itemDao() .getItem(itemId) } - private fun consumeItem(itemId: Long) { + private suspend fun consumeItem(itemId: Long) { database .itemDao() .useItem(itemId) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt index 8709ae2..a58b2b2 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt @@ -30,7 +30,9 @@ import com.github.cfogrady.vbnfc.data.NfcCharacter 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.domain.card.Card import com.github.nacabaro.vbhelper.navigation.NavigationItems +import com.github.nacabaro.vbhelper.screens.cardScreen.ChooseCard import com.github.nacabaro.vbhelper.source.StorageRepository import com.github.nacabaro.vbhelper.source.isMissingSecrets import com.github.nacabaro.vbhelper.source.proto.Secrets @@ -53,6 +55,8 @@ fun ScanScreen( val storageRepository = StorageRepository(application.container.db) var nfcCharacter by remember { mutableStateOf(null) } + var cardsRead by remember { mutableStateOf?>(null) } + val context = LocalContext.current LaunchedEffect(storageRepository) { @@ -71,6 +75,7 @@ fun ScanScreen( var readingScreen by remember { mutableStateOf(false) } var writingScreen by remember { mutableStateOf(false) } + var cardSelectScreen by remember { mutableStateOf(false) } var isDoneReadingCharacter by remember { mutableStateOf(false) } var isDoneSendingCard by remember { mutableStateOf(false) } var isDoneWritingCharacter by remember { mutableStateOf(false) } @@ -85,15 +90,33 @@ fun ScanScreen( } override fun onResume() { - scanScreenController.onClickRead(secrets!!) { - isDoneReadingCharacter = true - } + scanScreenController.onClickRead( + secrets = secrets!!, + onComplete = { + isDoneReadingCharacter = true + }, + onMultipleCards = { cards -> + cardsRead = cards + readingScreen = false + cardSelectScreen = true + isDoneReadingCharacter = true + } + ) } } ) - scanScreenController.onClickRead(secrets!!) { - isDoneReadingCharacter = true - } + scanScreenController.onClickRead( + secrets = secrets!!, + onComplete = { + isDoneReadingCharacter = true + }, + onMultipleCards = { cards -> + cardsRead = cards + readingScreen = false + cardSelectScreen = true + isDoneReadingCharacter = true + } + ) } onDispose { if(readingScreen) { @@ -149,7 +172,7 @@ fun ScanScreen( } } - if (isDoneReadingCharacter) { + if (isDoneReadingCharacter && !cardSelectScreen) { readingScreen = false navController.navigate(NavigationItems.Home.route) } else if (isDoneSendingCard && isDoneWritingCharacter) { @@ -181,6 +204,14 @@ fun ScanScreen( scanScreenController.cancelRead() } } + } else if (cardSelectScreen) { + ChooseCard( + cards = cardsRead!!, + onCardSelected = { card -> + cardSelectScreen = false + scanScreenController.flushCharacter(card.id) + } + ) } else { ChooseConnectOption( onClickRead = when { @@ -290,11 +321,12 @@ fun ScanScreenPreview() { ) { } - override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) {} + override fun flushCharacter(cardId: Long) {} + override fun onClickRead(secrets: Secrets, onComplete: ()->Unit, onMultipleCards: (List) -> Unit) {} override fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {} override fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {} override fun cancelRead() {} - override fun characterFromNfc(nfcCharacter: NfcCharacter): String { return "" } + override fun characterFromNfc(nfcCharacter: NfcCharacter, onMultipleCards: (List, NfcCharacter) -> Unit): String { return "" } override suspend fun characterToNfc(characterId: Long): NfcCharacter? { return null } }, characterId = null, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt index 72032cf..485fab8 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt @@ -2,12 +2,13 @@ package com.github.nacabaro.vbhelper.screens.scanScreen import com.github.cfogrady.vbnfc.data.NfcCharacter import com.github.nacabaro.vbhelper.ActivityLifecycleListener +import com.github.nacabaro.vbhelper.domain.card.Card import com.github.nacabaro.vbhelper.source.proto.Secrets import kotlinx.coroutines.flow.Flow interface ScanScreenController { val secretsFlow: Flow - fun onClickRead(secrets: Secrets, onComplete: ()->Unit) + fun onClickRead(secrets: Secrets, onComplete: ()->Unit, onMultipleCards: (List) -> Unit) fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) @@ -16,6 +17,11 @@ interface ScanScreenController { fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener) fun unregisterActivityLifecycleListener(key: String) - fun characterFromNfc(nfcCharacter: NfcCharacter): String + fun flushCharacter(cardId: Long) + + fun characterFromNfc( + nfcCharacter: NfcCharacter, + onMultipleCards: (List, NfcCharacter) -> Unit + ): String suspend fun characterToNfc(characterId: Long): NfcCharacter? } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt index f610f5f..9ce42bc 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt @@ -11,8 +11,11 @@ import android.widget.Toast import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope import com.github.cfogrady.vbnfc.TagCommunicator +import com.github.cfogrady.vbnfc.be.BENfcCharacter import com.github.cfogrady.vbnfc.data.NfcCharacter +import com.github.cfogrady.vbnfc.vb.VBNfcCharacter import com.github.nacabaro.vbhelper.ActivityLifecycleListener +import com.github.nacabaro.vbhelper.domain.card.Card import com.github.nacabaro.vbhelper.screens.scanScreen.converters.FromNfcConverter import com.github.nacabaro.vbhelper.screens.scanScreen.converters.ToNfcConverter import com.github.nacabaro.vbhelper.source.getCryptographicTransformerMap @@ -29,7 +32,7 @@ class ScanScreenControllerImpl( private val registerActivityLifecycleListener: (String, ActivityLifecycleListener)->Unit, private val unregisterActivityLifecycleListener: (String)->Unit, ): ScanScreenController { - + private var lastScannedCharacter: NfcCharacter? = null private val nfcAdapter: NfcAdapter init { @@ -41,10 +44,14 @@ class ScanScreenControllerImpl( checkSecrets() } - override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) { + override fun onClickRead(secrets: Secrets, onComplete: ()->Unit, onMultipleCards: (List) -> Unit) { handleTag(secrets) { tagCommunicator -> val character = tagCommunicator.receiveCharacter() - val resultMessage = characterFromNfc(character) + val resultMessage = characterFromNfc(character) { cards, nfcCharacter -> + lastScannedCharacter = nfcCharacter + onMultipleCards(cards) + + } onComplete.invoke() resultMessage } @@ -118,7 +125,15 @@ class ScanScreenControllerImpl( ) { handleTag(secrets) { tagCommunicator -> try { - tagCommunicator.sendCharacter(nfcCharacter) + if (nfcCharacter is VBNfcCharacter) { + Log.d("SendCharacter", "VBNfcCharacter") + val castNfcCharacter: VBNfcCharacter = nfcCharacter + tagCommunicator.sendCharacter(castNfcCharacter) + } else if (nfcCharacter is BENfcCharacter) { + Log.d("SendCharacter", "BENfcCharacter") + val castNfcCharacter: BENfcCharacter = nfcCharacter + tagCommunicator.sendCharacter(castNfcCharacter) + } onComplete.invoke() "Sent character successfully!" } catch (e: Throwable) { @@ -146,17 +161,36 @@ class ScanScreenControllerImpl( componentActivity.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS)) } - override fun characterFromNfc(nfcCharacter: NfcCharacter): String { + override fun characterFromNfc( + nfcCharacter: NfcCharacter, + onMultipleCards: (List, NfcCharacter) -> Unit + ): String { val nfcConverter = FromNfcConverter( componentActivity = componentActivity ) - return nfcConverter.addCharacter(nfcCharacter) + return nfcConverter.addCharacter(nfcCharacter, onMultipleCards) } override suspend fun characterToNfc(characterId: Long): NfcCharacter { val nfcGenerator = ToNfcConverter( componentActivity = componentActivity ) - return nfcGenerator.characterToNfc(characterId) + + val character = nfcGenerator.characterToNfc(characterId) + Log.d("CharacterType", character.toString()) + return character + } + + override fun flushCharacter(cardId: Long) { + val nfcConverter = FromNfcConverter( + componentActivity = componentActivity + ) + + componentActivity.lifecycleScope.launch(Dispatchers.IO) { + if (lastScannedCharacter != null) { + nfcConverter.addCharacterUsingCard(lastScannedCharacter!!, cardId) + lastScannedCharacter = null + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/cardSelect/ChooseCard.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/cardSelect/ChooseCard.kt new file mode 100644 index 0000000..ace9911 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/cardSelect/ChooseCard.kt @@ -0,0 +1,48 @@ +package com.github.nacabaro.vbhelper.screens.cardScreen + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.github.nacabaro.vbhelper.components.TopBanner +import com.github.nacabaro.vbhelper.domain.card.Card +import com.github.nacabaro.vbhelper.screens.scanScreen.cardSelect.ScanCardEntry +import com.github.nacabaro.vbhelper.utils.BitmapData + +@Composable +fun ChooseCard( + cards: List, + onCardSelected: (Card) -> Unit +) { + Scaffold ( + topBar = { + TopBanner( + text = "Choose card", + ) + } + ) { contentPadding -> + LazyColumn ( + modifier = Modifier + .padding(top = contentPadding.calculateTopPadding()) + ) { + items(cards) { + ScanCardEntry( + name = it.name, + logo = BitmapData( + it.logo, + it.logoWidth, + it.logoHeight + ), + onClick = { + onCardSelected(it) + }, + modifier = Modifier + .padding(8.dp) + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/components/DexDimEntry.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/cardSelect/ScanCardEntry.kt similarity index 82% rename from app/src/main/java/com/github/nacabaro/vbhelper/components/DexDimEntry.kt rename to app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/cardSelect/ScanCardEntry.kt index 36c4976..d81bb8e 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/components/DexDimEntry.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/cardSelect/ScanCardEntry.kt @@ -1,4 +1,4 @@ -package com.github.nacabaro.vbhelper.components +package com.github.nacabaro.vbhelper.screens.scanScreen.cardSelect import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement @@ -21,11 +21,9 @@ import com.github.nacabaro.vbhelper.utils.BitmapData import com.github.nacabaro.vbhelper.utils.getBitmap @Composable -fun DexDiMEntry( +fun ScanCardEntry( name: String, logo: BitmapData, - obtainedCharacters: Int, - totalCharacters: Int, onClick: () -> Unit, modifier: Modifier = Modifier ) { @@ -56,17 +54,12 @@ fun DexDiMEntry( Column( modifier = Modifier .padding(8.dp) + .weight(1f) ) { Text( text = name, modifier = Modifier ) - Text( - text = "$obtainedCharacters of $totalCharacters characters obtained", - fontFamily = MaterialTheme.typography.labelSmall.fontFamily, - fontSize = MaterialTheme.typography.labelSmall.fontSize, - modifier = Modifier - ) } } } diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt index 459afbc..a398aae 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt @@ -21,17 +21,70 @@ class FromNfcConverter ( ) { private val application = componentActivity.applicationContext as VBHelper private val database = application.container.db - - - - fun addCharacter(nfcCharacter: NfcCharacter): String { + + + fun addCharacterUsingCard( + nfcCharacter: NfcCharacter, + cardId: Long + ): String { val cardData = database .cardDao() - .getDimById(nfcCharacter.dimId.toInt()) + .getCardById(cardId) - if (cardData == null) + if (cardData == null) { return "Card not found" + } + return insertCharacter(nfcCharacter, cardData) + } + + + fun addCharacter( + nfcCharacter: NfcCharacter, + onMultipleCards: (List, NfcCharacter) -> Unit + ): String { + val appReservedCardId = nfcCharacter + .appReserved2[0].toLong() + + var cardData: Card? = null + + if (appReservedCardId != 0L) { + val fetchedCard = database + .cardDao() + .getCardById(appReservedCardId) + + if (fetchedCard == null) { + return "Card not found" + } else if (fetchedCard.cardId == nfcCharacter.dimId.toInt()) { + cardData = fetchedCard + } + } + + if (cardData == null) { + val allCards = database + .cardDao() + .getCardByCardId(nfcCharacter.dimId.toInt()) + + if (allCards.isEmpty()) + return "Card not found" + + if (allCards.size > 1) { + onMultipleCards(allCards, nfcCharacter) + return "Multiple cards found" + } + + cardData = allCards[0] + } + + return insertCharacter(nfcCharacter, cardData) + } + + + + private fun insertCharacter( + nfcCharacter: NfcCharacter, + cardData: Card + ): String { val cardCharData = database .characterDao() .getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), cardData.id) @@ -92,7 +145,7 @@ class FromNfcConverter ( return "Done reading character!" } - + private fun updateCardProgress( diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt index 819aa2a..644e69e 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt @@ -59,7 +59,7 @@ class ToNfcConverter( .userCharacterDao() .getVbData(characterId) - val paddedTransformationArray = generateTransformationHistory(characterId) + val paddedTransformationArray = generateTransformationHistory(characterId, 9) val watchSpecialMissions = generateSpecialMissionsArray(characterId) @@ -84,7 +84,7 @@ class ToNfcConverter( transformationHistory = paddedTransformationArray, vitalHistory = generateVitalsHistoryArray(characterId), appReserved1 = ByteArray(12) {0}, - appReserved2 = Array(3) {0u}, + appReserved2 = generateUShortAppReserved(userCharacter), generation = vbData.generation.toUShort(), totalTrophies = vbData.totalTrophies.toUShort(), specialMissions = watchSpecialMissions.toTypedArray() @@ -94,6 +94,23 @@ class ToNfcConverter( } + private suspend fun generateUShortAppReserved( + userCharacter: UserCharacter + ): Array { + val cardData = database + .cardDao() + .getCardByCharacterId(userCharacter.id) + + val appReserved = Array(3) { + 0u + } + + appReserved[0] = cardData.id.toUShort() + + return appReserved + } + + private suspend fun generateSpecialMissionsArray( characterId: Long @@ -218,7 +235,8 @@ class ToNfcConverter( private suspend fun generateTransformationHistory( - characterId: Long + characterId: Long, + length: Int = 8 ): Array { val transformationHistory = database .userCharacterDao() @@ -242,7 +260,7 @@ class ToNfcConverter( ) }.toTypedArray() - val paddedTransformationArray = padTransformationArray(transformationHistory) + val paddedTransformationArray = padTransformationArray(transformationHistory, length) return paddedTransformationArray } @@ -250,13 +268,14 @@ class ToNfcConverter( private fun padTransformationArray( - transformationArray: Array + transformationArray: Array, + length: Int ): Array { if (transformationArray.size >= 8) { return transformationArray } - val paddedArray = Array(8) { + val paddedArray = Array(length) { NfcCharacter.Transformation( toCharIndex = 255u, year = 65535u, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/CreditsScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/CreditsScreen.kt index c57a0a1..1b8f41a 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/CreditsScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/CreditsScreen.kt @@ -35,6 +35,7 @@ fun CreditsScreen( SettingsEntry(title = "cfogrady", description = "Developed vb-lib-nfc and part of this application.") { } SettingsEntry(title = "nacabaro", description = "Developed this application.") { } SettingsEntry(title = "lightheel", description = "Developing the battling part for this application, including server. Still in the works.") { } + SettingsEntry(title = "shvstrz", description = "Designing the app icon in SVG.") { } } } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt index 0e46146..632716d 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt @@ -129,7 +129,7 @@ class SettingsScreenControllerImpl( val dimId = database .cardDao() - .insertNewDim(cardModel) + .insertNewCard(cardModel) val cardProgress = CardProgress( cardId = dimId, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt b/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt index d4caee8..61aff4a 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt @@ -2,7 +2,10 @@ package com.github.nacabaro.vbhelper.source import com.github.nacabaro.vbhelper.database.AppDatabase 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.VBCharacterData import com.github.nacabaro.vbhelper.dtos.CharacterDtos +import com.github.nacabaro.vbhelper.dtos.ItemDtos class StorageRepository ( private val db: AppDatabase @@ -23,6 +26,18 @@ class StorageRepository ( return db.userCharacterDao().getTransformationHistory(characterId) } + suspend fun getCharacterVbData(id: Long): VBCharacterData { + return db.userCharacterDao().getVbData(id) + } + + suspend fun getSpecialMissions(id: Long): List { + return db.userCharacterDao().getSpecialMissions(id) + } + + suspend fun getItem(id: Long): ItemDtos.ItemsWithQuantities { + return db.itemDao().getItem(id) + } + suspend fun getActiveCharacter(): CharacterDtos.CharacterWithSprites? { return db.userCharacterDao().getActiveCharacter() } @@ -34,4 +49,12 @@ class StorageRepository ( suspend fun getAdventureCharacters(): List { return db.adventureDao().getAdventureCharacters() } + + suspend fun getBECharacters(): List { + return db.userCharacterDao().getBECharacters() + } + + suspend fun getVBCharacters(): List { + return db.userCharacterDao().getVBDimCharacters() + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/baseline_edit_24.xml b/app/src/main/res/drawable/baseline_edit_24.xml new file mode 100644 index 0000000..9a3ef8b --- /dev/null +++ b/app/src/main/res/drawable/baseline_edit_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 2b068d1..6b43c65 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,30 +1,39 @@ - - - - - - - - - - \ No newline at end of file + android:viewportWidth="512" + android:viewportHeight="512"> + + + + + + + + + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 6f3b755..7353dbd 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,5 @@ - - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 6f3b755..7353dbd 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,6 +1,5 @@ - - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp index c209e78..90a0579 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp index b2dfe3d..8407439 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp index 4f0f1d6..463df80 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp index 62b611d..fbbb979 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp index 948a307..6bd253a 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 1b9a695..8f6a4ba 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 28d4b77..8933917 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp index 9287f50..60bfe21 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index aa7d642..f0e70c6 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 9126ae3..f2afaeb 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..beab31f --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #000000 + \ No newline at end of file