Start implementing search

This commit is contained in:
FirephoenixX02 2024-04-16 14:54:24 +02:00
parent e5a8586560
commit 72fe8363b8
4 changed files with 1096 additions and 10 deletions

View file

@ -7,13 +7,23 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.TextFieldColors
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
@ -28,8 +38,12 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import io.kamel.image.KamelImage
import io.kamel.image.asyncPainterResource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.painterResource
import java.util.Locale
class HomeScreen: Screen {
@ -38,6 +52,8 @@ class HomeScreen: Screen {
override fun Content() {
val orange = Color(0xFFffa500)
val navigator = LocalNavigator.currentOrThrow
val coroutineScope = rememberCoroutineScope()
var searchQuery by remember { mutableStateOf("") }
Box(modifier = Modifier.background(color = orange).fillMaxSize()) {
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 256.dp),
@ -88,6 +104,20 @@ class HomeScreen: Screen {
}
}
}
OutlinedTextField(
value = searchQuery,
onValueChange = { newName -> searchQuery = newName;
if (PokemonNames.names.contains(searchQuery.lowercase(Locale.getDefault()))) {
coroutineScope.launch {
withContext(Dispatchers.IO) {
val newMap = loadPokemonDataFromName(searchQuery);
newMap?.let { pokemap.clear(); pokemap.addAll(it) }
}
}
}
},
modifier = Modifier.background(color = Color.White),
)
}
}

File diff suppressed because it is too large Load diff

View file

@ -37,6 +37,7 @@ import java.util.Locale
var pokemap = ArrayList<Pokemon>()
val apiString = "https://pokeapi.co/api/v2/pokemon/"
@OptIn(ExperimentalResourceApi::class)
val pokemonTypeDrawableMap = hashMapOf(
"normal" to Res.drawable.normal,
@ -59,7 +60,6 @@ val pokemonTypeDrawableMap = hashMapOf(
"fairy" to Res.drawable.fairy
)
@OptIn(ExperimentalResourceApi::class)
@Composable
@Preview
fun App() {
@ -67,14 +67,14 @@ fun App() {
MaterialTheme {
if (!dataLoaded) {
Navigator(screen = LoadingScreen()) {
navigator -> FadeTransition(navigator)
Navigator(screen = LoadingScreen()) { navigator ->
FadeTransition(navigator)
}
// Load data asynchronously
LaunchedEffect(Unit) {
pokemap = withContext(Dispatchers.IO) {
loadPokemonData(apiString, 1, 10)
loadPokemonData(1, 10)
} as ArrayList<Pokemon>
pokemap.forEach { pokemon ->
@ -87,25 +87,26 @@ fun App() {
} else {
println("Pokemon should show up any second!")
//Display Pokemon Grid
Navigator(screen = HomeScreen()) {
navigator -> SlideTransition(navigator)
Navigator(screen = HomeScreen()) { navigator ->
SlideTransition(navigator)
}
}
}
}
// Function to load Pokemon data asynchronously, leave suspend even if IDE complains
suspend fun loadPokemonData(apiString: String, startId: Int, endId: Int): List<Pokemon> {
suspend fun loadPokemonData(startId: Int, endId: Int): List<Pokemon> {
val pokemap = ArrayList<Pokemon>()
for (i in startId..endId) {
val json = JSONObject(URL(apiString + i).readText());
val sprites = json.optJSONObject("sprites")
val type: String = json.getJSONArray("types").optJSONObject(0).optJSONObject("type").optString("name")
val type: String =
json.getJSONArray("types").optJSONObject(0).optJSONObject("type")?.optString("name") ?: "null"
val name: String = json.optString("name")
.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
val pokemon = Pokemon(
name, URL(sprites.optString("front_default")), type, json.optInt("id")
name, URL(sprites?.optString("front_default") ?: "null"), type, json.optInt("id")
)
pokemap.add(pokemon)
@ -113,6 +114,31 @@ suspend fun loadPokemonData(apiString: String, startId: Int, endId: Int): List<P
return pokemap
}
fun getPokeMap(): ArrayList<Pokemon> {
suspend fun loadPokemonDataFromName(name: String): ArrayList<Pokemon>? {
if (name.equals("")) return null
var json: JSONObject = JSONObject("{}")
try {
json = JSONObject(URL(apiString + name).readText());
} catch (e: Exception) {
return null
}
val sprites = json.optJSONObject("sprites")
val type: String =
json.getJSONArray("types").optJSONObject(0).optJSONObject("type")?.optString("name") ?: "null"
val name: String = json.optString("name")
.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
val pokemon = Pokemon(
name, URL(sprites?.optString("front_default") ?: "null"), type, json.optInt("id")
)
val pokemap = ArrayList<Pokemon>()
pokemap.add(pokemon)
return pokemap
}
fun getPokeMap(): ArrayList<Pokemon> {
return pokemap
}

View file

@ -0,0 +1,5 @@
object PokemonNames {
val names: ArrayList<String> = arrayListOf(
)
}