Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate product list to Jetpack Compose #190

Merged
merged 2 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 33
compileSdk 34
buildToolsVersion "31.0.0"

defaultConfig {
Expand Down Expand Up @@ -88,6 +88,8 @@ dependencies {
implementation libs.gson
implementation libs.moshi
implementation libs.kotlin.coroutines.play.services
implementation(libs.kotlinx.immutable)
implementation(libs.glide.compose)

implementation platform(libs.firebase.bom)
implementation libs.bundles.firebase
Expand All @@ -101,7 +103,7 @@ dependencies {
implementation "io.ktor:ktor-client-logging-jvm:1.6.0"
implementation("io.ktor:ktor-client-core:2.2.4")

def composeBom = platform('androidx.compose:compose-bom:2023.05.00')
def composeBom = platform('androidx.compose:compose-bom:2023.09.02')
implementation(composeBom)
androidTestImplementation(composeBom)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package com.hieuwu.groceriesstore.domain.usecases

import com.hieuwu.groceriesstore.data.database.entities.LineItem

interface AddToCartUseCase: UseCase<AddToCartUseCase.Input, AddToCartUseCase.Output> {
interface AddToCartUseCase: SuspendUseCase<AddToCartUseCase.Input, AddToCartUseCase.Output> {
class Input (val lineItem: LineItem)

class Output
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.hieuwu.groceriesstore.domain.usecases
import com.hieuwu.groceriesstore.data.database.entities.Order

interface CreateNewOrderUseCase :
UseCase<CreateNewOrderUseCase.Input, CreateNewOrderUseCase.Output> {
SuspendUseCase<CreateNewOrderUseCase.Input, CreateNewOrderUseCase.Output> {
class Input(val order: Order)

class Output(result: Unit)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import com.hieuwu.groceriesstore.domain.models.CategoryModel
import kotlinx.coroutines.flow.Flow

interface GetCategoriesListUseCase :
UseCase<GetCategoriesListUseCase.Input, GetCategoriesListUseCase.Output> {
SuspendUseCase<GetCategoriesListUseCase.Input, GetCategoriesListUseCase.Output> {
class Input

class Output(val result: Flow<List<CategoryModel>>)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.hieuwu.groceriesstore.domain.models.OrderModel
import kotlinx.coroutines.flow.Flow

interface GetCurrentCartUseCase :
UseCase<GetCurrentCartUseCase.Input, GetCurrentCartUseCase.Output> {
SuspendUseCase<GetCurrentCartUseCase.Input, GetCurrentCartUseCase.Output> {
class Input
data class Output(val result: Flow<OrderModel?>)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.hieuwu.groceriesstore.domain.usecases

import com.hieuwu.groceriesstore.domain.models.OrderModel
import kotlinx.coroutines.flow.Flow

interface GetOrderListUseCase : UseCase<GetOrderListUseCase.Input, GetOrderListUseCase.Output> {
interface GetOrderListUseCase : SuspendUseCase<GetOrderListUseCase.Input, GetOrderListUseCase.Output> {
class Input
sealed class Output {
class Success(val data: List<OrderModel>) : Output()
object Failure : Output()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ import kotlinx.coroutines.flow.Flow
interface GetProductsListUseCase: UseCase<GetProductsListUseCase.Input, GetProductsListUseCase.Output> {
class Input
class Output(val result: Flow<List<ProductModel>>)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.hieuwu.groceriesstore.domain.usecases
import com.hieuwu.groceriesstore.domain.models.UserModel
import kotlinx.coroutines.flow.Flow

interface GetProfileUseCase:UseCase<GetProfileUseCase.Input, GetProfileUseCase.Output> {
interface GetProfileUseCase:SuspendUseCase<GetProfileUseCase.Input, GetProfileUseCase.Output> {
class Input
open class Output(val result: Flow<UserModel?>)
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.hieuwu.groceriesstore.domain.usecases

interface RefreshAppDataUseCase : UseCase<Unit, Unit>
interface RefreshAppDataUseCase : SuspendUseCase<Unit, Unit>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.hieuwu.groceriesstore.domain.usecases
import com.hieuwu.groceriesstore.domain.models.ProductModel
import kotlinx.coroutines.flow.Flow

interface SearchProductUseCase : UseCase<SearchProductUseCase.Input, SearchProductUseCase.Output> {
interface SearchProductUseCase : SuspendUseCase<SearchProductUseCase.Input, SearchProductUseCase.Output> {
class Input(val name: String? = null)
class Output(val result: Flow<List<ProductModel>>)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.hieuwu.groceriesstore.domain.usecases

interface SignInUseCase : UseCase<SignInUseCase.Input, SignInUseCase.Output> {
interface SignInUseCase : SuspendUseCase<SignInUseCase.Input, SignInUseCase.Output> {
data class Input(val email: String, val password: String)
open class Output(val result: Boolean) {
sealed class Error : Output(false)
object AccountNotExistedError : Output(false)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.hieuwu.groceriesstore.domain.usecases

interface SignOutUseCase : UseCase<SignOutUseCase.Input, SignOutUseCase.Output> {
interface SignOutUseCase : SuspendUseCase<SignOutUseCase.Input, SignOutUseCase.Output> {
class Input
class Output
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.hieuwu.groceriesstore.domain.usecases

import com.hieuwu.groceriesstore.domain.models.OrderModel

interface SubmitOrderUseCase : UseCase<SubmitOrderUseCase.Input, SubmitOrderUseCase.Output> {
interface SubmitOrderUseCase : SuspendUseCase<SubmitOrderUseCase.Input, SubmitOrderUseCase.Output> {
class Input(val order: OrderModel)
data class Output(val result: Boolean)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.hieuwu.groceriesstore.domain.usecases

interface UpdateProfileUseCase : UseCase<UpdateProfileUseCase.Input, UpdateProfileUseCase.Output> {
interface UpdateProfileUseCase : SuspendUseCase<UpdateProfileUseCase.Input, UpdateProfileUseCase.Output> {
data class Input(
val userId: String,
val name: String,
Expand All @@ -9,4 +9,4 @@ interface UpdateProfileUseCase : UseCase<UpdateProfileUseCase.Input, UpdateProfi
val address: String
)
class Output
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.hieuwu.groceriesstore.domain.usecases

interface UseCase<Input, Output> {
interface SuspendUseCase<Input, Output> {
suspend fun execute(input: Input): Output
}
}

interface UseCase<Input, Output> {
fun execute(input: Input): Output
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.hieuwu.groceriesstore.domain.usecases

interface UserSettingsUseCase : UseCase<UserSettingsUseCase.Input, UserSettingsUseCase.Output> {
interface UserSettingsUseCase : SuspendUseCase<UserSettingsUseCase.Input, UserSettingsUseCase.Output> {
class Input(
val id: String,
val isOrderCreatedEnabled: Boolean,
Expand All @@ -9,4 +9,4 @@ interface UserSettingsUseCase : UseCase<UserSettingsUseCase.Input, UserSettingsU
)

class Output
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ import javax.inject.Inject

class GetProductsByCategoryUseCaseImpl @Inject constructor(private val productRepository: ProductRepository) :
GetProductsByCategoryUseCase {
override suspend fun execute(input: GetProductsByCategoryUseCase.Input): GetProductsByCategoryUseCase.Output {
return withContext(Dispatchers.IO) {
val result = productRepository.getAllProductsByCategory(input.categoryId)
GetProductsByCategoryUseCase.Output(result)
}
override fun execute(input: GetProductsByCategoryUseCase.Input): GetProductsByCategoryUseCase.Output {
val result = productRepository.getAllProductsByCategory(input.categoryId)
return GetProductsByCategoryUseCase.Output(result)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import javax.inject.Inject

class GetProductsListUseCaseImpl @Inject constructor(private val productRepository: ProductRepository) :
GetProductsListUseCase {
override suspend fun execute(input: GetProductsListUseCase.Input): GetProductsListUseCase.Output {
override fun execute(input: GetProductsListUseCase.Input): GetProductsListUseCase.Output {
val result = productRepository.products
return GetProductsListUseCase.Output(result)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.hieuwu.groceriesstore.presentation.core.widgets

import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.hieuwu.groceriesstore.R

@Composable
fun PrimaryIconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = IconButtonDefaults.filledShape,
content: @Composable () -> Unit
) {
FilledIconButton(
onClick = onClick,
modifier = modifier.defaultMinSize(minWidth = 48.dp, minHeight = 48.dp),
enabled = enabled,
shape = shape,
colors = IconButtonDefaults.filledIconButtonColors(
containerColor = colorResource(id = R.color.colorPrimary),
disabledContainerColor = colorResource(id = R.color.light_gray),
contentColor = Color.White,
),
content = content
)
}

@Composable
fun PrimarySquareIconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
content: @Composable () -> Unit
) = PrimaryIconButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
shape = RoundedCornerShape(8.dp),
content = content
)

@Preview
@Composable
private fun PrimaryIconButtonPreview() {
PrimaryIconButton(onClick = {}) {
Icon(imageVector = Icons.Default.Search, contentDescription = "")
}
}

@Preview
@Composable
private fun PrimarySquareIconButtonPreview() {
PrimarySquareIconButton(onClick = {}) {
Icon(imageVector = Icons.Default.Search, contentDescription = "")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.hieuwu.groceriesstore.presentation.core.widgets

import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi
import com.bumptech.glide.integration.compose.GlideImage
import com.bumptech.glide.integration.compose.placeholder
import com.hieuwu.groceriesstore.R

@OptIn(ExperimentalGlideComposeApi::class)
@Composable
fun WebImage(
model: Any?,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
) = GlideImage(
model = model,
contentDescription = contentDescription,
modifier = modifier,
alignment = alignment,
contentScale = contentScale,
loading = placeholder(R.drawable.loading_animation),
failure = placeholder(R.drawable.ic_broken_image)
)
Loading
Loading