First big update :)
This commit is contained in:
parent
2fdc2d5ba3
commit
2b69f0fc24
Binary file not shown.
@ -109,6 +109,11 @@ interface ServerService {
|
||||
@GET(ApiRoutes.TANK)
|
||||
suspend fun getTanks(): List<TankRemote>
|
||||
|
||||
@GET(ApiRoutes.TANK)
|
||||
suspend fun getTanks(
|
||||
@Query("id") id: List<Long>
|
||||
): List<TankRemote>
|
||||
|
||||
@GET("${ApiRoutes.TANK}/{id}")
|
||||
suspend fun getTank(
|
||||
@Path("id") id: Long
|
||||
@ -144,8 +149,10 @@ interface ServerService {
|
||||
|
||||
// :[USER_TANK_CROSS_REF]
|
||||
|
||||
@GET(ApiRoutes.USER_TANK)
|
||||
suspend fun getUserTankCrossRef(): List<UserTankCrossRefRemote>
|
||||
@GET("${ApiRoutes.USER_TANK}")
|
||||
suspend fun getUserTankCrossRef(
|
||||
@Query("id") id: Long
|
||||
): List<UserTankCrossRefRemote>
|
||||
|
||||
@POST(ApiRoutes.USER_TANK)
|
||||
suspend fun insertUserTankCrossRef(
|
||||
|
@ -7,13 +7,11 @@ import androidx.paging.RemoteMediator
|
||||
import androidx.room.withTransaction
|
||||
import retrofit2.HttpException
|
||||
import ru.ulstu.`is`.pmu.tank.api.ServerService
|
||||
import ru.ulstu.`is`.pmu.tank.api.model.toNation
|
||||
import ru.ulstu.`is`.pmu.tank.api.model.toTank
|
||||
import ru.ulstu.`is`.pmu.tank.database.AppDatabase
|
||||
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||
import ru.ulstu.`is`.pmu.tank.model.RemoteKeyType
|
||||
import ru.ulstu.`is`.pmu.tank.model.RemoteKeys
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineNationRepository
|
||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineRemoteKeyRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineTankRepository
|
||||
import java.io.IOException
|
||||
@ -24,7 +22,7 @@ class TankRemoteMediator(
|
||||
private val dbTankRepository: OfflineTankRepository,
|
||||
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
|
||||
private val database: AppDatabase
|
||||
) : RemoteMediator<Int, Nation>() {
|
||||
) : RemoteMediator<Int, Tank>() {
|
||||
|
||||
override suspend fun initialize(): InitializeAction {
|
||||
return InitializeAction.LAUNCH_INITIAL_REFRESH
|
||||
@ -32,7 +30,7 @@ class TankRemoteMediator(
|
||||
|
||||
override suspend fun load(
|
||||
loadType: LoadType,
|
||||
state: PagingState<Int, Nation>
|
||||
state: PagingState<Int, Tank>
|
||||
): MediatorResult {
|
||||
val page = when (loadType) {
|
||||
LoadType.REFRESH -> {
|
||||
@ -85,26 +83,26 @@ class TankRemoteMediator(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Nation>): RemoteKeys? {
|
||||
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Tank>): RemoteKeys? {
|
||||
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
|
||||
?.let { nation ->
|
||||
dbRemoteKeyRepository.getAllRemoteKeys(nation.uid!!.toInt(), RemoteKeyType.NATION)
|
||||
?.let { tank ->
|
||||
dbRemoteKeyRepository.getAllRemoteKeys(tank.tankId!!.toInt(), RemoteKeyType.NATION)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Nation>): RemoteKeys? {
|
||||
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Tank>): RemoteKeys? {
|
||||
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
|
||||
?.let { nation ->
|
||||
dbRemoteKeyRepository.getAllRemoteKeys(nation.uid!!.toInt(), RemoteKeyType.NATION)
|
||||
?.let { tank ->
|
||||
dbRemoteKeyRepository.getAllRemoteKeys(tank.tankId!!.toInt(), RemoteKeyType.NATION)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getRemoteKeyClosestToCurrentPosition(
|
||||
state: PagingState<Int, Nation>
|
||||
state: PagingState<Int, Tank>
|
||||
): RemoteKeys? {
|
||||
return state.anchorPosition?.let { position ->
|
||||
state.closestItemToPosition(position)?.uid?.let { nationUid ->
|
||||
dbRemoteKeyRepository.getAllRemoteKeys(nationUid.toInt(), RemoteKeyType.NATION)
|
||||
state.closestItemToPosition(position)?.tankId?.let { tankUid ->
|
||||
dbRemoteKeyRepository.getAllRemoteKeys(tankUid.toInt(), RemoteKeyType.NATION)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,27 @@
|
||||
package ru.ulstu.`is`.pmu.tank.api.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import ru.ulstu.`is`.pmu.tank.database.DateSerializer
|
||||
import ru.ulstu.`is`.pmu.tank.model.Level
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
import java.util.Date
|
||||
|
||||
@Serializable
|
||||
data class UserTankCrossRefRemote (
|
||||
val id: Long = 0,
|
||||
val tankId: Long = 0
|
||||
val tankId: Long = 0,
|
||||
@Serializable(with = DateSerializer::class)
|
||||
val date: Date = Date()
|
||||
)
|
||||
|
||||
fun UserTankCrossRefRemote.toUserTankCrossRef(): UserTankCrossRef = UserTankCrossRef(
|
||||
userId = id,
|
||||
tankId = tankId
|
||||
tankId = tankId,
|
||||
date = date
|
||||
)
|
||||
|
||||
fun UserTankCrossRef.toRemote(): UserTankCrossRefRemote = UserTankCrossRefRemote(
|
||||
id = userId,
|
||||
tankId = tankId
|
||||
tankId = tankId,
|
||||
date = date
|
||||
)
|
@ -26,6 +26,7 @@ import ru.ulstu.`is`.pmu.tank.repository.OfflineUsersTanksRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.TankRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.UsersTanksRepository
|
||||
import java.nio.file.Files.find
|
||||
import java.util.Date
|
||||
|
||||
class RestTankRepository (
|
||||
private val service: ServerService,
|
||||
@ -38,13 +39,13 @@ class RestTankRepository (
|
||||
|
||||
override suspend fun getForUserAll(userId: Long): List<Tank> {
|
||||
val totalList: List<Tank> = getAll()
|
||||
val totalUserTankList: List<UserTankCrossRef> = service.getUserTankCrossRef().map{ it.toUserTankCrossRef() }
|
||||
val totalUserTankList: List<UserTankCrossRef> = service.getUserTankCrossRef(100L).map{ it.toUserTankCrossRef() }
|
||||
|
||||
//спискок, который вернём
|
||||
var supportList = ArrayList<Tank>()
|
||||
|
||||
//вспомогательный список для проверки отсутствия танка у пользователя
|
||||
var notToUser: List<UserTankCrossRef> = totalList.map{ UserTankCrossRef(userId, it.tankId!!) }
|
||||
var notToUser: List<UserTankCrossRef> = totalList.map{ UserTankCrossRef(userId, it.tankId!!, Date()) }
|
||||
|
||||
if (totalUserTankList.isEmpty()){
|
||||
return totalList
|
||||
@ -72,26 +73,31 @@ class RestTankRepository (
|
||||
val totalNationList: List<Nation> = service.getAllNations().map { it.toNation() }
|
||||
|
||||
//все имеющиеся танки у пользователя
|
||||
val totalUserTankList: List<UserTankCrossRef> = service.getUserTankCrossRef().map{ it.toUserTankCrossRef() }
|
||||
val totalUserTankList: List<UserTankCrossRef> = service.getUserTankCrossRef(100L).map{ it.toUserTankCrossRef() }
|
||||
|
||||
//спискок, который вернём
|
||||
var supportList = ArrayList<TankWithNationAndLevel>()
|
||||
|
||||
//вспомогательный список для проверки наличия танка у пользователя
|
||||
var notToUser: List<UserTankCrossRef> = totalList.map{ UserTankCrossRef(userId, it.tankId!!) }
|
||||
//список id-шников танков пользователя
|
||||
var idList = ArrayList<Long>()
|
||||
|
||||
totalUserTankList.forEach(){ tank ->
|
||||
idList.add(tank.tankId)
|
||||
}
|
||||
|
||||
//список танков пользователя
|
||||
var simpleTankList = service.getTanks(idList)
|
||||
|
||||
if (totalUserTankList.isEmpty()){
|
||||
return listOf()
|
||||
} else {
|
||||
notToUser.forEach(){userTank ->
|
||||
if(totalUserTankList.contains(userTank)){
|
||||
val tank = totalList.firstOrNull { it.tankId == userTank.tankId }!!
|
||||
supportList.add(
|
||||
TankWithNationAndLevel(tank.tankId, tank.name, tank.price, tank.miniature,
|
||||
totalLevelList.first { it.uid == tank.levelId }.level,
|
||||
totalNationList.first { it.uid == tank.nationId }.nationName)
|
||||
)
|
||||
}
|
||||
simpleTankList.forEach(){userTank ->
|
||||
val tank = totalList.firstOrNull { it.tankId == userTank.id }!!
|
||||
supportList.add(
|
||||
TankWithNationAndLevel(tank.tankId, tank.name, tank.price, tank.miniature,
|
||||
totalLevelList.first { it.uid == tank.levelId }.level,
|
||||
totalNationList.first { it.uid == tank.nationId }.nationName)
|
||||
)
|
||||
}
|
||||
return supportList
|
||||
}
|
||||
@ -101,8 +107,8 @@ class RestTankRepository (
|
||||
service.insertTank(tank.toRemote())
|
||||
}
|
||||
|
||||
override suspend fun buyTank(tankId: Long, userId: Long) {
|
||||
service.insertUserTankCrossRef(UserTankCrossRefRemote(userId, tankId))
|
||||
override suspend fun buyTank(tankId: Long, userId: Long, date: Date) {
|
||||
service.insertUserTankCrossRef(UserTankCrossRefRemote(userId, tankId, date))
|
||||
}
|
||||
|
||||
override suspend fun insertMany(tankList: List<Tank>) {
|
||||
|
@ -25,6 +25,7 @@ import ru.ulstu.`is`.pmu.tank.model.TankImage
|
||||
import ru.ulstu.`is`.pmu.tank.model.User
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserRole
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
import java.util.Date
|
||||
|
||||
//тут, собственно говоря, всё и мутится с БД :)))
|
||||
@Database(
|
||||
@ -51,7 +52,7 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun remoteKeysDao(): RemoteKeysDao
|
||||
|
||||
companion object {
|
||||
private const val DB_NAME: String = "22-db"
|
||||
private const val DB_NAME: String = "23-db"
|
||||
|
||||
@Volatile
|
||||
private var INSTANCE: AppDatabase? = null
|
||||
@ -150,11 +151,11 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
userDao.insert(user)
|
||||
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank1.tankId ?: 0))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank3.tankId ?: 0))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank5.tankId ?: 0))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank7.tankId ?: 0))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank9.tankId ?: 0))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank1.tankId ?: 0, Date()))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank3.tankId ?: 0, Date()))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank5.tankId ?: 0, Date()))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank7.tankId ?: 0, Date()))
|
||||
userDao.insert(UserTankCrossRef(user.userId, tank9.tankId ?: 0, Date()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
package ru.ulstu.`is`.pmu.tank.database
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
@Serializer(forClass = Date::class)
|
||||
object DateSerializer : KSerializer<Date> {
|
||||
private val dateFormat =
|
||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") // Adjust the format as needed
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Date) {
|
||||
encoder.encodeString(dateFormat.format(value))
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): Date {
|
||||
return dateFormat.parse(decoder.decodeString()) ?: Date()
|
||||
}
|
||||
}
|
@ -3,13 +3,9 @@ package ru.ulstu.`is`.pmu.tank.model
|
||||
import android.graphics.Bitmap
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.TypeConverters
|
||||
import com.application.ui.getEmptyBitmap
|
||||
import ru.ulstu.`is`.pmu.R
|
||||
import ru.ulstu.`is`.pmu.tank.database.Converters
|
||||
|
||||
@Entity(
|
||||
tableName = "tanks",
|
||||
|
@ -1,11 +1,13 @@
|
||||
package ru.ulstu.`is`.pmu.tank.model
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import java.util.Date
|
||||
|
||||
//many to many for user and tank
|
||||
@Entity(
|
||||
@ -14,14 +16,37 @@ import org.jetbrains.annotations.NotNull
|
||||
)
|
||||
data class UserTankCrossRef(
|
||||
val userId: Long,
|
||||
val tankId: Long
|
||||
val tankId: Long,
|
||||
@ColumnInfo(name = "date")
|
||||
val date: Date,
|
||||
){
|
||||
companion object {
|
||||
fun getEmpty(): UserTankCrossRef {
|
||||
return UserTankCrossRef(
|
||||
userId = 0,
|
||||
tankId = 0
|
||||
tankId = 0,
|
||||
date = Date()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as UserTankCrossRef
|
||||
|
||||
if (userId != other.userId) return false
|
||||
if (tankId != other.tankId) return false
|
||||
if (date != other.date) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = userId.hashCode()
|
||||
result = 31 * result + tankId.hashCode()
|
||||
result = 31 * result + date.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import ru.ulstu.`is`.pmu.tank.model.TankExtra
|
||||
import ru.ulstu.`is`.pmu.tank.model.TankImage
|
||||
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
import java.util.Date
|
||||
|
||||
class OfflineTankRepository(
|
||||
private val tankDao: TankDao,
|
||||
@ -27,8 +28,8 @@ class OfflineTankRepository(
|
||||
tankDao.insert(tank)
|
||||
}
|
||||
|
||||
override suspend fun buyTank(tankId: Long, userId: Long) {
|
||||
usersTanksDao.insert(UserTankCrossRef(userId, tankId))
|
||||
override suspend fun buyTank(tankId: Long, userId: Long, date: Date) {
|
||||
usersTanksDao.insert(UserTankCrossRef(userId, tankId, date))
|
||||
}
|
||||
|
||||
override suspend fun insertMany(tankList: List<Tank>) {
|
||||
|
@ -5,6 +5,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||
import ru.ulstu.`is`.pmu.tank.model.TankExtra
|
||||
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||
import java.util.Date
|
||||
|
||||
interface TankRepository {
|
||||
suspend fun getAll(): List<Tank>
|
||||
@ -12,7 +13,7 @@ interface TankRepository {
|
||||
suspend fun getTank(uid: Long): Tank
|
||||
suspend fun getUserTanks(uid: Long): List<TankWithNationAndLevel>
|
||||
suspend fun insertTank(tank: Tank, image: Bitmap)
|
||||
suspend fun buyTank(tankId: Long, userId: Long)
|
||||
suspend fun buyTank(tankId: Long, userId: Long, date: Date)
|
||||
suspend fun insertMany(tankList: List<Tank>)
|
||||
suspend fun updateTank(tank: Tank, image: Bitmap)
|
||||
suspend fun deleteTank(tank: Tank)
|
||||
|
@ -189,20 +189,59 @@
|
||||
"password": "Tujh2003",
|
||||
"role": 1,
|
||||
"balance": 12300000
|
||||
},
|
||||
{
|
||||
"id": 101,
|
||||
"nickname": "KorbenDallas",
|
||||
"email": "korbenDetka@mail.ru",
|
||||
"password": "Korben2013",
|
||||
"role": 0,
|
||||
"balance": 11223300
|
||||
},
|
||||
{
|
||||
"id": 102,
|
||||
"nickname": "Amway921",
|
||||
"email": "amway@mail.ru",
|
||||
"password": "Amway2013",
|
||||
"role": 0,
|
||||
"balance": 11223300
|
||||
}
|
||||
],
|
||||
"users_tanks": [
|
||||
{
|
||||
"id": 100,
|
||||
"tankId": 1
|
||||
"tankId": 1,
|
||||
"date": "2023-12-12T12:06:14.720+0000"
|
||||
},
|
||||
{
|
||||
"id": 100,
|
||||
"tankId": 5
|
||||
"tankId": 5,
|
||||
"date": "2023-12-13T12:06:14.720+0000"
|
||||
},
|
||||
{
|
||||
"id": 100,
|
||||
"tankId": 6
|
||||
"tankId": 6,
|
||||
"date": "2023-12-14T12:06:14.720+0000"
|
||||
},
|
||||
{
|
||||
"id": 101,
|
||||
"tankId": 6,
|
||||
"date": "2023-12-15T12:06:14.720+0000"
|
||||
},
|
||||
{
|
||||
"id": 101,
|
||||
"tankId": 11,
|
||||
"date": "2023-12-16T12:06:14.720+0000"
|
||||
},
|
||||
{
|
||||
"id": 102,
|
||||
"tankId": 6,
|
||||
"date": "2023-12-17T12:06:14.720+0000"
|
||||
},
|
||||
{
|
||||
"id": 102,
|
||||
"tankId": 1,
|
||||
"date": "2023-12-18T12:06:14.720+0000"
|
||||
}
|
||||
]
|
||||
}
|
4
compose/server/package-lock.json
generated
4
compose/server/package-lock.json
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "fake-db",
|
||||
"name": "20-db",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "fake-db",
|
||||
"name": "20-db",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"json-server": "0.17.4"
|
||||
|
Loading…
Reference in New Issue
Block a user