add rest reps and mediators

This commit is contained in:
andrew 2023-12-14 11:49:24 +04:00
parent 5d7442934d
commit 9dcc14add5
64 changed files with 1127 additions and 313 deletions

View File

@ -1,8 +1,8 @@
package com.example.testapp package com.example.testapp
import android.app.Application import android.app.Application
import com.example.testapp.room.AppContainer import com.example.testapp.data.room.AppContainer
import com.example.testapp.room.AppDataContainer import com.example.testapp.data.room.AppDataContainer
class CryptoDealApplication : Application() { class CryptoDealApplication : Application() {
lateinit var container: AppContainer lateinit var container: AppContainer

View File

@ -0,0 +1,135 @@
package com.example.testapp.data.api
import com.example.testapp.data.api.model.CoinRemote
import com.example.testapp.data.api.model.DealRemote
import com.example.testapp.data.api.model.UserRemote
import com.example.testapp.data.api.model.WalletItemRemote
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface UserRequests {
/**
* <i>User Request interface</i>
* */
@GET("users")
suspend fun getUsers(): List<UserRemote>
@GET("users/{id}")
suspend fun getUserById(@Path("id") id: Int): UserRemote
@POST("users")
suspend fun insert(@Body obj: UserRemote): UserRemote
@PUT("users/{id}")
suspend fun update(@Path("id") id: Int, @Body obj: UserRemote): UserRemote
@DELETE("users/{id}")
suspend fun deleteUser(@Path("id") id: Int): UserRemote
@GET("user_wallet/{id}")
suspend fun getUserWallet(@Path("id") id: Int): List<WalletItemRemote>
@GET("user_deal/{id}")
suspend fun getUserDeal(@Path("id") id: Int): List<DealRemote>
}
interface DealRequests {
/**
* <i>Deal Request interface</i>
*/
@GET("deals")
suspend fun getDeals(): List<DealRemote>
@GET("deals/{id}")
suspend fun getDealById(@Path("id") id: Int): DealRemote
@POST("deals")
suspend fun insert(@Body obj: DealRemote): DealRemote
@PUT("deals/{id}")
suspend fun update(@Path("id") id: Int, @Body obj: DealRemote): DealRemote
@DELETE("deals/{id}")
suspend fun deleteDeal(@Path("id") id: Int): DealRemote
@GET("p_deals")
suspend fun pagingDeals(
@Query("_page") page: Int,
@Query("_limit") limit: Int
): List<DealRemote>
@POST("complete_deal}")
suspend fun completeDeal(
@Query("dealId") dealId: Int,
@Query("sellerId")sellerId: Int,
@Query("buyerId") buyerId: Int,
): Boolean
}
interface CoinRequests {
/**
* <i>Coin Request interface</i>
*/
@GET("")
suspend fun getCoins(): List<CoinRemote>
}
interface WalletItemRequests {
/**
* <i>Wallet Item Request interface</i>
*/
@GET("wal_item")
suspend fun getWalletItems(): List<WalletItemRemote>
@POST("wal_item")
suspend fun insert(@Body obj: WalletItemRemote): WalletItemRemote
@PUT("wal_item")
suspend fun update(@Body obj: WalletItemRemote): WalletItemRemote
@DELETE("wal_item/{id}")
suspend fun deleteWalletItem(@Path("id") id: Int): WalletItemRemote
@GET("p_wal_item")
suspend fun pagingWalletItems(
@Query("_page") page: Int,
@Query("_limit") limit: Int
): List<WalletItemRemote>
}
interface CryptoDealService : UserRequests, DealRequests, CoinRequests, WalletItemRequests {
companion object {
private const val BASE_URL = "http://10.0.2.2:8079/"
@Volatile
private var INSTANCE: CryptoDealService? = null
fun getInstance(): CryptoDealService {
return INSTANCE ?: synchronized(this) {
val logger = HttpLoggingInterceptor()
logger.level = HttpLoggingInterceptor.Level.BASIC
val client = OkHttpClient.Builder()
.addInterceptor(logger)
.build()
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
.create(CryptoDealService::class.java)
.also { INSTANCE = it }
}
}
}
}

View File

@ -0,0 +1,105 @@
package com.example.testapp.data.api.mediator
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import com.example.testapp.data.api.CryptoDealService
import com.example.testapp.data.api.model.toDeal
import com.example.testapp.data.room.database.CryptoDealDb
import com.example.testapp.data.room.models.Deal
import com.example.testapp.data.room.models.RemoteKeyType
import com.example.testapp.data.room.models.RemoteKeys
import com.example.testapp.data.room.repository.offline.OfflineDealRepository
import com.example.testapp.data.room.repository.offline.OfflineRemoteKeyRepository
import okio.IOException
import retrofit2.HttpException
@OptIn(ExperimentalPagingApi::class)
class DealRemoteMediator(
private val service: CryptoDealService,
private val dbDealRepository: OfflineDealRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: CryptoDealDb
) : RemoteMediator<Int, Deal>() {
override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(loadType: LoadType, state: PagingState<Int, Deal>): MediatorResult {
val page = when (loadType) {
LoadType.REFRESH -> {
val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
remoteKeys?.nextKey?.minus(1) ?: 1
}
LoadType.PREPEND -> {
val remoteKeys = getRemoteKeyForFirstItem(state)
remoteKeys?.prevKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
LoadType.APPEND -> {
val remoteKeys = getRemoteKeyForLastItem(state)
remoteKeys?.nextKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
}
try {
val articles = service.pagingDeals(page, state.config.pageSize).map { it.toDeal() }
val endOfPaginationReached = articles.isEmpty()
database.withTransaction {
if (loadType == LoadType.REFRESH) {
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.DEAL)
dbDealRepository.clearData()
}
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
)
}
}
dbRemoteKeyRepository.createRemoteKeys(keys)
dbDealRepository.insert(articles)
}
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
} catch (exception: IOException) {
return MediatorResult.Error(exception)
} catch (exception: HttpException) {
return MediatorResult.Error(exception)
}
}
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Deal>): RemoteKeys? {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { art ->
art.id?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.DEAL) }
}
}
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Deal>): RemoteKeys? {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { art ->
art.id?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.DEAL) }
}
}
private suspend fun getRemoteKeyClosestToCurrentPosition(
state: PagingState<Int, Deal>
): RemoteKeys? {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.id?.let { artid ->
dbRemoteKeyRepository.getAllRemoteKeys(artid, RemoteKeyType.DEAL)
}
}
}
}

View File

@ -0,0 +1,105 @@
package com.example.testapp.data.api.mediator
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import com.example.testapp.data.api.CryptoDealService
import com.example.testapp.data.api.model.toWalletItem
import com.example.testapp.data.room.database.CryptoDealDb
import com.example.testapp.data.room.models.RemoteKeyType
import com.example.testapp.data.room.models.RemoteKeys
import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.data.room.repository.offline.OfflineRemoteKeyRepository
import com.example.testapp.data.room.repository.offline.OfflineWalletItemRepository
import okio.IOException
import retrofit2.HttpException
@OptIn(ExperimentalPagingApi::class)
class WalletItemRemoteMediator(
private val service: CryptoDealService,
private val dbWalletItemRepository: OfflineWalletItemRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: CryptoDealDb
) : RemoteMediator<Int, WalletItem>() {
override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(loadType: LoadType, state: PagingState<Int, WalletItem>): MediatorResult {
val page = when (loadType) {
LoadType.REFRESH -> {
val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
remoteKeys?.nextKey?.minus(1) ?: 1
}
LoadType.PREPEND -> {
val remoteKeys = getRemoteKeyForFirstItem(state)
remoteKeys?.prevKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
LoadType.APPEND -> {
val remoteKeys = getRemoteKeyForLastItem(state)
remoteKeys?.nextKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
}
try {
val articles = service.pagingWalletItems(page, state.config.pageSize).map { it.toWalletItem() }
val endOfPaginationReached = articles.isEmpty()
database.withTransaction {
if (loadType == LoadType.REFRESH) {
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.WALLETITEM)
dbWalletItemRepository.clearData()
}
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
)
}
}
dbRemoteKeyRepository.createRemoteKeys(keys)
dbWalletItemRepository.insert(articles)
}
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
} catch (exception: IOException) {
return MediatorResult.Error(exception)
} catch (exception: HttpException) {
return MediatorResult.Error(exception)
}
}
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, WalletItem>): RemoteKeys? {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { art ->
art.id?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.WALLETITEM) }
}
}
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, WalletItem>): RemoteKeys? {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { art ->
art.id?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.WALLETITEM) }
}
}
private suspend fun getRemoteKeyClosestToCurrentPosition(
state: PagingState<Int, WalletItem>
): RemoteKeys? {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.id?.let { artid ->
dbRemoteKeyRepository.getAllRemoteKeys(artid, RemoteKeyType.WALLETITEM)
}
}
}
}

View File

@ -0,0 +1,13 @@
package com.example.testapp.data.api.model
import com.example.testapp.data.room.models.Coin
import kotlinx.serialization.Serializable
@Serializable
data class CoinRemote(
val id: Int?,
val name: String
)
fun CoinRemote.toCoin(): Coin = Coin(id, name)
fun Coin.toRemote(): CoinRemote = CoinRemote(id, name)

View File

@ -0,0 +1,44 @@
package com.example.testapp.data.api.model
import com.example.testapp.data.room.models.Deal
import kotlinx.serialization.Serializable
@Serializable
data class DealRemote(
val id: Int?,
var sellerId: Int?,
val buyerId: Int?,
val sellerCoinId: Int,
val buyerCoinId: Int,
val countSell: Float,
val countBuy: Float,
val operation: String,
var date: Long?,
val tip: String
)
fun DealRemote.toDeal(): Deal = Deal(
id,
sellerId,
buyerId,
sellerCoinId,
buyerCoinId,
countSell,
countBuy,
operation,
date,
tip
)
fun Deal.toRemote(): DealRemote = DealRemote(
id,
sellerId,
buyerId,
sellerCoinId,
buyerCoinId,
countSell,
countBuy,
operation,
date,
tip
)

View File

@ -0,0 +1,14 @@
package com.example.testapp.data.api.model
import com.example.testapp.data.room.models.User
import kotlinx.serialization.Serializable
@Serializable
data class UserRemote(
val id: Int? = 0,
var email: String = "",
var password: String = ""
)
fun UserRemote.toUser(): User = User(id, email, password)
fun User.toRemote(): UserRemote = UserRemote(id, email, password)

View File

@ -0,0 +1,15 @@
package com.example.testapp.data.api.model
import com.example.testapp.data.room.models.WalletItem
import kotlinx.serialization.Serializable
@Serializable
data class WalletItemRemote(
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)

View File

@ -0,0 +1,46 @@
package com.example.testapp.data.api.repository
import com.example.testapp.data.api.CryptoDealService
import com.example.testapp.data.api.model.toCoin
import com.example.testapp.data.room.models.Coin
import com.example.testapp.data.room.repository.basic.CoinRepository
import com.example.testapp.data.room.repository.offline.OfflineCoinRepository
class CoinRestRepository(
private val service: CryptoDealService,
private val dbCoinRepository: OfflineCoinRepository
) : CoinRepository {
override suspend fun insert(x: Coin) {
TODO("Not yet implemented")
}
override suspend fun update(x: Coin) {
TODO("Not yet implemented")
}
override suspend fun delete(x: Coin) {
TODO("Not yet implemented")
}
override suspend fun getById(id: Int): Coin {
TODO("Not yet implemented")
}
override suspend fun getAll(): List<Coin> {
val exists = dbCoinRepository.getAll().associateBy { it.id }.toMutableMap()
service.getCoins()
.map { it.toCoin() }
.forEach { item ->
val existUser = exists[item.id]
if (existUser == null) {
dbCoinRepository.insert(item)
} else if (existUser != item) {
dbCoinRepository.update(item)
}
exists[item.id] = item
}
return exists.map { it.value }.sortedBy { it.id }
}
}

View File

@ -0,0 +1,105 @@
package com.example.testapp.data.api.repository
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.testapp.data.api.CryptoDealService
import com.example.testapp.data.api.mediator.DealRemoteMediator
import com.example.testapp.data.api.model.toDeal
import com.example.testapp.data.api.model.toRemote
import com.example.testapp.data.room.AppContainer
import com.example.testapp.data.room.database.CryptoDealDb
import com.example.testapp.data.room.models.Deal
import com.example.testapp.data.room.repository.basic.DealRepository
import com.example.testapp.data.room.repository.offline.OfflineDealRepository
import com.example.testapp.data.room.repository.offline.OfflineRemoteKeyRepository
import kotlinx.coroutines.flow.Flow
class DealRestRepository(
private val service: CryptoDealService,
private val dbDealRepository: OfflineDealRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: CryptoDealDb
) : DealRepository {
override suspend fun getUserDeals(id: Int): List<Deal> {
val exists = dbDealRepository.getAll().associateBy { it.id }.toMutableMap()
service.getDeals()
.map { it.toDeal() }
.forEach { item ->
val existUser = exists[item.id]
if (existUser == null) {
dbDealRepository.insert(item)
} else if (existUser != item) {
dbDealRepository.update(item)
}
exists[item.id] = item
}
return exists.map { it.value }.sortedBy { it.id }
}
override suspend fun completeDeal(deal: Deal, sellerId: Int, buyerId: Int): Boolean {
return service.completeDeal(deal.id!!, sellerId, buyerId)
}
override fun pagingData(): Flow<PagingData<Deal>> {
val pagingSourceFactory = { dbDealRepository.getAllPagingData() }
@OptIn(ExperimentalPagingApi::class)
return Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
remoteMediator = DealRemoteMediator(
service,
dbDealRepository,
dbRemoteKeyRepository,
database
),
pagingSourceFactory = pagingSourceFactory
).flow
}
override fun getAllPagingData(): PagingSource<Int, Deal> {
TODO("Not yet implemented")
}
override suspend fun insert(x: Deal) {
service.insert(x.toRemote())
}
override suspend fun update(x: Deal) {
x.id?.let { service.update(it, x.toRemote()) }
}
override suspend fun delete(x: Deal) {
x.id?.let { service.deleteDeal(it) }
}
override suspend fun getById(id: Int): Deal {
return service.getDealById(id).toDeal()
}
override suspend fun getAll(): List<Deal> {
val exists = dbDealRepository.getAll().associateBy { it.id }.toMutableMap()
service.getDeals()
.map { it.toDeal() }
.forEach { item ->
val existUser = exists[item.id]
if (existUser == null) {
dbDealRepository.insert(item)
} else if (existUser != item) {
dbDealRepository.update(item)
}
exists[item.id] = item
}
return exists.map { it.value }.sortedBy { it.id }
}
}

View File

@ -0,0 +1,97 @@
package com.example.testapp.data.api.repository
import com.example.testapp.data.api.CryptoDealService
import com.example.testapp.data.api.model.toDeal
import com.example.testapp.data.api.model.toRemote
import com.example.testapp.data.api.model.toUser
import com.example.testapp.data.api.model.toWalletItem
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.DealRepository
import com.example.testapp.data.room.repository.basic.UserRepository
import com.example.testapp.data.room.repository.basic.WalletItemRepository
class UserRestRepository(
private val service: CryptoDealService,
private val dbUserRepository: UserRepository,
private val dbDealRepository: DealRepository,
private val dbWalletItemRepository: WalletItemRepository
) : UserRepository {
override suspend fun getUserWallet(id: Int): List<WalletItem> {
val existArticles = dbUserRepository.getUserWallet(id)
.associateBy { it.userId * 10 + it.coinId }.toMutableMap()
service.getUserWallet(id)
.map { it.toWalletItem() }
.forEach { walletItem ->
val pseudoId = walletItem.userId * 10 + walletItem.coinId
if (walletItem.userId == id) {
val existArt = existArticles[pseudoId]
if (existArt == null) {
dbWalletItemRepository.insert(walletItem)
} else if (existArt != walletItem) {
dbWalletItemRepository.update(walletItem)
}
existArticles[pseudoId] = walletItem
}
}
return existArticles.map { it.value }.sortedBy { it.count }
}
override suspend fun getUserDeals(id: Int): List<Deal> {
val existArticles = dbUserRepository.getUserDeals(id)
.associateBy { it.id }.toMutableMap()
service.getUserDeal(id)
.map { it.toDeal() }
.forEach { deal ->
if (deal.buyerId == id) {
val existArt = existArticles[deal.id]
if (existArt == null) {
dbDealRepository.insert(deal)
} else if (existArt != deal) {
dbDealRepository.update(deal)
}
existArticles[deal.id] = deal
}
}
return existArticles.map { it.value }.sortedBy { it.id }
}
override suspend fun insert(x: User) {
service.insert(x.toRemote())
}
override suspend fun update(x: User) {
x.id?.let { service.update(it, x.toRemote()) }
}
override suspend fun delete(x: User) {
x.id?.let { service.deleteUser(it) }
}
override suspend fun getById(id: Int): User {
return service.getUserById(id).toUser()
}
override suspend fun getAll(): List<User> {
val existUsers = dbUserRepository.getAll().associateBy { it.id }.toMutableMap()
service.getUsers()
.map { it.toUser() }
.forEach { user ->
val existUser = existUsers[user.id]
if (existUser == null) {
dbUserRepository.insert(user)
} else if (existUser != user) {
dbUserRepository.update(user)
}
existUsers[user.id] = user
}
return existUsers.map { it.value }.sortedBy { it.id }
}
}

View File

@ -0,0 +1,86 @@
package com.example.testapp.data.api.repository
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.testapp.data.api.CryptoDealService
import com.example.testapp.data.api.mediator.WalletItemRemoteMediator
import com.example.testapp.data.api.model.toRemote
import com.example.testapp.data.api.model.toWalletItem
import com.example.testapp.data.room.AppContainer
import com.example.testapp.data.room.database.CryptoDealDb
import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.data.room.repository.basic.WalletItemRepository
import com.example.testapp.data.room.repository.offline.OfflineRemoteKeyRepository
import com.example.testapp.data.room.repository.offline.OfflineWalletItemRepository
import kotlinx.coroutines.flow.Flow
class WalletItemRestRepository(
private val service: CryptoDealService,
private val dbWalletItemRepository: OfflineWalletItemRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: CryptoDealDb
) : WalletItemRepository {
override fun getUserWallet(id: Int): List<WalletItem> {
TODO("Not yet implemented")
}
override fun pagingData(id: Int): Flow<PagingData<WalletItem>> {
val pagingSourceFactory = { dbWalletItemRepository.getWalletItemsPaging(id) }
@OptIn(ExperimentalPagingApi::class)
return Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
remoteMediator = WalletItemRemoteMediator(
service,
dbWalletItemRepository,
dbRemoteKeyRepository,
database
),
pagingSourceFactory = pagingSourceFactory
).flow
}
override fun getWalletItemsPaging(id: Int): PagingSource<Int, WalletItem> {
TODO("Not yet implemented")
}
override suspend fun insert(x: WalletItem) {
service.insert(x.toRemote())
}
override suspend fun update(x: WalletItem) {
service.update(x.toRemote())
}
override suspend fun delete(x: WalletItem) {
x.id?.let { service.deleteWalletItem(it) }
}
override suspend fun getById(id: Int): WalletItem {
TODO("Not yet implemented")
}
override suspend fun getAll(): List<WalletItem> {
val exists = dbWalletItemRepository.getAll().associateBy { it.id }.toMutableMap()
service.getWalletItems()
.map { it.toWalletItem() }
.forEach { item ->
val existUser = exists[item.id]
if (existUser == null) {
dbWalletItemRepository.insert(item)
} else if (existUser != item) {
dbWalletItemRepository.update(item)
}
exists[item.id] = item
}
return exists.map { it.value }.sortedBy { it.id }
}
}

View File

@ -1,30 +1,31 @@
package com.example.testapp.room package com.example.testapp.data.room
import android.content.Context import android.content.Context
import com.example.testapp.room.database.CryptoDealDb import com.example.testapp.data.room.database.CryptoDealDb
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.data.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.data.room.repository.basic.DealRepository
import com.example.testapp.room.repository.basic.UserRepository import com.example.testapp.data.room.repository.basic.UserRepository
import com.example.testapp.room.repository.basic.WalletItemRepository import com.example.testapp.data.room.repository.basic.WalletItemRepository
import com.example.testapp.room.repository.offline.OfflineCoinRepository import com.example.testapp.data.room.repository.offline.OfflineCoinRepository
import com.example.testapp.room.repository.offline.OfflineDealRepository import com.example.testapp.data.room.repository.offline.OfflineDealRepository
import com.example.testapp.room.repository.offline.OfflineUserRepository import com.example.testapp.data.room.repository.offline.OfflineUserRepository
import com.example.testapp.room.repository.offline.OfflineWalletItemRepository import com.example.testapp.data.room.repository.offline.OfflineWalletItemRepository
interface AppContainer { interface AppContainer {
val userRepository: UserRepository val userRepository: UserRepository
val dealRepository: DealRepository val dealRepository: DealRepository
val coinRepository: CoinRepository val coinRepository: CoinRepository
val walletItemRepository: WalletItemRepository val walletItemRepository: WalletItemRepository
companion object {
const val TIMEOUT = 5000L
const val LIMIT = 10
}
} }
class AppDataContainer( class AppDataContainer(
private val context: Context private val context: Context
) : AppContainer { ) : AppContainer {
companion object {
const val TIMEOUT = 5000L
}
override val userRepository: UserRepository by lazy { override val userRepository: UserRepository by lazy {
OfflineUserRepository(CryptoDealDb.getInstance(context).userDao()) OfflineUserRepository(CryptoDealDb.getInstance(context).userDao())
} }

View File

@ -0,0 +1,11 @@
package com.example.testapp.data.room.dao
import androidx.room.Dao
import androidx.room.Query
import com.example.testapp.data.room.models.Coin
@Dao
interface CoinDao : IDao<Coin> {
@Query("select * from coin")
fun getAll(): List<Coin>
}

View File

@ -1,9 +1,9 @@
package com.example.testapp.room.dao package com.example.testapp.data.room.dao
import androidx.paging.PagingSource
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.data.room.models.Deal
import com.example.testapp.room.models.User
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao
@ -19,4 +19,10 @@ interface DealDao : IDao<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")
fun getUserDeals(idUser: Int): Flow<List<Deal>> fun getUserDeals(idUser: Int): Flow<List<Deal>>
@Query("SELECT * FROM deal where deal.date IS NULL ORDER BY id ASC")
fun getDeals(): PagingSource<Int, Deal>
@Query("DELETE FROM deal")
suspend fun deleteAll()
} }

View File

@ -1,4 +1,4 @@
package com.example.testapp.room.dao package com.example.testapp.data.room.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
@ -8,7 +8,7 @@ import androidx.room.Update
@Dao @Dao
interface IDao<T> { interface IDao<T> {
@Insert @Insert
suspend fun insert(obj: T) suspend fun insert(vararg obj: T)
@Update @Update
suspend fun update(obj: T) suspend fun update(obj: T)

View File

@ -0,0 +1,18 @@
package com.example.testapp.data.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 {
@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<RemoteKeys?>)
@Query("DELETE FROM remote_keys WHERE type = :type")
suspend fun clearRemoteKeys(type: RemoteKeyType)
}

View File

@ -1,10 +1,10 @@
package com.example.testapp.room.dao package com.example.testapp.data.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.data.room.models.Deal
import com.example.testapp.room.models.User import com.example.testapp.data.room.models.User
import com.example.testapp.room.models.WalletItem import com.example.testapp.data.room.models.WalletItem
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao

View File

@ -0,0 +1,24 @@
package com.example.testapp.data.room.dao
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Query
import com.example.testapp.data.room.models.WalletItem
@Dao
interface WalletItemDao : IDao<WalletItem> {
@Query("select * from walletitem")
fun getAll(): 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")
fun getUserWallet(id: Int): List<WalletItem>
@Query("SELECT * FROM walletitem where walletitem.userId = :id ORDER BY walletitem.coinId ASC")
fun getDeals(id: Int): PagingSource<Int, WalletItem>
@Query("DELETE FROM walletitem")
suspend fun deleteAll()
}

View File

@ -1,18 +1,22 @@
package com.example.testapp.room.database package com.example.testapp.data.room.database
import android.content.Context import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase import com.example.testapp.data.room.dao.CoinDao
import com.example.testapp.room.dao.* import com.example.testapp.data.room.dao.DealDao
import com.example.testapp.room.models.* import com.example.testapp.data.room.dao.RemoteKeysDao
import kotlinx.coroutines.CoroutineScope import com.example.testapp.data.room.dao.UserDao
import kotlinx.coroutines.Dispatchers import com.example.testapp.data.room.dao.WalletItemDao
import kotlinx.coroutines.launch import com.example.testapp.data.room.models.Coin
import com.example.testapp.data.room.models.Deal
import com.example.testapp.data.room.models.RemoteKeys
import com.example.testapp.data.room.models.User
import com.example.testapp.data.room.models.WalletItem
@Database( @Database(
entities = [User::class, Deal::class, Coin::class, WalletItem::class], entities = [User::class, Deal::class, Coin::class, WalletItem::class, RemoteKeys::class],
version = 2, version = 2,
exportSchema = false) exportSchema = false)
abstract class CryptoDealDb: RoomDatabase() { abstract class CryptoDealDb: RoomDatabase() {
@ -20,6 +24,7 @@ abstract class CryptoDealDb: RoomDatabase() {
abstract fun coinDao(): CoinDao; abstract fun coinDao(): CoinDao;
abstract fun dealDao(): DealDao; abstract fun dealDao(): DealDao;
abstract fun walletItemDao(): WalletItemDao; abstract fun walletItemDao(): WalletItemDao;
abstract fun RemoteKeysDao(): RemoteKeysDao;
companion object { companion object {
private const val DB_NAME: String = "crypto-deal7" private const val DB_NAME: String = "crypto-deal7"
@ -91,14 +96,14 @@ abstract class CryptoDealDb: RoomDatabase() {
CryptoDealDb::class.java, CryptoDealDb::class.java,
DB_NAME DB_NAME
) )
.addCallback(object : Callback() { // .addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) { // override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db) // super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch { // CoroutineScope(Dispatchers.IO).launch {
populateDatabase() // populateDatabase()
} // }
} // }
}) // })
.allowMainThreadQueries() .allowMainThreadQueries()
.build() .build()
.also { INSTANCE = it } .also { INSTANCE = it }

View File

@ -1,4 +1,4 @@
package com.example.testapp.room.models package com.example.testapp.data.room.models
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity

View File

@ -1,8 +1,7 @@
package com.example.testapp.room.models package com.example.testapp.data.room.models
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import java.time.LocalDateTime
@Entity @Entity
class Deal ( class Deal (

View File

@ -0,0 +1,26 @@
package com.example.testapp.data.room.models
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
enum class RemoteKeyType(private val type: String) {
DEAL(Deal::class.simpleName ?: "Deal"),
WALLETITEM(WalletItem::class.simpleName ?: "WalletItem");
@TypeConverter
fun toRemoteKeyType(value: String) = RemoteKeyType.values().first { it.type == value }
@TypeConverter
fun fromRemoteKeyType(value: RemoteKeyType) = value.type
}
@Entity(tableName = "remote_keys")
data class RemoteKeys(
@PrimaryKey val entityId: Int,
@TypeConverters(RemoteKeyType::class)
val type: RemoteKeyType,
val prevKey: Int?,
val nextKey: Int?
)

View File

@ -1,4 +1,4 @@
package com.example.testapp.room.models package com.example.testapp.data.room.models
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity

View File

@ -1,7 +1,8 @@
package com.example.testapp.room.models package com.example.testapp.data.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"],
@ -11,6 +12,8 @@ import androidx.room.ForeignKey
] ]
) )
class WalletItem ( class WalletItem (
@PrimaryKey(autoGenerate = true)
val id: Int?,
val coinId: Int, val coinId: Int,
val userId: Int, val userId: Int,
var count: Float, var count: Float,

View File

@ -1,10 +1,9 @@
package com.example.testapp.room.pagination package com.example.testapp.data.room.pagination
import android.util.Log
import androidx.paging.PagingSource import androidx.paging.PagingSource
import androidx.paging.PagingState import androidx.paging.PagingState
import com.example.testapp.room.dao.DealDao import com.example.testapp.data.room.dao.DealDao
import com.example.testapp.room.models.Deal import com.example.testapp.data.room.models.Deal
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
class DealPagination( class DealPagination(

View File

@ -1,11 +1,10 @@
package com.example.testapp.room.pagination package com.example.testapp.data.room.pagination
import android.util.Log import android.util.Log
import androidx.paging.PagingSource import androidx.paging.PagingSource
import androidx.paging.PagingState import androidx.paging.PagingState
import com.example.testapp.room.dao.WalletItemDao import com.example.testapp.data.room.dao.WalletItemDao
import com.example.testapp.room.models.WalletItem import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
class WalletPagination( class WalletPagination(

View File

@ -0,0 +1,6 @@
package com.example.testapp.data.room.repository.basic
import com.example.testapp.data.room.models.Coin
interface CoinRepository : IRepository<Coin> {
}

View File

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

View File

@ -0,0 +1,9 @@
package com.example.testapp.data.room.repository.basic
interface IRepository<T> {
suspend fun insert(vararg x: T)
suspend fun update(x: T)
suspend fun delete(x: T)
suspend fun getById(id: Int): T
suspend fun getAll(): List<T>
}

View File

@ -0,0 +1,10 @@
package com.example.testapp.data.room.repository.basic
import com.example.testapp.data.room.models.RemoteKeyType
import com.example.testapp.data.room.models.RemoteKeys
interface RemoteKeyRepository {
suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType): RemoteKeys?
suspend fun createRemoteKeys(remoteKeys: List<RemoteKeys?>)
suspend fun deleteRemoteKey(type: RemoteKeyType)
}

View File

@ -0,0 +1,10 @@
package com.example.testapp.data.room.repository.basic
import com.example.testapp.data.room.models.Deal
import com.example.testapp.data.room.models.User
import com.example.testapp.data.room.models.WalletItem
interface UserRepository : IRepository<User> {
suspend fun getUserWallet(id: Int): List<WalletItem>
suspend fun getUserDeals(id: Int): List<Deal>
}

View File

@ -0,0 +1,13 @@
package com.example.testapp.data.room.repository.basic
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.testapp.data.room.models.WalletItem
import kotlinx.coroutines.flow.Flow
interface WalletItemRepository : IRepository<WalletItem> {
fun getUserWallet(id: Int): List<WalletItem>
fun pagingData(id: Int): Flow<PagingData<WalletItem>>
fun getWalletItemsPaging(id: Int): PagingSource<Int, WalletItem>
suspend fun clearData()
}

View File

@ -0,0 +1,12 @@
package com.example.testapp.data.room.repository.offline
import com.example.testapp.data.room.dao.CoinDao
import com.example.testapp.data.room.models.Coin
import com.example.testapp.data.room.repository.basic.CoinRepository
class OfflineCoinRepository(
private val coinDao: CoinDao
) : OfflineRepository<Coin>(coinDao), CoinRepository {
override suspend fun getAll(): List<Coin> = coinDao.getAll()
override suspend fun getById(id: Int): Coin = throw NotImplementedError()
}

View File

@ -0,0 +1,33 @@
package com.example.testapp.data.room.repository.offline
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.testapp.data.room.dao.DealDao
import com.example.testapp.data.room.models.Deal
import com.example.testapp.data.room.pagination.DealPagination
import com.example.testapp.data.room.repository.basic.DealRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
class OfflineDealRepository(
private val dealDao: DealDao
) : OfflineRepository<Deal>(dealDao), DealRepository {
override suspend fun getAll(): List<Deal> = dealDao.getAll().first()
override suspend fun getById(id: Int): Deal = dealDao.getById(id);
override suspend fun getUserDeals(id: Int): List<Deal> = dealDao.getUserDeals(id).first()
override suspend fun completeDeal(deal: Deal, sellerId: Int, buyerId: Int): Boolean {
return true;
}
override suspend fun clearData() = dealDao.deleteAll()
override fun pagingData(): Flow<PagingData<Deal>> = Pager(config = PagingConfig(
pageSize = 4, jumpThreshold = 4, initialLoadSize = 4
), pagingSourceFactory = { DealPagination(dealDao) }, initialKey = 1).flow
override fun getAllPagingData() = dealDao.getDeals()
suspend fun insert(list: List<Deal>) = dealDao.insert(*list.toTypedArray())
}

View File

@ -0,0 +1,17 @@
package com.example.testapp.data.room.repository.offline
import com.example.testapp.data.room.dao.RemoteKeysDao
import com.example.testapp.data.room.models.RemoteKeyType
import com.example.testapp.data.room.models.RemoteKeys
import com.example.testapp.data.room.repository.basic.RemoteKeyRepository
class OfflineRemoteKeyRepository(private val remoteKeysDao: RemoteKeysDao) : RemoteKeyRepository {
override suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType) =
remoteKeysDao.getRemoteKeys(id, type)
override suspend fun createRemoteKeys(remoteKeys: List<RemoteKeys?>) =
remoteKeysDao.insertAll(remoteKeys)
override suspend fun deleteRemoteKey(type: RemoteKeyType) =
remoteKeysDao.clearRemoteKeys(type)
}

View File

@ -0,0 +1,12 @@
package com.example.testapp.data.room.repository.offline
import com.example.testapp.data.room.dao.IDao
import com.example.testapp.data.room.repository.basic.IRepository
abstract class OfflineRepository<T> (
private val dao: IDao<T>
) : IRepository<T> {
override suspend fun insert(vararg x: T) = dao.insert(*x)
override suspend fun update(x: T) = dao.update(x)
override suspend fun delete(x: T) = dao.delete(x)
}

View File

@ -0,0 +1,17 @@
package com.example.testapp.data.room.repository.offline
import com.example.testapp.data.room.dao.UserDao
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<User>(userDao), UserRepository {
override suspend fun getAll(): Flow<List<User>> = userDao.getAll()
override suspend fun getById(id: Int): User = userDao.getUserById(id)
override suspend fun getUserWallet(id: Int): Flow<List<WalletItem>> = userDao.getUserWallet(id)
override suspend fun getUserDeals(id: Int): Flow<List<Deal>> = userDao.getUserDeals(id)
}

View File

@ -0,0 +1,27 @@
package com.example.testapp.data.room.repository.offline
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.testapp.data.room.dao.WalletItemDao
import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.data.room.pagination.WalletPagination
import com.example.testapp.data.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.flow.Flow
class OfflineWalletItemRepository(
private val walletItemDao: WalletItemDao
) : OfflineRepository<WalletItem>(walletItemDao), WalletItemRepository {
override fun getUserWallet(id: Int): List<WalletItem> = walletItemDao.getUserWallet(id)
override suspend fun getAll(): List<WalletItem> = walletItemDao.getAll()
override suspend fun getById(id: Int): 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 getWalletItemsPaging(id: Int): PagingSource<Int, WalletItem> = walletItemDao.getDeals(id)
override suspend fun clearData() = walletItemDao.deleteAll()
suspend fun insert(list: List<WalletItem>) = walletItemDao.insert(*list.toTypedArray())
}

View File

@ -32,8 +32,8 @@ import androidx.compose.ui.text.style.TextAlign
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 com.example.testapp.room.models.Coin import com.example.testapp.data.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.data.room.models.Deal
@Composable @Composable
fun DealItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) { fun DealItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {

View File

@ -18,8 +18,6 @@ import androidx.compose.runtime.Composable
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
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -27,7 +25,7 @@ import androidx.compose.ui.text.style.TextAlign
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 com.example.testapp.room.models.Coin import com.example.testapp.data.room.models.Coin
@Composable @Composable
fun ListItem(modifier: Modifier = Modifier, coin : Coin, count: Float) { fun ListItem(modifier: Modifier = Modifier, coin : Coin, count: Float) {

View File

@ -1,12 +0,0 @@
package com.example.testapp.room.dao
import androidx.room.Dao
import androidx.room.Query
import com.example.testapp.room.models.Coin
import kotlinx.coroutines.flow.Flow
@Dao
interface CoinDao : IDao<Coin> {
@Query("select * from coin")
fun getAll(): Flow<List<Coin>>
}

View File

@ -1,19 +0,0 @@
package com.example.testapp.room.dao
import androidx.room.Dao
import androidx.room.Query
import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.WalletItem
import kotlinx.coroutines.flow.Flow
@Dao
interface WalletItemDao : IDao<WalletItem> {
@Query("select * from 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")
fun getUserWallet(id: Int): Flow<List<WalletItem>>
}

View File

@ -1,6 +0,0 @@
package com.example.testapp.room.repository.basic
import com.example.testapp.room.models.Coin
interface CoinRepository : IRepository<Coin> {
}

View File

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

View File

@ -1,11 +0,0 @@
package com.example.testapp.room.repository.basic
import kotlinx.coroutines.flow.Flow
interface IRepository<T> {
suspend fun insert(x: T)
suspend fun update(x: T)
suspend fun delete(x: T)
fun getById(id: Int): T
fun getAll(): Flow<List<T>>
}

View File

@ -1,11 +0,0 @@
package com.example.testapp.room.repository.basic
import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.User
import com.example.testapp.room.models.WalletItem
import kotlinx.coroutines.flow.Flow
interface UserRepository : IRepository<User> {
fun getUserWallet(id: Int): Flow<List<WalletItem>>
fun getUserDeals(id: Int): Flow<List<Deal>>
}

View File

@ -1,13 +0,0 @@
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 kotlinx.coroutines.flow.Flow
interface WalletItemRepository : IRepository<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,20 +0,0 @@
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.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 kotlinx.coroutines.flow.Flow
class OfflineCoinRepository(
private val coinDao: CoinDao
) : OfflineRepository<Coin>(coinDao), CoinRepository {
override fun getAll(): Flow<List<Coin>> = coinDao.getAll()
override fun getById(id: Int): Coin = throw NotImplementedError()
}

View File

@ -1,28 +0,0 @@
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.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 kotlinx.coroutines.flow.Flow
class OfflineDealRepository(
private val dealDao: DealDao
) : OfflineRepository<Deal>(dealDao), DealRepository {
override fun getAll(): Flow<List<Deal>> = dealDao.getAll()
override fun getById(id: Int): Deal = dealDao.getById(id);
override fun getUserDeals(id: Int): Flow<List<Deal>> = dealDao.getUserDeals(id)
override fun completeDeal(deal: Deal, sellerId: Int, buyerId: Int): Boolean {
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

@ -1,12 +0,0 @@
package com.example.testapp.room.repository.offline
import com.example.testapp.room.dao.IDao
import com.example.testapp.room.repository.basic.IRepository
abstract class OfflineRepository<T> (
private val dao: IDao<T>
) : IRepository<T> {
override suspend fun insert(x: T) = dao.insert(x)
override suspend fun update(x: T) = dao.update(x)
override suspend fun delete(x: T) = dao.delete(x)
}

View File

@ -1,17 +0,0 @@
package com.example.testapp.room.repository.offline
import com.example.testapp.room.dao.UserDao
import com.example.testapp.room.models.Deal
import com.example.testapp.room.models.User
import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.repository.basic.UserRepository
import kotlinx.coroutines.flow.Flow
class OfflineUserRepository(
private val userDao: UserDao
) : OfflineRepository<User>(userDao), UserRepository {
override fun getAll(): Flow<List<User>> = userDao.getAll()
override fun getById(id: Int): User = userDao.getUserById(id)
override fun getUserWallet(id: Int): Flow<List<WalletItem>> = userDao.getUserWallet(id)
override fun getUserDeals(id: Int): Flow<List<Deal>> = userDao.getUserDeals(id)
}

View File

@ -1,29 +0,0 @@
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.models.Deal
import com.example.testapp.room.models.WalletItem
import com.example.testapp.room.pagination.WalletPagination
import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.flow.Flow
class OfflineWalletItemRepository(
private val walletItemDao: WalletItemDao
) : OfflineRepository<WalletItem>(walletItemDao), WalletItemRepository {
override fun getUserWallet(id: Int): Flow<List<WalletItem>> = walletItemDao.getUserWallet(id)
override fun getAll(): Flow<List<WalletItem>> = walletItemDao.getAll()
override fun getById(id: Int): 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

@ -43,9 +43,9 @@ 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.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.data.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.data.room.models.Deal
import com.example.testapp.room.models.WalletItem import com.example.testapp.data.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

View File

@ -45,8 +45,8 @@ import androidx.paging.LoadState
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import com.example.testapp.designElem.SharedViewModel 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.data.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.data.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.DealCreateViewModel import com.example.testapp.viewModels.DealCreateViewModel

View File

@ -19,8 +19,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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
@ -36,8 +34,8 @@ import androidx.compose.ui.unit.sp
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.testapp.room.models.Coin import com.example.testapp.data.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.data.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

View File

@ -38,7 +38,7 @@ import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.testapp.graphs.AuthScreen import com.example.testapp.graphs.AuthScreen
import com.example.testapp.graphs.Graph import com.example.testapp.graphs.Graph
import com.example.testapp.room.models.User import com.example.testapp.data.room.models.User
import com.example.testapp.viewModels.CurrentUserViewModel import com.example.testapp.viewModels.CurrentUserViewModel
import com.example.testapp.viewModels.RegistrationScreenViewModel import com.example.testapp.viewModels.RegistrationScreenViewModel
import kotlinx.coroutines.async import kotlinx.coroutines.async

View File

@ -1,16 +1,10 @@
package com.example.testapp.viewModels package com.example.testapp.viewModels
import androidx.compose.runtime.getValue
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 com.example.testapp.room.models.User import com.example.testapp.data.room.models.User
import com.example.testapp.room.repository.basic.UserRepository import com.example.testapp.data.room.repository.basic.UserRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filterNotNull
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() {

View File

@ -1,24 +1,18 @@
package com.example.testapp.viewModels package com.example.testapp.viewModels
import androidx.compose.runtime.getValue
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 com.example.testapp.data.room.models.Coin
import com.example.testapp.room.models.Coin import com.example.testapp.data.room.models.Deal
import com.example.testapp.room.models.Deal import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.room.models.WalletItem import com.example.testapp.data.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.data.room.repository.basic.DealRepository
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.data.room.repository.basic.WalletItemRepository
import com.example.testapp.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow 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(

View File

@ -5,15 +5,14 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData import androidx.paging.PagingData
import androidx.paging.cachedIn import androidx.paging.cachedIn
import com.example.testapp.room.models.Coin import com.example.testapp.data.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.data.room.models.Deal
import com.example.testapp.room.models.WalletItem import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.data.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.data.room.repository.basic.DealRepository
import com.example.testapp.room.repository.basic.WalletItemRepository import com.example.testapp.data.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow 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 import java.util.Date

View File

@ -1,12 +1,9 @@
package com.example.testapp.viewModels package com.example.testapp.viewModels
import androidx.compose.runtime.getValue
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 com.example.testapp.room.models.User import com.example.testapp.data.room.models.User
import com.example.testapp.room.repository.basic.UserRepository import com.example.testapp.data.room.repository.basic.UserRepository
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View File

@ -1,14 +1,11 @@
package com.example.testapp.viewModels package com.example.testapp.viewModels
import androidx.compose.runtime.getValue
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 com.example.testapp.room.models.Coin import com.example.testapp.data.room.models.Coin
import com.example.testapp.room.models.Deal import com.example.testapp.data.room.models.Deal
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.data.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.DealRepository import com.example.testapp.data.room.repository.basic.DealRepository
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first

View File

@ -4,8 +4,8 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.testapp.room.models.User import com.example.testapp.data.room.models.User
import com.example.testapp.room.repository.basic.UserRepository import com.example.testapp.data.room.repository.basic.UserRepository
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View File

@ -1,24 +1,15 @@
package com.example.testapp.viewModels package com.example.testapp.viewModels
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
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.PagingData
import androidx.paging.cachedIn import androidx.paging.cachedIn
import androidx.paging.filter import com.example.testapp.data.room.models.Coin
import com.example.testapp.room.models.Coin import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.room.models.WalletItem import com.example.testapp.data.room.repository.basic.CoinRepository
import com.example.testapp.room.repository.basic.CoinRepository import com.example.testapp.data.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.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow 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