Skip to content

Commit

Permalink
Code improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
MohamedRejeb committed Mar 10, 2023
1 parent d93b804 commit b9e4f9b
Show file tree
Hide file tree
Showing 31 changed files with 751 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,16 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val koin = initKoin(
initKoin(
enableNetworkLogs = BuildConfig.DEBUG
) {
androidContext(applicationContext)
}.koin
}

val rootComponent =
RootComponent(
componentContext = defaultComponentContext(),
storeFactory = DefaultStoreFactory(),
pokemonRepository = koin.get()
)

setContent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import org.koin.core.scope.Scope

expect fun Scope.sqlDriverFactory(): SqlDriver
fun createDatabase(driver: SqlDriver): PokemonDatabase {
println("database created")
val database = PokemonDatabase(
driver = driver,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ data class Pokemon(
val url: String
) {

val imageUrl get(): String {
val index = url.split("/".toRegex()).dropLast(1).last()
return "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/$index.png"
private val number get() =
url.split("/").dropLast(1).last()

val numberString get() = when(number.length) {
1 -> "#00$number"
2 -> "#0$number"
else -> "#$number"
}

val imageUrl get() =
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/$number.png"
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ data class PokemonInfo(
val attack: Int = Random.nextInt(maxAttack),
val defense: Int = Random.nextInt(maxDefense),
val speed: Int = Random.nextInt(maxSpeed),
val exp: Int = Random.nextInt(maxExp)
val exp: Int = Random.nextInt(maxExp),
val isFavorite: Boolean = false
) {
val imageUrl: String =
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/$id.png"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import io.ktor.client.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.logging.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.json.Json

internal fun createHttpClient(enableLogging: Boolean): HttpClient {
return createPlatformHttpClient().config {
install(ContentNegotiation) {
json()
json(Json {
ignoreUnknownKeys = true
})
}

install(Logging) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ fun PokemonInfo.toPokemonInfoEntity() = PokemonInfoEntity(
height = height,
weight = weight,
experience = experience,
types = Json.encodeToString(types)
types = Json.encodeToString(types),
isFavorite = if (isFavorite) 1 else 0
)

fun PokemonInfoEntity.toPokemonInfo() = PokemonInfo(
Expand All @@ -35,5 +36,6 @@ fun PokemonInfoEntity.toPokemonInfo() = PokemonInfo(
height = height,
weight = weight,
experience = experience,
types = Json.decodeFromString(types)
types = Json.decodeFromString(types),
isFavorite = isFavorite != 0L
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.mocoding.pokedex.ui.comingsoon

import com.arkivanov.decompose.ComponentContext

class ComingSoonComponent(
componentContext: ComponentContext,
private val output: (Output) -> Unit
): ComponentContext by componentContext {

fun onOutput(output: Output) {
output(output)
}

sealed class Output {
object NavigateBack : Output()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.mocoding.pokedex.ui.comingsoon

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Timelapse
import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp

@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun ComingSoonScreen(component: ComingSoonComponent) {

Scaffold(
topBar = {
TopAppBar(
title = {},
navigationIcon = {
IconButton(
onClick = {
component.onOutput(ComingSoonComponent.Output.NavigateBack)
},
) {
Icon(Icons.Rounded.ArrowBack, contentDescription = null)
}
},
colors = TopAppBarDefaults.largeTopAppBarColors(
containerColor = MaterialTheme.colorScheme.background
)
)
}
) { paddingValue ->
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(paddingValue)
.fillMaxSize()
) {

Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(horizontal = 20.dp)
) {
Text(
text = "Coming Soon",
color = MaterialTheme.colorScheme.onBackground,
style = MaterialTheme.typography.displayMedium.copy(
fontWeight = FontWeight.Bold
),
)
Spacer(Modifier.height(4.dp))
Text(
text = "This feature is not implemented yet :D",
color = MaterialTheme.colorScheme.onBackground,
style = MaterialTheme.typography.titleMedium,
)

Spacer(Modifier.height(20.dp))

Image(
Icons.Outlined.Timelapse,
contentDescription = "Coming Soon",
modifier = Modifier.size(100.dp)
)
}

}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,14 @@ import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.core.instancekeeper.getStore
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.arkivanov.mvikotlin.extensions.coroutines.stateFlow
import com.arkivanov.mvikotlin.extensions.coroutines.states
import com.mocoding.pokedex.data.repository.PokemonRepository
import com.mocoding.pokedex.ui.details.store.DetailsStore
import com.mocoding.pokedex.ui.details.store.DetailsStoreFactory
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map

class DetailsComponent(
componentContext: ComponentContext,
storeFactory: StoreFactory,
pokemonRepository: PokemonRepository,
pokemonName: String,
private val output: (Output) -> Unit
): ComponentContext by componentContext {
Expand All @@ -25,7 +20,6 @@ class DetailsComponent(
instanceKeeper.getStore {
DetailsStoreFactory(
storeFactory = storeFactory,
pokemonRepository = pokemonRepository,
pokemonName = pokemonName
).create()
}
Expand All @@ -42,7 +36,7 @@ class DetailsComponent(
}

sealed class Output {
object Back : Output()
object NavigateBack : Output()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,9 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
Expand All @@ -32,14 +25,17 @@ internal fun DetailsScreen(component: DetailsComponent) {
TopAppBar(
navigationIcon = {
IconButton(
onClick = { component.onOutput(DetailsComponent.Output.Back) }
onClick = { component.onOutput(DetailsComponent.Output.NavigateBack) }
) {
Icon(Icons.Rounded.ArrowBack, contentDescription = null)
}
},
title = {
Text(text = "Pokedex KMP")
}
},
colors = TopAppBarDefaults.largeTopAppBarColors(
containerColor = MaterialTheme.colorScheme.background
)
)
}
) { paddingValue ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import com.mocoding.pokedex.core.model.PokemonInfo
import com.mocoding.pokedex.data.repository.PokemonRepository
import com.mocoding.pokedex.pokedexDispatchers
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

internal class DetailsStoreFactory(
private val storeFactory: StoreFactory,
private val pokemonRepository: PokemonRepository,
private val pokemonName: String
) {
): KoinComponent {
private val pokemonRepository by inject<PokemonRepository>()

fun create(): DetailsStore =
object : DetailsStore, Store<DetailsStore.Intent, DetailsStore.State, Nothing> by storeFactory.create(
name = "DetailsStore",
Expand Down Expand Up @@ -48,7 +51,7 @@ internal class DetailsStoreFactory(
pokemonRepository
.getPokemonByName(name)
.onSuccess { pokemonInfo ->
Msg.PokemonInfoLoaded(pokemonInfo)
dispatch(Msg.PokemonInfoLoaded(pokemonInfo))
}
.onFailure { e ->
dispatch(Msg.PokemonInfoFailed(e.message))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.mocoding.pokedex.ui.favorite

import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.core.instancekeeper.getStore
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.arkivanov.mvikotlin.extensions.coroutines.stateFlow
import com.mocoding.pokedex.ui.favorite.store.FavoriteStore
import com.mocoding.pokedex.ui.favorite.store.FavoriteStoreFactory
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.StateFlow

class FavoriteComponent(
componentContext: ComponentContext,
storeFactory: StoreFactory,
private val output: (Output) -> Unit
): ComponentContext by componentContext {

private val favoriteStore =
instanceKeeper.getStore {
FavoriteStoreFactory(
storeFactory = storeFactory,
).create()
}

@OptIn(ExperimentalCoroutinesApi::class)
val state: StateFlow<FavoriteStore.State> = favoriteStore.stateFlow

fun onEvent(event: FavoriteStore.Intent) {
favoriteStore.accept(event)
}

fun onOutput(output: Output) {
output(output)
}

sealed class Output {
object NavigateBack : Output()
data class NavigateToDetails(val name: String) : Output()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mocoding.pokedex.ui.favorite

import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import com.mocoding.pokedex.ui.favorite.components.FavoriteContent

@Composable
internal fun FavoriteScreen(favoriteComponent: FavoriteComponent) {
val state by favoriteComponent.state.collectAsState()

FavoriteContent(
state = state,
onEvent = favoriteComponent::onEvent,
onOutput = favoriteComponent::onOutput
)
}
Loading

0 comments on commit b9e4f9b

Please sign in to comment.