mirror of
https://github.com/owenlejeune/MYDex.git
synced 2026-02-17 02:36:51 -05:00
add about details
This commit is contained in:
@@ -5,6 +5,7 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.Pokemon
|
|||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
||||||
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.egggroup.EggGroup
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.Path
|
import retrofit2.http.Path
|
||||||
@@ -27,4 +28,7 @@ interface PokemonApi {
|
|||||||
@GET("stat/{id}")
|
@GET("stat/{id}")
|
||||||
suspend fun getPokemonStat(@Path("id") id: Int): Response<PokemonStat>
|
suspend fun getPokemonStat(@Path("id") id: Int): Response<PokemonStat>
|
||||||
|
|
||||||
|
@GET("egg-group/{id}")
|
||||||
|
suspend fun getEggGroup(@Path("id") id: Int): Response<EggGroup>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.Pokemon
|
|||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
||||||
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.egggroup.EggGroup
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
@@ -47,4 +48,8 @@ class PokemonService: KoinComponent {
|
|||||||
return service.getPokemonStat(id)
|
return service.getPokemonStat(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getEggGroup(id: Int): Response<EggGroup> {
|
||||||
|
return service.getEggGroup(id)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,6 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.misc.NameAndUrl
|
|||||||
class EggGroup(
|
class EggGroup(
|
||||||
@SerializedName("id") val id: Int,
|
@SerializedName("id") val id: Int,
|
||||||
@SerializedName("name") val name: String,
|
@SerializedName("name") val name: String,
|
||||||
@SerializedName("name") val names: List<NameAndLanguage>,
|
@SerializedName("names") val names: List<NameAndLanguage>,
|
||||||
@SerializedName("pokemon_species") val pokemonSpecies: List<NameAndUrl>
|
@SerializedName("pokemon_species") val pokemonSpecies: List<NameAndUrl>
|
||||||
)
|
)
|
||||||
@@ -5,5 +5,6 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.misc.NameAndLanguage
|
|||||||
|
|
||||||
fun List<NameAndLanguage>.getNameForLanguage(): String? {
|
fun List<NameAndLanguage>.getNameForLanguage(): String? {
|
||||||
val lang = Locale.current.language
|
val lang = Locale.current.language
|
||||||
return find { it.language.name == lang }?.name
|
val defLang = "en"
|
||||||
|
return find { it.language.name == lang }?.name ?: find { it.language.name == defLang}?.name
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ class AppPreferences(context: Context) {
|
|||||||
private val SELECTED_COLOR = "selected_color"
|
private val SELECTED_COLOR = "selected_color"
|
||||||
private val USE_WALLPAPER_COLORS = "use_wallpaper_colors"
|
private val USE_WALLPAPER_COLORS = "use_wallpaper_colors"
|
||||||
private val DARK_THEME = "dark_theme"
|
private val DARK_THEME = "dark_theme"
|
||||||
|
private val USE_METRIC = "use_metric"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
|
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
|
||||||
@@ -50,6 +51,12 @@ class AppPreferences(context: Context) {
|
|||||||
get() = preferences.getInt(SELECTED_COLOR, selectedColorDefault)
|
get() = preferences.getInt(SELECTED_COLOR, selectedColorDefault)
|
||||||
set(value) { preferences.put(SELECTED_COLOR, value) }
|
set(value) { preferences.put(SELECTED_COLOR, value) }
|
||||||
|
|
||||||
|
/******* Config ********/
|
||||||
|
val useMetricDefault: Boolean = false
|
||||||
|
var useMetric: Boolean
|
||||||
|
get() = preferences.getBoolean(USE_METRIC, useMetricDefault)
|
||||||
|
set(value) { preferences.put(USE_METRIC, value) }
|
||||||
|
|
||||||
/********* Helpers ********/
|
/********* Helpers ********/
|
||||||
private fun SharedPreferences.put(key: String, value: Any?) {
|
private fun SharedPreferences.put(key: String, value: Any?) {
|
||||||
edit().apply {
|
edit().apply {
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ import androidx.compose.ui.draw.rotate
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.intl.Locale
|
import androidx.compose.ui.text.intl.Locale
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
@@ -34,11 +36,16 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.Pokemon
|
|||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
||||||
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.egggroup.EggGroup
|
||||||
import com.owenlejeune.mydex.extensions.adjustBy
|
import com.owenlejeune.mydex.extensions.adjustBy
|
||||||
import com.owenlejeune.mydex.extensions.getIdFromUrl
|
import com.owenlejeune.mydex.extensions.getIdFromUrl
|
||||||
import com.owenlejeune.mydex.extensions.getNameForLanguage
|
import com.owenlejeune.mydex.extensions.getNameForLanguage
|
||||||
|
import com.owenlejeune.mydex.preferences.AppPreferences
|
||||||
import com.owenlejeune.mydex.ui.components.PokemonTypeLabel
|
import com.owenlejeune.mydex.ui.components.PokemonTypeLabel
|
||||||
import com.owenlejeune.mydex.ui.components.SmallTabIndicator
|
import com.owenlejeune.mydex.ui.components.SmallTabIndicator
|
||||||
|
import com.owenlejeune.mydex.ui.theme.PokeBlue
|
||||||
|
import com.owenlejeune.mydex.ui.theme.PokeGrey
|
||||||
|
import com.owenlejeune.mydex.ui.theme.PokeLightRed
|
||||||
import com.owenlejeune.mydex.utils.*
|
import com.owenlejeune.mydex.utils.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
@@ -225,20 +232,132 @@ private fun ColumnScope.Details(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun AboutView(
|
private fun AboutView(
|
||||||
pokemon: Pokemon,
|
pokemon: Pokemon,
|
||||||
pokemonSpecies: PokemonSpecies,
|
pokemonSpecies: PokemonSpecies,
|
||||||
service: PokemonService
|
service: PokemonService,
|
||||||
|
preferences: AppPreferences = get(AppPreferences::class.java)
|
||||||
) {
|
) {
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
Column(
|
Column (
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.fillMaxHeight()
|
||||||
|
.fillMaxWidth()
|
||||||
.padding(all = 24.dp)
|
.padding(all = 24.dp)
|
||||||
.verticalScroll(state = scrollState)
|
.verticalScroll(state = scrollState)
|
||||||
) {
|
) {
|
||||||
|
val lang = Locale.current.language
|
||||||
|
val flavorText = pokemonSpecies.flavorTextEntries.filter { it.language.name == lang }[0]
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = flavorText.flavorText.replace("\n", " "),
|
||||||
|
color = MaterialTheme.colorScheme.onBackground
|
||||||
|
)
|
||||||
|
|
||||||
|
Card(
|
||||||
|
elevation = CardDefaults.cardElevation(defaultElevation = 10.dp),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
|
||||||
|
) {
|
||||||
|
Row(modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 12.dp, end = 12.dp, top = 12.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.poke_details_height_title),
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.poke_details_weight_title),
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Row(modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 12.dp, end = 12.dp, bottom = 12.dp)
|
||||||
|
) {
|
||||||
|
val height = if (preferences.useMetric) {
|
||||||
|
PokeUtils.heightToCm(pokemon.height)
|
||||||
|
} else {
|
||||||
|
PokeUtils.heightToFtIn(pokemon.height)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = height,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
val weight = if (preferences.useMetric) {
|
||||||
|
PokeUtils.weightInKg(pokemon.weight)
|
||||||
|
} else {
|
||||||
|
PokeUtils.weightInPounds(pokemon.weight)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = weight,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.poke_details_breeding_title),
|
||||||
|
fontSize = 18.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(R.string.poke_details_gender_subtitle), color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||||
|
Text(text = stringResource(R.string.poke_details_egg_groups_subtitle), color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
val percentageFemale = PokeUtils.genderRateToPercentage(pokemonSpecies.genderRate)
|
||||||
|
val percentageMale = 100f - percentageFemale
|
||||||
|
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(painter = painterResource(id = R.drawable.male_symbol), contentDescription = null, tint = PokeBlue)
|
||||||
|
Text(text = "$percentageMale%")
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(painter = painterResource(id = R.drawable.female_symbol), contentDescription = null, tint = PokeLightRed)
|
||||||
|
Text(text = "$percentageFemale%")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val eggGroups = remember { mutableListOf<EggGroup>() }
|
||||||
|
if (eggGroups.isEmpty()) {
|
||||||
|
pokemonSpecies.eggGroups.forEach {
|
||||||
|
val id = it.url.getIdFromUrl()
|
||||||
|
DataManager.getEggGroupById(id) { eggGroup -> eggGroups.add(eggGroup) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (eggGroups.isNotEmpty()) {
|
||||||
|
Text(text = eggGroups.joinToString(separator = ", ") { it.names.getNameForLanguage() ?: it.name } )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,6 +516,44 @@ private fun BaseStatsView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun EvolutionView(
|
||||||
|
pokemon: Pokemon,
|
||||||
|
pokemonSpecies: PokemonSpecies,
|
||||||
|
service: PokemonService
|
||||||
|
) {
|
||||||
|
val scrollState = rememberScrollState()
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 24.dp)
|
||||||
|
.verticalScroll(state = scrollState)
|
||||||
|
.background(color = Color.Red)
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
Text(text = "Evolution")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun MovesView(
|
||||||
|
pokemon: Pokemon,
|
||||||
|
pokemonSpecies: PokemonSpecies,
|
||||||
|
service: PokemonService
|
||||||
|
) {
|
||||||
|
val scrollState = rememberScrollState()
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 24.dp)
|
||||||
|
.verticalScroll(state = scrollState)
|
||||||
|
.background(color = Color.Red)
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
Text(text = "Moves")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun TypeRelationChip (
|
private fun TypeRelationChip (
|
||||||
@@ -469,9 +626,7 @@ private sealed class DetailTab(
|
|||||||
object About: DetailTab(
|
object About: DetailTab(
|
||||||
stringRes = R.string.about_tab_title,
|
stringRes = R.string.about_tab_title,
|
||||||
route = "about_tab",
|
route = "about_tab",
|
||||||
screen = @Composable { pokemon, pokemonSpecies, service ->
|
screen = @Composable { p, ps, s -> AboutView(p, ps, s) }
|
||||||
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
object BaseStats: DetailTab(
|
object BaseStats: DetailTab(
|
||||||
@@ -483,17 +638,13 @@ private sealed class DetailTab(
|
|||||||
object Evolution: DetailTab(
|
object Evolution: DetailTab(
|
||||||
stringRes = R.string.evolution_tab_title,
|
stringRes = R.string.evolution_tab_title,
|
||||||
route = "evolution_tab",
|
route = "evolution_tab",
|
||||||
screen = @Composable { pokemon, pokemonSpecies, service ->
|
screen = @Composable { p, ps, s -> EvolutionView(p, ps, s) }
|
||||||
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
object Moves: DetailTab(
|
object Moves: DetailTab(
|
||||||
stringRes = R.string.moves_tab_title,
|
stringRes = R.string.moves_tab_title,
|
||||||
route = "moves_tab",
|
route = "moves_tab",
|
||||||
screen = @Composable { pokemon, pokemonSpecies, service ->
|
screen = @Composable { p, ps, s -> MovesView(p, ps, s) }
|
||||||
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.Pokemon
|
|||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
||||||
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.egggroup.EggGroup
|
||||||
|
|
||||||
object AppCache {
|
object AppCache {
|
||||||
|
|
||||||
@@ -12,5 +13,6 @@ object AppCache {
|
|||||||
var cachedPokemon = SparseArray<Pokemon>()
|
var cachedPokemon = SparseArray<Pokemon>()
|
||||||
var cachedTypes = SparseArray<PokemonType>()
|
var cachedTypes = SparseArray<PokemonType>()
|
||||||
var cachedStats = SparseArray<PokemonStat>()
|
var cachedStats = SparseArray<PokemonStat>()
|
||||||
|
var cachedEggGroups = SparseArray<EggGroup>()
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.Pokemon
|
|||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonSpecies
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonStat
|
||||||
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.PokemonType
|
||||||
|
import com.owenlejeune.mydex.api.pokeapi.v2.model.pokemon.egggroup.EggGroup
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -17,33 +18,23 @@ object DataManager: KoinComponent {
|
|||||||
private val service: PokemonService by inject()
|
private val service: PokemonService by inject()
|
||||||
|
|
||||||
fun getPokemonById(id: Int, callback: (Pokemon) -> Unit) {
|
fun getPokemonById(id: Int, callback: (Pokemon) -> Unit) {
|
||||||
AppCache.cachedPokemon[id]?.let(callback) ?: run {
|
getById(
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
id = id,
|
||||||
service.getPokemon(id).apply {
|
callback = callback,
|
||||||
if (isSuccessful) {
|
retriever = { AppCache.cachedPokemon[it] },
|
||||||
body()?.let {
|
fetcher = { service.getPokemon(it) },
|
||||||
AppCache.cachedPokemon.put(it.id, it)
|
storer = { AppCache.cachedPokemon.put(it.id, it) }
|
||||||
callback(it)
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPokemonSpeciesById(id: Int, callback: (PokemonSpecies) -> Unit) {
|
fun getPokemonSpeciesById(id: Int, callback: (PokemonSpecies) -> Unit) {
|
||||||
AppCache.cachedSpecies[id]?.let(callback) ?: run {
|
getById(
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
id = id,
|
||||||
service.getPokemonSpecies(id).apply {
|
callback = callback,
|
||||||
if (isSuccessful) {
|
retriever = { AppCache.cachedSpecies[it] },
|
||||||
body()?.let {
|
fetcher = { service.getPokemonSpecies(it) },
|
||||||
AppCache.cachedSpecies.put(it.id, it)
|
storer = { AppCache.cachedSpecies.put(it.id, it) }
|
||||||
callback(it)
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTypeById(id: Int, callback: (PokemonType) -> Unit) {
|
fun getTypeById(id: Int, callback: (PokemonType) -> Unit) {
|
||||||
@@ -57,18 +48,23 @@ object DataManager: KoinComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getStatById(id: Int, callback: (PokemonStat) -> Unit) {
|
fun getStatById(id: Int, callback: (PokemonStat) -> Unit) {
|
||||||
AppCache.cachedStats[id]?.let(callback) ?: run {
|
getById(
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
id = id,
|
||||||
service.getPokemonStat(id).apply {
|
callback = callback,
|
||||||
if (isSuccessful) {
|
retriever = { AppCache.cachedStats[id] },
|
||||||
body()?.let {
|
fetcher = { service.getPokemonStat(id) },
|
||||||
AppCache.cachedStats.put(it.id, it)
|
storer = { AppCache.cachedStats.put(it.id, it) }
|
||||||
callback(it)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
fun getEggGroupById(id: Int, callback: (EggGroup) -> Unit) {
|
||||||
}
|
getById(
|
||||||
}
|
id = id,
|
||||||
|
callback = callback,
|
||||||
|
retriever = { AppCache.cachedEggGroups[id] },
|
||||||
|
fetcher = { service.getEggGroup(id) },
|
||||||
|
storer = { AppCache.cachedEggGroups.put(it.id, it) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T> getById(
|
private fun <T> getById(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ object PokeUtils {
|
|||||||
private val DEC_TO_CM = 10
|
private val DEC_TO_CM = 10
|
||||||
private val CM_TO_IN = 2.54
|
private val CM_TO_IN = 2.54
|
||||||
private val IN_TO_FT = 12
|
private val IN_TO_FT = 12
|
||||||
|
private val GENDER_RATE = 1f/8f
|
||||||
|
|
||||||
fun idToDexNumber(id: Int, includeNumberSign: Boolean = true): String {
|
fun idToDexNumber(id: Int, includeNumberSign: Boolean = true): String {
|
||||||
val padded = id.toString().padStart(3, '0')
|
val padded = id.toString().padStart(3, '0')
|
||||||
@@ -25,25 +26,29 @@ object PokeUtils {
|
|||||||
return "https://assets.pokemon.com/assets/cms2/img/pokedex/full/${paddedNumber}.png"
|
return "https://assets.pokemon.com/assets/cms2/img/pokedex/full/${paddedNumber}.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun weightInPounds(weight: Int): Float {
|
fun weightInPounds(weight: Int): String {
|
||||||
return weight * HEC_TO_LBS
|
return "${weight * HEC_TO_LBS} lbs"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun weightInKg(weight: Int): Float {
|
fun weightInKg(weight: Int): String {
|
||||||
return weight * HEC_TO_KG
|
return "${weight * HEC_TO_KG} kg"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun heightToCm(height: Int): Int {
|
fun heightToCm(height: Int): String {
|
||||||
return height * DEC_TO_CM
|
return "${height * DEC_TO_CM} cm"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun heightToFtIn(height: Int): Pair<Int, Int> {
|
fun heightToFtIn(height: Int): String {
|
||||||
val heightCm = height * DEC_TO_CM
|
val heightCm = height * DEC_TO_CM
|
||||||
|
|
||||||
val feet = floor((height / CM_TO_IN) / IN_TO_FT).toInt()
|
val feet = floor((heightCm / CM_TO_IN) / IN_TO_FT).toInt()
|
||||||
val inches = ceil((height / CM_TO_IN) - (feet * IN_TO_FT)).toInt()
|
val inches = ceil((heightCm / CM_TO_IN) - (feet * IN_TO_FT)).toInt()
|
||||||
|
|
||||||
return Pair(feet, inches)
|
return "${feet}' ${inches}\""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun genderRateToPercentage(genderRate: Int): Float {
|
||||||
|
return genderRate.toFloat() * GENDER_RATE * 100
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
5
app/src/main/res/drawable/female_symbol.xml
Normal file
5
app/src/main/res/drawable/female_symbol.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#F7786B"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M17.5,9.5C17.5,6.46 15.04,4 12,4S6.5,6.46 6.5,9.5c0,2.7 1.94,4.93 4.5,5.4V17H9v2h2v2h2v-2h2v-2h-2v-2.1C15.56,14.43 17.5,12.2 17.5,9.5zM8.5,9.5C8.5,7.57 10.07,6 12,6s3.5,1.57 3.5,3.5S13.93,13 12,13S8.5,11.43 8.5,9.5z"/>
|
||||||
|
</vector>
|
||||||
5
app/src/main/res/drawable/male_symbol.xml
Normal file
5
app/src/main/res/drawable/male_symbol.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#429BED"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M9.5,11c1.93,0 3.5,1.57 3.5,3.5S11.43,18 9.5,18S6,16.43 6,14.5S7.57,11 9.5,11zM9.5,9C6.46,9 4,11.46 4,14.5S6.46,20 9.5,20s5.5,-2.46 5.5,-5.5c0,-1.16 -0.36,-2.23 -0.97,-3.12L18,7.42V10h2V4h-6v2h2.58l-3.97,3.97C11.73,9.36 10.66,9 9.5,9z"/>
|
||||||
|
</vector>
|
||||||
@@ -22,4 +22,9 @@
|
|||||||
<string name="type_defences_title">Type defences</string>
|
<string name="type_defences_title">Type defences</string>
|
||||||
<string name="type_defences_half_description">Pokémon of these types deal half damage to this Pokémon</string>
|
<string name="type_defences_half_description">Pokémon of these types deal half damage to this Pokémon</string>
|
||||||
<string name="type_defences_no_description">Pokémon of these types deal no damage to this Pokémon</string>
|
<string name="type_defences_no_description">Pokémon of these types deal no damage to this Pokémon</string>
|
||||||
|
<string name="poke_details_height_title">Height</string>
|
||||||
|
<string name="poke_details_weight_title">Height</string>
|
||||||
|
<string name="poke_details_breeding_title">Breeding</string>
|
||||||
|
<string name="poke_details_gender_subtitle">Gender</string>
|
||||||
|
<string name="poke_details_egg_groups_subtitle">Egg Groups</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user