Skip to content

Commit

Permalink
cat app for android
Browse files Browse the repository at this point in the history
  • Loading branch information
nameisjayant committed Feb 25, 2023
1 parent 3053e80 commit 81de373
Show file tree
Hide file tree
Showing 14 changed files with 241 additions and 37 deletions.
1 change: 1 addition & 0 deletions androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@ dependencies {
implementation(Coroutines.coroutineAndroid)
implementation(Koin.core)
implementation(Koin.android)
implementation(Compose.coilCompose)

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.nameisjayant.kmmproject.Greeting
import com.nameisjayant.kmmproject.android.feature.cat.screens.CatScreen
import com.nameisjayant.kmmproject.android.feature.ui.viewmodel.CatViewModel
import com.nameisjayant.kmmproject.android.feature.ui.viewmodel.PostState
import com.nameisjayant.kmmproject.android.feature.ui.viewmodel.PostViewModel
import com.nameisjayant.kmmproject.data.model.Post
import org.koin.android.ext.android.inject

class MainActivity : ComponentActivity() {
private val viewModel: PostViewModel by inject()
private val catViewModel:CatViewModel by inject()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Expand All @@ -33,35 +37,45 @@ class MainActivity : ComponentActivity() {
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
if (response.isLoading) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center){
CircularProgressIndicator()
}
}
if (response.error.isNotEmpty()) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center){
Text(
text = response.error, style = TextStyle(
color = Color.Gray,
fontSize = 16.sp,
fontWeight = FontWeight.Normal
)
)
}
}
if (response.data.isNotEmpty()) {
LazyColumn{
items(response.data, key = {it.id}){
PostEachRow(post = it)
}
}
}
// PostScreen(response)
CatScreen(viewModel = catViewModel)
}
}
}
}
}

@Composable
fun PostScreen(
response:PostState
) {

if (response.isLoading) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center){
CircularProgressIndicator()
}
}
if (response.error.isNotEmpty()) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center){
Text(
text = response.error, style = TextStyle(
color = Color.Gray,
fontSize = 16.sp,
fontWeight = FontWeight.Normal
)
)
}
}
if (response.data.isNotEmpty()) {
LazyColumn{
items(response.data, key = {it.id}){
PostEachRow(post = it)
}
}
}

}

@Composable
fun PostEachRow(
post: Post
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.nameisjayant.kmmproject.android.di

import com.nameisjayant.kmmproject.android.feature.ui.viewmodel.CatViewModel
import com.nameisjayant.kmmproject.android.feature.ui.viewmodel.PostViewModel
import com.nameisjayant.kmmproject.data.repository.CatRepository
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module

val appModule = module {
viewModel {
PostViewModel(get())
}
viewModel {
CatViewModel(get())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.nameisjayant.kmmproject.android.feature.cat.screens

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.nameisjayant.kmmproject.android.R
import com.nameisjayant.kmmproject.android.feature.ui.viewmodel.CatViewModel
import com.nameisjayant.kmmproject.data.model.Cat


@Composable
fun CatScreen(
viewModel: CatViewModel
) {

val res = viewModel.catResponse.value

if (res.isLoading)
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
if (res.data.isNotEmpty())
LazyColumn {
items(
res.data,
key = { it.id!! }
) {
CatEachRow(cat = it)
}
}
if (res.error.isNotEmpty())
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(text = res.error)
}

}

@Composable
fun CatEachRow(
cat: Cat
) {

Card(
modifier = Modifier.fillMaxWidth(),
) {
Row(
modifier = Modifier.padding(15.dp)
) {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(cat.url)
.crossfade(true)
.build(),
contentDescription = "",
contentScale = ContentScale.Crop,
placeholder = painterResource(id = R.drawable.img),
modifier = Modifier
.clip(CircleShape)
.size(100.dp)
)
Spacer(modifier = Modifier.width(20.dp))
Column(
modifier = Modifier.align(CenterVertically)
) {
Text(text = "Width: ${cat.width}")
Spacer(modifier = Modifier.height(15.dp))
Text(text = "Height: ${cat.height}")
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.nameisjayant.kmmproject.android.feature.ui.viewmodel

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.nameisjayant.kmmproject.data.model.Cat
import com.nameisjayant.kmmproject.data.model.Post
import com.nameisjayant.kmmproject.data.repository.CatRepository
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch

class CatViewModel constructor(
private val repository: CatRepository
) : ViewModel() {

private val _catResponse: MutableState<CatState> = mutableStateOf(CatState())
val catResponse: State<CatState> = _catResponse


init {
viewModelScope.launch {
repository.getCats()
.onStart {
_catResponse.value = CatState(
isLoading = true
)
}.catch {
_catResponse.value = CatState(
error = it.message ?: "Something went wrong!"
)
}.collect {
_catResponse.value = CatState(
data = it
)
}
}
}


}

data class CatState(
val data: List<Cat> = emptyList(),
val error: String = "",
val isLoading: Boolean = false
)
Binary file added androidApp/src/main/res/drawable/img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions buildSrc/src/main/java/dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ object Versions {
const val koin = "3.2.0"
const val kotlinxSerialization = "1.5.0-RC"
const val coroutine = "1.6.4"
const val coil = "2.2.2"
}

object ConfigData {
Expand Down Expand Up @@ -55,4 +56,5 @@ object Compose {
"androidx.compose.foundation:foundation:${Versions.composeFoundation}"
const val composeUiToolingPreview =
"androidx.compose.ui:ui-tooling-preview:${Versions.composeVersion}"
const val coilCompose = "io.coil-kt:coil-compose:${Versions.coil}"
}
2 changes: 2 additions & 0 deletions iosApp/iosApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ struct ContentView: View {





struct ActivityIndicator: View {

@State private var isAnimating: Bool = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ abstract class BaseRepository {
emit(ApiState.Failure(e))
}.flowOn(Dispatchers.Default)

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.nameisjayant.kmmproject.data.model

@kotlinx.serialization.Serializable
data class Cat(
val id: String? = null,
val url: String? = null,
val width: Int? = null,
val height: Int? = null
)
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package com.nameisjayant.kmmproject.data.network

import com.nameisjayant.kmmproject.data.model.Cat
import com.nameisjayant.kmmproject.data.model.Post
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*

class ApiService(
private val client:HttpClient,
private val baseUrl: String = "https://jsonplaceholder.typicode.com"
) {
private val client: HttpClient,

suspend fun getPosts():List<Post>{
) {
private val baseUrl: String = "https://jsonplaceholder.typicode.com"
private val catUrl = "https://api.thecatapi.com/v1/images/search?limit=20"
suspend fun getPosts(): List<Post> {
return client.get {
url("$baseUrl/posts")
}.body()
}

suspend fun getCats(): List<Cat> {
return client.get {
url(catUrl)
}.body()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.nameisjayant.kmmproject.data.repository

import com.nameisjayant.kmmproject.data.model.Cat
import com.nameisjayant.kmmproject.data.network.ApiService
import kotlinx.coroutines.flow.flow


class CatRepository constructor(
private val apiService: ApiService
) {

suspend fun getCats() = flow<List<Cat>> {
emit(apiService.getCats())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ class PostRepository constructor(
apiService.getPosts()
}

// suspend fun getPostForIos():Flow<List<Post>> {
// return execute {
// apiService.getPosts()
// }
// }

suspend fun getPostForIos() = flow{
emit(apiService.getPosts())
suspend fun getPostForIos():Flow<List<Post>> {
return execute {
apiService.getPosts()
}
}

// suspend fun getPostForIos() = flow{
// emit(apiService.getPosts())
// }

suspend fun getPostTest():List<Post> = apiService.getPosts()
}
Loading

0 comments on commit 81de373

Please sign in to comment.