M app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt => app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt +4 -120
@@ 1,26 1,16 @@
package com.github.nacabaro.vbhelper
-import android.content.Intent
import android.os.Bundle
import android.util.Log
-import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
-import androidx.activity.result.ActivityResultLauncher
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.Composable
-import androidx.lifecycle.lifecycleScope
-import com.github.cfogrady.vb.dim.card.BemCard
-import com.github.cfogrady.vb.dim.card.DimReader
import com.github.nacabaro.vbhelper.navigation.AppNavigation
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.di.VBHelper
-import com.github.nacabaro.vbhelper.domain.characters.Card
-import com.github.nacabaro.vbhelper.domain.Sprites
-import com.github.nacabaro.vbhelper.domain.characters.Character
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.navigation.AppNavigationHandlers
@@ 30,15 20,12 @@ import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControl
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
import com.github.nacabaro.vbhelper.utils.DeviceType
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.launch
import java.util.GregorianCalendar
class MainActivity : ComponentActivity() {
private var nfcCharacter = MutableStateFlow<NfcCharacter?>(null)
- private lateinit var activityResultLauncher: ActivityResultLauncher<Intent>
-
private val onActivityLifecycleListeners = HashMap<String, ActivityLifecycleListener>()
private fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener) {
@@ 53,8 40,6 @@ class MainActivity : ComponentActivity() {
}
override fun onCreate(savedInstanceState: Bundle?) {
- registerFileActivityResult()
-
val application = applicationContext as VBHelper
val scanScreenController = ScanScreenControllerImpl(
application.container.dataStoreSecretsRepository.secretsFlow,
@@ 67,7 52,9 @@ class MainActivity : ComponentActivity() {
val itemsScreenController = ItemsScreenControllerImpl(this)
super.onCreate(savedInstanceState)
+
enableEdgeToEdge()
+
setContent {
VBHelperTheme {
MainApplication(
@@ 77,6 64,7 @@ class MainActivity : ComponentActivity() {
)
}
}
+
Log.i("MainActivity", "Activity onCreated")
}
@@ 96,122 84,18 @@ class MainActivity : ComponentActivity() {
}
}
- private fun registerFileActivityResult() {
- activityResultLauncher = registerForActivityResult(
- ActivityResultContracts.StartActivityForResult()
- ) {
- lifecycleScope.launch {
- val application = applicationContext as VBHelper
- val storageRepository = application.container.db
-
- if (it.resultCode != RESULT_OK) {
- Toast.makeText(applicationContext, "Import operation cancelled.", Toast.LENGTH_SHORT).show()
- }
- val contentResolver = applicationContext.contentResolver
- val inputStream = contentResolver.openInputStream(it.data!!.data!!)
- inputStream.use { fileReader ->
- val dimReader = DimReader()
- val card = dimReader.readCard(fileReader, false)
-
- Log.i("MainActivity", "Card name: ${card is BemCard}")
-
- val cardModel = Card(
- dimId = card.header.dimId,
- logo = card.spriteData.sprites[0].pixelData,
- name = card.spriteData.text, // TODO Make user write card name
- stageCount = card.adventureLevels.levels.size,
- logoHeight = card.spriteData.sprites[0].height,
- logoWidth = card.spriteData.sprites[0].width,
- isBEm = card is BemCard
- )
-
- val dimId = storageRepository
- .dimDao()
- .insertNewDim(cardModel)
-
- val characters = card.characterStats.characterEntries
-
- var spriteCounter = when (card is BemCard) {
- true -> 55
- false -> 10
- }
-
- val domainCharacters = mutableListOf<Character>()
-
- for (index in 0 until characters.size) {
- domainCharacters.add(
- Character(
- dimId = dimId,
- monIndex = index,
- name = card.spriteData.sprites[spriteCounter].pixelData,
- stage = characters[index].stage,
- attribute = characters[index].attribute,
- baseHp = characters[index].hp,
- baseBp = characters[index].dp,
- baseAp = characters[index].ap,
- sprite1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
- sprite2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
- nameWidth = card.spriteData.sprites[spriteCounter].width,
- nameHeight = card.spriteData.sprites[spriteCounter].height,
- spritesWidth = card.spriteData.sprites[spriteCounter + 1].width,
- spritesHeight = card.spriteData.sprites[spriteCounter + 1].height
- )
- )
-
- // TODO: Improve this
- if (card is BemCard) {
- spriteCounter += 14
- } else {
- when (index) {
- 0 -> spriteCounter += 6
- 1 -> spriteCounter += 7
- else -> spriteCounter += 14
- }
- }
- }
-
- storageRepository
- .characterDao()
- .insertCharacter(*domainCharacters.toTypedArray())
-
- val sprites = card.spriteData.sprites.map { sprite ->
- Sprites(
- id = 0,
- sprite = sprite.pixelData,
- width = sprite.width,
- height = sprite.height
- )
- }
- storageRepository
- .characterDao()
- .insertSprite(*sprites.toTypedArray())
- }
- inputStream?.close()
- Toast.makeText(applicationContext, "Import successful!", Toast.LENGTH_SHORT).show()
- }
- }
- }
-
@Composable
private fun MainApplication(
scanScreenController: ScanScreenControllerImpl,
settingsScreenController: SettingsScreenControllerImpl,
itemsScreenController: ItemsScreenControllerImpl
) {
-
AppNavigation(
applicationNavigationHandlers = AppNavigationHandlers(
settingsScreenController,
scanScreenController,
itemsScreenController
- ),
- onClickImportCard = {
- val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
- addCategory(Intent.CATEGORY_OPENABLE)
- type = "*/*"
- }
- activityResultLauncher.launch(intent)
- }
+ )
)
}
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +1 -3
@@ 30,7 30,6 @@ data class AppNavigationHandlers(
@Composable
fun AppNavigation(
applicationNavigationHandlers: AppNavigationHandlers,
- onClickImportCard: () -> Unit,
) {
val navController = rememberNavController()
@@ 76,8 75,7 @@ fun AppNavigation(
composable(NavigationItems.Settings.route) {
SettingsScreen(
navController = navController,
- settingsScreenController = applicationNavigationHandlers.settingsScreenController,
- onClickImportCard = onClickImportCard,
+ settingsScreenController = applicationNavigationHandlers.settingsScreenController
)
}
composable(NavigationItems.Viewer.route) {
M app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreen.kt +3 -2
@@ 23,7 23,6 @@ import com.github.nacabaro.vbhelper.components.TopBanner
fun SettingsScreen(
navController: NavController,
settingsScreenController: SettingsScreenControllerImpl,
- onClickImportCard: () -> Unit
) {
Scaffold (
topBar = {
@@ 55,7 54,9 @@ fun SettingsScreen(
settingsScreenController.onClickImportDatabase()
}
SettingsSection("DiM/BEm management")
- SettingsEntry(title = "Import DiM card", description = "Import DiM/BEm card file", onClick = onClickImportCard)
+ SettingsEntry(title = "Import DiM card", description = "Import DiM/BEm card file") {
+ settingsScreenController.onClickImportCard()
+ }
SettingsEntry(title = "Rename DiM/BEm", description = "Set card name") { }
SettingsSection("About and credits")
SettingsEntry(title = "Credits", description = "Credits") { }
M app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenController.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenController.kt +1 -0
@@ 4,4 4,5 @@ interface SettingsScreenController {
fun onClickOpenDirectory()
fun onClickImportDatabase()
fun onClickImportApk()
+ fun onClickImportCard()
}=
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt +110 -0
@@ 9,7 9,13 @@ import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
+import com.github.cfogrady.vb.dim.card.BemCard
+import com.github.cfogrady.vb.dim.card.DimReader
+import com.github.nacabaro.vbhelper.database.AppDatabase
import com.github.nacabaro.vbhelper.di.VBHelper
+import com.github.nacabaro.vbhelper.domain.Sprites
+import com.github.nacabaro.vbhelper.domain.characters.Card
+import com.github.nacabaro.vbhelper.domain.characters.Character
import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
import com.github.nacabaro.vbhelper.source.SecretsImporter
import com.github.nacabaro.vbhelper.source.SecretsRepository
@@ 27,9 33,11 @@ class SettingsScreenControllerImpl(
private val filePickerLauncher: ActivityResultLauncher<String>
private val filePickerOpenerLauncher: ActivityResultLauncher<Array<String>>
private val filePickerApk: ActivityResultLauncher<Array<String>>
+ private val filePickerCard: ActivityResultLauncher<Array<String>>
private val secretsImporter: SecretsImporter = ApkSecretsImporter()
private val application = context.applicationContext as VBHelper
private val secretsRepository: SecretsRepository = application.container.dataStoreSecretsRepository
+ private val database: AppDatabase = application.container.db
init {
filePickerLauncher = context.registerForActivityResult(
@@ 68,6 76,18 @@ class SettingsScreenControllerImpl(
}
}
}
+
+ filePickerCard = context.registerForActivityResult(
+ ActivityResultContracts.OpenDocument()
+ ) { uri ->
+ if (uri != null) {
+ importCard(uri)
+ } else {
+ context.runOnUiThread {
+ Toast.makeText(context, "Card import cancelled", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
}
override fun onClickOpenDirectory() {
@@ 82,6 102,96 @@ class SettingsScreenControllerImpl(
filePickerApk.launch(arrayOf("*/*"))
}
+ override fun onClickImportCard() {
+ filePickerCard.launch(arrayOf("*/*"))
+ }
+
+ private fun importCard(uri: Uri) {
+ context.lifecycleScope.launch(Dispatchers.IO) {
+ val contentResolver = context.contentResolver
+ val inputStream = contentResolver.openInputStream(uri)
+ inputStream.use { fileReader ->
+ val dimReader = DimReader()
+ val card = dimReader.readCard(fileReader, false)
+
+ val cardModel = Card(
+ dimId = card.header.dimId,
+ logo = card.spriteData.sprites[0].pixelData,
+ name = card.spriteData.text, // TODO Make user write card name// TODO Make user write card name
+ stageCount = card.adventureLevels.levels.size,
+ logoHeight = card.spriteData.sprites[0].height,
+ logoWidth = card.spriteData.sprites[0].width,
+ isBEm = card is BemCard
+ )
+
+ val dimId = database
+ .dimDao()
+ .insertNewDim(cardModel)
+
+ val characters = card.characterStats.characterEntries
+
+ var spriteCounter = when (card is BemCard) {
+ true -> 55
+ false -> 10
+ }
+
+ val domainCharacters = mutableListOf<Character>()
+
+ for (index in 0 until characters.size) {
+ domainCharacters.add(
+ Character(
+ dimId = dimId,
+ monIndex = index,
+ name = card.spriteData.sprites[spriteCounter].pixelData,
+ stage = characters[index].stage,
+ attribute = characters[index].attribute,
+ baseHp = characters[index].hp,
+ baseBp = characters[index].dp,
+ baseAp = characters[index].ap,
+ sprite1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
+ sprite2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
+ nameWidth = card.spriteData.sprites[spriteCounter].width,
+ nameHeight = card.spriteData.sprites[spriteCounter].height,
+ spritesWidth = card.spriteData.sprites[spriteCounter + 1].width,
+ spritesHeight = card.spriteData.sprites[spriteCounter + 1].height
+ )
+ )
+
+ spriteCounter += if (card is BemCard) {
+ 14
+ } else {
+ when (index) {
+ 0 -> 6
+ 1 -> 7
+ else -> 14
+ }
+ }
+ }
+
+ database
+ .characterDao()
+ .insertCharacter(*domainCharacters.toTypedArray())
+
+ val sprites = card.spriteData.sprites.map { sprite ->
+ Sprites(
+ id = 0,
+ sprite = sprite.pixelData,
+ width = sprite.width,
+ height = sprite.height
+ )
+ }
+ database
+ .characterDao()
+ .insertSprite(*sprites.toTypedArray())
+ }
+
+ inputStream?.close()
+ context.runOnUiThread {
+ Toast.makeText(context, "Import successful!", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
private fun exportDatabase(destinationUri: Uri) {
context.lifecycleScope.launch(Dispatchers.IO) {
try {