From 702cf2d2594e8a9dbfc29688e9c6a6dd9b59d2a1 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 20 Dec 2023 11:21:54 +0400 Subject: [PATCH] Complete lab 5 --- .../java/com/example/testapp/MainActivity.kt | 2 +- .../testapp/data/api/CryptoDealService.kt | 12 +- .../data/api/mediator/DealRemoteMediator.kt | 22 +- .../api/mediator/WalletItemRemoteMediator.kt | 26 +- .../data/api/model/WalletItemRemote.kt | 4 +- .../data/api/repository/CoinRestRepository.kt | 2 +- .../data/api/repository/DealRestRepository.kt | 8 +- .../data/api/repository/UserRestRepository.kt | 6 +- .../repository/WalletItemRestRepository.kt | 14 +- .../example/testapp/data/room/AppContainer.kt | 44 +++ .../example/testapp/data/room/dao/DealDao.kt | 5 +- .../testapp/data/room/dao/RemoteKeysDao.kt | 6 +- .../example/testapp/data/room/dao/UserDao.kt | 7 +- .../testapp/data/room/dao/WalletItemDao.kt | 2 +- .../data/room/database/CryptoDealDb.kt | 42 +-- .../example/testapp/data/room/models/Deal.kt | 6 + .../testapp/data/room/models/WalletItem.kt | 20 +- .../repository/basic/RemoteKeyRepository.kt | 2 +- .../offline/OfflineRemoteKeysRepository.kt | 2 +- .../offline/OfflineUserRepository.kt | 7 +- .../offline/OfflineWalletItemRepository.kt | 2 +- .../com/example/testapp/designElem/NavBar.kt | 6 +- .../testapp/designElem/SharedViewModel.kt | 24 -- .../example/testapp/graphs/HomeNavGraph.kt | 12 +- .../example/testapp/graphs/RootNavGraph.kt | 7 +- .../testapp/navigate/BottomBarScreen.kt | 4 + .../testapp/screensMobile/AccountPage.kt | 78 ++--- .../testapp/screensMobile/CreateDeal.kt | 8 +- .../example/testapp/screensMobile/DealList.kt | 22 +- .../example/testapp/screensMobile/History.kt | 34 +- .../testapp/screensMobile/ReportScreen.kt | 294 ++++++++++++++++++ .../example/testapp/screensMobile/Wallet.kt | 34 +- .../viewModels/AppViewModelProvider.kt | 37 ++- .../viewModels/CurrentUserViewModel.kt | 5 +- .../testapp/viewModels/DealCreateViewModel.kt | 9 +- .../testapp/viewModels/DealListViewModel.kt | 14 +- .../viewModels/EntryScreenViewModel.kt | 3 +- .../testapp/viewModels/HistoryViewModel.kt | 20 +- .../viewModels/RegistrationScreenViewModel.kt | 3 +- .../testapp/viewModels/ReportViewModel.kt | 49 +++ .../testapp/viewModels/SharedViewModel.kt | 16 + .../testapp/viewModels/WalletViewModel.kt | 9 +- .../main/res/xml/network_security_config.xml | 6 + 43 files changed, 670 insertions(+), 265 deletions(-) delete mode 100644 app/src/main/java/com/example/testapp/designElem/SharedViewModel.kt create mode 100644 app/src/main/java/com/example/testapp/screensMobile/ReportScreen.kt create mode 100644 app/src/main/java/com/example/testapp/viewModels/ReportViewModel.kt create mode 100644 app/src/main/java/com/example/testapp/viewModels/SharedViewModel.kt create mode 100644 app/src/main/res/xml/network_security_config.xml diff --git a/app/src/main/java/com/example/testapp/MainActivity.kt b/app/src/main/java/com/example/testapp/MainActivity.kt index 34a39dd..7051b8e 100644 --- a/app/src/main/java/com/example/testapp/MainActivity.kt +++ b/app/src/main/java/com/example/testapp/MainActivity.kt @@ -8,7 +8,7 @@ import androidx.activity.viewModels import androidx.annotation.RequiresApi import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.rememberNavController -import com.example.testapp.designElem.SharedViewModel +import com.example.testapp.viewModels.SharedViewModel import com.example.testapp.graphs.RootNavigationGraph import com.example.testapp.ui.theme.TestAppTheme import com.example.testapp.viewModels.AppViewModelProvider diff --git a/app/src/main/java/com/example/testapp/data/api/CryptoDealService.kt b/app/src/main/java/com/example/testapp/data/api/CryptoDealService.kt index 3f1c10c..bfa4ef6 100644 --- a/app/src/main/java/com/example/testapp/data/api/CryptoDealService.kt +++ b/app/src/main/java/com/example/testapp/data/api/CryptoDealService.kt @@ -63,7 +63,7 @@ interface DealRequests { @DELETE("deals/{id}") suspend fun deleteDeal(@Path("id") id: Int): DealRemote - @GET("p_deals") + @GET("deals") suspend fun pagingDeals( @Query("_page") page: Int, @Query("_limit") limit: Int @@ -81,7 +81,7 @@ interface CoinRequests { /** * Coin Request interface */ - @GET("") + @GET("coins") suspend fun getCoins(): List } @@ -95,13 +95,13 @@ interface WalletItemRequests { @POST("wal_item") suspend fun insert(@Body obj: WalletItemRemote): WalletItemRemote - @PUT("wal_item") - suspend fun update(@Body obj: WalletItemRemote): WalletItemRemote + @PUT("wal_item/{id}") + suspend fun update(@Path("id") id: Int, @Body obj: WalletItemRemote): WalletItemRemote @DELETE("wal_item/{id}") suspend fun deleteWalletItem(@Path("id") id: Int): WalletItemRemote - @GET("p_wal_item") + @GET("wal_item") suspend fun pagingWalletItems( @Query("_page") page: Int, @Query("_limit") limit: Int @@ -110,7 +110,7 @@ interface WalletItemRequests { interface CryptoDealService : UserRequests, DealRequests, CoinRequests, WalletItemRequests { companion object { - private const val BASE_URL = "http://10.0.2.2:8079/" + private const val BASE_URL = "http://172.20.10.13:8079/" @Volatile private var INSTANCE: CryptoDealService? = null diff --git a/app/src/main/java/com/example/testapp/data/api/mediator/DealRemoteMediator.kt b/app/src/main/java/com/example/testapp/data/api/mediator/DealRemoteMediator.kt index 52a50d9..28d3a77 100644 --- a/app/src/main/java/com/example/testapp/data/api/mediator/DealRemoteMediator.kt +++ b/app/src/main/java/com/example/testapp/data/api/mediator/DealRemoteMediator.kt @@ -49,8 +49,8 @@ class DealRemoteMediator( } try { - val articles = service.pagingDeals(page, state.config.pageSize).map { it.toDeal() } - val endOfPaginationReached = articles.isEmpty() + val deals = service.pagingDeals(page, state.config.pageSize).map { it.toDeal() } + val endOfPaginationReached = deals.isEmpty() database.withTransaction { if (loadType == LoadType.REFRESH) { dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.DEAL) @@ -58,18 +58,16 @@ class DealRemoteMediator( } val prevKey = if (page == 1) null else page - 1 val nextKey = if (endOfPaginationReached) null else page + 1 - val keys = articles.map { - it.id?.let { it1 -> - RemoteKeys( - entityId = it1, - type = RemoteKeyType.DEAL, - prevKey = prevKey, - nextKey = nextKey - ) - } + val keys = deals.map { + RemoteKeys( + entityId = it.id!!, + type = RemoteKeyType.DEAL, + prevKey = prevKey, + nextKey = nextKey + ) } dbRemoteKeyRepository.createRemoteKeys(keys) - dbDealRepository.insert(articles) + dbDealRepository.insert(deals) } return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached) } catch (exception: IOException) { diff --git a/app/src/main/java/com/example/testapp/data/api/mediator/WalletItemRemoteMediator.kt b/app/src/main/java/com/example/testapp/data/api/mediator/WalletItemRemoteMediator.kt index 5ec5195..19a8196 100644 --- a/app/src/main/java/com/example/testapp/data/api/mediator/WalletItemRemoteMediator.kt +++ b/app/src/main/java/com/example/testapp/data/api/mediator/WalletItemRemoteMediator.kt @@ -59,14 +59,12 @@ class WalletItemRemoteMediator( val prevKey = if (page == 1) null else page - 1 val nextKey = if (endOfPaginationReached) null else page + 1 val keys = articles.map { - it.id?.let { it1 -> - RemoteKeys( - entityId = it1, - type = RemoteKeyType.WALLETITEM, - prevKey = prevKey, - nextKey = nextKey - ) - } + RemoteKeys( + entityId = it.id!!, + type = RemoteKeyType.WALLETITEM, + prevKey = prevKey, + nextKey = nextKey + ) } dbRemoteKeyRepository.createRemoteKeys(keys) dbWalletItemRepository.insert(articles) @@ -81,15 +79,15 @@ class WalletItemRemoteMediator( private suspend fun getRemoteKeyForLastItem(state: PagingState): RemoteKeys? { return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull() - ?.let { art -> - art.id?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.WALLETITEM) } + ?.let { item -> + item.id!!.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.WALLETITEM) } } } private suspend fun getRemoteKeyForFirstItem(state: PagingState): RemoteKeys? { return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull() - ?.let { art -> - art.id?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.WALLETITEM) } + ?.let { item -> + item.id!!.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.WALLETITEM) } } } @@ -97,8 +95,8 @@ class WalletItemRemoteMediator( state: PagingState ): RemoteKeys? { return state.anchorPosition?.let { position -> - state.closestItemToPosition(position)?.id?.let { artid -> - dbRemoteKeyRepository.getAllRemoteKeys(artid, RemoteKeyType.WALLETITEM) + state.closestItemToPosition(position)?.id?.let { itemId -> + dbRemoteKeyRepository.getAllRemoteKeys(itemId, RemoteKeyType.WALLETITEM) } } } diff --git a/app/src/main/java/com/example/testapp/data/api/model/WalletItemRemote.kt b/app/src/main/java/com/example/testapp/data/api/model/WalletItemRemote.kt index 2e12c6c..2dfc804 100644 --- a/app/src/main/java/com/example/testapp/data/api/model/WalletItemRemote.kt +++ b/app/src/main/java/com/example/testapp/data/api/model/WalletItemRemote.kt @@ -5,11 +5,11 @@ import kotlinx.serialization.Serializable @Serializable data class WalletItemRemote( - val id: Int?, + val id: Int, val coinId: Int, val userId: Int, var count: Float, ) fun WalletItemRemote.toWalletItem(): WalletItem = WalletItem(id, coinId, userId, count) -fun WalletItem.toRemote(): WalletItemRemote = WalletItemRemote(id, coinId, userId, count) \ No newline at end of file +fun WalletItem.toRemote(): WalletItemRemote = WalletItemRemote(id!!, coinId, userId, count) \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/data/api/repository/CoinRestRepository.kt b/app/src/main/java/com/example/testapp/data/api/repository/CoinRestRepository.kt index cbed51d..ba3b53e 100644 --- a/app/src/main/java/com/example/testapp/data/api/repository/CoinRestRepository.kt +++ b/app/src/main/java/com/example/testapp/data/api/repository/CoinRestRepository.kt @@ -10,7 +10,7 @@ class CoinRestRepository( private val service: CryptoDealService, private val dbCoinRepository: OfflineCoinRepository ) : CoinRepository { - override suspend fun insert(x: Coin) { + override suspend fun insert(vararg x: Coin) { TODO("Not yet implemented") } diff --git a/app/src/main/java/com/example/testapp/data/api/repository/DealRestRepository.kt b/app/src/main/java/com/example/testapp/data/api/repository/DealRestRepository.kt index 35f1399..d359bf2 100644 --- a/app/src/main/java/com/example/testapp/data/api/repository/DealRestRepository.kt +++ b/app/src/main/java/com/example/testapp/data/api/repository/DealRestRepository.kt @@ -46,6 +46,10 @@ class DealRestRepository( return service.completeDeal(deal.id!!, sellerId, buyerId) } + override suspend fun clearData() { + TODO("Not yet implemented") + } + override fun pagingData(): Flow> { val pagingSourceFactory = { dbDealRepository.getAllPagingData() } @@ -69,8 +73,8 @@ class DealRestRepository( TODO("Not yet implemented") } - override suspend fun insert(x: Deal) { - service.insert(x.toRemote()) + override suspend fun insert(vararg x: Deal) { + x.forEach {y -> service.insert(y.toRemote()) } } override suspend fun update(x: Deal) { diff --git a/app/src/main/java/com/example/testapp/data/api/repository/UserRestRepository.kt b/app/src/main/java/com/example/testapp/data/api/repository/UserRestRepository.kt index 4005ac8..f565709 100644 --- a/app/src/main/java/com/example/testapp/data/api/repository/UserRestRepository.kt +++ b/app/src/main/java/com/example/testapp/data/api/repository/UserRestRepository.kt @@ -61,8 +61,10 @@ class UserRestRepository( return existArticles.map { it.value }.sortedBy { it.id } } - override suspend fun insert(x: User) { - service.insert(x.toRemote()) + override suspend fun insert(vararg x: User) { + x.forEach { user -> + service.insert(user.toRemote()) + } } override suspend fun update(x: User) { diff --git a/app/src/main/java/com/example/testapp/data/api/repository/WalletItemRestRepository.kt b/app/src/main/java/com/example/testapp/data/api/repository/WalletItemRestRepository.kt index 385e200..826a3e3 100644 --- a/app/src/main/java/com/example/testapp/data/api/repository/WalletItemRestRepository.kt +++ b/app/src/main/java/com/example/testapp/data/api/repository/WalletItemRestRepository.kt @@ -24,7 +24,7 @@ class WalletItemRestRepository( private val database: CryptoDealDb ) : WalletItemRepository { override fun getUserWallet(id: Int): List { - TODO("Not yet implemented") + return dbWalletItemRepository.getUserWallet(id) } override fun pagingData(id: Int): Flow> { @@ -50,16 +50,20 @@ class WalletItemRestRepository( TODO("Not yet implemented") } - override suspend fun insert(x: WalletItem) { - service.insert(x.toRemote()) + override suspend fun clearData() { + TODO("Not yet implemented") + } + + override suspend fun insert(vararg x: WalletItem) { + x.forEach {y -> service.insert(y.toRemote()) } } override suspend fun update(x: WalletItem) { - service.update(x.toRemote()) + service.update(x.id!!, x.toRemote()) } override suspend fun delete(x: WalletItem) { - x.id?.let { service.deleteWalletItem(it) } + x.id.let { service.deleteWalletItem(it!!) } } override suspend fun getById(id: Int): WalletItem { diff --git a/app/src/main/java/com/example/testapp/data/room/AppContainer.kt b/app/src/main/java/com/example/testapp/data/room/AppContainer.kt index b167f9d..68b80a2 100644 --- a/app/src/main/java/com/example/testapp/data/room/AppContainer.kt +++ b/app/src/main/java/com/example/testapp/data/room/AppContainer.kt @@ -1,6 +1,11 @@ package com.example.testapp.data.room import android.content.Context +import com.example.testapp.data.api.CryptoDealService +import com.example.testapp.data.api.repository.CoinRestRepository +import com.example.testapp.data.api.repository.DealRestRepository +import com.example.testapp.data.api.repository.UserRestRepository +import com.example.testapp.data.api.repository.WalletItemRestRepository import com.example.testapp.data.room.database.CryptoDealDb import com.example.testapp.data.room.repository.basic.CoinRepository import com.example.testapp.data.room.repository.basic.DealRepository @@ -8,6 +13,7 @@ import com.example.testapp.data.room.repository.basic.UserRepository import com.example.testapp.data.room.repository.basic.WalletItemRepository import com.example.testapp.data.room.repository.offline.OfflineCoinRepository import com.example.testapp.data.room.repository.offline.OfflineDealRepository +import com.example.testapp.data.room.repository.offline.OfflineRemoteKeyRepository import com.example.testapp.data.room.repository.offline.OfflineUserRepository import com.example.testapp.data.room.repository.offline.OfflineWalletItemRepository @@ -17,6 +23,11 @@ interface AppContainer { val coinRepository: CoinRepository val walletItemRepository: WalletItemRepository + val coinRestRepository: CoinRestRepository + val dealRestRepository: DealRestRepository + val userRestRepository: UserRestRepository + val walletItemRestRepository: WalletItemRestRepository + companion object { const val TIMEOUT = 5000L const val LIMIT = 10 @@ -26,6 +37,9 @@ interface AppContainer { class AppDataContainer( private val context: Context ) : AppContainer { + private val remoteKeyRepository: OfflineRemoteKeyRepository by lazy { + OfflineRemoteKeyRepository(CryptoDealDb.getInstance(context).remoteKeysDao()) + } override val userRepository: UserRepository by lazy { OfflineUserRepository(CryptoDealDb.getInstance(context).userDao()) } @@ -38,4 +52,34 @@ class AppDataContainer( override val walletItemRepository: WalletItemRepository by lazy { OfflineWalletItemRepository(CryptoDealDb.getInstance(context).walletItemDao()) } + override val userRestRepository: UserRestRepository by lazy { + UserRestRepository( + CryptoDealService.getInstance(), + userRepository as OfflineUserRepository, + dealRepository as OfflineDealRepository, + walletItemRepository + ) + } + override val coinRestRepository: CoinRestRepository by lazy { + CoinRestRepository( + CryptoDealService.getInstance(), + coinRepository as OfflineCoinRepository + ) + } + override val dealRestRepository: DealRestRepository by lazy { + DealRestRepository( + CryptoDealService.getInstance(), + dealRepository as OfflineDealRepository, + remoteKeyRepository, + CryptoDealDb.getInstance(context) + ) + } + override val walletItemRestRepository: WalletItemRestRepository by lazy { + WalletItemRestRepository( + CryptoDealService.getInstance(), + walletItemRepository as OfflineWalletItemRepository, + remoteKeyRepository, + CryptoDealDb.getInstance(context) + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/data/room/dao/DealDao.kt b/app/src/main/java/com/example/testapp/data/room/dao/DealDao.kt index f66c54f..4045727 100644 --- a/app/src/main/java/com/example/testapp/data/room/dao/DealDao.kt +++ b/app/src/main/java/com/example/testapp/data/room/dao/DealDao.kt @@ -20,7 +20,10 @@ interface DealDao : IDao { @Query("select * from deal where deal.buyerId = :idUser OR deal.sellerId = :idUser") fun getUserDeals(idUser: Int): Flow> - @Query("SELECT * FROM deal where deal.date IS NULL ORDER BY id ASC") + @Query("SELECT * FROM deal WHERE deal.buyerId = :idUser AND deal.date IS NULL OR deal.sellerId = :idUser") + fun getUserDealsPaging(idUser: Int): PagingSource + + @Query("SELECT * FROM deal ORDER BY id ASC") fun getDeals(): PagingSource @Query("DELETE FROM deal") diff --git a/app/src/main/java/com/example/testapp/data/room/dao/RemoteKeysDao.kt b/app/src/main/java/com/example/testapp/data/room/dao/RemoteKeysDao.kt index 9396edd..cb4ada6 100644 --- a/app/src/main/java/com/example/testapp/data/room/dao/RemoteKeysDao.kt +++ b/app/src/main/java/com/example/testapp/data/room/dao/RemoteKeysDao.kt @@ -1,17 +1,19 @@ package com.example.testapp.data.room.dao +import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import com.example.testapp.data.room.models.RemoteKeyType import com.example.testapp.data.room.models.RemoteKeys -interface RemoteKeysDao { +@Dao +interface RemoteKeysDao: IDao { @Query("SELECT * FROM remote_keys WHERE entityId = :entityId AND type = :type") suspend fun getRemoteKeys(entityId: Int, type: RemoteKeyType): RemoteKeys? @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertAll(remoteKey: List) + suspend fun insertAll(remoteKey: List) @Query("DELETE FROM remote_keys WHERE type = :type") suspend fun clearRemoteKeys(type: RemoteKeyType) diff --git a/app/src/main/java/com/example/testapp/data/room/dao/UserDao.kt b/app/src/main/java/com/example/testapp/data/room/dao/UserDao.kt index 8e7fae6..d2ca1bb 100644 --- a/app/src/main/java/com/example/testapp/data/room/dao/UserDao.kt +++ b/app/src/main/java/com/example/testapp/data/room/dao/UserDao.kt @@ -5,19 +5,18 @@ import androidx.room.Query import com.example.testapp.data.room.models.Deal import com.example.testapp.data.room.models.User import com.example.testapp.data.room.models.WalletItem -import kotlinx.coroutines.flow.Flow @Dao interface UserDao : IDao { @Query("select * from user") - fun getAll(): Flow> + fun getAll(): List @Query("select * from user where user.id = :idUser") fun getUserById(idUser: Int): User @Query("select * from walletitem where walletitem.userId = :idUser") - fun getUserWallet(idUser: Int): Flow> + fun getUserWallet(idUser: Int): List @Query("select * from deal where deal.buyerId = :idUser OR deal.sellerId = :idUser") - fun getUserDeals(idUser: Int): Flow> + fun getUserDeals(idUser: Int): List } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/data/room/dao/WalletItemDao.kt b/app/src/main/java/com/example/testapp/data/room/dao/WalletItemDao.kt index 80a0459..9bf46e3 100644 --- a/app/src/main/java/com/example/testapp/data/room/dao/WalletItemDao.kt +++ b/app/src/main/java/com/example/testapp/data/room/dao/WalletItemDao.kt @@ -17,7 +17,7 @@ interface WalletItemDao : IDao { fun getUserWallet(id: Int): List @Query("SELECT * FROM walletitem where walletitem.userId = :id ORDER BY walletitem.coinId ASC") - fun getDeals(id: Int): PagingSource + fun getWallet(id: Int): PagingSource @Query("DELETE FROM walletitem") suspend fun deleteAll() diff --git a/app/src/main/java/com/example/testapp/data/room/database/CryptoDealDb.kt b/app/src/main/java/com/example/testapp/data/room/database/CryptoDealDb.kt index 1cc3673..a5fb58f 100644 --- a/app/src/main/java/com/example/testapp/data/room/database/CryptoDealDb.kt +++ b/app/src/main/java/com/example/testapp/data/room/database/CryptoDealDb.kt @@ -24,10 +24,10 @@ abstract class CryptoDealDb: RoomDatabase() { abstract fun coinDao(): CoinDao; abstract fun dealDao(): DealDao; abstract fun walletItemDao(): WalletItemDao; - abstract fun RemoteKeysDao(): RemoteKeysDao; + abstract fun remoteKeysDao(): RemoteKeysDao; companion object { - private const val DB_NAME: String = "crypto-deal7" + private const val DB_NAME: String = "crypto-deal13" @Volatile private var INSTANCE: CryptoDealDb? = null @@ -57,25 +57,25 @@ abstract class CryptoDealDb: RoomDatabase() { coinDao.insert(c6) coinDao.insert(c7) - val walletItemDao = database.walletItemDao(); - val wi1 = WalletItem(0, 0, 0.5f); - val wi2 = WalletItem(1, 0, 0.6f); - val wi3 = WalletItem(3, 0, 0.7f); - val wi4 = WalletItem(0, 1, 1000f); - val wi5 = WalletItem(3, 1, 10f); - 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(wi2); - walletItemDao.insert(wi3); - walletItemDao.insert(wi4); - walletItemDao.insert(wi5); - walletItemDao.insert(wi6); - walletItemDao.insert(wi7); - walletItemDao.insert(wi8); - walletItemDao.insert(wi9); +// val walletItemDao = database.walletItemDao(); +// val wi1 = WalletItem(0, 0, 0.5f); +// val wi2 = WalletItem(1, 0, 0.6f); +// val wi3 = WalletItem(3, 0, 0.7f); +// val wi4 = WalletItem(0, 1, 1000f); +// val wi5 = WalletItem(3, 1, 10f); +// 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(wi2); +// walletItemDao.insert(wi3); +// walletItemDao.insert(wi4); +// walletItemDao.insert(wi5); +// walletItemDao.insert(wi6); +// walletItemDao.insert(wi7); +// walletItemDao.insert(wi8); +// walletItemDao.insert(wi9); val dealDao = database.dealDao(); val d1 = Deal(0, null, 0, 2, 0, 0.1f, 0.2f, "Buy", null, "TEST1") diff --git a/app/src/main/java/com/example/testapp/data/room/models/Deal.kt b/app/src/main/java/com/example/testapp/data/room/models/Deal.kt index 4f5eb1b..a3cf262 100644 --- a/app/src/main/java/com/example/testapp/data/room/models/Deal.kt +++ b/app/src/main/java/com/example/testapp/data/room/models/Deal.kt @@ -17,5 +17,11 @@ class Deal ( var date: Long?, val tip: String, ) { + override fun equals(other: Any?): Boolean { + return (other as Deal).id == this.id + } + override fun hashCode(): Int { + return id ?: -1 + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/data/room/models/WalletItem.kt b/app/src/main/java/com/example/testapp/data/room/models/WalletItem.kt index 2b9b172..2010695 100644 --- a/app/src/main/java/com/example/testapp/data/room/models/WalletItem.kt +++ b/app/src/main/java/com/example/testapp/data/room/models/WalletItem.kt @@ -2,20 +2,28 @@ package com.example.testapp.data.room.models import androidx.room.Entity import androidx.room.ForeignKey +import androidx.room.Index import androidx.room.PrimaryKey @Entity( - primaryKeys = ["coinId", "userId"], foreignKeys = [ ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["userId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE), ForeignKey(entity = Coin::class, parentColumns = ["id"], childColumns = ["coinId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE) - ] + ], + indices = [Index(value = ["coinId", "userId"])] ) class WalletItem ( - @PrimaryKey(autoGenerate = true) - val id: Int?, + @PrimaryKey(autoGenerate = true) val id: Int?, val coinId: Int, val userId: Int, var count: Float, -// val freeze: Float -) \ No newline at end of file +) { + override fun equals(other: Any?): Boolean { + other as WalletItem + return other.coinId == this.coinId && other.userId == this.userId + } + + override fun hashCode(): Int { + return id!! + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/data/room/repository/basic/RemoteKeyRepository.kt b/app/src/main/java/com/example/testapp/data/room/repository/basic/RemoteKeyRepository.kt index 16bf74a..59f72ed 100644 --- a/app/src/main/java/com/example/testapp/data/room/repository/basic/RemoteKeyRepository.kt +++ b/app/src/main/java/com/example/testapp/data/room/repository/basic/RemoteKeyRepository.kt @@ -5,6 +5,6 @@ import com.example.testapp.data.room.models.RemoteKeys interface RemoteKeyRepository { suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType): RemoteKeys? - suspend fun createRemoteKeys(remoteKeys: List) + suspend fun createRemoteKeys(remoteKeys: List) suspend fun deleteRemoteKey(type: RemoteKeyType) } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineRemoteKeysRepository.kt b/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineRemoteKeysRepository.kt index 768eed9..0bcd99a 100644 --- a/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineRemoteKeysRepository.kt +++ b/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineRemoteKeysRepository.kt @@ -9,7 +9,7 @@ class OfflineRemoteKeyRepository(private val remoteKeysDao: RemoteKeysDao) : Rem override suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType) = remoteKeysDao.getRemoteKeys(id, type) - override suspend fun createRemoteKeys(remoteKeys: List) = + override suspend fun createRemoteKeys(remoteKeys: List) = remoteKeysDao.insertAll(remoteKeys) override suspend fun deleteRemoteKey(type: RemoteKeyType) = diff --git a/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineUserRepository.kt b/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineUserRepository.kt index a82483c..b85c5bb 100644 --- a/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineUserRepository.kt +++ b/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineUserRepository.kt @@ -5,13 +5,12 @@ import com.example.testapp.data.room.models.Deal import com.example.testapp.data.room.models.User import com.example.testapp.data.room.models.WalletItem import com.example.testapp.data.room.repository.basic.UserRepository -import kotlinx.coroutines.flow.Flow class OfflineUserRepository( private val userDao: UserDao ) : OfflineRepository(userDao), UserRepository { - override suspend fun getAll(): Flow> = userDao.getAll() + override suspend fun getAll(): List = userDao.getAll() override suspend fun getById(id: Int): User = userDao.getUserById(id) - override suspend fun getUserWallet(id: Int): Flow> = userDao.getUserWallet(id) - override suspend fun getUserDeals(id: Int): Flow> = userDao.getUserDeals(id) + override suspend fun getUserWallet(id: Int): List = userDao.getUserWallet(id) + override suspend fun getUserDeals(id: Int): List = userDao.getUserDeals(id) } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineWalletItemRepository.kt b/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineWalletItemRepository.kt index 43da4b6..730e559 100644 --- a/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineWalletItemRepository.kt +++ b/app/src/main/java/com/example/testapp/data/room/repository/offline/OfflineWalletItemRepository.kt @@ -21,7 +21,7 @@ class OfflineWalletItemRepository( pageSize = 10, jumpThreshold = 10, initialLoadSize = 10 ), pagingSourceFactory = { WalletPagination(walletItemDao, id) }, initialKey = 1).flow - override fun getWalletItemsPaging(id: Int): PagingSource = walletItemDao.getDeals(id) + override fun getWalletItemsPaging(id: Int): PagingSource = walletItemDao.getWallet(id) override suspend fun clearData() = walletItemDao.deleteAll() suspend fun insert(list: List) = walletItemDao.insert(*list.toTypedArray()) } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/designElem/NavBar.kt b/app/src/main/java/com/example/testapp/designElem/NavBar.kt index 03be17e..74a3130 100644 --- a/app/src/main/java/com/example/testapp/designElem/NavBar.kt +++ b/app/src/main/java/com/example/testapp/designElem/NavBar.kt @@ -1,7 +1,6 @@ package com.example.pmulabs.designElem import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.shrinkHorizontally import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -11,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredWidth -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.NavigationBar import androidx.compose.material3.Text @@ -21,7 +19,6 @@ 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.text.toUpperCase import androidx.compose.ui.unit.dp import androidx.navigation.NavController import androidx.navigation.NavDestination @@ -30,7 +27,6 @@ import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import com.example.testapp.navigate.BottomBarScreen -import java.util.Locale @Composable fun NavBar(navController: NavHostController){ @@ -84,7 +80,7 @@ fun AddItem( .clickable(onClick = { navController.navigate(screen.route) { popUpTo(navController.graph.findStartDestination().id) - launchSingleTop = false + launchSingleTop = true } }) .clip(shape = RoundedCornerShape(10.dp)) diff --git a/app/src/main/java/com/example/testapp/designElem/SharedViewModel.kt b/app/src/main/java/com/example/testapp/designElem/SharedViewModel.kt deleted file mode 100644 index 1f5e737..0000000 --- a/app/src/main/java/com/example/testapp/designElem/SharedViewModel.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.testapp.designElem - -import androidx.compose.runtime.mutableStateOf -import androidx.lifecycle.ViewModel - -class SharedViewModel : ViewModel() { - val argument = mutableStateOf(null) - val argument_edit = mutableStateOf(null) - val argument_add_f = mutableStateOf(null) - val argument_add_c = mutableStateOf(null) - - fun setArgumentAdd(arg1: Any, arg2: Any) { - argument_add_f.value = arg1 - argument_add_c.value = arg2 - } - - fun setArgumentEdit(arg: Any?) { - argument_edit.value = arg - } - - fun setArgument(arg: String) { - argument.value = arg - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/graphs/HomeNavGraph.kt b/app/src/main/java/com/example/testapp/graphs/HomeNavGraph.kt index cd7d957..924b306 100644 --- a/app/src/main/java/com/example/testapp/graphs/HomeNavGraph.kt +++ b/app/src/main/java/com/example/testapp/graphs/HomeNavGraph.kt @@ -6,18 +6,20 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable -import com.example.testapp.designElem.SharedViewModel import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.screensMobile.AccountPage import com.example.testapp.screensMobile.CreateDeal import com.example.testapp.screensMobile.DealList import com.example.testapp.screensMobile.History +import com.example.testapp.screensMobile.ReportScreen import com.example.testapp.screensMobile.Wallet import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.DealCreateViewModel import com.example.testapp.viewModels.DealListViewModel import com.example.testapp.viewModels.HistoryViewModel +import com.example.testapp.viewModels.ReportViewModel +import com.example.testapp.viewModels.SharedViewModel import com.example.testapp.viewModels.WalletViewModel @RequiresApi(34) @@ -29,6 +31,7 @@ fun HomeNavGraph( dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory), historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory), walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory), + reportViewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory), sharedViewModel: SharedViewModel ) { NavHost( @@ -72,5 +75,12 @@ fun HomeNavGraph( historyViewModel = historyViewModel ) } + composable(route = BottomBarScreen.Report.route) { + ReportScreen( + navController = navController, + currentUserViewModel = currentUserViewModel, + reportViewModel = reportViewModel + ) + } } } diff --git a/app/src/main/java/com/example/testapp/graphs/RootNavGraph.kt b/app/src/main/java/com/example/testapp/graphs/RootNavGraph.kt index 3450123..ee1dd40 100644 --- a/app/src/main/java/com/example/testapp/graphs/RootNavGraph.kt +++ b/app/src/main/java/com/example/testapp/graphs/RootNavGraph.kt @@ -8,7 +8,6 @@ import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.navArgument -import com.example.testapp.designElem.SharedViewModel import com.example.testapp.screensMobile.LoadScreen import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.CurrentUserViewModel @@ -17,6 +16,8 @@ import com.example.testapp.viewModels.DealListViewModel import com.example.testapp.viewModels.EntryScreenViewModel import com.example.testapp.viewModels.HistoryViewModel import com.example.testapp.viewModels.RegistrationScreenViewModel +import com.example.testapp.viewModels.ReportViewModel +import com.example.testapp.viewModels.SharedViewModel import com.example.testapp.viewModels.WalletViewModel const val USERID_ARGUMENT = "userId" @@ -32,6 +33,7 @@ fun RootNavigationGraph( historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory), registrationScreenViewModel: RegistrationScreenViewModel = viewModel(factory = AppViewModelProvider.Factory), walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory), + reportViewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory), sharedViewModel: SharedViewModel ) { NavHost( @@ -57,7 +59,8 @@ fun RootNavigationGraph( dealListViewModel = dealListViewModel, historyViewModel = historyViewModel, walletViewModel = walletViewModel, - sharedViewModel = sharedViewModel + sharedViewModel = sharedViewModel, + reportViewModel = reportViewModel ) } } diff --git a/app/src/main/java/com/example/testapp/navigate/BottomBarScreen.kt b/app/src/main/java/com/example/testapp/navigate/BottomBarScreen.kt index d5c214c..eb6b0c6 100644 --- a/app/src/main/java/com/example/testapp/navigate/BottomBarScreen.kt +++ b/app/src/main/java/com/example/testapp/navigate/BottomBarScreen.kt @@ -20,6 +20,10 @@ sealed class BottomBarScreen( route = "HISTORY", title = "History" ) + object Report: BottomBarScreen( + route = "REPORT", + title = "Report" + ) object CDEAL: BottomBarScreen( route = "CDEAL", title = "CDEAL" diff --git a/app/src/main/java/com/example/testapp/screensMobile/AccountPage.kt b/app/src/main/java/com/example/testapp/screensMobile/AccountPage.kt index b5e01ba..7a7e965 100644 --- a/app/src/main/java/com/example/testapp/screensMobile/AccountPage.kt +++ b/app/src/main/java/com/example/testapp/screensMobile/AccountPage.kt @@ -1,6 +1,8 @@ package com.example.testapp.screensMobile import android.annotation.SuppressLint +import android.os.Build +import androidx.annotation.RequiresApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -17,17 +19,18 @@ import androidx.compose.foundation.layout.requiredWidth import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.Fingerprint +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope 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.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign @@ -36,11 +39,12 @@ import androidx.compose.ui.unit.em import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController -import androidx.navigation.NavGraph.Companion.findStartDestination -import com.example.testapp.graphs.AuthScreen +import com.example.testapp.R +import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.CurrentUserViewModel +@RequiresApi(Build.VERSION_CODES.O) @SuppressLint("CoroutineCreationDuringComposition") @Composable fun AccountPage( @@ -122,8 +126,7 @@ fun AccountPage( y = 204.dp ) ) { - Property1Switch(modifier = Modifier.padding(vertical = 5.dp)) - Property1Arrow(modifier = Modifier.padding(vertical = 5.dp)) + Property1Arrow(modifier = Modifier.padding(vertical = 5.dp), navController) } Property1Clear(navController = navController) Property1( @@ -137,46 +140,6 @@ fun AccountPage( } } -@Composable -fun Property1Switch(modifier: Modifier = Modifier) { - Row( - horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally), - verticalAlignment = Alignment.CenterVertically, - modifier = modifier - .background(color = Color.White) - .padding( - start = 12.dp, - end = 16.dp, - top = 4.dp, - bottom = 4.dp - ) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .padding(all = 12.dp) - ) { -// Icon( -// painter = painterResource(id = R.drawable.sizem), -// contentDescription = "IconFavorite", -// tint = Color(0xff002033).copy(alpha = 0.35f)) - } - Text( - text = "Enable Notifications", - color = Color(0xff0b1f33), - lineHeight = 1.25.em, - style = TextStyle( - fontSize = 16.sp, - letterSpacing = 0.1.sp - ), - modifier = Modifier - .weight(weight = 1f) - .wrapContentHeight(align = Alignment.CenterVertically) - ) - Viewchecked() - } -} - @Composable fun Container(modifier: Modifier = Modifier, name: String) { Column( @@ -231,7 +194,7 @@ fun Viewchecked(modifier: Modifier = Modifier) { } @Composable -fun Property1Arrow(modifier: Modifier = Modifier) { +fun Property1Arrow(modifier: Modifier = Modifier, navController: NavController) { Row( horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally), verticalAlignment = Alignment.CenterVertically, @@ -243,19 +206,22 @@ fun Property1Arrow(modifier: Modifier = Modifier) { top = 4.dp, bottom = 4.dp ) + .clickable { + navController.navigate(route = BottomBarScreen.Report.route) + } ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .padding(all = 12.dp) ) { -// Icon( -// painter = painterResource(id = R.drawable.sizem), -// contentDescription = "IconFavorite", -// tint = Color(0xff002033).copy(alpha = 0.35f)) + Icon( + Icons.Rounded.Fingerprint, + contentDescription = stringResource(id = R.string.app_name) + ) } Text( - text = "Confirm Account", + text = "Report", color = Color(0xff0b1f33), lineHeight = 1.25.em, style = TextStyle( @@ -275,12 +241,6 @@ fun Property1Clear(modifier: Modifier = Modifier, navController: NavController) modifier = modifier .fillMaxSize() .clip(shape = RoundedCornerShape(10.dp)) - .clickable { - navController.navigate(route = AuthScreen.Entry.route) { - popUpTo(navController.graph.findStartDestination().id) - launchSingleTop = true - } - } .padding( start = 16.dp, end = 16.dp, diff --git a/app/src/main/java/com/example/testapp/screensMobile/CreateDeal.kt b/app/src/main/java/com/example/testapp/screensMobile/CreateDeal.kt index 156dbd6..d5125bd 100644 --- a/app/src/main/java/com/example/testapp/screensMobile/CreateDeal.kt +++ b/app/src/main/java/com/example/testapp/screensMobile/CreateDeal.kt @@ -39,16 +39,16 @@ import androidx.compose.ui.unit.em import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController -import com.example.testapp.designElem.DropDown -import com.example.testapp.designElem.DropDownConfig -import com.example.testapp.designElem.SharedViewModel -import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.data.room.models.Coin import com.example.testapp.data.room.models.Deal import com.example.testapp.data.room.models.WalletItem +import com.example.testapp.designElem.DropDown +import com.example.testapp.designElem.DropDownConfig +import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.DealCreateViewModel +import com.example.testapp.viewModels.SharedViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/example/testapp/screensMobile/DealList.kt b/app/src/main/java/com/example/testapp/screensMobile/DealList.kt index c1808b9..d6c1122 100644 --- a/app/src/main/java/com/example/testapp/screensMobile/DealList.kt +++ b/app/src/main/java/com/example/testapp/screensMobile/DealList.kt @@ -43,7 +43,7 @@ import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import androidx.paging.LoadState import androidx.paging.compose.collectAsLazyPagingItems -import com.example.testapp.designElem.SharedViewModel +import com.example.testapp.viewModels.SharedViewModel import com.example.testapp.navigate.BottomBarScreen import com.example.testapp.data.room.models.Coin import com.example.testapp.data.room.models.Deal @@ -98,16 +98,16 @@ fun DealList( } 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.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) } diff --git a/app/src/main/java/com/example/testapp/screensMobile/History.kt b/app/src/main/java/com/example/testapp/screensMobile/History.kt index 95fb520..cfe242d 100644 --- a/app/src/main/java/com/example/testapp/screensMobile/History.kt +++ b/app/src/main/java/com/example/testapp/screensMobile/History.kt @@ -6,15 +6,15 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -34,6 +34,7 @@ import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController +import androidx.paging.compose.collectAsLazyPagingItems import com.example.testapp.data.room.models.Coin import com.example.testapp.data.room.models.Deal import com.example.testapp.viewModels.AppViewModelProvider @@ -53,26 +54,31 @@ fun History( ) { val user by currentUserViewModel.user.collectAsState() val id = user!!.id - historyViewModel.setArgument(id.toString()); - val history by historyViewModel.deals.collectAsState() + historyViewModel.setArgument(id.toString()) + val history = historyViewModel.deals.collectAsLazyPagingItems() val coins by historyViewModel.coins.collectAsState() - Column( + LazyColumn( verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.Top), horizontalAlignment = Alignment.CenterHorizontally, + contentPadding = PaddingValues(bottom = 70.dp), modifier = modifier - .requiredHeight(height = 720.dp) .background(color = Color(0xfff4f7fb)) .padding(vertical = 20.dp) - .verticalScroll(rememberScrollState()) + .fillMaxSize() ) { - PropertyHistory() - history.forEach { x -> - HistoryCard( - deal = x, - modifier = Modifier.padding(vertical = 5.dp, horizontal = 5.dp), - coins = coins - ) + item { + PropertyHistory() + } + items(count = history.itemCount) { + val item = history[it] + if (item != null) { + HistoryCard( + deal = item, + modifier = Modifier.padding(vertical = 5.dp, horizontal = 5.dp), + coins = coins + ) + } } } } diff --git a/app/src/main/java/com/example/testapp/screensMobile/ReportScreen.kt b/app/src/main/java/com/example/testapp/screensMobile/ReportScreen.kt new file mode 100644 index 0000000..210d1b9 --- /dev/null +++ b/app/src/main/java/com/example/testapp/screensMobile/ReportScreen.kt @@ -0,0 +1,294 @@ +package com.example.testapp.screensMobile + +import android.annotation.SuppressLint +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredHeight +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.DatePicker +import androidx.compose.material3.DatePickerDialog +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.rememberDatePickerState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +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.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.em +import androidx.compose.ui.unit.sp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController +import com.example.testapp.data.room.models.Coin +import com.example.testapp.data.room.models.Deal +import com.example.testapp.navigate.BottomBarScreen +import com.example.testapp.viewModels.AppViewModelProvider +import com.example.testapp.viewModels.CurrentUserViewModel +import com.example.testapp.viewModels.ReportViewModel +import java.time.Instant +import java.time.LocalDateTime +import java.time.ZoneOffset + +@RequiresApi(Build.VERSION_CODES.O) +fun longToDate(value: Long): LocalDateTime { + return LocalDateTime + .ofInstant(Instant.ofEpochMilli(value), ZoneOffset.UTC) +} + +@OptIn(ExperimentalMaterial3Api::class) +@RequiresApi(Build.VERSION_CODES.O) +@SuppressLint("CoroutineCreationDuringComposition", "SimpleDateFormat") +@Composable +fun ReportScreen( + modifier: Modifier = Modifier, + navController: NavController, + currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory), + reportViewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory) +) { + reportViewModel.clearLists() + val user by currentUserViewModel.user.collectAsState() + val deals by reportViewModel.deals.collectAsState() + val coins by reportViewModel.coins.collectAsState() + + val dateStateFrom = rememberDatePickerState() + val showDialogFrom = rememberSaveable { mutableStateOf(false) } + + if (showDialogFrom.value) { + DatePickerDialog( + onDismissRequest = { showDialogFrom.value = false }, + confirmButton = { + TextButton(onClick = { showDialogFrom.value = false }) { + Text("Ok") + } + }, + dismissButton = { + TextButton(onClick = { showDialogFrom.value = false }) { + Text("Cancel") + } + } + ) { + DatePicker(state = dateStateFrom) + } + } + + val dateStateTo = rememberDatePickerState() + val showDialogTo = rememberSaveable { mutableStateOf(false) } + + if (showDialogTo.value) { + DatePickerDialog( + onDismissRequest = { showDialogTo.value = false }, + confirmButton = { + TextButton(onClick = { showDialogTo.value = false }) { + Text("Ok") + } + }, + dismissButton = { + TextButton(onClick = { showDialogTo.value = false }) { + Text("Cancel") + } + } + ) { + DatePicker(state = dateStateTo) + } + } + + LazyColumn( + verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.Top), + horizontalAlignment = Alignment.CenterHorizontally, + modifier = modifier + .fillMaxSize() + .background(color = Color(0xfff4f7fb)) + .padding( + horizontal = 5.dp, + vertical = 1.dp + ) + ) { + item { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth(1f) + .requiredHeight(height = 56.dp) + .background(color = Color.White) + .padding( + horizontal = 17.dp, + vertical = 6.dp + ) + ) { + Text( + text = "Report", + color = Color.Black, + lineHeight = 1.14.em, + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Medium + ) + ) + Text( + text = "Back", + color = Color(0xFFF94B4B), + textAlign = TextAlign.Center, + lineHeight = 0.83.em, + style = TextStyle( + fontSize = 14.sp, + letterSpacing = 0.1.sp + ), + modifier = Modifier + .clickable { + navController.navigate(route = BottomBarScreen.Profile.route) + } + .wrapContentHeight(align = Alignment.CenterVertically)) + } + } + item { + Button( + onClick = { + showDialogFrom.value = true; + }, + shape = RoundedCornerShape(10.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xff4bb2f9)), + modifier = Modifier + .fillMaxWidth() + ) { + Text( + if (dateStateFrom.selectedDateMillis != null) + longToDate(dateStateFrom.selectedDateMillis!!).toLocalDate().toString() else + "Select Date" + ) + } + Button( + onClick = { + showDialogTo.value = true; + }, + shape = RoundedCornerShape(10.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xff4bb2f9)), + modifier = Modifier + .fillMaxWidth() + ) { + Text( + if (dateStateTo.selectedDateMillis != null) + longToDate(dateStateTo.selectedDateMillis!!).toLocalDate().toString() else + "Select Date" + ) + } + } + item { + Button( + onClick = { + if (dateStateTo.selectedDateMillis != null && + dateStateFrom.selectedDateMillis != null) { + reportViewModel.setArguments( + user?.id!!, + longToDate(dateStateFrom.selectedDateMillis!!), + longToDate(dateStateTo.selectedDateMillis!!) + ) + } + }, + shape = RoundedCornerShape(10.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xff4bb2f9)), + modifier = Modifier + .fillMaxWidth() + ) { + Text("Create") + } + } + if (deals.isNotEmpty()) { + items(items = deals) { + ReportItem(deal = it, coins = coins) + } + } + else { + item { + Text(text = "No Data") + } + } + } +} + +@RequiresApi(Build.VERSION_CODES.O) +@Composable +fun ReportItem(modifier: Modifier = Modifier, deal: Deal, coins: List) { + Column( + verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically), + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxWidth() + .height(40.dp) + .clip(shape = RoundedCornerShape(8.dp)) + .background(color = Color.White) + .padding( + horizontal = 12.dp, + vertical = 5.dp + ) + ) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding(all = 2.dp) + ) { + Text( + text = "-${deal.countSell} ${ + coins.first { x -> x.id == deal.sellerCoinId }.shortName() + }", + color = Color(0xfff96161), + lineHeight = 1.25.em, + style = TextStyle( + fontSize = 16.sp, + letterSpacing = 0.1.sp + ), + modifier = Modifier + .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 = "+${deal.countBuy} ${ + coins.first { x -> x.id == deal.buyerCoinId }.shortName() + }", + color = Color(0xff5acb48), + lineHeight = 1.25.em, + style = TextStyle( + fontSize = 16.sp, + letterSpacing = 0.1.sp + ), + modifier = Modifier + .wrapContentHeight(align = Alignment.CenterVertically) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/screensMobile/Wallet.kt b/app/src/main/java/com/example/testapp/screensMobile/Wallet.kt index 58205cd..1386706 100644 --- a/app/src/main/java/com/example/testapp/screensMobile/Wallet.kt +++ b/app/src/main/java/com/example/testapp/screensMobile/Wallet.kt @@ -1,25 +1,21 @@ package com.example.testapp.screensMobile -import android.annotation.SuppressLint import android.os.Build import androidx.annotation.RequiresApi import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -28,22 +24,22 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.em import androidx.compose.ui.unit.sp -import androidx.paging.LoadState -import androidx.paging.compose.collectAsLazyPagingItems import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController +import androidx.paging.LoadState +import androidx.paging.compose.collectAsLazyPagingItems import com.example.pmulabs.designElem.NavBar import com.example.testapp.designElem.ListItem -import com.example.testapp.designElem.SharedViewModel import com.example.testapp.graphs.HomeNavGraph import com.example.testapp.viewModels.AppViewModelProvider import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.DealCreateViewModel import com.example.testapp.viewModels.DealListViewModel import com.example.testapp.viewModels.HistoryViewModel +import com.example.testapp.viewModels.ReportViewModel +import com.example.testapp.viewModels.SharedViewModel import com.example.testapp.viewModels.WalletViewModel -import kotlinx.coroutines.flow.first @RequiresApi(Build.VERSION_CODES.O) @Composable @@ -83,16 +79,16 @@ fun Wallet( } 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.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) } @@ -116,6 +112,7 @@ fun LoadScreen( dealListViewModel: DealListViewModel = viewModel(factory = AppViewModelProvider.Factory), historyViewModel: HistoryViewModel = viewModel(factory = AppViewModelProvider.Factory), walletViewModel: WalletViewModel = viewModel(factory = AppViewModelProvider.Factory), + reportViewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory), sharedViewModel: SharedViewModel ) { Scaffold( @@ -130,6 +127,7 @@ fun LoadScreen( dealListViewModel, historyViewModel, walletViewModel, + reportViewModel, sharedViewModel ) } diff --git a/app/src/main/java/com/example/testapp/viewModels/AppViewModelProvider.kt b/app/src/main/java/com/example/testapp/viewModels/AppViewModelProvider.kt index 2b50427..9809c26 100644 --- a/app/src/main/java/com/example/testapp/viewModels/AppViewModelProvider.kt +++ b/app/src/main/java/com/example/testapp/viewModels/AppViewModelProvider.kt @@ -1,5 +1,7 @@ package com.example.testapp.viewModels +import android.os.Build +import androidx.annotation.RequiresApi import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewmodel.CreationExtras import androidx.lifecycle.viewmodel.initializer @@ -7,39 +9,46 @@ import androidx.lifecycle.viewmodel.viewModelFactory import com.example.testapp.CryptoDealApplication object AppViewModelProvider { + @RequiresApi(Build.VERSION_CODES.O) val Factory = viewModelFactory { + initializer { + EntryScreenViewModel(application().container.userRestRepository) + } initializer { CurrentUserViewModel(application().container.userRepository) } + initializer { + WalletViewModel( + application().container.walletItemRestRepository, + application().container.coinRestRepository + ) + } initializer { DealListViewModel( - application().container.dealRepository, - application().container.coinRepository, - application().container.walletItemRepository + application().container.dealRestRepository, + application().container.coinRestRepository, + application().container.walletItemRestRepository ) } initializer { DealCreateViewModel( - application().container.dealRepository, - application().container.coinRepository, - application().container.walletItemRepository + application().container.dealRestRepository, + application().container.coinRestRepository, + application().container.walletItemRestRepository ) } - initializer { - EntryScreenViewModel(application().container.userRepository) - } initializer { HistoryViewModel( - application().container.dealRepository, - application().container.coinRepository + application().container.dealRestRepository, + application().container.coinRestRepository ) } initializer { - RegistrationScreenViewModel(application().container.userRepository) + RegistrationScreenViewModel(application().container.userRestRepository) } initializer { - WalletViewModel( - application().container.walletItemRepository, + ReportViewModel( + application().container.dealRestRepository, application().container.coinRepository ) } diff --git a/app/src/main/java/com/example/testapp/viewModels/CurrentUserViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/CurrentUserViewModel.kt index e4b2a45..2ccdc25 100644 --- a/app/src/main/java/com/example/testapp/viewModels/CurrentUserViewModel.kt +++ b/app/src/main/java/com/example/testapp/viewModels/CurrentUserViewModel.kt @@ -4,11 +4,12 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.testapp.data.room.models.User import com.example.testapp.data.room.repository.basic.UserRepository +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch class CurrentUserViewModel(private val userRepository: UserRepository) : ViewModel() { - val argument = MutableStateFlow(null) + private val argument = MutableStateFlow(null) val id = MutableStateFlow(null) var user = MutableStateFlow(null) @@ -16,7 +17,7 @@ class CurrentUserViewModel(private val userRepository: UserRepository) : ViewMod argument.value = arg id.value = arg.toInt() - viewModelScope.launch { + viewModelScope.launch(Dispatchers.IO) { user.emit(userRepository.getById(id.value!!)) } } diff --git a/app/src/main/java/com/example/testapp/viewModels/DealCreateViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/DealCreateViewModel.kt index feb01c3..ca5e810 100644 --- a/app/src/main/java/com/example/testapp/viewModels/DealCreateViewModel.kt +++ b/app/src/main/java/com/example/testapp/viewModels/DealCreateViewModel.kt @@ -12,7 +12,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch class DealCreateViewModel( @@ -36,12 +35,8 @@ class DealCreateViewModel( init { viewModelScope.launch(Dispatchers.IO) { - _coins.emit( - coinRepository.getAll().first() - ) - _wallet.emit( - walletItemRepository.getAll().first() - ) + _coins.emit(coinRepository.getAll()) + _wallet.emit(walletItemRepository.getAll()) } } diff --git a/app/src/main/java/com/example/testapp/viewModels/DealListViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/DealListViewModel.kt index 1497b7b..e72aa88 100644 --- a/app/src/main/java/com/example/testapp/viewModels/DealListViewModel.kt +++ b/app/src/main/java/com/example/testapp/viewModels/DealListViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn +import androidx.paging.filter import com.example.testapp.data.room.models.Coin import com.example.testapp.data.room.models.Deal import com.example.testapp.data.room.models.WalletItem @@ -27,19 +28,20 @@ class DealListViewModel( fun setupLists() { viewModelScope.launch(Dispatchers.IO) { - coins.emit(coinRepository.getAll().first()) + coins.emit(coinRepository.getAll()) deals.emit(dealRepository .pagingData() .cachedIn(viewModelScope) - .first()) + .first() + .filter { it.date == null }) } } @RequiresApi(34) fun submitDeal(deal: Deal, sellerId: Int, buyerId: Int) { viewModelScope.launch { - val walletSeller: List = walletItemRepository.getUserWallet(sellerId).first() - val walletBuyer: List = walletItemRepository.getUserWallet(buyerId).first() + val walletSeller: List = walletItemRepository.getUserWallet(sellerId) + val walletBuyer: List = walletItemRepository.getUserWallet(buyerId) val seller: WalletItem? = walletSeller.firstOrNull { x -> x.coinId == deal.sellerCoinId } val buyer: WalletItem? = walletBuyer.firstOrNull { x -> x.coinId == deal.buyerId } @@ -54,7 +56,7 @@ class DealListViewModel( } // Case if need insert else { - val item = WalletItem(deal.buyerCoinId, sellerId, deal.countBuy) + val item = WalletItem(null, deal.buyerCoinId, sellerId, deal.countBuy) walletItemRepository.insert(item) } @@ -67,7 +69,7 @@ class DealListViewModel( } // Case if need insert else { - val item = WalletItem(deal.sellerCoinId, buyerId, deal.countSell) + val item = WalletItem(null, deal.sellerCoinId, buyerId, deal.countSell) walletItemRepository.insert(item) } diff --git a/app/src/main/java/com/example/testapp/viewModels/EntryScreenViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/EntryScreenViewModel.kt index c31e753..c5d7045 100644 --- a/app/src/main/java/com/example/testapp/viewModels/EntryScreenViewModel.kt +++ b/app/src/main/java/com/example/testapp/viewModels/EntryScreenViewModel.kt @@ -5,7 +5,6 @@ import androidx.lifecycle.viewModelScope import com.example.testapp.data.room.models.User import com.example.testapp.data.room.repository.basic.UserRepository import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch class EntryScreenViewModel( @@ -15,7 +14,7 @@ class EntryScreenViewModel( fun setupList() { viewModelScope.launch { - userList.emit(userRepository.getAll().first()) + userList.emit(userRepository.getAll()) } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/viewModels/HistoryViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/HistoryViewModel.kt index 0b04f36..bbd1f60 100644 --- a/app/src/main/java/com/example/testapp/viewModels/HistoryViewModel.kt +++ b/app/src/main/java/com/example/testapp/viewModels/HistoryViewModel.kt @@ -2,6 +2,9 @@ package com.example.testapp.viewModels import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.paging.PagingData +import androidx.paging.cachedIn +import androidx.paging.filter import com.example.testapp.data.room.models.Coin import com.example.testapp.data.room.models.Deal import com.example.testapp.data.room.repository.basic.CoinRepository @@ -17,15 +20,26 @@ class HistoryViewModel( ) : ViewModel() { val argument = MutableStateFlow(null) private val id = MutableStateFlow(null) - var deals = MutableStateFlow>(emptyList()) + var deals = MutableStateFlow>(PagingData.empty()) var coins = MutableStateFlow>(emptyList()) + init { + viewModelScope.launch(Dispatchers.IO) { + deals.emit(dealRepository.pagingData().cachedIn(viewModelScope).first().filter { + x -> x.date == null + }) + coins.emit(coinRepository.getAll()) + } + } + fun setArgument(arg: String) { argument.value = arg id.value = arg.toInt() viewModelScope.launch(Dispatchers.IO) { - deals.emit(dealRepository.getAll().first()) - coins.emit(coinRepository.getAll().first()) + deals.emit(dealRepository.pagingData().cachedIn(viewModelScope).first().filter { + x -> (x.buyerId == arg.toInt() || x.sellerId == arg.toInt()) + }) + coins.emit(coinRepository.getAll()) } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/viewModels/RegistrationScreenViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/RegistrationScreenViewModel.kt index 5a6011f..5df3d70 100644 --- a/app/src/main/java/com/example/testapp/viewModels/RegistrationScreenViewModel.kt +++ b/app/src/main/java/com/example/testapp/viewModels/RegistrationScreenViewModel.kt @@ -6,7 +6,6 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.testapp.data.room.models.User import com.example.testapp.data.room.repository.basic.UserRepository -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch class RegistrationScreenViewModel(private val userRepository: UserRepository) : ViewModel() { @@ -15,7 +14,7 @@ class RegistrationScreenViewModel(private val userRepository: UserRepository) : fun setUserList() { viewModelScope.launch { - _users.value = userRepository.getAll().first() + _users.value = userRepository.getAll() } } diff --git a/app/src/main/java/com/example/testapp/viewModels/ReportViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/ReportViewModel.kt new file mode 100644 index 0000000..9206aad --- /dev/null +++ b/app/src/main/java/com/example/testapp/viewModels/ReportViewModel.kt @@ -0,0 +1,49 @@ +package com.example.testapp.viewModels + +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.testapp.data.room.models.Coin +import com.example.testapp.data.room.models.Deal +import com.example.testapp.data.room.repository.basic.CoinRepository +import com.example.testapp.data.room.repository.basic.DealRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import java.time.LocalDateTime +import java.time.ZoneOffset + +@RequiresApi(Build.VERSION_CODES.O) +class ReportViewModel( + private val dealRepository: DealRepository, + private val coinRepository: CoinRepository +) : ViewModel() { + private var startDate = MutableStateFlow(LocalDateTime.now().minusDays(1)) + private var endDate = MutableStateFlow(LocalDateTime.now()) + var deals = MutableStateFlow>(emptyList()) + var coins = MutableStateFlow>(emptyList()) + + fun clearLists() { + deals = MutableStateFlow(emptyList()) + coins = MutableStateFlow(emptyList()) + } + + fun setArguments(userId: Int, from : LocalDateTime, to : LocalDateTime) { + viewModelScope.launch(Dispatchers.IO) { + startDate.emit(from) + endDate.emit(to) + val eptf = from.toEpochSecond(ZoneOffset.UTC) * 1000 + val eptt = to.toEpochSecond(ZoneOffset.UTC) * 1000 + + deals.emit( + dealRepository.getUserDeals(userId).filter { + it.date != null && + it.date!! >= eptf && + it.date!! <= eptt + } + ) + coins.emit(coinRepository.getAll()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/viewModels/SharedViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/SharedViewModel.kt new file mode 100644 index 0000000..500ecc0 --- /dev/null +++ b/app/src/main/java/com/example/testapp/viewModels/SharedViewModel.kt @@ -0,0 +1,16 @@ +package com.example.testapp.viewModels + +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import com.example.testapp.data.room.models.Deal + +class SharedViewModel : ViewModel() { + var argument_edit = mutableStateOf(null) + + fun setArgumentEdit(arg: Deal?) { + if (arg == null) { + argument_edit = mutableStateOf(null) + } + argument_edit.value = arg + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/testapp/viewModels/WalletViewModel.kt b/app/src/main/java/com/example/testapp/viewModels/WalletViewModel.kt index d51aaf9..5678a4b 100644 --- a/app/src/main/java/com/example/testapp/viewModels/WalletViewModel.kt +++ b/app/src/main/java/com/example/testapp/viewModels/WalletViewModel.kt @@ -8,6 +8,7 @@ import com.example.testapp.data.room.models.Coin import com.example.testapp.data.room.models.WalletItem import com.example.testapp.data.room.repository.basic.CoinRepository import com.example.testapp.data.room.repository.basic.WalletItemRepository +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.first @@ -17,17 +18,17 @@ class WalletViewModel( private val walletItemRepository: WalletItemRepository, private val coinRepository: CoinRepository ) : ViewModel() { - val argument = MutableStateFlow(null) + private val argument = MutableStateFlow(null) private val id = MutableStateFlow(null) - var _wallet = MutableStateFlow>(PagingData.empty()) + private var _wallet = MutableStateFlow>(PagingData.empty()) var wallet = _wallet.asStateFlow(); var coins = MutableStateFlow?>(emptyList()) fun setArgument(arg: String) { argument.value = arg id.value = arg.toInt() - viewModelScope.launch { - coins.emit(coinRepository.getAll().first()) + viewModelScope.launch(Dispatchers.IO) { + coins.emit(coinRepository.getAll()) _wallet.emit(walletItemRepository .pagingData(id.value!!) .cachedIn(viewModelScope) diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..87e22ea --- /dev/null +++ b/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,6 @@ + + + + 172.20.10.13 + + \ No newline at end of file