2024-04-11 13:55:19 +02:00
|
|
|
import androidx.compose.material.MaterialTheme
|
2024-04-12 10:41:11 +02:00
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
|
|
|
import androidx.compose.runtime.getValue
|
|
|
|
|
import androidx.compose.runtime.mutableStateOf
|
|
|
|
|
import androidx.compose.runtime.remember
|
|
|
|
|
import androidx.compose.runtime.setValue
|
|
|
|
|
import cafe.adriel.voyager.navigator.Navigator
|
|
|
|
|
import cafe.adriel.voyager.transitions.FadeTransition
|
|
|
|
|
import cafe.adriel.voyager.transitions.SlideTransition
|
2024-04-11 16:13:38 +02:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
|
import kotlinx.coroutines.withContext
|
2024-04-12 10:41:11 +02:00
|
|
|
import org.jetbrains.compose.resources.ExperimentalResourceApi
|
2024-04-11 13:55:19 +02:00
|
|
|
import org.jetbrains.compose.ui.tooling.preview.Preview
|
|
|
|
|
import org.json.JSONObject
|
|
|
|
|
import pokedex.composeapp.generated.resources.Res
|
2024-04-12 10:41:11 +02:00
|
|
|
import pokedex.composeapp.generated.resources.bug
|
|
|
|
|
import pokedex.composeapp.generated.resources.dark
|
|
|
|
|
import pokedex.composeapp.generated.resources.dragon
|
|
|
|
|
import pokedex.composeapp.generated.resources.electric
|
|
|
|
|
import pokedex.composeapp.generated.resources.fairy
|
|
|
|
|
import pokedex.composeapp.generated.resources.fighting
|
|
|
|
|
import pokedex.composeapp.generated.resources.fire
|
|
|
|
|
import pokedex.composeapp.generated.resources.flying
|
|
|
|
|
import pokedex.composeapp.generated.resources.ghost
|
|
|
|
|
import pokedex.composeapp.generated.resources.grass
|
|
|
|
|
import pokedex.composeapp.generated.resources.ground
|
|
|
|
|
import pokedex.composeapp.generated.resources.ice
|
|
|
|
|
import pokedex.composeapp.generated.resources.normal
|
|
|
|
|
import pokedex.composeapp.generated.resources.poison
|
|
|
|
|
import pokedex.composeapp.generated.resources.psychic
|
|
|
|
|
import pokedex.composeapp.generated.resources.rock
|
|
|
|
|
import pokedex.composeapp.generated.resources.steel
|
|
|
|
|
import pokedex.composeapp.generated.resources.water
|
2024-04-11 13:55:19 +02:00
|
|
|
import java.net.URL
|
2024-04-11 16:29:28 +02:00
|
|
|
import java.util.Locale
|
2024-04-11 13:55:19 +02:00
|
|
|
|
2024-04-12 10:41:11 +02:00
|
|
|
var pokemap = ArrayList<Pokemon>()
|
|
|
|
|
val apiString = "https://pokeapi.co/api/v2/pokemon/"
|
|
|
|
|
|
2024-04-11 13:55:19 +02:00
|
|
|
@OptIn(ExperimentalResourceApi::class)
|
|
|
|
|
@Composable
|
|
|
|
|
@Preview
|
|
|
|
|
fun App() {
|
2024-04-11 16:13:38 +02:00
|
|
|
var dataLoaded by remember { mutableStateOf(false) }
|
2024-04-11 13:55:19 +02:00
|
|
|
|
|
|
|
|
val pokemonTypeDrawableMap = hashMapOf(
|
|
|
|
|
"normal" to Res.drawable.normal,
|
|
|
|
|
"fire" to Res.drawable.fire,
|
|
|
|
|
"water" to Res.drawable.water,
|
|
|
|
|
"electric" to Res.drawable.electric,
|
|
|
|
|
"grass" to Res.drawable.grass,
|
|
|
|
|
"ice" to Res.drawable.ice,
|
|
|
|
|
"fighting" to Res.drawable.fighting,
|
|
|
|
|
"poison" to Res.drawable.poison,
|
|
|
|
|
"ground" to Res.drawable.ground,
|
|
|
|
|
"flying" to Res.drawable.flying,
|
|
|
|
|
"psychic" to Res.drawable.psychic,
|
|
|
|
|
"bug" to Res.drawable.bug,
|
|
|
|
|
"rock" to Res.drawable.rock,
|
|
|
|
|
"ghost" to Res.drawable.ghost,
|
|
|
|
|
"dragon" to Res.drawable.dragon,
|
|
|
|
|
"dark" to Res.drawable.dark,
|
|
|
|
|
"steel" to Res.drawable.steel,
|
|
|
|
|
"fairy" to Res.drawable.fairy
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
MaterialTheme {
|
2024-04-11 16:13:38 +02:00
|
|
|
if (!dataLoaded) {
|
2024-04-12 10:41:11 +02:00
|
|
|
Navigator(screen = LoadingScreen()) {
|
|
|
|
|
navigator -> FadeTransition(navigator)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-11 16:13:38 +02:00
|
|
|
// Load data asynchronously
|
|
|
|
|
LaunchedEffect(Unit) {
|
2024-04-11 16:29:28 +02:00
|
|
|
pokemap = withContext(Dispatchers.IO) {
|
|
|
|
|
loadPokemonData(apiString, 1, 10)
|
|
|
|
|
} as ArrayList<Pokemon>
|
2024-04-11 16:13:38 +02:00
|
|
|
|
|
|
|
|
pokemap.forEach { pokemon ->
|
|
|
|
|
println(pokemon)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dataLoaded = true
|
|
|
|
|
}
|
2024-04-11 16:29:28 +02:00
|
|
|
|
2024-04-11 16:13:38 +02:00
|
|
|
} else {
|
|
|
|
|
println("Pokemon should show up any second!")
|
|
|
|
|
//Display Pokemon Grid
|
2024-04-12 10:41:11 +02:00
|
|
|
Navigator(screen = HomeScreen(getPokeMap(), pokemonTypeDrawableMap)) {
|
|
|
|
|
navigator -> SlideTransition(navigator)
|
2024-04-11 13:55:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-11 16:13:38 +02:00
|
|
|
}
|
2024-04-11 13:55:19 +02:00
|
|
|
|
2024-04-12 10:41:11 +02:00
|
|
|
// Function to load Pokemon data asynchronously, leave suspend even if IDE complains
|
2024-04-11 16:29:28 +02:00
|
|
|
suspend fun loadPokemonData(apiString: String, startId: Int, endId: Int): List<Pokemon> {
|
2024-04-11 16:13:38 +02:00
|
|
|
val pokemap = ArrayList<Pokemon>()
|
2024-04-11 16:29:28 +02:00
|
|
|
for (i in startId..endId) {
|
2024-04-11 16:13:38 +02:00
|
|
|
val json = JSONObject(URL(apiString + i).readText());
|
|
|
|
|
val sprites = json.optJSONObject("sprites")
|
2024-04-12 10:41:11 +02:00
|
|
|
val type: String = json.getJSONArray("types").optJSONObject(0).optJSONObject("type").optString("name")
|
2024-04-11 16:29:28 +02:00
|
|
|
val name: String = json.optString("name")
|
|
|
|
|
.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
2024-04-11 13:55:19 +02:00
|
|
|
|
2024-04-11 16:13:38 +02:00
|
|
|
val pokemon = Pokemon(
|
2024-04-11 16:29:28 +02:00
|
|
|
name, URL(sprites.optString("front_default")), type, json.optInt("id")
|
2024-04-11 16:13:38 +02:00
|
|
|
)
|
2024-04-11 13:55:19 +02:00
|
|
|
|
2024-04-11 16:13:38 +02:00
|
|
|
pokemap.add(pokemon)
|
2024-04-11 13:55:19 +02:00
|
|
|
}
|
2024-04-11 16:13:38 +02:00
|
|
|
return pokemap
|
2024-04-11 13:55:19 +02:00
|
|
|
}
|
2024-04-12 10:41:11 +02:00
|
|
|
|
|
|
|
|
fun getPokeMap(): ArrayList<Pokemon> {
|
|
|
|
|
return pokemap
|
|
|
|
|
}
|