Чё-то делается
This commit is contained in:
parent
178d0953d3
commit
9fea8e3bc4
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8
compose/.idea/modules/app/pmu-demo.app.iml
generated
8
compose/.idea/modules/app/pmu-demo.app.iml
generated
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module version="4">
|
|
||||||
<component name="ModuleClassLoaderOverlays">
|
|
||||||
<paths>
|
|
||||||
<option value="C:\Users\egore\AppData\Local\Temp\overlay16197097467506260191" />
|
|
||||||
</paths>
|
|
||||||
</component>
|
|
||||||
</module>
|
|
@ -0,0 +1,11 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api
|
||||||
|
|
||||||
|
object ApiRoutes {
|
||||||
|
const val BASE = "http://10.0.2.2:8079/"
|
||||||
|
const val USER = "users"
|
||||||
|
const val LEVEL = "level"
|
||||||
|
const val NATION = "nation"
|
||||||
|
const val TANK = "TANK"
|
||||||
|
const val USER_TANK = "userTanks"
|
||||||
|
const val NOT_USER_TANK = "notUserTanks"
|
||||||
|
}
|
@ -0,0 +1,184 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api
|
||||||
|
|
||||||
|
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
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.LevelRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.NationRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.TankRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.TankWithNationAndLevelRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.UserRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.UserTankCrossRefRemote
|
||||||
|
|
||||||
|
interface ServerService {
|
||||||
|
// :[USER]
|
||||||
|
|
||||||
|
@GET(ApiRoutes.USER)
|
||||||
|
suspend fun getUserByEmail(
|
||||||
|
@Query("email") email: String
|
||||||
|
): UserRemote
|
||||||
|
|
||||||
|
@POST(ApiRoutes.USER)
|
||||||
|
suspend fun insertUser(
|
||||||
|
@Body user: UserRemote
|
||||||
|
): UserRemote
|
||||||
|
|
||||||
|
@PUT("${ApiRoutes.USER}/{id}")
|
||||||
|
suspend fun updateUser(
|
||||||
|
@Path("id") id: Long,
|
||||||
|
@Body user: UserRemote
|
||||||
|
): UserRemote
|
||||||
|
|
||||||
|
|
||||||
|
// ![USER]
|
||||||
|
|
||||||
|
// :[LEVEL]
|
||||||
|
|
||||||
|
@GET(ApiRoutes.LEVEL)
|
||||||
|
suspend fun getLevels(): List<LevelRemote>
|
||||||
|
|
||||||
|
@GET("${ApiRoutes.LEVEL}/{id}")
|
||||||
|
suspend fun getLevel(
|
||||||
|
@Path("id") id: Long
|
||||||
|
): LevelRemote
|
||||||
|
|
||||||
|
@POST(ApiRoutes.LEVEL)
|
||||||
|
suspend fun insertLevel(
|
||||||
|
@Body level: LevelRemote
|
||||||
|
): LevelRemote
|
||||||
|
|
||||||
|
@PUT("${ApiRoutes.LEVEL}/{id}")
|
||||||
|
suspend fun updateLevel(
|
||||||
|
@Path("id") id: Long,
|
||||||
|
@Body level: LevelRemote
|
||||||
|
): LevelRemote
|
||||||
|
|
||||||
|
@DELETE("${ApiRoutes.LEVEL}/{id}")
|
||||||
|
suspend fun deleteLevel(
|
||||||
|
@Path("id") id: Long
|
||||||
|
): LevelRemote
|
||||||
|
|
||||||
|
// ![LEVEL]
|
||||||
|
|
||||||
|
// :[NATION]
|
||||||
|
|
||||||
|
@GET(ApiRoutes.NATION)
|
||||||
|
suspend fun getNations(
|
||||||
|
@Query("_page") page: Int,
|
||||||
|
@Query("_limit") limit: Int
|
||||||
|
): List<NationRemote>
|
||||||
|
|
||||||
|
@GET("${ApiRoutes.NATION}/{id}")
|
||||||
|
suspend fun getNation(
|
||||||
|
@Path("id") id: Long
|
||||||
|
): NationRemote
|
||||||
|
|
||||||
|
@POST(ApiRoutes.NATION)
|
||||||
|
suspend fun insertNation(
|
||||||
|
@Body product: NationRemote
|
||||||
|
): NationRemote
|
||||||
|
|
||||||
|
@PUT("${ApiRoutes.NATION}/{id}")
|
||||||
|
suspend fun updateNation(
|
||||||
|
@Path("id") id: Long,
|
||||||
|
@Body product: NationRemote
|
||||||
|
): NationRemote
|
||||||
|
|
||||||
|
@DELETE("${ApiRoutes.NATION}/{id}")
|
||||||
|
suspend fun deleteNation(
|
||||||
|
@Path("id") id: Long
|
||||||
|
): NationRemote
|
||||||
|
|
||||||
|
// ![NATION]
|
||||||
|
|
||||||
|
// :[TANK]
|
||||||
|
|
||||||
|
@GET(ApiRoutes.TANK)
|
||||||
|
suspend fun getTanks(): List<TankRemote>
|
||||||
|
|
||||||
|
@GET("${ApiRoutes.TANK}/{id}")
|
||||||
|
suspend fun getTank(
|
||||||
|
@Path("id") id: Long
|
||||||
|
): TankRemote
|
||||||
|
|
||||||
|
@GET("${ApiRoutes.TANK}/forPurchase")
|
||||||
|
suspend fun getTanksForPurchase(
|
||||||
|
@Path("id") userId: Long
|
||||||
|
): List<TankRemote>
|
||||||
|
|
||||||
|
@GET("${ApiRoutes.TANK}/myHangar")
|
||||||
|
suspend fun getTanksFromHangar(
|
||||||
|
@Path("id") userId: Long
|
||||||
|
): List<TankWithNationAndLevelRemote>
|
||||||
|
|
||||||
|
@POST(ApiRoutes.TANK)
|
||||||
|
suspend fun insertTank(
|
||||||
|
@Body tank: TankRemote
|
||||||
|
): TankRemote
|
||||||
|
|
||||||
|
@PUT("${ApiRoutes.TANK}/{id}")
|
||||||
|
suspend fun updateTank(
|
||||||
|
@Path("id") id: Long,
|
||||||
|
@Body tank: TankRemote
|
||||||
|
): TankRemote
|
||||||
|
|
||||||
|
@DELETE("${ApiRoutes.TANK}/{id}")
|
||||||
|
suspend fun deleteTank(
|
||||||
|
@Path("id") id: Long
|
||||||
|
): TankRemote
|
||||||
|
|
||||||
|
// ![TANK]
|
||||||
|
|
||||||
|
// :[USER_TANK_CROSS_REF]
|
||||||
|
|
||||||
|
@GET("${ApiRoutes.USER_TANK}?_hangar={userId}")
|
||||||
|
suspend fun getUserTankCrossRef(
|
||||||
|
@Path("userId") userId: Long,
|
||||||
|
): List<UserTankCrossRefRemote>
|
||||||
|
|
||||||
|
@POST(ApiRoutes.USER_TANK)
|
||||||
|
suspend fun insertUserTankCrossRef(
|
||||||
|
@Body tank: UserTankCrossRefRemote
|
||||||
|
) : UserTankCrossRefRemote
|
||||||
|
|
||||||
|
@DELETE("${ApiRoutes.USER_TANK}/deleteMyTank")
|
||||||
|
suspend fun deleteUserTankCrossRef(
|
||||||
|
@Body tank: UserTankCrossRefRemote
|
||||||
|
): UserTankCrossRefRemote
|
||||||
|
|
||||||
|
// ![USER_TANK_CROSS_REF]
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val BASE_URL = ApiRoutes.BASE
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: ServerService? = null
|
||||||
|
|
||||||
|
fun getInstance(): ServerService {
|
||||||
|
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(ServerService::class.java)
|
||||||
|
.also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.mediator
|
||||||
|
|
||||||
|
import androidx.paging.ExperimentalPagingApi
|
||||||
|
import androidx.paging.LoadType
|
||||||
|
import androidx.paging.PagingState
|
||||||
|
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.toLevel
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toNation
|
||||||
|
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.repository.OfflineRemoteKeyRepository
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPagingApi::class)
|
||||||
|
class NationRemoteMediator(
|
||||||
|
private val service: ServerService,
|
||||||
|
private val dbNationRepository: OfflineNationRepository,
|
||||||
|
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
|
||||||
|
private val database: AppDatabase
|
||||||
|
) : RemoteMediator<Int, Nation>() {
|
||||||
|
|
||||||
|
override suspend fun initialize(): InitializeAction {
|
||||||
|
return InitializeAction.LAUNCH_INITIAL_REFRESH
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun load(
|
||||||
|
loadType: LoadType,
|
||||||
|
state: PagingState<Int, Nation>
|
||||||
|
): 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 nations = service.getNations(page, state.config.pageSize).map { it.toNation() }
|
||||||
|
val endOfPaginationReached = nations.isEmpty()
|
||||||
|
|
||||||
|
database.withTransaction {
|
||||||
|
if (loadType == LoadType.REFRESH) {
|
||||||
|
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.NATION)
|
||||||
|
dbNationRepository.deleteNations()
|
||||||
|
}
|
||||||
|
|
||||||
|
val prevKey = if (page == 1) null else page - 1
|
||||||
|
val nextKey = if (endOfPaginationReached) null else page + 1
|
||||||
|
val keys = nations.map {
|
||||||
|
RemoteKeys(
|
||||||
|
entityId = it.uid!!.toInt(),
|
||||||
|
type = RemoteKeyType.NATION,
|
||||||
|
prevKey = prevKey,
|
||||||
|
nextKey = nextKey
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbRemoteKeyRepository.createRemoteKeys(keys)
|
||||||
|
dbNationRepository.insertNations(nations)
|
||||||
|
}
|
||||||
|
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, Nation>): RemoteKeys? {
|
||||||
|
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
|
||||||
|
?.let { nation ->
|
||||||
|
dbRemoteKeyRepository.getAllRemoteKeys(nation.uid!!.toInt(), RemoteKeyType.NATION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Nation>): RemoteKeys? {
|
||||||
|
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
|
||||||
|
?.let { nation ->
|
||||||
|
dbRemoteKeyRepository.getAllRemoteKeys(nation.uid!!.toInt(), RemoteKeyType.NATION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getRemoteKeyClosestToCurrentPosition(
|
||||||
|
state: PagingState<Int, Nation>
|
||||||
|
): RemoteKeys? {
|
||||||
|
return state.anchorPosition?.let { position ->
|
||||||
|
state.closestItemToPosition(position)?.uid?.let { nationUid ->
|
||||||
|
dbRemoteKeyRepository.getAllRemoteKeys(nationUid.toInt(), RemoteKeyType.NATION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.model
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Level
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class LevelRemote (
|
||||||
|
val uid: Long = 0,
|
||||||
|
val level: Int = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
fun LevelRemote.toLevel(): Level = Level(
|
||||||
|
uid,
|
||||||
|
level
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Level.toRemote(): LevelRemote = LevelRemote(
|
||||||
|
uid!!,
|
||||||
|
level
|
||||||
|
)
|
@ -0,0 +1,20 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class NationRemote(
|
||||||
|
val uid: Long = 0,
|
||||||
|
val nationName: String = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
fun NationRemote.toNation(): Nation = Nation(
|
||||||
|
uid,
|
||||||
|
nationName
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Nation.toRemote(): NationRemote = NationRemote(
|
||||||
|
uid!!,
|
||||||
|
nationName
|
||||||
|
)
|
@ -0,0 +1,38 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.model
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import com.application.ui.toBase64
|
||||||
|
import com.application.ui.toBitmap
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class TankRemote(
|
||||||
|
val tankId: Long = 0,
|
||||||
|
val name: String = "",
|
||||||
|
val price: Int = 0,
|
||||||
|
val miniature: String = "",
|
||||||
|
val imageId: Long = 0,
|
||||||
|
val levelId: Long = 0,
|
||||||
|
val nationId: Long = 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun TankRemote.toTank(): Tank = Tank(
|
||||||
|
tankId = tankId,
|
||||||
|
name = name,
|
||||||
|
price = price,
|
||||||
|
miniature = miniature.toBitmap(),
|
||||||
|
imageId = imageId,
|
||||||
|
levelId = levelId,
|
||||||
|
nationId = nationId
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Tank.toRemote(): TankRemote = TankRemote(
|
||||||
|
tankId = tankId!!,
|
||||||
|
name = name,
|
||||||
|
price = price,
|
||||||
|
miniature = miniature.toBase64(),
|
||||||
|
imageId = imageId,
|
||||||
|
levelId = levelId!!,
|
||||||
|
nationId = nationId!!
|
||||||
|
)
|
@ -0,0 +1,34 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.model
|
||||||
|
|
||||||
|
import com.application.ui.toBase64
|
||||||
|
import com.application.ui.toBitmap
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class TankWithNationAndLevelRemote(
|
||||||
|
val tankId: Long,
|
||||||
|
val name: String,
|
||||||
|
val price: Int,
|
||||||
|
val image: String,
|
||||||
|
val level: Int,
|
||||||
|
val nationName: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun TankWithNationAndLevelRemote.toTankWithNationAndLevel(): TankWithNationAndLevel = TankWithNationAndLevel(
|
||||||
|
tankId = tankId,
|
||||||
|
name = name,
|
||||||
|
price = price,
|
||||||
|
image = image.toBitmap(),
|
||||||
|
level = level,
|
||||||
|
nationName = nationName
|
||||||
|
)
|
||||||
|
|
||||||
|
fun TankWithNationAndLevel.toRemote(): TankWithNationAndLevelRemote = TankWithNationAndLevelRemote(
|
||||||
|
tankId = tankId!!,
|
||||||
|
name = name,
|
||||||
|
price = price,
|
||||||
|
image = image.toBase64(),
|
||||||
|
level = level,
|
||||||
|
nationName = nationName
|
||||||
|
)
|
@ -0,0 +1,33 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.User
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.UserRole
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UserRemote (
|
||||||
|
val id: Long = 0,
|
||||||
|
val nickname: String = "",
|
||||||
|
val email: String = " ",
|
||||||
|
val role: Int = -1,
|
||||||
|
val password: String = "",
|
||||||
|
val balance: Int = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
fun UserRemote.toUser(): User = User(
|
||||||
|
userId = id,
|
||||||
|
nickname = nickname,
|
||||||
|
email = email,
|
||||||
|
password = password,
|
||||||
|
role = enumValues<UserRole>()[role],
|
||||||
|
balance = balance
|
||||||
|
)
|
||||||
|
|
||||||
|
fun User.toRemote(): UserRemote = UserRemote(
|
||||||
|
id = userId,
|
||||||
|
nickname = nickname,
|
||||||
|
email = email,
|
||||||
|
password = password,
|
||||||
|
role = role.ordinal,
|
||||||
|
balance = balance
|
||||||
|
)
|
@ -0,0 +1,9 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UserTankCrossRefRemote (
|
||||||
|
val userId: Long = 0,
|
||||||
|
val tankId: Long = 0
|
||||||
|
)
|
@ -0,0 +1,51 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.repository
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.ServerService
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toLevel
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Level
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.LevelWithTanks
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.LevelRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.OfflineLevelRepository
|
||||||
|
|
||||||
|
class RestLevelRepository(
|
||||||
|
private val service: ServerService,
|
||||||
|
private val dbLevelRepository: OfflineLevelRepository,
|
||||||
|
) : LevelRepository {
|
||||||
|
override suspend fun getAllLevels(): List<Level> {
|
||||||
|
dbLevelRepository.deleteAll()
|
||||||
|
val levels = service.getLevels().map { it.toLevel() }
|
||||||
|
dbLevelRepository.insertMany(levels)
|
||||||
|
return levels
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getSimpleLevel(uid: Long): Level {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFullLevel(uid: Long): Flow<LevelWithTanks?> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertLevel(level: Level) {
|
||||||
|
service.insertLevel(level.toRemote())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertMany(levels: List<Level>) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun updateLevel(level: Level) {
|
||||||
|
service.updateLevel(level.uid!!, level.toRemote())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteLevel(level: Level) {
|
||||||
|
service.deleteLevel(level.uid!!)
|
||||||
|
dbLevelRepository.deleteLevel(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteAll() {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.repository
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.paging.ExperimentalPagingApi
|
||||||
|
import androidx.paging.Pager
|
||||||
|
import androidx.paging.PagingConfig
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import androidx.paging.PagingSource
|
||||||
|
import androidx.paging.map
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.ServerService
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.mediator.NationRemoteMediator
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.NationRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toNation
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.database.AppContainer
|
||||||
|
import ru.ulstu.`is`.pmu.tank.database.AppDatabase
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.NationRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.OfflineNationRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.OfflineRemoteKeyRepository
|
||||||
|
|
||||||
|
class RestNationRepository(
|
||||||
|
private val service: ServerService,
|
||||||
|
private val dbNationRepository: OfflineNationRepository,
|
||||||
|
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
|
||||||
|
private val database: AppDatabase
|
||||||
|
) : NationRepository {
|
||||||
|
override suspend fun getAllNations(): List<Nation> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getAll(): Flow<PagingData<Nation>> {
|
||||||
|
@OptIn(ExperimentalPagingApi::class)
|
||||||
|
return Pager(
|
||||||
|
config = PagingConfig(
|
||||||
|
pageSize = 10,
|
||||||
|
enablePlaceholders = false
|
||||||
|
),
|
||||||
|
remoteMediator = NationRemoteMediator(
|
||||||
|
service = service,
|
||||||
|
dbNationRepository = dbNationRepository,
|
||||||
|
dbRemoteKeyRepository = dbRemoteKeyRepository,
|
||||||
|
database = database,
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
dbNationRepository.pagingSource()
|
||||||
|
}.flow
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSimpleNation(uid: Long): Flow<Nation?> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFullNation(uid: Long): Flow<NationWithTanks?> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pagingSource(): PagingSource<Int, Nation> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertNation(nation: Nation) {
|
||||||
|
service.insertNation(nation.toRemote()).toNation()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertNations(nations: List<Nation>) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun updateNation(nation: Nation) {
|
||||||
|
service.updateNation(nation.uid!!, nation.toRemote())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteNation(nation: Nation) {
|
||||||
|
service.deleteNation(nation.uid!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteNations() {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.repository
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.ServerService
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toLevel
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toTank
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toTankWithNationAndLevel
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toUser
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.User
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.OfflineTankRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.OfflineUserRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.TankRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.UserRepository
|
||||||
|
|
||||||
|
class RestTankReppository (
|
||||||
|
private val service: ServerService,
|
||||||
|
private val dbTankRepository: OfflineTankRepository,
|
||||||
|
) : TankRepository {
|
||||||
|
override suspend fun getAll(): List<Tank> {
|
||||||
|
dbTankRepository.deleteAll()
|
||||||
|
val tanks = service.getTanks().map { it.toTank() }
|
||||||
|
dbTankRepository.insertMany(tanks)
|
||||||
|
return tanks
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getForUserAll(userId: Long): List<Tank> {
|
||||||
|
return service.getTanksForPurchase(userId).map { it.toTank() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getTank(uid: Long): Tank {
|
||||||
|
return service.getTank(uid).toTank()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getUserTanks(uid: Long): List<TankWithNationAndLevel> {
|
||||||
|
return service.getTanksFromHangar(uid).map { it.toTankWithNationAndLevel() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertTank(tank: Tank, image: Bitmap) {
|
||||||
|
service.insertTank(tank.toRemote())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertMany(tankList: List<Tank>) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun updateTank(tank: Tank, image: Bitmap) {
|
||||||
|
service.updateTank(tank.tankId!!, tank.toRemote())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteTank(tank: Tank) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun delete(tankId: Long) {
|
||||||
|
service.deleteTank(tankId)
|
||||||
|
dbTankRepository.delete(tankId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteAll() {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.api.repository
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.ServerService
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toLevel
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toRemote
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.toUser
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.Level
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.LevelWithTanks
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.User
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.LevelRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.OfflineLevelRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.OfflineUserRepository
|
||||||
|
import ru.ulstu.`is`.pmu.tank.repository.UserRepository
|
||||||
|
|
||||||
|
class RestUserRepository(
|
||||||
|
private val service: ServerService,
|
||||||
|
private val dbUserRepository: OfflineUserRepository,
|
||||||
|
) : UserRepository {
|
||||||
|
override fun getAllUsers(): Flow<List<User>> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getSimpleUser(email: String): User {
|
||||||
|
return service.getUserByEmail(email).toUser()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertUser(user: User) {
|
||||||
|
service.insertUser(user.toRemote())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun updateUser(user: User) {
|
||||||
|
service.updateUser(user.userId, user.toRemote())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteUser(user: User) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
@ -73,13 +73,11 @@ fun TankList(
|
|||||||
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||||
listNations: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
listNations: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
||||||
) {
|
) {
|
||||||
val tankListUiState by viewModel.tankListUiState.collectAsState()
|
|
||||||
|
|
||||||
// Lazy Column, Pass the numbers array
|
// Lazy Column, Pass the numbers array
|
||||||
if (navController != null) {
|
if (navController != null) {
|
||||||
TankList(
|
TankList(
|
||||||
nations = listNations.nationsListUiState,
|
nations = listNations.nationsListUiState,
|
||||||
listTanks = tankListUiState.tankList
|
listTanks = viewModel.tankListUiState.tankList
|
||||||
) { uid: Long ->
|
) { uid: Long ->
|
||||||
val route = Screen.Constructor.route.replace("{id}", uid.toString())
|
val route = Screen.Constructor.route.replace("{id}", uid.toString())
|
||||||
navController.navigate(route)
|
navController.navigate(route)
|
||||||
|
@ -33,8 +33,6 @@ class TankEditViewModel(
|
|||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if (tankUid > 0) {
|
if (tankUid > 0) {
|
||||||
tankUiState = tankRepository.getTank(tankUid)
|
tankUiState = tankRepository.getTank(tankUid)
|
||||||
.filterNotNull()
|
|
||||||
.first()
|
|
||||||
.toUiState(true)
|
.toUiState(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.filterNotNull
|
|||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.ulstu.`is`.pmu.tank.model.User
|
import ru.ulstu.`is`.pmu.tank.model.User
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.UserRole
|
||||||
import ru.ulstu.`is`.pmu.tank.repository.UserRepository
|
import ru.ulstu.`is`.pmu.tank.repository.UserRepository
|
||||||
|
|
||||||
class UserEditViewModel(
|
class UserEditViewModel(
|
||||||
@ -22,14 +23,12 @@ class UserEditViewModel(
|
|||||||
|
|
||||||
//private val userUid: Long = checkNotNull(savedStateHandle["id"])
|
//private val userUid: Long = checkNotNull(savedStateHandle["id"])
|
||||||
|
|
||||||
private val userUid: Long = 100L
|
private val userEmail: String = "egor@mail.ru"
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if (userUid > 0) {
|
if (userEmail.length > 0) {
|
||||||
userUiState = userRepository.getSimpleUser(userUid)
|
userUiState = userRepository.getSimpleUser(userEmail)
|
||||||
.filterNotNull()
|
|
||||||
.first()
|
|
||||||
.toUiState(true)
|
.toUiState(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,8 +43,8 @@ class UserEditViewModel(
|
|||||||
|
|
||||||
suspend fun saveUser() {
|
suspend fun saveUser() {
|
||||||
if (validateInput()) {
|
if (validateInput()) {
|
||||||
if (userUid > 0) {
|
if (userEmail.length > 0) {
|
||||||
userRepository.updateUser(userUiState.userDetails.toUser(userUid))
|
userRepository.updateUser(userUiState.userDetails.toUser(100L))
|
||||||
} else {
|
} else {
|
||||||
userRepository.insertUser(userUiState.userDetails.toUser())
|
userRepository.insertUser(userUiState.userDetails.toUser())
|
||||||
}
|
}
|
||||||
@ -57,6 +56,7 @@ class UserEditViewModel(
|
|||||||
nickname.isNotBlank()
|
nickname.isNotBlank()
|
||||||
&& email.isNotBlank()
|
&& email.isNotBlank()
|
||||||
&& password.isNotBlank()
|
&& password.isNotBlank()
|
||||||
|
&& role.value > -1
|
||||||
&& balance > 0
|
&& balance > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,6 +71,7 @@ data class UserDetails(
|
|||||||
val nickname: String = "",
|
val nickname: String = "",
|
||||||
val email: String = "",
|
val email: String = "",
|
||||||
val password: String = "",
|
val password: String = "",
|
||||||
|
val role: UserRole = UserRole.USER,
|
||||||
val balance: Int = 0,
|
val balance: Int = 0,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -79,6 +80,7 @@ fun UserDetails.toUser(uid: Long = 0): User = User(
|
|||||||
nickname = nickname,
|
nickname = nickname,
|
||||||
email = email,
|
email = email,
|
||||||
password = password,
|
password = password,
|
||||||
|
role = role,
|
||||||
balance = balance
|
balance = balance
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -86,6 +88,7 @@ fun User.toDetails(): UserDetails = UserDetails(
|
|||||||
nickname = nickname,
|
nickname = nickname,
|
||||||
email = email,
|
email = email,
|
||||||
password = password,
|
password = password,
|
||||||
|
role = role,
|
||||||
balance = balance
|
balance = balance
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package ru.ulstu.`is`.pmu.tank.composeui.list
|
package ru.ulstu.`is`.pmu.tank.composeui.list
|
||||||
|
|
||||||
|
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 kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
@ -15,21 +18,11 @@ class TankListViewModel(
|
|||||||
private val tankRepository: TankRepository,
|
private val tankRepository: TankRepository,
|
||||||
private var userId: Long = 100L
|
private var userId: Long = 100L
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
val tankListUiState: StateFlow<TankListUiState> = tankRepository.getForUserAll(userId).map {
|
var tankListUiState by mutableStateOf(TankListUiState())
|
||||||
TankListUiState(it)
|
private set
|
||||||
}.stateIn(
|
|
||||||
scope = viewModelScope,
|
|
||||||
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
|
||||||
initialValue = TankListUiState()
|
|
||||||
)
|
|
||||||
|
|
||||||
val usersTanksUiState: StateFlow<UserTankListUiState> = tankRepository.getUserTanks(userId).map {
|
var usersTanksUiState by mutableStateOf(UserTankListUiState())
|
||||||
UserTankListUiState(it)
|
private set
|
||||||
}.stateIn(
|
|
||||||
scope = viewModelScope,
|
|
||||||
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
|
||||||
initialValue = UserTankListUiState()
|
|
||||||
)
|
|
||||||
|
|
||||||
suspend fun deleteTank(tank: Tank) {
|
suspend fun deleteTank(tank: Tank) {
|
||||||
tankRepository.deleteTank(tank)
|
tankRepository.deleteTank(tank)
|
||||||
|
@ -30,14 +30,21 @@ interface LevelDao {
|
|||||||
@Query(
|
@Query(
|
||||||
"SELECT level FROM levels where levels.uid = :uid"
|
"SELECT level FROM levels where levels.uid = :uid"
|
||||||
)
|
)
|
||||||
open fun getSimpleLevelUid(uid: Long): Flow<Level?>
|
open fun getSimpleLevelUid(uid: Long): Level
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insert(level: Level)
|
suspend fun insert(level: Level)
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insertMany(level: List<Level>)
|
||||||
|
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
suspend fun update(level: Level)
|
suspend fun update(level: Level)
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
suspend fun delete(level: Level)
|
suspend fun delete(level: Level)
|
||||||
|
|
||||||
|
@Query("DELETE FROM levels")
|
||||||
|
suspend fun deleteAll()
|
||||||
}
|
}
|
@ -23,24 +23,33 @@ interface NationDao {
|
|||||||
suspend fun getNationsWithTanks(): List<NationWithTanks>
|
suspend fun getNationsWithTanks(): List<NationWithTanks>
|
||||||
|
|
||||||
//получить конкретную нацию
|
//получить конкретную нацию
|
||||||
|
@Transaction
|
||||||
@Query("select * from nations where nations.uid = :uid")
|
@Query("select * from nations where nations.uid = :uid")
|
||||||
fun getNationUid(uid: Long): Flow<NationWithTanks?>
|
fun getNationUid(uid: Long): Flow<NationWithTanks?>
|
||||||
|
|
||||||
//получить нацию без списка танков
|
//получить нацию без списка танков
|
||||||
|
@Transaction
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT nationName FROM nations where nations.uid = :uid"
|
"SELECT nationName FROM nations where nations.uid = :uid"
|
||||||
)
|
)
|
||||||
open fun getSimpleNationUid(uid: Long): Flow<Nation?>
|
open fun getSimpleNationUid(uid: Long): Flow<Nation?>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
@Query("SELECT * FROM nations")
|
@Query("SELECT * FROM nations")
|
||||||
fun pagingSource(): PagingSource<Int, Nation>
|
fun pagingSource(): PagingSource<Int, Nation>
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insert(nation: Nation)
|
suspend fun insert(nation: Nation)
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insertMany(nations: List<Nation>)
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
suspend fun update(nation: Nation)
|
suspend fun update(nation: Nation)
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
suspend fun delete(nation: Nation)
|
suspend fun delete(nation: Nation)
|
||||||
|
|
||||||
|
@Query("DELETE FROM nations")
|
||||||
|
suspend fun deleteAll()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.RemoteKeyType
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.RemoteKeys
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
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)
|
||||||
|
}
|
@ -16,33 +16,36 @@ import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
|||||||
@Dao
|
@Dao
|
||||||
interface TankDao {
|
interface TankDao {
|
||||||
@Query("select * from tanks GROUP BY nationId, levelId ORDER BY nationId")
|
@Query("select * from tanks GROUP BY nationId, levelId ORDER BY nationId")
|
||||||
fun getAll(): Flow<List<Tank>>
|
fun getAll(): List<Tank>
|
||||||
|
|
||||||
//получить конкретный танк
|
//получить конкретный танк
|
||||||
@Query("select t.*, ti.data from tanks AS t " +
|
@Query("select t.*, ti.data from tanks AS t " +
|
||||||
"LEFT JOIN tank_images as ti on t.image_id = ti.image_id " +
|
"LEFT JOIN tank_images as ti on t.image_id = ti.image_id " +
|
||||||
"where t.tankId = :uid")
|
"where t.tankId = :uid")
|
||||||
fun getTankUid(uid: Long): Flow<Tank?>
|
fun getTankUid(uid: Long): Tank
|
||||||
|
|
||||||
//получаем все танки пользователя по его Id
|
//получаем все танки пользователя по его Id
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT t.tankId, t.name, t.price, t.image_id, l.level, n.nationName, ti.data AS image FROM UserTankCrossRef AS ut " +
|
"SELECT t.tankId, t.name, t.price, t.image_id, l.level, n.nationName, ti.data AS image FROM users_tanks AS ut " +
|
||||||
"LEFT JOIN tanks as t on ut.tankId = t.tankId " +
|
"LEFT JOIN tanks as t on ut.tankId = t.tankId " +
|
||||||
"LEFT JOIN tank_images as ti on t.image_id = ti.image_id " +
|
"LEFT JOIN tank_images as ti on t.image_id = ti.image_id " +
|
||||||
"LEFT JOIN levels as l on t.levelId = l.uid " +
|
"LEFT JOIN levels as l on t.levelId = l.uid " +
|
||||||
"LEFT JOIN nations as n on t.nationId = n.uid " +
|
"LEFT JOIN nations as n on t.nationId = n.uid " +
|
||||||
"WHERE ut.userId = :uid GROUP BY t.nationId, t.levelId ORDER BY t.nationId"
|
"WHERE ut.userId = :uid GROUP BY t.nationId, t.levelId ORDER BY t.nationId"
|
||||||
)
|
)
|
||||||
fun getUserTanks(uid: Long): Flow<List<TankWithNationAndLevel>>
|
fun getUserTanks(uid: Long): List<TankWithNationAndLevel>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT t.* FROM tanks AS t WHERE t.tankId NOT IN (SELECT ut.tankId FROM UserTankCrossRef AS ut WHERE ut.userId = :uid)"
|
"SELECT t.* FROM tanks AS t WHERE t.tankId NOT IN (SELECT ut.tankId FROM users_tanks AS ut WHERE ut.userId = :uid)"
|
||||||
)
|
)
|
||||||
fun getNotUserTank(uid: Long): Flow<List<Tank>>
|
fun getNotUserTank(uid: Long): List<Tank>
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insert(tank: Tank)
|
suspend fun insert(tank: Tank)
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insertMany(tankList: List<Tank>)
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
suspend fun update(tank: Tank)
|
suspend fun update(tank: Tank)
|
||||||
|
|
||||||
@ -51,4 +54,7 @@ interface TankDao {
|
|||||||
|
|
||||||
@Query("DELETE FROM tanks WHERE tankId = :id")
|
@Query("DELETE FROM tanks WHERE tankId = :id")
|
||||||
suspend fun delete(id: Long)
|
suspend fun delete(id: Long)
|
||||||
|
|
||||||
|
@Query("DELETE FROM tanks")
|
||||||
|
suspend fun deleteAll()
|
||||||
}
|
}
|
@ -11,7 +11,6 @@ import ru.ulstu.`is`.pmu.tank.model.Tank
|
|||||||
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||||
import ru.ulstu.`is`.pmu.tank.model.User
|
import ru.ulstu.`is`.pmu.tank.model.User
|
||||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||||
import ru.ulstu.`is`.pmu.tank.model.UserWithTanks
|
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface UserDao {
|
interface UserDao {
|
||||||
@ -21,7 +20,7 @@ interface UserDao {
|
|||||||
//получить конкретного пользователя
|
//получить конкретного пользователя
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT u.*, t.*, l.level, n.nationName, ti.data AS image FROM users AS u " +
|
"SELECT u.*, t.*, l.level, n.nationName, ti.data AS image FROM users AS u " +
|
||||||
"LEFT JOIN UserTankCrossRef as ut on u.userId = ut.userId " +
|
"LEFT JOIN users_tanks as ut on u.userId = ut.userId " +
|
||||||
"LEFT JOIN tanks as t on ut.tankId = t.tankId " +
|
"LEFT JOIN tanks as t on ut.tankId = t.tankId " +
|
||||||
"LEFT JOIN tank_images as ti on ut.tankId = ti.image_id " +
|
"LEFT JOIN tank_images as ti on ut.tankId = ti.image_id " +
|
||||||
"LEFT JOIN levels as l on t.levelId = l.uid " +
|
"LEFT JOIN levels as l on t.levelId = l.uid " +
|
||||||
@ -30,8 +29,8 @@ interface UserDao {
|
|||||||
)
|
)
|
||||||
fun getUserUid(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>>
|
fun getUserUid(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>>
|
||||||
|
|
||||||
@Query("select * from users where users.userId = :uid")
|
@Query("select * from users where users.email = :email")
|
||||||
fun getSimpleUserUid(uid: Long): Flow<User?>
|
fun getSimpleUserUid(email: String): User
|
||||||
|
|
||||||
//добавить танк в ангар пользователя
|
//добавить танк в ангар пользователя
|
||||||
@Insert
|
@Insert
|
||||||
|
@ -20,8 +20,8 @@ import ru.ulstu.`is`.pmu.tank.model.Nation
|
|||||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||||
import ru.ulstu.`is`.pmu.tank.model.TankImage
|
import ru.ulstu.`is`.pmu.tank.model.TankImage
|
||||||
import ru.ulstu.`is`.pmu.tank.model.User
|
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 ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||||
import ru.ulstu.`is`.pmu.tank.model.UserWithTanks
|
|
||||||
|
|
||||||
//тут, собственно говоря, всё и мутится с БД :)))
|
//тут, собственно говоря, всё и мутится с БД :)))
|
||||||
@Database(entities = [Nation::class, Level::class, Tank::class, User::class, UserTankCrossRef::class, TankImage::class], version = 1, exportSchema = false)
|
@Database(entities = [Nation::class, Level::class, Tank::class, User::class, UserTankCrossRef::class, TankImage::class], version = 1, exportSchema = false)
|
||||||
@ -34,7 +34,7 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
abstract fun tankImageDao() : TankImageDao
|
abstract fun tankImageDao() : TankImageDao
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DB_NAME: String = "19-db"
|
private const val DB_NAME: String = "20-db"
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var INSTANCE: AppDatabase? = null
|
private var INSTANCE: AppDatabase? = null
|
||||||
@ -129,7 +129,7 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
|
|
||||||
//Users
|
//Users
|
||||||
val userDao = database.userDao()
|
val userDao = database.userDao()
|
||||||
val user = User(100L,"3tankista73", "egor@mail.ru", "12032003", 10000000)
|
val user = User(100L,"3tankista73", "egor@mail.ru", "12032003", UserRole.ADMIN, 10000000)
|
||||||
|
|
||||||
userDao.insert(user)
|
userDao.insert(user)
|
||||||
|
|
||||||
@ -148,14 +148,14 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
AppDatabase::class.java,
|
AppDatabase::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(appContext)
|
// populateDatabase(appContext)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
.build()
|
.build()
|
||||||
.also { INSTANCE = it }
|
.also { INSTANCE = it }
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.model
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import androidx.room.TypeConverters
|
||||||
|
|
||||||
|
enum class RemoteKeyType(private val type: String) {
|
||||||
|
NATION(Nation::class.simpleName ?: "Nation");
|
||||||
|
|
||||||
|
@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?
|
||||||
|
)
|
@ -17,6 +17,8 @@ data class User (
|
|||||||
val email: String,
|
val email: String,
|
||||||
@ColumnInfo(name = "password")
|
@ColumnInfo(name = "password")
|
||||||
val password: String,
|
val password: String,
|
||||||
|
@ColumnInfo(name = "role")
|
||||||
|
val role: UserRole,
|
||||||
@ColumnInfo(name = "balance")
|
@ColumnInfo(name = "balance")
|
||||||
val balance: Int
|
val balance: Int
|
||||||
){
|
){
|
||||||
@ -25,8 +27,9 @@ data class User (
|
|||||||
nickname: String,
|
nickname: String,
|
||||||
email: String,
|
email: String,
|
||||||
password: String,
|
password: String,
|
||||||
|
role: UserRole,
|
||||||
balance: Int
|
balance: Int
|
||||||
) : this(0L, nickname, email, password, balance)
|
) : this(0L, nickname, email, password, UserRole.ADMIN, balance)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getUser(index: Long = 0L): User {
|
fun getUser(index: Long = 0L): User {
|
||||||
@ -35,6 +38,7 @@ data class User (
|
|||||||
"3tankista73",
|
"3tankista73",
|
||||||
"egor@mail.ru",
|
"egor@mail.ru",
|
||||||
"1234567890!",
|
"1234567890!",
|
||||||
|
UserRole.USER,
|
||||||
10000000
|
10000000
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -50,6 +54,7 @@ data class User (
|
|||||||
if (nickname != other.nickname) return false
|
if (nickname != other.nickname) return false
|
||||||
if (email != other.email) return false
|
if (email != other.email) return false
|
||||||
if (password != other.password) return false
|
if (password != other.password) return false
|
||||||
|
if (role != other.role) return false
|
||||||
if (balance != other.balance) return false
|
if (balance != other.balance) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -60,6 +65,7 @@ data class User (
|
|||||||
result = 31 * result + nickname.hashCode()
|
result = 31 * result + nickname.hashCode()
|
||||||
result = 31 * result + email.hashCode()
|
result = 31 * result + email.hashCode()
|
||||||
result = 31 * result + password.hashCode()
|
result = 31 * result + password.hashCode()
|
||||||
|
result = 31 * result + role.hashCode()
|
||||||
result = 31 * result + balance
|
result = 31 * result + balance
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.model
|
||||||
|
|
||||||
|
enum class UserRole(val value: Int) {
|
||||||
|
USER(0),
|
||||||
|
ADMIN(1)
|
||||||
|
}
|
@ -8,7 +8,10 @@ import androidx.room.PrimaryKey
|
|||||||
import org.jetbrains.annotations.NotNull
|
import org.jetbrains.annotations.NotNull
|
||||||
|
|
||||||
//many to many for user and tank
|
//many to many for user and tank
|
||||||
@Entity(primaryKeys = ["userId", "tankId"])
|
@Entity(
|
||||||
|
tableName = "users_tanks",
|
||||||
|
primaryKeys = ["userId", "tankId"]
|
||||||
|
)
|
||||||
data class UserTankCrossRef(
|
data class UserTankCrossRef(
|
||||||
val userId: Long,
|
val userId: Long,
|
||||||
val tankId: Long
|
val tankId: Long
|
||||||
|
@ -6,9 +6,11 @@ import ru.ulstu.`is`.pmu.tank.model.LevelWithTanks
|
|||||||
|
|
||||||
interface LevelRepository {
|
interface LevelRepository {
|
||||||
suspend fun getAllLevels(): List<Level>
|
suspend fun getAllLevels(): List<Level>
|
||||||
fun getSimpleLevel(uid: Long): Flow<Level?>
|
suspend fun getSimpleLevel(uid: Long): Level
|
||||||
fun getFullLevel(uid: Long): Flow<LevelWithTanks?>
|
fun getFullLevel(uid: Long): Flow<LevelWithTanks?>
|
||||||
suspend fun insertLevel(level: Level)
|
suspend fun insertLevel(level: Level)
|
||||||
|
suspend fun insertMany(levels: List<Level>)
|
||||||
suspend fun updateLevel(level: Level)
|
suspend fun updateLevel(level: Level)
|
||||||
suspend fun deleteLevel(level: Level)
|
suspend fun deleteLevel(level: Level)
|
||||||
|
suspend fun deleteAll()
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
package ru.ulstu.`is`.pmu.tank.repository
|
package ru.ulstu.`is`.pmu.tank.repository
|
||||||
|
|
||||||
|
import androidx.paging.PagingData
|
||||||
import androidx.paging.PagingSource
|
import androidx.paging.PagingSource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import ru.ulstu.`is`.pmu.tank.api.model.NationRemote
|
||||||
import ru.ulstu.`is`.pmu.tank.model.Nation
|
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||||
import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
|
import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
|
||||||
|
|
||||||
interface NationRepository {
|
interface NationRepository {
|
||||||
suspend fun getAllNations(): List<Nation>
|
suspend fun getAllNations(): List<Nation>
|
||||||
|
suspend fun getAll(): Flow<PagingData<Nation>>
|
||||||
fun getSimpleNation(uid: Long): Flow<Nation?>
|
fun getSimpleNation(uid: Long): Flow<Nation?>
|
||||||
fun getFullNation(uid: Long): Flow<NationWithTanks?>
|
fun getFullNation(uid: Long): Flow<NationWithTanks?>
|
||||||
fun pagingSource(): PagingSource<Int, Nation>
|
fun pagingSource(): PagingSource<Int, Nation>
|
||||||
suspend fun insertNation(nation: Nation)
|
suspend fun insertNation(nation: Nation)
|
||||||
|
suspend fun insertNations(nations: List<Nation>)
|
||||||
suspend fun updateNation(nation: Nation)
|
suspend fun updateNation(nation: Nation)
|
||||||
suspend fun deleteNation(nation: Nation)
|
suspend fun deleteNation(nation: Nation)
|
||||||
|
suspend fun deleteNations()
|
||||||
}
|
}
|
@ -8,13 +8,16 @@ import ru.ulstu.`is`.pmu.tank.model.LevelWithTanks
|
|||||||
class OfflineLevelRepository(private val levelDao: LevelDao) : LevelRepository {
|
class OfflineLevelRepository(private val levelDao: LevelDao) : LevelRepository {
|
||||||
override suspend fun getAllLevels(): List<Level> = levelDao.getAll()
|
override suspend fun getAllLevels(): List<Level> = levelDao.getAll()
|
||||||
|
|
||||||
override fun getSimpleLevel(uid: Long): Flow<Level?> = levelDao.getSimpleLevelUid(uid)
|
override suspend fun getSimpleLevel(uid: Long): Level = levelDao.getSimpleLevelUid(uid)
|
||||||
|
|
||||||
override fun getFullLevel(uid: Long): Flow<LevelWithTanks?> = levelDao.getLevelUid(uid)
|
override fun getFullLevel(uid: Long): Flow<LevelWithTanks?> = levelDao.getLevelUid(uid)
|
||||||
|
|
||||||
override suspend fun insertLevel(level: Level) = levelDao.insert(level)
|
override suspend fun insertLevel(level: Level) = levelDao.insert(level)
|
||||||
|
override suspend fun insertMany(levels: List<Level>) = levelDao.insertMany(levels)
|
||||||
|
|
||||||
override suspend fun updateLevel(level: Level) = levelDao.update(level)
|
override suspend fun updateLevel(level: Level) = levelDao.update(level)
|
||||||
|
|
||||||
override suspend fun deleteLevel(level: Level) = levelDao.delete(level)
|
override suspend fun deleteLevel(level: Level) = levelDao.delete(level)
|
||||||
|
|
||||||
|
override suspend fun deleteAll() = levelDao.deleteAll()
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package ru.ulstu.`is`.pmu.tank.repository
|
package ru.ulstu.`is`.pmu.tank.repository
|
||||||
|
|
||||||
|
import androidx.paging.PagingData
|
||||||
import androidx.paging.PagingSource
|
import androidx.paging.PagingSource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import ru.ulstu.`is`.pmu.tank.dao.NationDao
|
import ru.ulstu.`is`.pmu.tank.dao.NationDao
|
||||||
@ -8,16 +9,25 @@ import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
|
|||||||
|
|
||||||
class OfflineNationRepository(private val nationDao: NationDao) : NationRepository {
|
class OfflineNationRepository(private val nationDao: NationDao) : NationRepository {
|
||||||
override suspend fun getAllNations(): List<Nation> = nationDao.getAll()
|
override suspend fun getAllNations(): List<Nation> = nationDao.getAll()
|
||||||
|
override suspend fun getAll(): Flow<PagingData<Nation>> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSimpleNation(uid: Long): Flow<Nation?> = nationDao.getSimpleNationUid(uid)
|
override fun getSimpleNation(uid: Long): Flow<Nation?> = nationDao.getSimpleNationUid(uid)
|
||||||
|
|
||||||
override fun getFullNation(uid: Long): Flow<NationWithTanks?> = nationDao.getNationUid(uid)
|
override fun getFullNation(uid: Long): Flow<NationWithTanks?> = nationDao.getNationUid(uid)
|
||||||
|
|
||||||
override fun pagingSource(): PagingSource<Int, Nation> = nationDao.pagingSource()
|
override fun pagingSource(): PagingSource<Int, Nation> {
|
||||||
|
return nationDao.pagingSource()
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun insertNation(nation: Nation) = nationDao.insert(nation)
|
override suspend fun insertNation(nation: Nation) = nationDao.insert(nation)
|
||||||
|
|
||||||
override suspend fun updateNation(nation: Nation) = nationDao.update(nation)
|
override suspend fun updateNation(nation: Nation) = nationDao.update(nation)
|
||||||
|
|
||||||
override suspend fun deleteNation(nation: Nation) = nationDao.delete(nation)
|
override suspend fun deleteNation(nation: Nation) = nationDao.delete(nation)
|
||||||
|
|
||||||
|
override suspend fun insertNations(nations: List<Nation>) = nationDao.insertMany(nations)
|
||||||
|
|
||||||
|
override suspend fun deleteNations() = nationDao.deleteAll()
|
||||||
}
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.repository
|
||||||
|
|
||||||
|
import ru.ulstu.`is`.pmu.tank.dao.RemoteKeysDao
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.RemoteKeyType
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.RemoteKeys
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
@ -13,13 +13,13 @@ class OfflineTankRepository(
|
|||||||
private val tankDao: TankDao,
|
private val tankDao: TankDao,
|
||||||
private val tankImageDao: TankImageDao
|
private val tankImageDao: TankImageDao
|
||||||
) : TankRepository {
|
) : TankRepository {
|
||||||
override fun getAll(): Flow<List<Tank>> = tankDao.getAll()
|
override suspend fun getAll(): List<Tank> = tankDao.getAll()
|
||||||
|
|
||||||
override fun getForUserAll(userId: Long): Flow<List<Tank>> = tankDao.getNotUserTank(userId)
|
override suspend fun getForUserAll(userId: Long): List<Tank> = tankDao.getNotUserTank(userId)
|
||||||
|
|
||||||
override fun getTank(uid: Long): Flow<Tank?> = tankDao.getTankUid(uid)
|
override suspend fun getTank(uid: Long): Tank = tankDao.getTankUid(uid)
|
||||||
|
|
||||||
override fun getUserTanks(uid: Long): Flow<List<TankWithNationAndLevel>> = tankDao.getUserTanks(uid)
|
override suspend fun getUserTanks(uid: Long): List<TankWithNationAndLevel> = tankDao.getUserTanks(uid)
|
||||||
|
|
||||||
override suspend fun insertTank(tank: Tank, image: Bitmap) {
|
override suspend fun insertTank(tank: Tank, image: Bitmap) {
|
||||||
val imageId = tankImageDao.insert(
|
val imageId = tankImageDao.insert(
|
||||||
@ -32,6 +32,10 @@ class OfflineTankRepository(
|
|||||||
tankDao.insert(tank.copy(imageId = imageId))
|
tankDao.insert(tank.copy(imageId = imageId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun insertMany(tankList: List<Tank>) {
|
||||||
|
tankDao.insertMany(tankList)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun updateTank(tank: Tank, image: Bitmap) {
|
override suspend fun updateTank(tank: Tank, image: Bitmap) {
|
||||||
val imageId = tankImageDao.insert(
|
val imageId = tankImageDao.insert(
|
||||||
TankImage(
|
TankImage(
|
||||||
@ -49,4 +53,8 @@ class OfflineTankRepository(
|
|||||||
override suspend fun delete(tankId: Long) {
|
override suspend fun delete(tankId: Long) {
|
||||||
tankDao.delete(tankId)
|
tankDao.delete(tankId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteAll() {
|
||||||
|
tankDao.deleteAll()
|
||||||
|
}
|
||||||
}
|
}
|
@ -8,7 +8,7 @@ import ru.ulstu.`is`.pmu.tank.model.User
|
|||||||
class OfflineUserRepository(private val userDao: UserDao) : UserRepository {
|
class OfflineUserRepository(private val userDao: UserDao) : UserRepository {
|
||||||
override fun getAllUsers(): Flow<List<User>> = userDao.getAll()
|
override fun getAllUsers(): Flow<List<User>> = userDao.getAll()
|
||||||
|
|
||||||
override fun getSimpleUser(uid: Long): Flow<User?> = userDao.getSimpleUserUid(uid)
|
override suspend fun getSimpleUser(email: String): User = userDao.getSimpleUserUid(email)
|
||||||
|
|
||||||
override fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>> = userDao.getUserUid(uid)
|
override fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>> = userDao.getUserUid(uid)
|
||||||
|
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package ru.ulstu.`is`.pmu.tank.repository
|
||||||
|
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.RemoteKeyType
|
||||||
|
import ru.ulstu.`is`.pmu.tank.model.RemoteKeys
|
||||||
|
|
||||||
|
interface RemoteKeyRepository {
|
||||||
|
suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType): RemoteKeys?
|
||||||
|
suspend fun createRemoteKeys(remoteKeys: List<RemoteKeys>)
|
||||||
|
suspend fun deleteRemoteKey(type: RemoteKeyType)
|
||||||
|
}
|
@ -7,12 +7,14 @@ import ru.ulstu.`is`.pmu.tank.model.TankExtra
|
|||||||
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||||
|
|
||||||
interface TankRepository {
|
interface TankRepository {
|
||||||
fun getAll(): Flow<List<Tank>>
|
suspend fun getAll(): List<Tank>
|
||||||
fun getForUserAll(userId: Long): Flow<List<Tank>>
|
suspend fun getForUserAll(userId: Long): List<Tank>
|
||||||
fun getTank(uid: Long): Flow<Tank?>
|
suspend fun getTank(uid: Long): Tank
|
||||||
fun getUserTanks(uid: Long): Flow<List<TankWithNationAndLevel>>
|
suspend fun getUserTanks(uid: Long): List<TankWithNationAndLevel>
|
||||||
suspend fun insertTank(tank: Tank, image: Bitmap)
|
suspend fun insertTank(tank: Tank, image: Bitmap)
|
||||||
|
suspend fun insertMany(tankList: List<Tank>)
|
||||||
suspend fun updateTank(tank: Tank, image: Bitmap)
|
suspend fun updateTank(tank: Tank, image: Bitmap)
|
||||||
suspend fun deleteTank(tank: Tank)
|
suspend fun deleteTank(tank: Tank)
|
||||||
suspend fun delete(tankId: Long)
|
suspend fun delete(tankId: Long)
|
||||||
|
suspend fun deleteAll()
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ import ru.ulstu.`is`.pmu.tank.model.User
|
|||||||
|
|
||||||
interface UserRepository {
|
interface UserRepository {
|
||||||
fun getAllUsers(): Flow<List<User>>
|
fun getAllUsers(): Flow<List<User>>
|
||||||
fun getSimpleUser(uid: Long): Flow<User?>
|
suspend fun getSimpleUser(email: String): User
|
||||||
fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>>
|
fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>>
|
||||||
suspend fun insertUser(user: User)
|
suspend fun insertUser(user: User)
|
||||||
suspend fun updateUser(user: User)
|
suspend fun updateUser(user: User)
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
package ru.ulstu.`is`.pmu.tanks.composeui
|
package ru.ulstu.`is`.pmu.tanks.composeui
|
||||||
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.util.Log
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@ -20,20 +17,12 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
|||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.key
|
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
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.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
@ -41,23 +30,8 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.FlowCollector
|
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import ru.ulstu.`is`.pmu.R
|
|
||||||
import ru.ulstu.`is`.pmu.composeui.navigation.Screen
|
|
||||||
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListViewModel
|
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListViewModel
|
||||||
import ru.ulstu.`is`.pmu.tank.database.AppDatabase
|
|
||||||
import ru.ulstu.`is`.pmu.tank.model.Level
|
|
||||||
import ru.ulstu.`is`.pmu.tank.model.Nation
|
|
||||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
|
||||||
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||||
import ru.ulstu.`is`.pmu.tank.model.UserWithTanks
|
|
||||||
import ru.ulstu.`is`.pmu.tanks.composeui.image.CuteImage
|
|
||||||
import ru.ulstu.`is`.pmu.tanks.composeui.image.Dimensions
|
import ru.ulstu.`is`.pmu.tanks.composeui.image.Dimensions
|
||||||
import ru.ulstu.`is`.pmu.tanks.composeui.image.RoundedCorderImage
|
import ru.ulstu.`is`.pmu.tanks.composeui.image.RoundedCorderImage
|
||||||
import ru.ulstu.`is`.pmu.ui.AppViewModelProvider
|
import ru.ulstu.`is`.pmu.ui.AppViewModelProvider
|
||||||
@ -71,10 +45,9 @@ fun Hangar(
|
|||||||
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
||||||
){
|
){
|
||||||
viewModel.setUserId(100L)
|
viewModel.setUserId(100L)
|
||||||
val userTankListUiState by viewModel.usersTanksUiState.collectAsState()
|
|
||||||
|
|
||||||
//новый вызов основного списка
|
//новый вызов основного списка
|
||||||
Hangar(tankList = userTankListUiState.userTankList )
|
Hangar(tankList = viewModel.usersTanksUiState.userTankList )
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.application.ui
|
package com.application.ui
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.util.Base64
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
const val miniatureBound: Int = 250
|
const val miniatureBound: Int = 250
|
||||||
@ -24,3 +27,21 @@ fun Bitmap.resize(bound: Int): Bitmap {
|
|||||||
val newHeight: Int = (height / factor).toInt()
|
val newHeight: Int = (height / factor).toInt()
|
||||||
return Bitmap.createScaledBitmap(this, newWidth, newHeight, false)
|
return Bitmap.createScaledBitmap(this, newWidth, newHeight, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Bitmap.toByteArray(): ByteArray {
|
||||||
|
val outputStream = ByteArrayOutputStream()
|
||||||
|
this.compress(Bitmap.CompressFormat.PNG, 1, outputStream)
|
||||||
|
return outputStream.toByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Bitmap.toBase64(): String {
|
||||||
|
return Base64.encodeToString(this.toByteArray(), Base64.DEFAULT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ByteArray.toBitmap(): Bitmap {
|
||||||
|
return BitmapFactory.decodeByteArray(this, 0, this.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.toBitmap(): Bitmap {
|
||||||
|
return Base64.decode(this, Base64.DEFAULT).toBitmap()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user