Создание продуктов

This commit is contained in:
Данила Мочалов 2023-12-20 20:27:38 +04:00
parent 5c2284ff79
commit 12d67bba56
8 changed files with 38 additions and 34 deletions

View File

@ -49,8 +49,8 @@ object AppModule {
@Provides
@Singleton
fun provideProductRepository(db: AppDatabase) : ProductRepository {
return ProductRepository(database = db, db.productDao(), db.orderProductDao())
fun provideProductRepository(db: AppDatabase, restProductRepository: RestProductRepository) : ProductRepository {
return ProductRepository(database = db, db.productDao(), db.orderProductDao(), restProductRepository)
}
@Provides

View File

@ -1,6 +1,7 @@
package com.example.shawarma.data.api
import com.example.shawarma.data.api.models.ProductListResponse
import com.example.shawarma.data.api.models.ProductModelRemote
import com.example.shawarma.data.api.models.TokenModelRemote
import com.example.shawarma.data.api.models.UserModelRemote
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
@ -40,6 +41,13 @@ interface MyServerService {
@GET("user/items/{after}")
suspend fun getItemsList(@Path("after") after: Int, @Header("Authorization") token: String) : ProductListResponse
@POST("product")
suspend fun insertProduct(
@Body product: ProductModelRemote
) : ProductModelRemote
companion object {
private const val BASE_URL = "https://10.0.2.2:80/api/"

View File

@ -27,30 +27,16 @@ class ProductRemoteMediator (
state: PagingState<Int, ProductModel>
): MediatorResult {
return try {
// The network load method takes an optional `after=<user.id>` parameter. For every
// page after the first, we pass the last user ID to let it continue from where it
// left off. For REFRESH, pass `null` to load the first page.
var loadKey = when (loadType) {
LoadType.REFRESH -> null
// In this example, we never need to prepend, since REFRESH will always load the
// first page in the list. Immediately return, reporting end of pagination.
LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
LoadType.APPEND -> {
val lastItem = state.lastItemOrNull()
?: return MediatorResult.Success(endOfPaginationReached = true)
// We must explicitly check if the last item is `null` when appending,
// since passing `null` to networkService is only valid for initial load.
// If lastItem is `null` it means no items were loaded after the initial
// REFRESH and there are no more items to load.
lastItem.id
}
}
// Suspending network load via Retrofit. This doesn't need to be wrapped in a
// withContext(Dispatcher.IO) { ... } block since Retrofit's Coroutine CallAdapter
// dispatches on a worker thread.
if (loadKey == null) {
loadKey = 0
}
@ -74,8 +60,6 @@ class ProductRemoteMediator (
productDao.deleteByQuery(query)
}
// Insert new users into database, which invalidates the current
// PagingData, allowing Paging to present the updates in the DB.
val products = mutableListOf<ProductModel>()
for (prod in response.products) {
products.add(prod.toProductModel())

View File

@ -0,0 +1,4 @@
package com.example.shawarma.data.api.repos
class RestOrderRepository {
}

View File

@ -1,10 +1,14 @@
package com.example.shawarma.data.api.repos
import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.models.toProductModelRemote
import com.example.shawarma.data.models.ProductModel
import javax.inject.Inject
class RestProductRepository @Inject constructor(
private val service: MyServerService
) {
suspend fun insert(product: ProductModel) {
service.insertProduct(product.toProductModelRemote())
}
}

View File

@ -6,6 +6,7 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.mediators.ProductRemoteMediator
import com.example.shawarma.data.api.repos.RestProductRepository
import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.data.interfaces.dao.OrderProductDao
import com.example.shawarma.data.interfaces.dao.ProductDao
@ -16,10 +17,11 @@ import javax.inject.Inject
class ProductRepository @Inject constructor(
private val database: AppDatabase,
private val productDao: ProductDao,
private val orderProductDao: OrderProductDao
private val orderProductDao: OrderProductDao,
private val restRepository: RestProductRepository
) {
suspend fun insert(product: ProductModel) {
return productDao.insert(product)
return restRepository.insert(product)
}
suspend fun update(product: ProductModel) {
return productDao.update(product)
@ -51,12 +53,14 @@ class ProductRepository @Inject constructor(
remoteMediator = ProductRemoteMediator(database = database, serverService = MyServerService.getInstance(), query = "discounts", token = token)
).flow
fun getAllItemsPaged(): Flow<PagingData<ProductModel>> = Pager(
@OptIn(ExperimentalPagingApi::class)
fun getAllItemsPaged(token: String): Flow<PagingData<ProductModel>> = Pager(
config = PagingConfig(
pageSize = 6,
enablePlaceholders = false
),
pagingSourceFactory = productDao::getPagedItems
pagingSourceFactory = productDao::getPagedItems,
remoteMediator = ProductRemoteMediator(database = database, serverService = MyServerService.getInstance(), query = "items", token = token)
).flow
}

View File

@ -24,6 +24,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@ -35,6 +36,7 @@ import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey
import com.example.shawarma.R
import com.example.shawarma.data.models.ProductModel
import com.example.shawarma.data.sharedpref.PreferencesManager
import com.example.shawarma.ui.theme.MarckFamily
import com.example.shawarma.ui.theme.MyLightRed
import com.example.shawarma.ui.theme.MyLightYellow
@ -59,9 +61,12 @@ fun ProductsScreen(navHostController: NavHostController) {
@Composable
fun ProductsList(navHostController: NavHostController){
val preferencesManager = PreferencesManager(LocalContext.current)
val searchToken = preferencesManager.getData("token", "")
val productsViewModel: ProductsViewModel = hiltViewModel<ProductsViewModel>()
val products = productsViewModel.productListUiState.collectAsLazyPagingItems()
val products = productsViewModel.getItemsList(searchToken).collectAsLazyPagingItems()
Box(
modifier = Modifier
@ -108,7 +113,7 @@ fun ProductsList(navHostController: NavHostController){
products.itemCount,
key = products.itemKey()
) { index ->
ProductItem(products[index]!!, navHostController)
ProductItem(products[index]!!, navHostController, productsViewModel)
Spacer(modifier = Modifier.height(20.dp))
if (index == products.itemCount - 1) {
Spacer(modifier = Modifier.height(70.dp))
@ -120,9 +125,7 @@ fun ProductsList(navHostController: NavHostController){
}
@Composable
fun ProductItem(product: ProductModel, navHostController: NavHostController){
val productsViewModel: ProductsViewModel = hiltViewModel<ProductsViewModel>()
fun ProductItem(product: ProductModel, navHostController: NavHostController, productsViewModel: ProductsViewModel){
Card(
border = BorderStroke(width = 2.dp, color = MyOrange),
shape = RoundedCornerShape(size = 20.dp),

View File

@ -1,7 +1,5 @@
package com.example.shawarma.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
@ -16,11 +14,10 @@ import javax.inject.Inject
class ProductsViewModel @Inject constructor(
private val productRepository: ProductRepository
) : ViewModel() {
private val _products = MutableLiveData<List<ProductModel>>()
val products: LiveData<List<ProductModel>>
get() = _products
val productListUiState: Flow<PagingData<ProductModel>> = productRepository.getAllItemsPaged()
fun getItemsList(token:String): Flow<PagingData<ProductModel>> {
return productRepository.getAllItemsPaged(token)
}
fun deleteProduct(product: ProductModel) {
viewModelScope.launch {