some basic details

This commit is contained in:
Owen LeJeune
2022-09-16 14:55:13 -04:00
parent 2f5b197a81
commit 0af10c1eab
6 changed files with 206 additions and 16 deletions

View File

@@ -7,5 +7,5 @@ class ChainLink(
@SerializedName("is_baby") val isBaby: Boolean,
@SerializedName("species") val species: NameAndUrl,
@SerializedName("evolution_details") val evolutionDetails: EvolutionDetails,
@SerializedName("evolves_to") val evolves_to: List<ChainLink>?
@SerializedName("evolves_to") val evolves_to: List<ChainLink?>?
)

View File

@@ -6,5 +6,5 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.misc.NameAndUrl
class EvolutionChain(
@SerializedName("id") val id: Int,
@SerializedName("baby_trigger_item") val babyTriggerItem: NameAndUrl?,
@SerializedName("chain") val chain: ChainLink
@SerializedName("chain") val chain: ChainLink?
)

View File

@@ -0,0 +1,9 @@
package com.owenlejeune.mydex.extensions
import androidx.compose.ui.text.intl.Locale
import com.owenlejeune.mydex.api.pokeapi.v2.model.misc.NameAndLanguage
fun List<NameAndLanguage>.getNameForLanguage(): String? {
val lang = Locale.current.language
return find { it.language.name == lang }?.name
}

View File

@@ -61,7 +61,7 @@ class MainActivity : MonetCompatActivity() {
) {
val id = it.arguments?.getInt("id")
id?.let {
PokemonDetailView(pokemonId = it)
PokemonDetailView(pokemonId = id, appNavController = appNavController)
}
}
}

View File

@@ -1,13 +1,195 @@
package com.owenlejeune.mydex.ui.views
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.owenlejeune.mydex.R
import com.owenlejeune.mydex.api.pokeapi.v2.PokemonService
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
import com.owenlejeune.mydex.extensions.getIdFromUrl
import com.owenlejeune.mydex.extensions.getNameForLanguage
import com.owenlejeune.mydex.ui.components.PokemonTypeLabel
import com.owenlejeune.mydex.utils.AppCache
import com.owenlejeune.mydex.utils.ColorUtils
import org.koin.java.KoinJavaComponent.get
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PokemonDetailView(
pokemonId: Int
pokemonId: Int,
appNavController: NavController
) {
val pokemon = AppCache.cachedSpecies[pokemonId]
Text(text = pokemon.name)
val pokemonSpecies = AppCache.cachedSpecies[pokemonId]
val pokemon = AppCache.cachedPokemon[pokemonId]
Box(
modifier = Modifier
.fillMaxSize()
.background(color = ColorUtils.pokeColorToComposeColor(color = pokemonSpecies.color.name))
) {
AsyncImage(
model = R.drawable.pokeball,
contentDescription = null,
modifier = Modifier
.offset(y = 200.dp)
.rotate(65f)
.size(240.dp)
.align(Alignment.TopCenter),
colorFilter = ColorFilter.tint(Color.White.copy(alpha = 0.25f))
)
Column(
modifier = Modifier
.fillMaxSize()
) {
Spacer(modifier = Modifier.height(120.dp))
Header(pokemonSpecies = pokemonSpecies, modifier = Modifier.padding(horizontal = 36.dp))
Box {
Card(
modifier = Modifier
.fillMaxSize()
.padding(top = 140.dp),
shape = RoundedCornerShape(topStart = 32.dp, topEnd = 32.dp),
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.background)
) {
}
AsyncImage(
model = pokemon.sprites.frontDefault,
contentDescription = null,
contentScale = ContentScale.FillBounds,
modifier = Modifier
.size(250.dp)
.align(Alignment.TopCenter)
)
}
}
SmallTopAppBar(
modifier = Modifier
.statusBarsPadding(),
navigationIcon = {
IconButton(onClick = { appNavController.popBackStack() }) {
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null)
}
},
title = {},
colors = TopAppBarDefaults
.smallTopAppBarColors(
containerColor = Color.Transparent//.copy(alpha = 0.4f)
)
)
}
}
@Composable
private fun Header(
modifier: Modifier = Modifier,
pokemonSpecies: PokemonSpecies,
service: PokemonService = get(PokemonService::class.java)
) {
val pokemon = AppCache.cachedPokemon.get(pokemonSpecies.id)
Row(
modifier = modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
val pokemonName = pokemonSpecies.names.getNameForLanguage() ?: pokemonSpecies.name
Text(
text = pokemonName,
style = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 30.sp,
color = MaterialTheme.colorScheme.onBackground
)
)
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
pokemon.types.forEach { type ->
val id = type.type.url.getIdFromUrl()
val pokemonType = remember { mutableStateOf<PokemonType?>(AppCache.cachedTypes[id]) }
LaunchedEffect(key1 = pokemonType.value) {
fetchPokemonType(id, pokemonType, service)
}
pokemonType.value?.let { t ->
val typeName = t.names.getNameForLanguage() ?: ""
PokemonTypeLabel(type = typeName)
}
}
}
}
Spacer(modifier = Modifier.weight(1f))
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
val dexNumber = pokemon.id.toString().padStart(3, '0')
Text(
modifier = Modifier.align(Alignment.End),
text = "#${dexNumber}",
style = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 18.sp,
color = MaterialTheme.colorScheme.onBackground
)
)
val genus = pokemonSpecies.genera.find { it.language.name == Locale.current.language }?.genus ?: ""
Text(
text = genus,
modifier = Modifier.align(Alignment.End),
style = TextStyle(
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onBackground
)
)
}
}
}
private suspend fun fetchPokemonType(
id: Int,
pokemonType: MutableState<PokemonType?>,
service: PokemonService
) {
if (pokemonType.value == null) {
service.getPokemonType(id).apply {
if (isSuccessful) {
body()?.let {
pokemonType.value = it
AppCache.cachedTypes.put(it.id, it)
}
}
}
}
}

View File

@@ -32,6 +32,7 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
import com.owenlejeune.mydex.api.pokeapi.v2.viewmodel.PokemonViewModel
import com.owenlejeune.mydex.extensions.getIdFromUrl
import com.owenlejeune.mydex.extensions.getNameForLanguage
import com.owenlejeune.mydex.extensions.header
import com.owenlejeune.mydex.extensions.lazyPagingItems
import com.owenlejeune.mydex.ui.components.PokemonTypeLabel
@@ -67,7 +68,7 @@ fun PokedexView(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.padding(start = 36.dp, end = 36.dp)
.padding(horizontal = 36.dp)
.fillMaxSize()
) {
header {
@@ -95,8 +96,7 @@ fun PokedexView(
SmallTopAppBar(
modifier = Modifier
.statusBarsPadding()
.blur(radius = 10.dp),
.statusBarsPadding(),
navigationIcon = {
IconButton(onClick = { appNavController.popBackStack() }) {
Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = null)
@@ -134,7 +134,7 @@ fun PokedexCard(
val bgColor = remember { mutableStateOf(defBg) }
Card(
modifier = Modifier
.height(160.dp)
.height(130.dp)
.fillMaxWidth(),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = bgColor.value),
@@ -153,7 +153,7 @@ fun PokedexCard(
contentDescription = null,
modifier = Modifier
.align(Alignment.BottomEnd)
.offset(x = 20.dp, y = 0.dp)
.offset(x = 20.dp, y = 20.dp)
.size(width = 96.dp, height = 96.dp),
colorFilter = ColorFilter.tint(Color.White.copy(alpha = 0.15f))
)
@@ -166,8 +166,7 @@ fun PokedexCard(
species.value?.let { species ->
bgColor.value = ColorUtils.pokeColorToComposeColor(color = species.color.name)
val locale = Locale.current.language
val name = species.names.find { it.language.name == locale }?.name ?: species.name
val name = species.names.getNameForLanguage() ?: species.name
val dexNumber = pokemon.value!!.id.toString().padStart(3, '0')
Text(
@@ -191,7 +190,7 @@ fun PokedexCard(
}
pokemonType.value?.let { t ->
val typeName = t.names.find { it.language.name == locale }?.name ?: ""//type.type.name
val typeName = t.names.getNameForLanguage() ?: ""//type.type.name
PokemonTypeLabel(type = typeName)
}
}