Skip to content

Commit

Permalink
Merge pull request #247 from hieuwu/feature/upload-image-meal-planning
Browse files Browse the repository at this point in the history
Support user upload meal image
  • Loading branch information
hieuwu committed May 3, 2024
2 parents 8bb1f24 + a6c1a03 commit 56d6c11
Show file tree
Hide file tree
Showing 25 changed files with 278 additions and 274 deletions.
4 changes: 1 addition & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,14 @@ dependencies {

implementation platform(libs.firebase.bom)
implementation libs.bundles.firebase
// implementation 'io.supabase:postgrest-kt:0.9.0-alpha-4'

// implementation("io.github.jan-tennert.supabase:postgrest-kt:0.2.0")
implementation(libs.ktor.client.cio)
implementation(libs.postgrest.kt.android)
implementation libs.ktor.client.android
implementation libs.ktor.utils.jvm
implementation libs.ktor.client.logging.jvm
implementation(libs.ktor.client.core)

implementation("io.github.jan-tennert.supabase:storage-kt:2.0.0")
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
@@ -0,0 +1,9 @@
package com.hieuwu.groceriesstore.data.network

enum class RemoteTable(val tableName: String) {
Product("products"),
Categories("categories"),
Orders("orders"),
Users("users"),
LineItems("line_items"),
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ data class Meal(

@SerialName("meal_type")
val mealType: String,

@SerialName("image")
val image: String?,

)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ interface MealPlanRepository {
weekDay: String,
name: String,
ingredients: List<String>,
mealType: String
mealType: String,
mealImageUri: ByteArray
)

suspend fun retrieveMealByType(type: String, weekDayValue: String): List<MealModel>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.hieuwu.groceriesstore.data.repository.impl

import com.hieuwu.groceriesstore.data.database.dao.CategoryDao
import com.hieuwu.groceriesstore.data.database.entities.Category
import com.hieuwu.groceriesstore.data.database.entities.asDomainModel
import com.hieuwu.groceriesstore.data.network.RemoteTable
import com.hieuwu.groceriesstore.data.network.dto.CategoriesDto
import com.hieuwu.groceriesstore.data.repository.CategoryRepository
import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import io.github.jan.supabase.postgrest.Postgrest
import kotlinx.coroutines.flow.map
import timber.log.Timber
Expand All @@ -19,10 +19,10 @@ class CategoryRepositoryImpl @Inject constructor(

override suspend fun refreshDatabase() {
try {
val result = supabasePostgrest[CollectionNames.categories]
val result = supabasePostgrest[RemoteTable.Categories.tableName]
.select()
val res = result.decodeList<CategoriesDto>()
val categories = res.map { SupabaseMapper.mapToEntity(it) }
val categories = res.map { it.asEntity() }
categoryDao.insertAll(categories)
} catch (e: Exception) {
Timber.e(e.message)
Expand All @@ -31,4 +31,10 @@ class CategoryRepositoryImpl @Inject constructor(

override fun getFromLocal() = categoryDao.getAll().map { it.asDomainModel() }

private fun CategoriesDto.asEntity(): Category = Category(
id = id,
name = name,
image = image,
)

}
Original file line number Diff line number Diff line change
@@ -1,39 +1,55 @@
package com.hieuwu.groceriesstore.data.repository.impl

import com.hieuwu.groceriesstore.data.network.dto.Meal
import com.hieuwu.groceriesstore.data.network.dto.ProductDto
import com.hieuwu.groceriesstore.data.repository.MealPlanRepository
import com.hieuwu.groceriesstore.data.repository.UserRepository
import com.hieuwu.groceriesstore.domain.models.MealModel
import com.hieuwu.groceriesstore.utilities.SupabaseHelper
import io.github.jan.supabase.postgrest.Postgrest
import io.github.jan.supabase.storage.Storage
import java.util.UUID
import kotlinx.coroutines.flow.first
import timber.log.Timber
import javax.inject.Inject

class MealPlanRepositoryImpl @Inject constructor(
private val postgrest: Postgrest,
private val userRepository: UserRepository
private val userRepository: UserRepository,
private val storage: Storage
) : MealPlanRepository {
override suspend fun addMealToPlan(
weekDay: String,
name: String,
ingredients: List<String>,
mealType: String
mealType: String,
mealImageUri: ByteArray
) {
val mealId = UUID.randomUUID().toString()
val userId = userRepository.getCurrentUser().first()?.id ?: ""
postgrest["meal_plans"].insert<Meal>(
Meal(
id = UUID.randomUUID().toString(),
id = mealId,
name = name,
ingredients = ingredients,
creatorId = userId,
weekDay = weekDay,
mealType = mealType,
image = null,
)
)
val imageKey =
storage.from("meals").upload(path = "$mealId.png", data = mealImageUri, upsert = true)
val imageUrl = SupabaseHelper.buildImageUrl(imageKey)
postgrest["meal_plans"].update({
set("image", imageUrl)
}) {
filter {
eq("id", mealId)
}
}
}


override suspend fun retrieveMealByType(type: String, weekDayValue: String): List<MealModel> {
val userId = userRepository.getCurrentUser().first()?.id ?: ""
val result = postgrest["meal_plans"].select {
Expand All @@ -50,7 +66,8 @@ class MealPlanRepositoryImpl @Inject constructor(
ingredients = it.ingredients,
weekDay = it.weekDay,
creatorId = it.creatorId,
mealType = it.mealType
mealType = it.mealType,
imageUrl = it.image ?: ""
)
}
return result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import com.hieuwu.groceriesstore.data.database.entities.asDomainModel
import com.hieuwu.groceriesstore.data.network.dto.OrderDto
import com.hieuwu.groceriesstore.data.repository.OrderRepository
import com.hieuwu.groceriesstore.domain.models.OrderModel
import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.OrderStatus
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import com.hieuwu.groceriesstore.data.network.RemoteTable
import com.hieuwu.groceriesstore.data.network.dto.LineItemDto
import com.hieuwu.groceriesstore.domain.models.LineItemModel
import io.github.jan.supabase.postgrest.Postgrest
import java.util.Date
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
Expand Down Expand Up @@ -52,11 +54,11 @@ class OrderRepositoryImpl @Inject constructor(
}

override suspend fun sendOrderToServer(order: OrderModel): Boolean {
val orderDto = SupabaseMapper.mapModelToDto(order)
val lineItems = SupabaseMapper.mapModelListToDto(order)
val orderDto = mapModelToDto(order)
val lineItems = mapModelListToDto(order)
return try {
postgrest[CollectionNames.orders].insert(orderDto)
postgrest[CollectionNames.lineItems].insert(lineItems)
postgrest[RemoteTable.Orders.tableName].insert(orderDto)
postgrest[RemoteTable.LineItems.tableName].insert(lineItems)
orderDao.clear()
true
} catch (e: Exception) {
Expand All @@ -67,10 +69,47 @@ class OrderRepositoryImpl @Inject constructor(

override suspend fun getOrders(): List<OrderModel> {
return try {
val result = postgrest[CollectionNames.orders].select().decodeList<OrderDto>()
result.map { SupabaseMapper.mapToModel(it) }
val result = postgrest[RemoteTable.Orders.tableName].select().decodeList<OrderDto>()
result.map { mapToModel(it) }
} catch (e: Exception) {
listOf()
}
}

private fun mapToModel(order: OrderDto): OrderModel {
return OrderModel(
id = order.orderId,
status = order.status,
address = order.address,
lineItemList = mutableListOf(),
createdAt = order.createdAt
).apply {
totalPrice = order.total
}
}

private fun mapModelToDto(order: OrderModel): OrderDto {
return OrderDto(
orderId = order.id,
address = order.address,
status = order.status ?: "",
createdAt = Date().toString(),
total = order.total
)
}

private fun mapModelToDto(lineItemModel: LineItemModel, orderId: String): LineItemDto {
return LineItemDto(
id = lineItemModel.id ?: 0,
productId = lineItemModel.productId ?: "",
orderId = orderId,
quantity = lineItemModel.quantity ?: 0,
subtotal = lineItemModel.subtotal ?: 0.0,
lineItemId = lineItemModel.id ?: 0
)
}

private fun mapModelListToDto(order: OrderModel): List<LineItemDto> {
return order.lineItemList.map { mapModelToDto(it, order.id) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package com.hieuwu.groceriesstore.data.repository.impl

import com.hieuwu.groceriesstore.data.database.dao.LineItemDao
import com.hieuwu.groceriesstore.data.database.dao.ProductDao
import com.hieuwu.groceriesstore.data.database.entities.Product
import com.hieuwu.groceriesstore.data.database.entities.asDomainModel
import com.hieuwu.groceriesstore.data.network.RemoteTable
import com.hieuwu.groceriesstore.data.network.dto.ProductDto
import com.hieuwu.groceriesstore.data.repository.ProductRepository
import com.hieuwu.groceriesstore.domain.models.ProductModel
import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import io.github.jan.supabase.postgrest.Postgrest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
Expand All @@ -28,9 +28,9 @@ class ProductRepositoryImpl @Inject constructor(

override suspend fun refreshDatabase() {
try {
val result = supabasePostgrest[CollectionNames.products]
val result = supabasePostgrest[RemoteTable.Product.tableName]
.select().decodeList<ProductDto>()
val products = result.map { SupabaseMapper.mapToEntity(it) }
val products = result.map { it.asEntity() }
productDao.insertAll(products)
} catch (e: Exception) {
Timber.e(e.message)
Expand Down Expand Up @@ -79,4 +79,14 @@ class ProductRepositoryImpl @Inject constructor(
return flow {}
}

private fun ProductDto.asEntity(): Product = Product(
id = productId,
name = name,
nutrition = nutrition,
description = description,
image = image,
price = price,
category = category,
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import com.hieuwu.groceriesstore.data.database.entities.User
import com.hieuwu.groceriesstore.data.database.entities.asDomainModel
import com.hieuwu.groceriesstore.data.network.dto.UserDto
import com.hieuwu.groceriesstore.data.repository.UserRepository
import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import com.hieuwu.groceriesstore.data.network.RemoteTable
import io.github.jan.supabase.gotrue.Auth
import io.github.jan.supabase.gotrue.providers.builtin.Email
import io.github.jan.supabase.postgrest.Postgrest
import java.util.*
import java.util.UUID
import kotlinx.coroutines.flow.map
import timber.log.Timber
import javax.inject.Inject
Expand All @@ -37,8 +36,8 @@ class UserRepositoryImpl @Inject constructor(
isPromotionNotiEnabled = false,
isDataRefreshedNotiEnabled = false
)
postgrest[CollectionNames.users].upsert(value = userDto)
val user = SupabaseMapper.mapDtoToEntity(userDto)
postgrest[RemoteTable.Users.tableName].upsert(value = userDto)
val user = userDto.asEntity()
userDao.insert(user)
true
} catch (e: Exception) {
Expand All @@ -54,14 +53,14 @@ class UserRepositoryImpl @Inject constructor(
this.password = password
}

val userDto = postgrest[CollectionNames.users].select()
val userDto = postgrest[RemoteTable.Users.tableName].select()
{
filter {
UserDto::email eq email
}
}
.decodeSingle<UserDto>()
val user = SupabaseMapper.mapDtoToEntity(userDto)
val user = userDto.asEntity()
userDao.insert(user)
true
} catch (e: Exception) {
Expand All @@ -84,7 +83,7 @@ class UserRepositoryImpl @Inject constructor(
isDataRefreshedNotiEnabled = false
)
try {
postgrest[CollectionNames.users].update(
postgrest[RemoteTable.Users.tableName].update(
{
UserDto::phone setTo phone
UserDto::email setTo email
Expand All @@ -110,7 +109,7 @@ class UserRepositoryImpl @Inject constructor(
isPromotionEnabled: Boolean
) {
try {
postgrest[CollectionNames.users].update(
postgrest[RemoteTable.Users.tableName].update(
{
UserDto::isOrderCreatedNotiEnabled setTo isOrderCreatedEnabled
UserDto::isDataRefreshedNotiEnabled setTo isDatabaseRefreshedEnabled
Expand All @@ -136,4 +135,14 @@ class UserRepositoryImpl @Inject constructor(
it?.asDomainModel()
}

private fun UserDto.asEntity(): User = User(
id = id,
name = name,
email = email,
address = address,
phone = phone,
isDataRefreshedNotiEnabled = isDataRefreshedNotiEnabled,
isOrderCreatedNotiEnabled = isOrderCreatedNotiEnabled,
isPromotionNotiEnabled = isPromotionNotiEnabled,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import io.github.jan.supabase.gotrue.auth
import io.github.jan.supabase.postgrest.Postgrest
import io.github.jan.supabase.postgrest.postgrest
import io.github.jan.supabase.serializer.KotlinXSerializer
import io.ktor.client.plugins.*
import io.github.jan.supabase.storage.Storage
import io.github.jan.supabase.storage.storage
import kotlinx.serialization.json.Json
import javax.inject.Singleton

Expand All @@ -30,6 +31,7 @@ object SupabaseModule {
defaultSerializer = KotlinXSerializer(Json { ignoreUnknownKeys = true })
install(Postgrest)
install(Auth)
install(Storage)
}
}

Expand All @@ -45,4 +47,10 @@ object SupabaseModule {
return client.auth
}

@Provides
@Singleton
fun provideSupabaseStorage(client: SupabaseClient): Storage {
return client.storage
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ data class MealModel(
val weekDay: String,
val creatorId: String,
val mealType: String,
val imageUrl: String,
)
Loading

0 comments on commit 56d6c11

Please sign in to comment.