This commit is contained in:
andrew 2023-12-14 00:36:39 +04:00
parent 5a9c56f573
commit 5d7442934d
34 changed files with 489 additions and 195 deletions

View File

@ -6,9 +6,12 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.testapp.designElem.SharedViewModel
import com.example.testapp.graphs.RootNavigationGraph import com.example.testapp.graphs.RootNavigationGraph
import com.example.testapp.ui.theme.TestAppTheme import com.example.testapp.ui.theme.TestAppTheme
import com.example.testapp.viewModels.AppViewModelProvider
import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.CurrentUserViewModel
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@ -22,7 +25,8 @@ class MainActivity : ComponentActivity() {
TestAppTheme { TestAppTheme {
RootNavigationGraph( RootNavigationGraph(
navController = rememberNavController(), navController = rememberNavController(),
currentUserViewModel = currentUserViewModel currentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
sharedViewModel = SharedViewModel()
) )
} }
} }

View File

@ -4,7 +4,9 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth import androidx.compose.foundation.layout.requiredWidth
@ -33,8 +35,8 @@ fun ListItem(modifier: Modifier = Modifier, coin : Coin, count: Float) {
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = modifier modifier = modifier
.requiredWidth(width = 340.dp) .fillMaxWidth()
.requiredHeight(height = 36.dp) .fillMaxHeight()
.clip(shape = RoundedCornerShape(8.dp)) .clip(shape = RoundedCornerShape(8.dp))
.background(color = Color.White) .background(color = Color.White)
.padding(end = 12.dp, .padding(end = 12.dp,

View File

@ -84,7 +84,7 @@ fun AddItem(
.clickable(onClick = { .clickable(onClick = {
navController.navigate(screen.route) { navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id) popUpTo(navController.graph.findStartDestination().id)
launchSingleTop = true launchSingleTop = false
} }
}) })
.clip(shape = RoundedCornerShape(10.dp)) .clip(shape = RoundedCornerShape(10.dp))

View File

@ -14,7 +14,7 @@ class SharedViewModel : ViewModel() {
argument_add_c.value = arg2 argument_add_c.value = arg2
} }
fun setArgumentEdit(arg: Any) { fun setArgumentEdit(arg: Any?) {
argument_edit.value = arg argument_edit.value = arg
} }

View File

@ -6,6 +6,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import com.example.testapp.designElem.SharedViewModel
import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.navigate.BottomBarScreen
import com.example.testapp.screensMobile.AccountPage import com.example.testapp.screensMobile.AccountPage
import com.example.testapp.screensMobile.CreateDeal import com.example.testapp.screensMobile.CreateDeal
@ -27,7 +28,8 @@ fun HomeNavGraph(
dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory), dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory),
dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory), dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory),
historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory), historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory),
walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory) walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory),
sharedViewModel: SharedViewModel
) { ) {
NavHost( NavHost(
navController = navController, navController = navController,
@ -51,14 +53,16 @@ fun HomeNavGraph(
DealList( DealList(
navController = navController, navController = navController,
currentUserViewModel = currentUserViewModel, currentUserViewModel = currentUserViewModel,
dealListViewModel = dealListViewModel dealListViewModel = dealListViewModel,
sharedViewModel = sharedViewModel
) )
} }
composable(route = BottomBarScreen.CDEAL.route) { composable(route = BottomBarScreen.CDEAL.route) {
CreateDeal( CreateDeal(
navController = navController, navController = navController,
currentUserViewModel = currentUserViewModel, currentUserViewModel = currentUserViewModel,
dealCreateViewModel = dealCreateViewModel dealCreateViewModel = dealCreateViewModel,
sharedViewModel = sharedViewModel
) )
} }
composable(route = BottomBarScreen.History.route) { composable(route = BottomBarScreen.History.route) {

View File

@ -8,6 +8,7 @@ import androidx.navigation.NavType
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.navArgument import androidx.navigation.navArgument
import com.example.testapp.designElem.SharedViewModel
import com.example.testapp.screensMobile.LoadScreen import com.example.testapp.screensMobile.LoadScreen
import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.AppViewModelProvider
import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.CurrentUserViewModel
@ -30,7 +31,8 @@ fun RootNavigationGraph(
entryScreenViewModel: EntryScreenViewModel = viewModel(factory = AppViewModelProvider.Factory), entryScreenViewModel: EntryScreenViewModel = viewModel(factory = AppViewModelProvider.Factory),
historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory), historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory),
registrationScreenViewModel: RegistrationScreenViewModel = viewModel(factory = AppViewModelProvider.Factory), registrationScreenViewModel: RegistrationScreenViewModel = viewModel(factory = AppViewModelProvider.Factory),
walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory) walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory),
sharedViewModel: SharedViewModel
) { ) {
NavHost( NavHost(
navController = navController, navController = navController,
@ -54,7 +56,8 @@ fun RootNavigationGraph(
dealCreateViewModel = dealCreateViewModel, dealCreateViewModel = dealCreateViewModel,
dealListViewModel = dealListViewModel, dealListViewModel = dealListViewModel,
historyViewModel = historyViewModel, historyViewModel = historyViewModel,
walletViewModel = walletViewModel walletViewModel = walletViewModel,
sharedViewModel = sharedViewModel
) )
} }
} }

View File

@ -3,6 +3,7 @@ package com.example.testapp.room.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Query import androidx.room.Query
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.User
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao
@ -10,7 +11,10 @@ interface DealDao : IDao<Deal> {
@Query("select * from deal") @Query("select * from deal")
fun getAll(): Flow<List<Deal>> fun getAll(): Flow<List<Deal>>
@Query("select * from deal ORDER BY id DESC LIMIT :limit OFFSET :offset") @Query("select * from deal where deal.id = :id")
fun getById(id: Int): Deal
@Query("select * from deal where deal.date IS NULL ORDER BY id DESC LIMIT :limit OFFSET :offset")
fun getAll(limit: Int, offset: Int): List<Deal> fun getAll(limit: Int, offset: Int): List<Deal>
@Query("select * from deal where deal.buyerId = :idUser OR deal.sellerId = :idUser") @Query("select * from deal where deal.buyerId = :idUser OR deal.sellerId = :idUser")

View File

@ -13,7 +13,7 @@ interface UserDao : IDao<User> {
fun getAll(): Flow<List<User>> fun getAll(): Flow<List<User>>
@Query("select * from user where user.id = :idUser") @Query("select * from user where user.id = :idUser")
fun getUserById(idUser: Int): Flow<User> fun getUserById(idUser: Int): User
@Query("select * from walletitem where walletitem.userId = :idUser") @Query("select * from walletitem where walletitem.userId = :idUser")
fun getUserWallet(idUser: Int): Flow<List<WalletItem>> fun getUserWallet(idUser: Int): Flow<List<WalletItem>>

View File

@ -2,6 +2,7 @@ package com.example.testapp.room.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Query import androidx.room.Query
import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem import com.example.testapp.room.models.WalletItem
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -10,6 +11,9 @@ interface WalletItemDao : IDao<WalletItem> {
@Query("select * from walletitem") @Query("select * from walletitem")
fun getAll(): Flow<List<WalletItem>> fun getAll(): Flow<List<WalletItem>>
@Query("select * from walletitem where walletitem.userId = :id ORDER BY walletitem.coinId DESC LIMIT :limit OFFSET :offset")
fun getAll(limit: Int, offset: Int, id: Int): List<WalletItem>
@Query("select * from walletitem where walletitem.userId = :id") @Query("select * from walletitem where walletitem.userId = :id")
fun getUserWallet(id: Int): Flow<List<WalletItem>> fun getUserWallet(id: Int): Flow<List<WalletItem>>
} }

View File

@ -22,7 +22,7 @@ abstract class CryptoDealDb: RoomDatabase() {
abstract fun walletItemDao(): WalletItemDao; abstract fun walletItemDao(): WalletItemDao;
companion object { companion object {
private const val DB_NAME: String = "crypto-deal2" private const val DB_NAME: String = "crypto-deal7"
@Volatile @Volatile
private var INSTANCE: CryptoDealDb? = null private var INSTANCE: CryptoDealDb? = null
@ -41,10 +41,16 @@ abstract class CryptoDealDb: RoomDatabase() {
val c2 = Coin(1, "Edhereum"); val c2 = Coin(1, "Edhereum");
val c3 = Coin(2, "CatCoin"); val c3 = Coin(2, "CatCoin");
val c4 = Coin(3, "BuzCoin"); val c4 = Coin(3, "BuzCoin");
val c5 = Coin(4, "LunaCoin");
val c6 = Coin(5, "HopeCoin");
val c7 = Coin(6, "DyrovCoin")
coinDao.insert(c1); coinDao.insert(c1);
coinDao.insert(c2) coinDao.insert(c2)
coinDao.insert(c3) coinDao.insert(c3)
coinDao.insert(c4) coinDao.insert(c4)
coinDao.insert(c5)
coinDao.insert(c6)
coinDao.insert(c7)
val walletItemDao = database.walletItemDao(); val walletItemDao = database.walletItemDao();
val wi1 = WalletItem(0, 0, 0.5f); val wi1 = WalletItem(0, 0, 0.5f);
@ -53,18 +59,28 @@ abstract class CryptoDealDb: RoomDatabase() {
val wi4 = WalletItem(0, 1, 1000f); val wi4 = WalletItem(0, 1, 1000f);
val wi5 = WalletItem(3, 1, 10f); val wi5 = WalletItem(3, 1, 10f);
val wi6 = WalletItem(2, 1, 1f); val wi6 = WalletItem(2, 1, 1f);
val wi7 = WalletItem(4, 0, 1.1f);
val wi8 = WalletItem(5, 0, 1.1f);
val wi9 = WalletItem(6, 0, 1.1f);
walletItemDao.insert(wi1); walletItemDao.insert(wi1);
walletItemDao.insert(wi2); walletItemDao.insert(wi2);
walletItemDao.insert(wi3); walletItemDao.insert(wi3);
walletItemDao.insert(wi4); walletItemDao.insert(wi4);
walletItemDao.insert(wi5); walletItemDao.insert(wi5);
walletItemDao.insert(wi6); walletItemDao.insert(wi6);
walletItemDao.insert(wi7);
walletItemDao.insert(wi8);
walletItemDao.insert(wi9);
val dealDao = database.dealDao(); val dealDao = database.dealDao();
val d1 = Deal(0, null, 0, 2, 0, 0.1f, 0.2f, "Buy", null, "TEST1") val d1 = Deal(0, null, 0, 2, 0, 0.1f, 0.2f, "Buy", null, "TEST1")
val d2 = Deal(1, null, 0, 0, 2, 0.1f, 0.2f, "Buy", null, "TEST2") val d2 = Deal(1, null, 0, 0, 2, 0.1f, 0.2f, "Buy", null, "TEST2")
val d3 = Deal(2, null, 0, 2, 0, 0.1f, 0.2f, "Buy", null, "TEST3")
val d4 = Deal(3, null, 0, 0, 2, 0.1f, 0.2f, "Buy", null, "TEST4")
dealDao.insert(d1); dealDao.insert(d1);
dealDao.insert(d2); dealDao.insert(d2);
dealDao.insert(d3);
dealDao.insert(d4);
} }
} }
@ -83,6 +99,7 @@ abstract class CryptoDealDb: RoomDatabase() {
} }
} }
}) })
.allowMainThreadQueries()
.build() .build()
.also { INSTANCE = it } .also { INSTANCE = it }
} }

View File

@ -8,7 +8,7 @@ import java.time.LocalDateTime
class Deal ( class Deal (
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
val id: Int?, val id: Int?,
val sellerId: Int?, var sellerId: Int?,
val buyerId: Int?, val buyerId: Int?,
val sellerCoinId: Int, val sellerCoinId: Int,
val buyerCoinId: Int, val buyerCoinId: Int,

View File

@ -2,7 +2,6 @@ package com.example.testapp.room.models
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.PrimaryKey
@Entity( @Entity(
primaryKeys = ["coinId", "userId"], primaryKeys = ["coinId", "userId"],
@ -14,5 +13,6 @@ import androidx.room.PrimaryKey
class WalletItem ( class WalletItem (
val coinId: Int, val coinId: Int,
val userId: Int, val userId: Int,
val count: Float var count: Float,
// val freeze: Float
) )

View File

@ -14,7 +14,6 @@ class DealPagination(
val page = params.key ?: 0 val page = params.key ?: 0
return try { return try {
Log.d("MainPagingSource", "load: $page")
val entities = dao.getAll(params.loadSize, page * params.loadSize) val entities = dao.getAll(params.loadSize, page * params.loadSize)
if (page != 0) delay(1000) if (page != 0) delay(1000)
LoadResult.Page( LoadResult.Page(

View File

@ -0,0 +1,40 @@
package com.example.testapp.room.pagination
import android.util.Log
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.example.testapp.room.dao.WalletItemDao
import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.delay
class WalletPagination(
private val dao: WalletItemDao,
private val id: Int
) : PagingSource<Int, WalletItem>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, WalletItem> {
val page = params.key ?: 0
return try {
Log.d("MainPagingSource", "load: $page")
val entities = dao.getAll(params.loadSize, page * params.loadSize, id)
if (page != 0) delay(1000)
LoadResult.Page(
data = entities,
prevKey = if (page == 0) null else page - 1,
nextKey = if (entities.isEmpty()) null else page + 1
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
override val jumpingSupported: Boolean = true
override fun getRefreshKey(state: PagingState<Int, WalletItem>): Int? {
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
}
}

View File

@ -1,9 +1,12 @@
package com.example.testapp.room.repository.basic package com.example.testapp.room.repository.basic
import androidx.paging.PagingData
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface DealRepository : IRepository<Deal> { interface DealRepository : IRepository<Deal> {
fun getUserDeals(id: Int): Flow<List<Deal>> fun getUserDeals(id: Int): Flow<List<Deal>>
fun completeDeal(deal: Deal, sellerId: Int, buyerId: Int): Boolean fun completeDeal(deal: Deal, sellerId: Int, buyerId: Int): Boolean
fun pagingData(): Flow<PagingData<Deal>>
} }

View File

@ -6,7 +6,6 @@ interface IRepository<T> {
suspend fun insert(x: T) suspend fun insert(x: T)
suspend fun update(x: T) suspend fun update(x: T)
suspend fun delete(x: T) suspend fun delete(x: T)
fun getById(id: Int): T
fun getAll(): Flow<List<T>> fun getAll(): Flow<List<T>>
fun getById(id: Int): Flow<T>
fun getAll(limit: Int, offset: Int): List<T>
} }

View File

@ -1,8 +1,13 @@
package com.example.testapp.room.repository.basic package com.example.testapp.room.repository.basic
import androidx.lifecycle.LiveData
import androidx.paging.PagingData
import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem import com.example.testapp.room.models.WalletItem
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface WalletItemRepository : IRepository<WalletItem> { interface WalletItemRepository : IRepository<WalletItem> {
fun getUserWallet(id: Int): Flow<List<WalletItem>> fun getUserWallet(id: Int): Flow<List<WalletItem>>
fun pagingData(id: Int): Flow<PagingData<WalletItem>>
fun pagingDataTest(id: Int): LiveData<PagingData<WalletItem>>
} }

View File

@ -1,7 +1,14 @@
package com.example.testapp.room.repository.offline package com.example.testapp.room.repository.offline
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.testapp.room.dao.CoinDao import com.example.testapp.room.dao.CoinDao
import com.example.testapp.room.models.Coin import com.example.testapp.room.models.Coin
import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.pagination.DealPagination
import com.example.testapp.room.pagination.WalletPagination
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.room.repository.basic.CoinRepository
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -9,6 +16,5 @@ class OfflineCoinRepository(
private val coinDao: CoinDao private val coinDao: CoinDao
) : OfflineRepository<Coin>(coinDao), CoinRepository { ) : OfflineRepository<Coin>(coinDao), CoinRepository {
override fun getAll(): Flow<List<Coin>> = coinDao.getAll() override fun getAll(): Flow<List<Coin>> = coinDao.getAll()
override fun getAll(limit: Int, offset: Int): List<Coin> = throw NotImplementedError() override fun getById(id: Int): Coin = throw NotImplementedError()
override fun getById(id: Int): Flow<Coin> = throw NotImplementedError()
} }

View File

@ -1,7 +1,13 @@
package com.example.testapp.room.repository.offline package com.example.testapp.room.repository.offline
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.testapp.room.dao.DealDao import com.example.testapp.room.dao.DealDao
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.pagination.DealPagination
import com.example.testapp.room.pagination.WalletPagination
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.room.repository.basic.DealRepository
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -9,35 +15,14 @@ class OfflineDealRepository(
private val dealDao: DealDao private val dealDao: DealDao
) : OfflineRepository<Deal>(dealDao), DealRepository { ) : OfflineRepository<Deal>(dealDao), DealRepository {
override fun getAll(): Flow<List<Deal>> = dealDao.getAll() override fun getAll(): Flow<List<Deal>> = dealDao.getAll()
override fun getAll(limit: Int, offset: Int) = dealDao.getAll(limit, offset) override fun getById(id: Int): Deal = dealDao.getById(id);
override fun getById(id: Int): Flow<Deal> = throw NotImplementedError()
override fun getUserDeals(id: Int): Flow<List<Deal>> = dealDao.getUserDeals(id) override fun getUserDeals(id: Int): Flow<List<Deal>> = dealDao.getUserDeals(id)
override fun completeDeal(deal: Deal, sellerId: Int, buyerId: Int): Boolean { override fun completeDeal(deal: Deal, sellerId: Int, buyerId: Int): Boolean {
// val userRepository = UserRepository()
// val buyer = deal.buyerId?.let { userRepository.getById(it) }
// val seller = userRepository.getById(id)
//
// val coin = seller.wallet[deal.sellerCoin]
// if (coin != null && coin >= deal.countSell) {
// if (buyer != null) {
// if (buyer.wallet.containsKey(deal.sellerCoin))
// buyer.wallet[deal.sellerCoin] = buyer.wallet[deal.sellerCoin]!! + deal.countSell
// else buyer.wallet[deal.sellerCoin] = deal.countSell
// buyer.wallet[deal.buyerCoin] = buyer.wallet[deal.buyerCoin]!! - deal.countBuy
// }
// seller.wallet[deal.sellerCoin] = seller.wallet[deal.sellerCoin]!! - deal.countSell
// if (seller.wallet.containsKey(deal.buyerCoin))
// seller.wallet[deal.buyerCoin] = seller.wallet[deal.buyerCoin]!! + deal.countBuy
// else seller.wallet[deal.buyerCoin] = deal.countSell
// }
// deal.date = LocalDateTime.now()
// deal.sellerId = id
// DealRepository().update(deal)
// navController.navigate(BottomBarScreen.Deals.route) {
// popUpTo(navController.graph.findStartDestination().id)
// launchSingleTop = true
// }
return true; return true;
} }
override fun pagingData(): Flow<PagingData<Deal>> = Pager(config = PagingConfig(
pageSize = 4, jumpThreshold = 4, initialLoadSize = 4
), pagingSourceFactory = { DealPagination(dealDao) }, initialKey = 1).flow
} }

View File

@ -11,8 +11,7 @@ class OfflineUserRepository(
private val userDao: UserDao private val userDao: UserDao
) : OfflineRepository<User>(userDao), UserRepository { ) : OfflineRepository<User>(userDao), UserRepository {
override fun getAll(): Flow<List<User>> = userDao.getAll() override fun getAll(): Flow<List<User>> = userDao.getAll()
override fun getAll(limit: Int, offset: Int) = throw NotImplementedError() override fun getById(id: Int): User = userDao.getUserById(id)
override fun getById(id: Int): Flow<User> = userDao.getUserById(id)
override fun getUserWallet(id: Int): Flow<List<WalletItem>> = userDao.getUserWallet(id) override fun getUserWallet(id: Int): Flow<List<WalletItem>> = userDao.getUserWallet(id)
override fun getUserDeals(id: Int): Flow<List<Deal>> = userDao.getUserDeals(id) override fun getUserDeals(id: Int): Flow<List<Deal>> = userDao.getUserDeals(id)
} }

View File

@ -1,7 +1,14 @@
package com.example.testapp.room.repository.offline package com.example.testapp.room.repository.offline
import androidx.lifecycle.LiveData
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.liveData
import com.example.testapp.room.dao.WalletItemDao import com.example.testapp.room.dao.WalletItemDao
import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.pagination.WalletPagination
import com.example.testapp.room.repository.basic.WalletItemRepository import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -10,6 +17,13 @@ class OfflineWalletItemRepository(
) : OfflineRepository<WalletItem>(walletItemDao), WalletItemRepository { ) : OfflineRepository<WalletItem>(walletItemDao), WalletItemRepository {
override fun getUserWallet(id: Int): Flow<List<WalletItem>> = walletItemDao.getUserWallet(id) override fun getUserWallet(id: Int): Flow<List<WalletItem>> = walletItemDao.getUserWallet(id)
override fun getAll(): Flow<List<WalletItem>> = walletItemDao.getAll() override fun getAll(): Flow<List<WalletItem>> = walletItemDao.getAll()
override fun getAll(limit: Int, offset: Int): List<WalletItem> = throw NotImplementedError() override fun getById(id: Int): WalletItem = throw NotImplementedError()
override fun getById(id: Int): Flow<WalletItem> = throw NotImplementedError()
override fun pagingData(id: Int): Flow<PagingData<WalletItem>> = Pager(config = PagingConfig(
pageSize = 10, jumpThreshold = 10, initialLoadSize = 10
), pagingSourceFactory = { WalletPagination(walletItemDao, id) }, initialKey = 1).flow
override fun pagingDataTest(id: Int): LiveData<PagingData<WalletItem>> = Pager(config = PagingConfig(
pageSize = 1, jumpThreshold = 1, initialLoadSize = 1
), pagingSourceFactory = { WalletPagination(walletItemDao, id) }, initialKey = 1).liveData
} }

View File

@ -19,6 +19,7 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -47,8 +48,7 @@ fun AccountPage(
navController: NavController, navController: NavController,
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory) currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val user by remember { mutableStateOf(currentUserViewModel.user) } val user by currentUserViewModel.user.collectAsState()
val coroutineScope = rememberCoroutineScope()
Box( Box(
modifier = modifier modifier = modifier

View File

@ -21,11 +21,11 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -41,8 +41,11 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.example.testapp.designElem.DropDown import com.example.testapp.designElem.DropDown
import com.example.testapp.designElem.DropDownConfig import com.example.testapp.designElem.DropDownConfig
import com.example.testapp.designElem.SharedViewModel
import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.navigate.BottomBarScreen
import com.example.testapp.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem
import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.AppViewModelProvider
import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.CurrentUserViewModel
import com.example.testapp.viewModels.DealCreateViewModel import com.example.testapp.viewModels.DealCreateViewModel
@ -57,37 +60,60 @@ fun CreateDeal(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
navController: NavHostController, navController: NavHostController,
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory), currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory) dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory),
sharedViewModel: SharedViewModel
) { ) {
dealCreateViewModel.setupLists(currentUserViewModel.user!!.id.toString()) val user by currentUserViewModel.user.collectAsState()
val isEdit = dealCreateViewModel.isEdit() val editDeal = sharedViewModel.argument_edit.value as Deal?
val editDeal: Deal? = dealCreateViewModel.deal val isEdit = editDeal != null
val id = if (isEdit) editDeal?.buyerId else currentUserViewModel.user!!.id val id = if (isEdit) editDeal?.buyerId else user!!.id
val coins = mutableStateOf(dealCreateViewModel.coins) val coins by dealCreateViewModel.coins.collectAsState()
val wallet = mutableStateOf(dealCreateViewModel.wallet) val wallet by dealCreateViewModel.wallet.collectAsState()
val coinsBuyer = wallet.filter { x -> x.userId == id }.toList()
val coinsBuyer = wallet.value.filter { x -> x.userId == id }.toList() var coinBuyer by remember {
var coinBuyer by rememberSaveable { mutableStateOf(
mutableStateOf(if (isEdit) coins.value.first { y -> y.id == editDeal?.buyerCoinId }.name else coinsBuyer[0]) if (isEdit) coinsBuyer.first { y -> y.coinId == editDeal?.buyerCoinId }
else coinsBuyer[0]
)
} }
var buyCount by remember { var buyCount by remember {
mutableFloatStateOf(if (isEdit) editDeal?.countBuy!! else 0f) mutableFloatStateOf(
} if (isEdit) editDeal?.countBuy!!
var tip by remember { else 0f
mutableStateOf(if (isEdit) editDeal?.tip else "") )
} }
val coinsSeller = val coinsSeller = coins
wallet.value.map { x -> coins.value.first { y -> y.id == x.coinId }.name }.toList() var coinSeller by remember {
var coinSeller by rememberSaveable { mutableStateOf(
mutableStateOf(if (isEdit) coins.value.first { y -> y.id == editDeal?.sellerCoinId }.name else coinsSeller[0]) if (isEdit) coins.first { y -> y.id == editDeal?.sellerCoinId }
else coinsSeller[0]
)
} }
var sellCount by remember { var sellCount by remember {
mutableFloatStateOf(if (isEdit) editDeal?.countSell!! else 0f) mutableFloatStateOf(
if (isEdit) editDeal?.countSell!!
else 0f
)
}
var tip by remember {
mutableStateOf(
if (isEdit) editDeal?.tip
else ""
)
}
val dictionaryName: Map<String, WalletItem?> = coins.associate { x ->
x.name to coinsBuyer.firstOrNull { y -> y.coinId == x.id }
}
val dictionaryId: Map<Int?, String> = coins.associate { x ->
x.id to x.name
} }
@ -126,15 +152,18 @@ fun CreateDeal(
) )
Text( Text(
text = "-", text = "-",
color = Color(0xff4bb2f9), color = Color(0xFFF94B4B),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
lineHeight = 0.83.em, lineHeight = 0.83.em,
style = TextStyle( style = TextStyle(
fontSize = 24.sp, fontSize = 20.sp,
letterSpacing = 0.1.sp letterSpacing = 0.1.sp
), ),
modifier = Modifier modifier = Modifier
.clickable { .clickable {
CoroutineScope(Dispatchers.IO).launch {
dealCreateViewModel.delete(editDeal!!)
}
navController.navigate(route = BottomBarScreen.Deals.route) navController.navigate(route = BottomBarScreen.Deals.route)
} }
.wrapContentHeight(align = Alignment.CenterVertically)) .wrapContentHeight(align = Alignment.CenterVertically))
@ -157,11 +186,10 @@ fun CreateDeal(
DropDown( DropDown(
modifier = Modifier.padding(horizontal = 10.dp), modifier = Modifier.padding(horizontal = 10.dp),
downConfig = DropDownConfig<String>( downConfig = DropDownConfig<String>(
values = coinsBuyer.map { x -> coins.value.first { y -> y.id == x.coinId }.name } values = dictionaryName.filter { x -> x.value != null }.keys.toList(),
.toList(),
title = "Select coin", title = "Select coin",
onValueChange = { x -> coinBuyer = x }, onValueChange = { x -> coinBuyer = dictionaryName[x]!! },
selected = coinBuyer as String selected = dictionaryId[(coinBuyer as WalletItem).coinId]
) )
) )
} }
@ -169,15 +197,14 @@ fun CreateDeal(
OutlinedTextField( OutlinedTextField(
value = buyCount.toString(), value = buyCount.toString(),
onValueChange = { onValueChange = {
val value = val value = (coinBuyer as WalletItem)
coinsBuyer.first { x -> coinBuyer == coins.value.first { y -> y.id == x.coinId } }
if (it.toFloatOrNull() != null && it.toFloat() <= value.count) { if (it.toFloatOrNull() != null && it.toFloat() <= value.count) {
buyCount = it.toFloat() buyCount = it.toFloat()
} }
}, },
label = { label = {
Text( Text(
text = "Fill count 0 -> ${coinsBuyer.first { x -> coinBuyer == coins.value.first { y -> y.id == x.coinId } }.count}", text = "Fill count 0 -> ${(coinBuyer as WalletItem).count}",
color = Color.Black, color = Color.Black,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
lineHeight = 1.43.em, lineHeight = 1.43.em,
@ -243,10 +270,10 @@ fun CreateDeal(
DropDown( DropDown(
modifier = Modifier.padding(horizontal = 10.dp), modifier = Modifier.padding(horizontal = 10.dp),
downConfig = DropDownConfig<String>( downConfig = DropDownConfig<String>(
values = coinsSeller.filter { x -> x != (coinBuyer as String) }, values = dictionaryName.keys.toList(),
title = "Select coin", title = "Select coin",
onValueChange = { x -> coinSeller = x }, onValueChange = { x -> coinSeller = coins.first { y -> y.name == x } },
selected = coinSeller selected = dictionaryId[(coinSeller as Coin).id]
) )
) )
} }
@ -285,9 +312,9 @@ fun CreateDeal(
id = editDeal?.id, id = editDeal?.id,
sellerId = editDeal?.sellerId, sellerId = editDeal?.sellerId,
buyerId = id, buyerId = id,
buyerCoinId = coins.value.first { x -> x.name == coinBuyer }.id!!, buyerCoinId = coinBuyer.coinId,
countBuy = buyCount, countBuy = buyCount,
sellerCoinId = coins.value.first { x -> x.name == coinSeller }.id!!, sellerCoinId = coinSeller.id!!,
countSell = sellCount, countSell = sellCount,
tip = tip!!, tip = tip!!,
operation = "Buy", operation = "Buy",
@ -296,14 +323,16 @@ fun CreateDeal(
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
dealCreateViewModel.update(deal) dealCreateViewModel.update(deal)
} }
sharedViewModel.setArgumentEdit(null);
} else { } else {
if (buyCount == 0f || sellCount == 0f) return@Button;
val deal = Deal( val deal = Deal(
id = null, id = null,
sellerId = null, sellerId = null,
buyerId = id, buyerId = id,
buyerCoinId = coins.value.first { x -> x.name == coinBuyer }.id!!, buyerCoinId = coinBuyer.coinId,
countBuy = buyCount, countBuy = buyCount,
sellerCoinId = coins.value.first { x -> x.name == coinSeller }.id!!, sellerCoinId = coinSeller.id!!,
countSell = sellCount, countSell = sellCount,
tip = tip!!, tip = tip!!,
operation = "Buy", operation = "Buy",
@ -358,6 +387,7 @@ fun CreateDeal(
item { item {
Button( Button(
onClick = { onClick = {
sharedViewModel.setArgumentEdit(null);
navController.navigate(route = BottomBarScreen.Deals.route) navController.navigate(route = BottomBarScreen.Deals.route)
}, },
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),

View File

@ -7,6 +7,7 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -19,11 +20,12 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -39,6 +41,9 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.paging.LoadState
import androidx.paging.compose.collectAsLazyPagingItems
import com.example.testapp.designElem.SharedViewModel
import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.navigate.BottomBarScreen
import com.example.testapp.room.models.Coin import com.example.testapp.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
@ -54,18 +59,20 @@ fun DealList(
navController: NavHostController, navController: NavHostController,
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory), currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory), dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory),
dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory) dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory),
sharedViewModel: SharedViewModel
) { ) {
val id = currentUserViewModel.user!!.id val user by currentUserViewModel.user.collectAsState()
val id = user!!.id
dealListViewModel.setupLists() dealListViewModel.setupLists()
val deals = remember { mutableStateOf(dealListViewModel.deals) } val deals = dealListViewModel.deals.collectAsLazyPagingItems()
val coins = remember { mutableStateOf(dealListViewModel.coins) } val coins by dealListViewModel.coins.collectAsState()
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top), verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
contentPadding = PaddingValues(bottom = 70.dp),
modifier = modifier modifier = modifier
.background(color = Color(0xfff4f7fb)) .background(color = Color(0xfff4f7fb))
.padding(vertical = 20.dp) .padding(vertical = 20.dp)
@ -74,19 +81,43 @@ fun DealList(
item { item {
PropertyDeal(navController = navController) PropertyDeal(navController = navController)
} }
item { items(count = deals.itemCount) { x ->
deals.value.filter { x -> x.date == null }.forEach { x -> val deal = deals[x]
if (deal != null) {
DealItem( DealItem(
deal = x, deal = deal,
coins = coins.value, coins = coins,
modifier = Modifier.padding(vertical = 5.dp), modifier = Modifier.padding(vertical = 5.dp),
id = id, id = id,
navController = navController, navController = navController,
dealCreateViewModel = dealCreateViewModel, dealCreateViewModel = dealCreateViewModel,
dealListViewModel = dealListViewModel dealListViewModel = dealListViewModel,
sharedViewModel = sharedViewModel
) )
} }
} }
deals.apply {
when{
loadState.refresh is LoadState.Loading -> {
item { CircularProgressIndicator(
modifier = Modifier.fillParentMaxSize(0.5f),
color = Color(0xff423a99)) }
}
loadState.append is LoadState.Loading -> {
item { CircularProgressIndicator(
modifier = Modifier.fillParentMaxSize(0.5f),
color = Color(0xff423a99)) }
}
loadState.refresh is LoadState.Error -> {
val err = deals.loadState.refresh as LoadState.Error
item { Text(err.error.localizedMessage) }
}
loadState.append is LoadState.Error -> {
val err = deals.loadState.append as LoadState.Error
item { Text(err.error.localizedMessage) }
}
}
}
} }
} }
@ -99,7 +130,8 @@ fun DealItem(
id: Int?, id: Int?,
navController: NavHostController, navController: NavHostController,
dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory), dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory),
dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory) dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory),
sharedViewModel: SharedViewModel
) { ) {
Column( Column(
verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.Top), verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.Top),
@ -195,16 +227,22 @@ fun DealItem(
onClick = { onClick = {
if (id != null && id != deal.buyerId) { if (id != null && id != deal.buyerId) {
deal.buyerId?.let { dealListViewModel.submitDeal(deal, id, it) } deal.buyerId?.let { dealListViewModel.submitDeal(deal, id, it) }
navController.navigate(route = BottomBarScreen.Deals.route)
} else { } else {
deal.id?.let { dealCreateViewModel.setupEdit(it) } sharedViewModel.setArgumentEdit(deal);
navController.navigate(BottomBarScreen.CDEAL.route) { navController.navigate(BottomBarScreen.CDEAL.route) {
popUpTo(navController.graph.findStartDestination().id) popUpTo(navController.graph.findStartDestination().id)
launchSingleTop = true launchSingleTop = false
} }
} }
}, },
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xff5acb48)), colors = ButtonDefaults.buttonColors(
// containerColor = Color(0xff5acb48)
containerColor = if (id != deal.buyerId)
Color(0xff5acb48) else
Color(0xFFCB48C9)
),
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.weight(weight = 0.5f) .weight(weight = 0.5f)
@ -315,7 +353,7 @@ fun PropertyDeal(modifier: Modifier = Modifier, navController: NavHostController
.clickable { .clickable {
navController.navigate(BottomBarScreen.CDEAL.route) { navController.navigate(BottomBarScreen.CDEAL.route) {
popUpTo(navController.graph.findStartDestination().id) popUpTo(navController.graph.findStartDestination().id)
launchSingleTop = true launchSingleTop = false
} }
} }
.wrapContentHeight(align = Alignment.CenterVertically)) .wrapContentHeight(align = Alignment.CenterVertically))

View File

@ -17,6 +17,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -39,6 +41,9 @@ import com.example.testapp.room.models.Deal
import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.AppViewModelProvider
import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.CurrentUserViewModel
import com.example.testapp.viewModels.HistoryViewModel import com.example.testapp.viewModels.HistoryViewModel
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneOffset
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
@Composable @Composable
@ -48,10 +53,11 @@ fun History(
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory), currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory) historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val id = currentUserViewModel.user!!.id val user by currentUserViewModel.user.collectAsState()
val id = user!!.id
historyViewModel.setArgument(id.toString()); historyViewModel.setArgument(id.toString());
val history = remember { mutableStateOf(historyViewModel.deals) } val history by historyViewModel.deals.collectAsState()
val coins = remember { mutableStateOf(historyViewModel.coins) } val coins by historyViewModel.coins.collectAsState()
Column( Column(
verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top), verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top),
@ -63,22 +69,23 @@ fun History(
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
PropertyHistory() PropertyHistory()
history.value?.forEach { x -> history.forEach { x ->
coins.value?.let { HistoryCard(
HistoryCard( deal = x,
deal = x, modifier = Modifier.padding(vertical = 5.dp, horizontal = 5.dp),
modifier = Modifier.padding(vertical = 5.dp, horizontal = 5.dp), coins = coins
coins = it )
)
}
} }
} }
} }
@RequiresApi(Build.VERSION_CODES.O)
@Composable @Composable
fun HistoryCard(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) { fun HistoryCard(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
val status = !(deal.buyerId == null || deal.sellerId == null) val status = !(deal.buyerId == null || deal.sellerId == null)
val text = if (!status) "In work" else deal.date.toString() val text = if (!status) "In work"
else LocalDateTime
.ofInstant(deal.date?.let { Instant.ofEpochMilli(it) }, ZoneOffset.UTC).toString()
val color = if (!status) 0xfff96161 else 0xff5acb48 val color = if (!status) 0xfff96161 else 0xff5acb48
Column( Column(
@ -114,6 +121,17 @@ fun HistoryCard(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
modifier = Modifier modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically) .wrapContentHeight(align = Alignment.CenterVertically)
) )
Text(
text = "->",
color = Color(0xFF009688),
lineHeight = 1.25.em,
style = TextStyle(
fontSize = 16.sp,
letterSpacing = 0.1.sp
),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically)
)
Text( Text(
text = "+${deal.countBuy} ${ text = "+${deal.countBuy} ${
coins.first { x -> x.id == deal.buyerCoinId }.shortName() coins.first { x -> x.id == deal.buyerCoinId }.shortName()

View File

@ -6,17 +6,20 @@ import androidx.annotation.RequiresApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@ -25,11 +28,14 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.paging.LoadState
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.pmulabs.designElem.NavBar import com.example.pmulabs.designElem.NavBar
import com.example.testapp.designElem.ListItem import com.example.testapp.designElem.ListItem
import com.example.testapp.designElem.SharedViewModel
import com.example.testapp.graphs.HomeNavGraph import com.example.testapp.graphs.HomeNavGraph
import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.AppViewModelProvider
import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.CurrentUserViewModel
@ -37,6 +43,7 @@ import com.example.testapp.viewModels.DealCreateViewModel
import com.example.testapp.viewModels.DealListViewModel import com.example.testapp.viewModels.DealListViewModel
import com.example.testapp.viewModels.HistoryViewModel import com.example.testapp.viewModels.HistoryViewModel
import com.example.testapp.viewModels.WalletViewModel import com.example.testapp.viewModels.WalletViewModel
import kotlinx.coroutines.flow.first
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
@Composable @Composable
@ -46,13 +53,13 @@ fun Wallet(
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory), currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory) walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val id = currentUserViewModel.user!!.id val getUser by currentUserViewModel.user.collectAsState()
walletViewModel.setArgument(id.toString()) walletViewModel.setArgument(getUser!!.id.toString())
val wallet = remember { mutableStateOf(walletViewModel.wallet) } val wallet = walletViewModel.wallet.collectAsLazyPagingItems()
val coins = remember { mutableStateOf(walletViewModel.coins) } val coins by walletViewModel.coins.collectAsState()
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.Top), verticalArrangement = Arrangement.spacedBy(15.dp, Alignment.Top),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier modifier = modifier
.background(color = Color(0xfff4f7fb)) .background(color = Color(0xfff4f7fb))
@ -62,30 +69,54 @@ fun Wallet(
item { item {
PropertyWallet() PropertyWallet()
} }
item { items(count = wallet.itemCount) {x ->
wallet.value?.forEach { coin -> val wi = wallet[x]
coins.value?.let { coins?.let {
if (wi != null) {
ListItem( ListItem(
coin = it.first { x -> x.id == coin.coinId }, coin = it.first { y -> y.id == wi.coinId },
count = coin.count, count = wi.count,
modifier = Modifier.padding(vertical = 5.dp) modifier = Modifier
) )
} }
} }
} }
wallet.apply {
when{
loadState.refresh is LoadState.Loading -> {
item { CircularProgressIndicator(
modifier = Modifier.fillParentMaxSize(0.5f),
color = Color(0xff423a99)) }
}
loadState.append is LoadState.Loading -> {
item { CircularProgressIndicator(
modifier = Modifier.fillParentMaxSize(0.5f),
color = Color(0xff423a99)) }
}
loadState.refresh is LoadState.Error -> {
val err = wallet.loadState.refresh as LoadState.Error
item { Text(err.error.localizedMessage) }
}
loadState.append is LoadState.Error -> {
val err = wallet.loadState.append as LoadState.Error
item { Text(err.error.localizedMessage) }
}
}
}
} }
} }
@RequiresApi(34) @RequiresApi(34)
@Composable @Composable
fun LoadScreen( fun LoadScreen(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(), navController: NavHostController = rememberNavController(),
@SuppressLint("ModifierParameter") modifier: Modifier = Modifier,
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory), currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory), dealCreateViewModel: DealCreateViewModel = viewModel(factory = AppViewModelProvider.Factory),
dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory), dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory),
historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory), historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory),
walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory) walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory),
sharedViewModel: SharedViewModel
) { ) {
Scaffold( Scaffold(
bottomBar = { NavBar(navController = navController) }, bottomBar = { NavBar(navController = navController) },
@ -98,7 +129,8 @@ fun LoadScreen(
dealCreateViewModel, dealCreateViewModel,
dealListViewModel, dealListViewModel,
historyViewModel, historyViewModel,
walletViewModel walletViewModel,
sharedViewModel
) )
} }
} }

View File

@ -69,9 +69,7 @@ fun EntryScreen(
var passwordValue by rememberSaveable { mutableStateOf("") } var passwordValue by rememberSaveable { mutableStateOf("") }
entryScreenViewModel.setupList() entryScreenViewModel.setupList()
val users = mutableStateOf(entryScreenViewModel.userList) val users = mutableStateOf(entryScreenViewModel.userList)
val argument = currentUserViewModel.argument.value
var passwordVisibility by rememberSaveable { mutableStateOf(false) } var passwordVisibility by rememberSaveable { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
Box( Box(
modifier = modifier modifier = modifier
@ -109,6 +107,12 @@ fun EntryScreen(
TextField( TextField(
value = emailValue, value = emailValue,
onValueChange = { emailValue = it }, onValueChange = { emailValue = it },
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White,
disabledContainerColor = Color.White,
),
singleLine = true,
label = { label = {
Text( Text(
text = "Email", text = "Email",
@ -127,6 +131,8 @@ fun EntryScreen(
), ),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.shadow(shape = RoundedCornerShape(5.dp), elevation = 5.dp)
.clip(shape = RoundedCornerShape(5.dp)),
) )
TextField( TextField(
value = passwordValue, value = passwordValue,
@ -138,8 +144,8 @@ fun EntryScreen(
), ),
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.shadow(shape = RoundedCornerShape(40.dp), elevation = 5.dp) .shadow(shape = RoundedCornerShape(5.dp), elevation = 5.dp)
.clip(shape = RoundedCornerShape(40.dp)), .clip(shape = RoundedCornerShape(5.dp)),
label = { Text("Password") }, label = { Text("Password") },
singleLine = true, singleLine = true,
placeholder = { Text("Enter password") }, placeholder = { Text("Enter password") },
@ -177,7 +183,7 @@ fun EntryScreen(
btnConfig = btnConfig( btnConfig = btnConfig(
onClick = { onClick = {
if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) { if (passwordValue.isNotEmpty() && isValidEmail(emailValue)) {
users.value.forEach { user -> users.value.value.forEach { user ->
if (user.password == passwordValue && user.email == emailValue) { if (user.password == passwordValue && user.email == emailValue) {
currentUserViewModel.setArgument(user.id.toString()) currentUserViewModel.setArgument(user.id.toString())
navController.navigate(route = Graph.passUserId(user.id.toString())) navController.navigate(route = Graph.passUserId(user.id.toString()))

View File

@ -14,7 +14,8 @@ object AppViewModelProvider {
initializer { initializer {
DealListViewModel( DealListViewModel(
application().container.dealRepository, application().container.dealRepository,
application().container.coinRepository application().container.coinRepository,
application().container.walletItemRepository
) )
} }
initializer { initializer {

View File

@ -7,22 +7,23 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.testapp.room.models.User import com.example.testapp.room.models.User
import com.example.testapp.room.repository.basic.UserRepository import com.example.testapp.room.repository.basic.UserRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class CurrentUserViewModel(private val userRepository: UserRepository) : ViewModel() { class CurrentUserViewModel(private val userRepository: UserRepository) : ViewModel() {
val argument = mutableStateOf<String?>(null) val argument = MutableStateFlow<String?>(null)
private val id = mutableStateOf<Int?>(null) val id = MutableStateFlow<Int?>(null)
var user by mutableStateOf<User?>(null) var user = MutableStateFlow<User?>(null)
fun setArgument(arg: String) { fun setArgument(arg: String) {
argument.value = arg argument.value = arg
id.value = arg.toInt() id.value = arg.toInt()
viewModelScope.launch { viewModelScope.launch {
user = userRepository.getById(id.value!!) user.emit(userRepository.getById(id.value!!))
.filterNotNull()
.first()
} }
} }
} }

View File

@ -5,13 +5,20 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import com.example.testapp.room.models.Coin import com.example.testapp.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.room.repository.basic.DealRepository
import com.example.testapp.room.repository.basic.WalletItemRepository import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class DealCreateViewModel( class DealCreateViewModel(
@ -19,38 +26,37 @@ class DealCreateViewModel(
private val coinRepository: CoinRepository, private val coinRepository: CoinRepository,
private val walletItemRepository: WalletItemRepository private val walletItemRepository: WalletItemRepository
) : ViewModel() { ) : ViewModel() {
val argument = mutableStateOf<String?>(null) private val dealId = MutableStateFlow<Int?>(null)
private val user_id = mutableStateOf<Int?>(null) var id = 0
private val deal_id = mutableStateOf<Int?>(null)
var deal by mutableStateOf<Deal?>(null) private var _deal = MutableStateFlow<Deal?>(null)
private var _coins = MutableStateFlow<List<Coin>>(emptyList())
var deals by mutableStateOf<List<Deal>>(emptyList()) private var _wallet = MutableStateFlow<List<WalletItem>>(emptyList())
var coins by mutableStateOf<List<Coin>>(emptyList()) var deal: StateFlow<Deal?> = _deal.asStateFlow()
var wallet by mutableStateOf<List<WalletItem>>(emptyList()) var coins = _coins.asStateFlow()
var wallet = _wallet.asStateFlow()
suspend fun update(deal: Deal) = dealRepository.update(deal) suspend fun update(deal: Deal) = dealRepository.update(deal)
suspend fun create(deal: Deal) = dealRepository.insert(deal) suspend fun create(deal: Deal) = dealRepository.insert(deal)
suspend fun delete(deal: Deal) = dealRepository.delete(deal)
fun setupLists(arg: String) { init {
argument.value = arg viewModelScope.launch(Dispatchers.IO) {
user_id.value = arg.toInt() _coins.emit(
coinRepository.getAll().first()
viewModelScope.launch { )
deals = dealRepository.getAll().first(); _wallet.emit(
coins = coinRepository.getAll().first(); walletItemRepository.getAll().first()
wallet = walletItemRepository.getUserWallet(user_id.value!!).first(); )
} }
} }
fun isEdit(): Boolean { fun isEdit(): Boolean {
return deal != null; return deal.value != null;
} }
fun setupEdit(id: Int) { fun setupEdit(deal: Deal) {
deal_id.value = id; dealId.value = deal.id
viewModelScope.launch { _deal.value = deal
deal = dealRepository.getById(id).first();
}
} }
} }

View File

@ -1,32 +1,86 @@
package com.example.testapp.viewModels package com.example.testapp.viewModels
import androidx.compose.runtime.getValue import androidx.annotation.RequiresApi
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.example.testapp.room.models.Coin import com.example.testapp.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.room.repository.basic.DealRepository
import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Date
class DealListViewModel( class DealListViewModel(
private val dealRepository: DealRepository, private val dealRepository: DealRepository,
private val coinRepository: CoinRepository, private val coinRepository: CoinRepository,
private val walletItemRepository: WalletItemRepository
) : ViewModel() { ) : ViewModel() {
var deals by mutableStateOf<List<Deal>>(emptyList()) var deals = MutableStateFlow<PagingData<Deal>>(PagingData.empty())
var coins by mutableStateOf<List<Coin>>(emptyList()) var coins = MutableStateFlow<List<Coin>>(emptyList())
fun setupLists() { fun setupLists() {
viewModelScope.launch { viewModelScope.launch(Dispatchers.IO) {
deals = dealRepository.getAll().first(); coins.emit(coinRepository.getAll().first())
coins = coinRepository.getAll().first(); deals.emit(dealRepository
.pagingData()
.cachedIn(viewModelScope)
.first())
} }
} }
@RequiresApi(34)
fun submitDeal(deal: Deal, sellerId: Int, buyerId: Int) { fun submitDeal(deal: Deal, sellerId: Int, buyerId: Int) {
dealRepository.completeDeal(deal, sellerId, buyerId) viewModelScope.launch {
val walletSeller: List<WalletItem> = walletItemRepository.getUserWallet(sellerId).first()
val walletBuyer: List<WalletItem> = walletItemRepository.getUserWallet(buyerId).first()
val seller: WalletItem? = walletSeller.firstOrNull { x -> x.coinId == deal.sellerCoinId }
val buyer: WalletItem? = walletBuyer.firstOrNull { x -> x.coinId == deal.buyerId }
if (seller == null || buyer == null) return@launch
// Check what seller have buyer COIN or we need to insert new value to database:
// Case if need update
if (walletSeller.any { x -> x.coinId == deal.buyerCoinId }) {
val item = walletSeller.first { x -> x.coinId == deal.buyerCoinId }
item.count += deal.countBuy
walletItemRepository.update(item)
}
// Case if need insert
else {
val item = WalletItem(deal.buyerCoinId, sellerId, deal.countBuy)
walletItemRepository.insert(item)
}
// Check what buyer have buyer COIN or we need to insert new value to database:
// Case if need update
if (walletBuyer.any { x -> x.coinId == deal.sellerCoinId }) {
val item = walletBuyer.first { x -> x.coinId == deal.sellerCoinId }
item.count += deal.countSell
walletItemRepository.update(item)
}
// Case if need insert
else {
val item = WalletItem(deal.sellerCoinId, buyerId, deal.countSell)
walletItemRepository.insert(item)
}
seller.count -= deal.countSell
buyer.count -= deal.countBuy
walletItemRepository.update(seller);
walletItemRepository.update(buyer);
deal.sellerId = sellerId
deal.date = Date().time;
dealRepository.update(deal)
}
} }
} }

View File

@ -7,16 +7,18 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.testapp.room.models.User import com.example.testapp.room.models.User
import com.example.testapp.room.repository.basic.UserRepository import com.example.testapp.room.repository.basic.UserRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class EntryScreenViewModel( class EntryScreenViewModel(
private val userRepository: UserRepository private val userRepository: UserRepository
) : ViewModel() { ) : ViewModel() {
var userList by mutableStateOf<List<User>>(emptyList()) var userList = MutableStateFlow<List<User>>(emptyList())
fun setupList() { fun setupList() {
viewModelScope.launch { viewModelScope.launch {
userList = userRepository.getAll().first() userList.emit(userRepository.getAll().first())
} }
} }
} }

View File

@ -9,22 +9,26 @@ import com.example.testapp.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.room.models.Deal
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.room.repository.basic.DealRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class HistoryViewModel(private val dealRepository: DealRepository, class HistoryViewModel(
private val coinRepository: CoinRepository) : ViewModel() { private val dealRepository: DealRepository,
val argument = mutableStateOf<String?>(null) private val coinRepository: CoinRepository
private val id = mutableStateOf<Int?>(null) ) : ViewModel() {
var deals by mutableStateOf<List<Deal>?>(emptyList()) val argument = MutableStateFlow<String?>(null)
var coins by mutableStateOf<List<Coin>?>(emptyList()) private val id = MutableStateFlow<Int?>(null)
var deals = MutableStateFlow<List<Deal>>(emptyList())
var coins = MutableStateFlow<List<Coin>>(emptyList())
fun setArgument(arg: String) { fun setArgument(arg: String) {
argument.value = arg argument.value = arg
id.value = arg.toInt() id.value = arg.toInt()
viewModelScope.launch { viewModelScope.launch(Dispatchers.IO) {
deals = dealRepository.getUserDeals(id.value!!).first() deals.emit(dealRepository.getAll().first())
coins = coinRepository.getAll().first() coins.emit(coinRepository.getAll().first())
} }
} }
} }

View File

@ -3,12 +3,22 @@ package com.example.testapp.viewModels
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.filter
import com.example.testapp.room.models.Coin import com.example.testapp.room.models.Coin
import com.example.testapp.room.models.WalletItem import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.WalletItemRepository import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -16,17 +26,21 @@ class WalletViewModel(
private val walletItemRepository: WalletItemRepository, private val walletItemRepository: WalletItemRepository,
private val coinRepository: CoinRepository private val coinRepository: CoinRepository
) : ViewModel() { ) : ViewModel() {
val argument = mutableStateOf<String?>(null) val argument = MutableStateFlow<String?>(null)
private val id = mutableStateOf<Int?>(null) private val id = MutableStateFlow<Int?>(null)
var wallet by mutableStateOf<List<WalletItem>?>(emptyList()) var _wallet = MutableStateFlow<PagingData<WalletItem>>(PagingData.empty())
var coins by mutableStateOf<List<Coin>?>(emptyList()) var wallet = _wallet.asStateFlow();
var coins = MutableStateFlow<List<Coin>?>(emptyList())
fun setArgument(arg: String) { fun setArgument(arg: String) {
argument.value = arg argument.value = arg
id.value = arg.toInt() id.value = arg.toInt()
viewModelScope.launch { viewModelScope.launch {
wallet = walletItemRepository.getUserWallet(id.value!!).first() coins.emit(coinRepository.getAll().first())
coins = coinRepository.getAll().first() _wallet.emit(walletItemRepository
.pagingData(id.value!!)
.cachedIn(viewModelScope)
.first())
} }
} }
} }