LabWork05
This commit is contained in:
parent
c9fb6f4f33
commit
57ecc27364
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.
@ -6,6 +6,6 @@ object ApiRoutes {
|
||||
const val LEVEL = "levels"
|
||||
const val NATION = "nations"
|
||||
const val TANK = "tanks"
|
||||
const val USER_TANK = "userTanks"
|
||||
const val USER_TANK = "users_tanks"
|
||||
const val NOT_USER_TANK = "notUserTanks"
|
||||
}
|
@ -23,9 +23,9 @@ import ru.ulstu.`is`.pmu.tank.api.model.UserTankCrossRefRemote
|
||||
interface ServerService {
|
||||
// :[USER]
|
||||
|
||||
@GET(ApiRoutes.USER)
|
||||
suspend fun getUserByEmail(
|
||||
@Query("email") email: String
|
||||
@GET("${ApiRoutes.USER}/{id}")
|
||||
suspend fun getUser(
|
||||
@Path("id") userId: Long
|
||||
): UserRemote
|
||||
|
||||
@POST(ApiRoutes.USER)
|
||||
@ -78,7 +78,7 @@ interface ServerService {
|
||||
@Query("_limit") limit: Int
|
||||
): List<NationRemote>
|
||||
|
||||
@GET("/getall/${ApiRoutes.NATION}")
|
||||
@GET(ApiRoutes.NATION)
|
||||
suspend fun getAllNations(): List<NationRemote>
|
||||
|
||||
@GET("${ApiRoutes.NATION}/{id}")
|
||||
@ -114,14 +114,14 @@ interface ServerService {
|
||||
@Path("id") id: Long
|
||||
): TankRemote
|
||||
|
||||
@GET("${ApiRoutes.TANK}/forPurchase")
|
||||
@GET("${ApiRoutes.TANK}?_expand=users_tanks")
|
||||
suspend fun getTanksForPurchase(
|
||||
@Path("id") userId: Long
|
||||
@Query("id") userId: Long
|
||||
): List<TankRemote>
|
||||
|
||||
@GET("${ApiRoutes.TANK}/myHangar")
|
||||
@GET("${ApiRoutes.TANK}?_embed=users_tanks")
|
||||
suspend fun getTanksFromHangar(
|
||||
@Path("id") userId: Long
|
||||
@Query("id") id: Long
|
||||
): List<TankWithNationAndLevelRemote>
|
||||
|
||||
@POST(ApiRoutes.TANK)
|
||||
@ -144,10 +144,8 @@ interface ServerService {
|
||||
|
||||
// :[USER_TANK_CROSS_REF]
|
||||
|
||||
@GET("${ApiRoutes.USER_TANK}?_hangar={userId}")
|
||||
suspend fun getUserTankCrossRef(
|
||||
@Path("userId") userId: Long,
|
||||
): List<UserTankCrossRefRemote>
|
||||
@GET(ApiRoutes.USER_TANK)
|
||||
suspend fun getUserTankCrossRef(): List<UserTankCrossRefRemote>
|
||||
|
||||
@POST(ApiRoutes.USER_TANK)
|
||||
suspend fun insertUserTankCrossRef(
|
||||
@ -162,7 +160,7 @@ interface ServerService {
|
||||
// ![USER_TANK_CROSS_REF]
|
||||
|
||||
companion object {
|
||||
private const val BASE_URL = "http://10.0.2.2:8079/"
|
||||
private const val BASE_URL = ApiRoutes.BASE
|
||||
|
||||
@Volatile
|
||||
private var INSTANCE: ServerService? = null
|
||||
|
@ -107,5 +107,4 @@ class NationRemoteMediator(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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.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.repository.OfflineRemoteKeyRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineTankRepository
|
||||
import java.io.IOException
|
||||
|
||||
@OptIn(ExperimentalPagingApi::class)
|
||||
class TankRemoteMediator(
|
||||
private val service: ServerService,
|
||||
private val dbTankRepository: OfflineTankRepository,
|
||||
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 tanks = service.getTanks().map { it.toTank() }
|
||||
val endOfPaginationReached = tanks.isEmpty()
|
||||
|
||||
database.withTransaction {
|
||||
if (loadType == LoadType.REFRESH) {
|
||||
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.NATION)
|
||||
dbTankRepository.deleteAll()
|
||||
}
|
||||
|
||||
val prevKey = if (page == 1) null else page - 1
|
||||
val nextKey = if (endOfPaginationReached) null else page + 1
|
||||
val keys = tanks.map {
|
||||
RemoteKeys(
|
||||
entityId = it.tankId!!.toInt(),
|
||||
type = RemoteKeyType.NATION,
|
||||
prevKey = prevKey,
|
||||
nextKey = nextKey
|
||||
)
|
||||
}
|
||||
|
||||
dbRemoteKeyRepository.createRemoteKeys(keys)
|
||||
dbTankRepository.insertMany(tanks)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,16 +7,16 @@ import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||
|
||||
@Serializable
|
||||
data class LevelRemote (
|
||||
val uid: Long = 0,
|
||||
val id: Long = 0,
|
||||
val level: Int = 0
|
||||
)
|
||||
|
||||
fun LevelRemote.toLevel(): Level = Level(
|
||||
uid,
|
||||
uid = id,
|
||||
level
|
||||
)
|
||||
|
||||
fun Level.toRemote(): LevelRemote = LevelRemote(
|
||||
uid!!,
|
||||
id = uid!!,
|
||||
level
|
||||
)
|
@ -5,16 +5,16 @@ import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||
|
||||
@Serializable
|
||||
data class NationRemote(
|
||||
val uid: Long = 0,
|
||||
val id: Long = 0,
|
||||
val nationName: String = ""
|
||||
)
|
||||
|
||||
fun NationRemote.toNation(): Nation = Nation(
|
||||
uid,
|
||||
uid = id,
|
||||
nationName
|
||||
)
|
||||
|
||||
fun Nation.toRemote(): NationRemote = NationRemote(
|
||||
uid!!,
|
||||
id = uid!!,
|
||||
nationName
|
||||
)
|
||||
|
@ -8,31 +8,28 @@ import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||
|
||||
@Serializable
|
||||
data class TankRemote(
|
||||
val tankId: Long = 0,
|
||||
val id: 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,
|
||||
tankId = id,
|
||||
name = name,
|
||||
price = price,
|
||||
miniature = miniature.toBitmap(),
|
||||
imageId = imageId,
|
||||
levelId = levelId,
|
||||
nationId = nationId
|
||||
)
|
||||
|
||||
fun Tank.toRemote(): TankRemote = TankRemote(
|
||||
tankId = tankId!!,
|
||||
id = tankId!!,
|
||||
name = name,
|
||||
price = price,
|
||||
miniature = miniature.toBase64(),
|
||||
imageId = imageId,
|
||||
levelId = levelId!!,
|
||||
nationId = nationId!!
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||
|
||||
@Serializable
|
||||
data class TankWithNationAndLevelRemote(
|
||||
val tankId: Long,
|
||||
val id: Long,
|
||||
val name: String,
|
||||
val price: Int,
|
||||
val image: String,
|
||||
@ -16,7 +16,7 @@ data class TankWithNationAndLevelRemote(
|
||||
)
|
||||
|
||||
fun TankWithNationAndLevelRemote.toTankWithNationAndLevel(): TankWithNationAndLevel = TankWithNationAndLevel(
|
||||
tankId = tankId,
|
||||
tankId = id,
|
||||
name = name,
|
||||
price = price,
|
||||
image = image.toBitmap(),
|
||||
@ -25,7 +25,7 @@ fun TankWithNationAndLevelRemote.toTankWithNationAndLevel(): TankWithNationAndLe
|
||||
)
|
||||
|
||||
fun TankWithNationAndLevel.toRemote(): TankWithNationAndLevelRemote = TankWithNationAndLevelRemote(
|
||||
tankId = tankId!!,
|
||||
id = tankId!!,
|
||||
name = name,
|
||||
price = price,
|
||||
image = image.toBase64(),
|
||||
|
@ -9,8 +9,8 @@ data class UserRemote (
|
||||
val id: Long = 0,
|
||||
val nickname: String = "",
|
||||
val email: String = "",
|
||||
val role: Int = -1,
|
||||
val password: String = "",
|
||||
val role: Int = 0,
|
||||
val balance: Int = 0
|
||||
)
|
||||
|
||||
|
@ -1,9 +1,21 @@
|
||||
package ru.ulstu.`is`.pmu.tank.api.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import ru.ulstu.`is`.pmu.tank.model.Level
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
|
||||
@Serializable
|
||||
data class UserTankCrossRefRemote (
|
||||
val userId: Long = 0,
|
||||
val id: Long = 0,
|
||||
val tankId: Long = 0
|
||||
)
|
||||
|
||||
fun UserTankCrossRefRemote.toUserTankCrossRef(): UserTankCrossRef = UserTankCrossRef(
|
||||
userId = id,
|
||||
tankId = tankId
|
||||
)
|
||||
|
||||
fun UserTankCrossRef.toRemote(): UserTankCrossRefRemote = UserTankCrossRefRemote(
|
||||
id = userId,
|
||||
tankId = tankId
|
||||
)
|
@ -35,7 +35,7 @@ class RestNationRepository(
|
||||
return nations
|
||||
}
|
||||
|
||||
override suspend fun getAll(): Flow<PagingData<Nation>> {
|
||||
override fun getAll(): Flow<PagingData<Nation>> {
|
||||
@OptIn(ExperimentalPagingApi::class)
|
||||
return Pager(
|
||||
config = PagingConfig(
|
||||
|
@ -1,42 +1,110 @@
|
||||
package ru.ulstu.`is`.pmu.tank.api.repository
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import kotlinx.coroutines.flow.flatMapConcat
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import ru.ulstu.`is`.pmu.tank.api.ServerService
|
||||
import ru.ulstu.`is`.pmu.tank.api.model.UserTankCrossRefRemote
|
||||
import ru.ulstu.`is`.pmu.tank.api.model.toLevel
|
||||
import ru.ulstu.`is`.pmu.tank.api.model.toNation
|
||||
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.toUserTankCrossRef
|
||||
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.UserTankCrossRef
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineLevelRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineNationRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineTankRepository
|
||||
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
|
||||
|
||||
class RestTankRepository (
|
||||
private val service: ServerService,
|
||||
private val dbTankRepository: OfflineTankRepository,
|
||||
private val dbUsersTanksRepository: OfflineUsersTanksRepository
|
||||
) : TankRepository {
|
||||
override suspend fun getAll(): List<Tank> {
|
||||
dbTankRepository.deleteAll()
|
||||
val tanks = service.getTanks().map { it.toTank() }
|
||||
dbTankRepository.insertMany(tanks)
|
||||
return tanks
|
||||
return service.getTanks().map { it.toTank() }
|
||||
}
|
||||
|
||||
override suspend fun getForUserAll(userId: Long): List<Tank> {
|
||||
return service.getTanksForPurchase(userId).map { it.toTank() }
|
||||
val totalList: List<Tank> = getAll()
|
||||
val totalUserTankList: List<UserTankCrossRef> = service.getUserTankCrossRef().map{ it.toUserTankCrossRef() }
|
||||
|
||||
//спискок, который вернём
|
||||
var supportList = ArrayList<Tank>()
|
||||
|
||||
//вспомогательный список для проверки отсутствия танка у пользователя
|
||||
var notToUser: List<UserTankCrossRef> = totalList.map{ UserTankCrossRef(userId, it.tankId!!) }
|
||||
|
||||
if (totalUserTankList.isEmpty()){
|
||||
return totalList
|
||||
} else {
|
||||
notToUser.forEach(){userTank ->
|
||||
if(!totalUserTankList.contains(userTank)){
|
||||
supportList.add(totalList.firstOrNull { it.tankId == userTank.tankId }!!)
|
||||
}
|
||||
}
|
||||
return supportList
|
||||
}
|
||||
}
|
||||
|
||||
//очень классная штука
|
||||
private suspend fun <T> Flow<List<T>>.flattenToList() =
|
||||
flatMapConcat { it.asFlow() }.toList()
|
||||
|
||||
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 getUserTanks(userId: Long): List<TankWithNationAndLevel> {
|
||||
val totalList: List<Tank> = getAll()
|
||||
val totalLevelList: List<Level> = service.getLevels().map { it.toLevel() }
|
||||
val totalNationList: List<Nation> = service.getAllNations().map { it.toNation() }
|
||||
|
||||
//все имеющиеся танки у пользователя
|
||||
val totalUserTankList: List<UserTankCrossRef> = service.getUserTankCrossRef().map{ it.toUserTankCrossRef() }
|
||||
|
||||
//спискок, который вернём
|
||||
var supportList = ArrayList<TankWithNationAndLevel>()
|
||||
|
||||
//вспомогательный список для проверки наличия танка у пользователя
|
||||
var notToUser: List<UserTankCrossRef> = totalList.map{ UserTankCrossRef(userId, it.tankId!!) }
|
||||
|
||||
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)
|
||||
)
|
||||
}
|
||||
}
|
||||
return supportList
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun insertTank(tank: Tank, image: Bitmap) {
|
||||
service.insertTank(tank.toRemote())
|
||||
}
|
||||
|
||||
override suspend fun buyTank(tankId: Long, userId: Long) {
|
||||
service.insertUserTankCrossRef(UserTankCrossRefRemote(userId, tankId))
|
||||
}
|
||||
|
||||
override suspend fun insertMany(tankList: List<Tank>) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
@ -46,7 +114,7 @@ class RestTankRepository (
|
||||
}
|
||||
|
||||
override suspend fun deleteTank(tank: Tank) {
|
||||
TODO("Not yet implemented")
|
||||
service.deleteTank(tank.tankId!!)
|
||||
}
|
||||
|
||||
override suspend fun delete(tankId: Long) {
|
||||
|
@ -22,8 +22,8 @@ class RestUserRepository(
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun getSimpleUser(email: String): User {
|
||||
return service.getUserByEmail(email).toUser()
|
||||
override suspend fun getSimpleUser(userId: Long): User {
|
||||
return service.getUser(userId).toUser()
|
||||
}
|
||||
|
||||
override fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>> {
|
||||
|
@ -31,11 +31,13 @@ import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -52,10 +54,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.ulstu.`is`.pmu.R
|
||||
import ru.ulstu.`is`.pmu.composeui.navigation.Screen
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.UsersTanksEditViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||
@ -70,14 +76,20 @@ import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme
|
||||
@Composable
|
||||
fun TankList(
|
||||
navController: NavController?,
|
||||
userTankEditViewModel: UsersTanksEditViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
listNations: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
||||
) {
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.refreshTankListState()
|
||||
}
|
||||
|
||||
// Lazy Column, Pass the numbers array
|
||||
if (navController != null) {
|
||||
TankList(
|
||||
nations = listNations.nationsListUiState,
|
||||
listTanks = viewModel.tankListUiState.tankList
|
||||
listTanks = viewModel.tankListUiState.tankList,
|
||||
viewModel = userTankEditViewModel
|
||||
) { uid: Long ->
|
||||
val route = Screen.Constructor.route.replace("{id}", uid.toString())
|
||||
navController.navigate(route)
|
||||
@ -89,8 +101,20 @@ fun TankList(
|
||||
fun ColumnItem(
|
||||
nation: Nation,
|
||||
tanks: List<Tank>?,
|
||||
onClick: (uid: Long) -> Unit
|
||||
onClick: (uid: Long) -> Unit,
|
||||
viewModel: UsersTanksEditViewModel
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val tank = viewModel.usersTanksUiState
|
||||
|
||||
fun handleTankButtonClick() {
|
||||
scope.launch {
|
||||
if (tank.userTankCrossRef.tankId == 0L) {
|
||||
viewModel.saveUserTank()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(0.dp, 10.dp)
|
||||
) {
|
||||
@ -121,6 +145,7 @@ fun ColumnItem(
|
||||
{
|
||||
if(!tanks.isNullOrEmpty()){
|
||||
tanks.forEach { tank ->
|
||||
//TODO
|
||||
if(tank.tankId != null){
|
||||
key(tank.tankId) {
|
||||
//val studentId = Screen.StudentView.route.replace("{id}", index.toString())
|
||||
@ -152,7 +177,7 @@ fun ColumnItem(
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = CustomRed,
|
||||
contentColor = CustomDark),
|
||||
onClick = { onClick(tank.tankId) }
|
||||
onClick = { handleTankButtonClick() }
|
||||
) {
|
||||
//navController?.navigate(Screen.Hangar.route)
|
||||
//navController?.navigate(studentId)
|
||||
@ -189,6 +214,7 @@ fun ColumnItem(
|
||||
private fun TankList(
|
||||
nations: NationsListUiState,
|
||||
listTanks: List<Tank>,
|
||||
viewModel: UsersTanksEditViewModel,
|
||||
onClick: (uid: Long) -> Unit,
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -231,7 +257,7 @@ private fun TankList(
|
||||
}
|
||||
|
||||
items(nations.nationList) {nation ->
|
||||
ColumnItem(nation = nation, tanks = totalDictionary[nation], onClick = onClick)
|
||||
ColumnItem(nation = nation, tanks = totalDictionary[nation], onClick = onClick, viewModel = viewModel)
|
||||
}
|
||||
|
||||
// items(list/array) places number of
|
||||
@ -254,6 +280,7 @@ fun TankListPreview() {
|
||||
) {
|
||||
TankList(
|
||||
nations = NationsListUiState(listOf()),
|
||||
viewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
listTanks = (1..20).map { i -> Tank.getTank(i.toLong()) }
|
||||
) { }
|
||||
}
|
||||
@ -270,6 +297,7 @@ fun TankEmptyListPreview() {
|
||||
) {
|
||||
TankList(
|
||||
nations = NationsListUiState(listOf()),
|
||||
viewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
listTanks = listOf()
|
||||
) { }
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ class TankEditViewModel(
|
||||
&& price > 0
|
||||
&& levelId!! != 0L
|
||||
&& nationId!! != 0L
|
||||
&& imageId !! != 0L
|
||||
&& miniature != null
|
||||
}
|
||||
}
|
||||
@ -101,7 +100,6 @@ fun TankDetails.toTank(uid: Long = 0): Tank = Tank(
|
||||
levelId = levelId,
|
||||
nationId = nationId,
|
||||
miniature = miniature,
|
||||
imageId = imageId
|
||||
)
|
||||
|
||||
fun Tank.toDetails(): TankDetails = TankDetails(
|
||||
@ -110,7 +108,6 @@ fun Tank.toDetails(): TankDetails = TankDetails(
|
||||
levelId = levelId,
|
||||
nationId = nationId,
|
||||
miniature = miniature,
|
||||
imageId = imageId
|
||||
)
|
||||
|
||||
fun Tank.toUiState(isEntryValid: Boolean = false): TankUiState = TankUiState(
|
||||
|
@ -23,12 +23,12 @@ class UserEditViewModel(
|
||||
|
||||
//private val userUid: Long = checkNotNull(savedStateHandle["id"])
|
||||
|
||||
private val userEmail: String = "egor@mail.ru"
|
||||
private val userId: Long = 100L
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
if (userEmail.length > 0) {
|
||||
userUiState = userRepository.getSimpleUser(userEmail)
|
||||
if (userId > 0) {
|
||||
userUiState = userRepository.getSimpleUser(userId)
|
||||
.toUiState(true)
|
||||
}
|
||||
}
|
||||
@ -43,10 +43,11 @@ class UserEditViewModel(
|
||||
|
||||
suspend fun saveUser() {
|
||||
if (validateInput()) {
|
||||
if (userEmail.length > 0) {
|
||||
userRepository.updateUser(userUiState.userDetails.toUser(100L))
|
||||
val user: User = userUiState.userDetails.toUser()
|
||||
if (user.userId != 0.toLong()) {
|
||||
userRepository.updateUser(user)
|
||||
} else {
|
||||
userRepository.insertUser(userUiState.userDetails.toUser())
|
||||
userRepository.insertUser(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package ru.ulstu.`is`.pmu.tank.composeui.edit
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.launch
|
||||
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.repository.OfflineUsersTanksRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.UserRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.UsersTanksRepository
|
||||
|
||||
class UsersTanksEditViewModel(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val usersTanksRepository: UsersTanksRepository
|
||||
) : ViewModel() {
|
||||
var usersTanksUiState by mutableStateOf(UserTankCrossRefUiState())
|
||||
private set
|
||||
|
||||
//val tankId: Long = checkNotNull(savedStateHandle["id"])
|
||||
|
||||
private val userId: Long = 100L
|
||||
|
||||
suspend fun saveUserTank() {
|
||||
//usersTanksRepository.insertUserTank(UserTankCrossRef(userId, tankId))
|
||||
}
|
||||
}
|
||||
|
||||
data class UserTankCrossRefUiState(
|
||||
val userTankCrossRef: UserTankCrossRef = UserTankCrossRef.getEmpty(),
|
||||
)
|
@ -1,21 +1,31 @@
|
||||
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.viewModelScope
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.cachedIn
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||
import ru.ulstu.`is`.pmu.tank.repository.NationRepository
|
||||
|
||||
class NationListViewModel(
|
||||
nationRepository: NationRepository
|
||||
private val nationRepository: NationRepository
|
||||
) : ViewModel() {
|
||||
private val pager = Pager(
|
||||
config = PagingConfig(pageSize = 10),
|
||||
pagingSourceFactory = {
|
||||
nationRepository.pagingSource()
|
||||
}
|
||||
)
|
||||
var nationPagingFlow by mutableStateOf(NationPagingFlowState())
|
||||
private set
|
||||
|
||||
val nationPagingFlow = pager.flow.cachedIn(viewModelScope)
|
||||
fun refresh() {
|
||||
val pagingSource = nationRepository.getAll()
|
||||
nationPagingFlow = NationPagingFlowState(pagingSource.cachedIn(viewModelScope))
|
||||
}
|
||||
}
|
||||
|
||||
data class NationPagingFlowState(
|
||||
val flow: Flow<PagingData<Nation>> = emptyFlow(),
|
||||
)
|
@ -5,17 +5,22 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.ulstu.`is`.pmu.tank.database.AppDataContainer
|
||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
import ru.ulstu.`is`.pmu.tank.repository.TankRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.UsersTanksRepository
|
||||
|
||||
class TankListViewModel(
|
||||
private val tankRepository: TankRepository,
|
||||
private val usersTanksRepository: UsersTanksRepository,
|
||||
private var userId: Long = 100L
|
||||
) : ViewModel() {
|
||||
var tankListUiState by mutableStateOf(TankListUiState())
|
||||
@ -31,6 +36,18 @@ class TankListViewModel(
|
||||
fun setUserId(uid: Long){
|
||||
userId = uid
|
||||
}
|
||||
|
||||
fun refreshTankListState() {
|
||||
viewModelScope.launch {
|
||||
tankListUiState = TankListUiState(tankRepository.getForUserAll(userId))
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun refreshUserTanksListState(){
|
||||
viewModelScope.launch {
|
||||
usersTanksUiState = UserTankListUiState(tankRepository.getUserTanks(userId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class TankListUiState(val tankList: List<Tank> = listOf())
|
||||
|
@ -19,16 +19,14 @@ interface TankDao {
|
||||
fun getAll(): List<Tank>
|
||||
|
||||
//получить конкретный танк
|
||||
@Query("select t.*, ti.data from tanks AS t " +
|
||||
"LEFT JOIN tank_images as ti on t.image_id = ti.image_id " +
|
||||
@Query("select t.* from tanks AS t " +
|
||||
"where t.tankId = :uid")
|
||||
fun getTankUid(uid: Long): Tank
|
||||
|
||||
//получаем все танки пользователя по его Id
|
||||
@Query(
|
||||
"SELECT t.tankId, t.name, t.price, t.image_id, l.level, n.nationName, ti.data AS image FROM users_tanks AS ut " +
|
||||
"SELECT t.tankId, t.name, t.price, t.miniature AS image, l.level, n.nationName FROM users_tanks AS ut " +
|
||||
"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 levels as l on t.levelId = l.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"
|
||||
|
@ -29,8 +29,8 @@ interface UserDao {
|
||||
)
|
||||
fun getUserUid(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>>
|
||||
|
||||
@Query("select * from users where users.email = :email")
|
||||
fun getSimpleUserUid(email: String): User
|
||||
@Query("select * from users where users.userId = :userId")
|
||||
fun getSimpleUserUid(userId: Long): User
|
||||
|
||||
//добавить танк в ангар пользователя
|
||||
@Insert
|
||||
|
@ -0,0 +1,25 @@
|
||||
package ru.ulstu.`is`.pmu.tank.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
|
||||
@Dao
|
||||
interface UsersTanksDao {
|
||||
@Query("select * from users_tanks GROUP BY userId")
|
||||
fun getAll(): List<UserTankCrossRef>
|
||||
|
||||
@Query("select * from users_tanks WHERE userId = :userId GROUP BY userId")
|
||||
suspend fun getAllById(userId: Long): List<UserTankCrossRef>
|
||||
|
||||
@Insert
|
||||
suspend fun insert(userTankCrossRef: UserTankCrossRef)
|
||||
|
||||
@Insert
|
||||
suspend fun insertMany(userTankCrossRefList: List<UserTankCrossRef>)
|
||||
|
||||
@Query("DELETE FROM users_tanks")
|
||||
suspend fun deleteAll()
|
||||
}
|
@ -13,14 +13,17 @@ import ru.ulstu.`is`.pmu.tank.repository.OfflineNationRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineRemoteKeyRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineTankRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineUserRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.OfflineUsersTanksRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.TankRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.UserRepository
|
||||
import ru.ulstu.`is`.pmu.tank.repository.UsersTanksRepository
|
||||
|
||||
interface AppContainer {
|
||||
val levelRestRepository: RestLevelRepository
|
||||
val nationRestRepository: RestNationRepository
|
||||
val userRestRepository: RestUserRepository
|
||||
val tankRestRepository: RestTankRepository
|
||||
val usersTanksRepository: UsersTanksRepository
|
||||
|
||||
companion object {
|
||||
const val TIMEOUT = 5000L
|
||||
@ -36,18 +39,18 @@ class AppDataContainer(private val context: Context) : AppContainer {
|
||||
OfflineNationRepository(AppDatabase.getInstance(context).nationDao())
|
||||
}
|
||||
private val tankRepository: OfflineTankRepository by lazy {
|
||||
OfflineTankRepository(
|
||||
AppDatabase.getInstance(context).tankDao(),
|
||||
tankImageDao = AppDatabase.getInstance(context).tankImageDao())
|
||||
OfflineTankRepository(AppDatabase.getInstance(context).tankDao(),
|
||||
AppDatabase.getInstance(context).usersTanksDao())
|
||||
}
|
||||
private val userRepository: OfflineUserRepository by lazy {
|
||||
OfflineUserRepository(AppDatabase.getInstance(context).userDao())
|
||||
}
|
||||
|
||||
private val remoteKeyRepository: OfflineRemoteKeyRepository by lazy {
|
||||
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao())
|
||||
}
|
||||
|
||||
override val usersTanksRepository: OfflineUsersTanksRepository by lazy {
|
||||
OfflineUsersTanksRepository(AppDatabase.getInstance(context).usersTanksDao())
|
||||
}
|
||||
override val levelRestRepository: RestLevelRepository by lazy {
|
||||
RestLevelRepository(
|
||||
service = ServerService.getInstance(),
|
||||
@ -74,7 +77,8 @@ class AppDataContainer(private val context: Context) : AppContainer {
|
||||
override val tankRestRepository: RestTankRepository by lazy {
|
||||
RestTankRepository(
|
||||
service = ServerService.getInstance(),
|
||||
dbTankRepository = tankRepository
|
||||
dbTankRepository = tankRepository,
|
||||
dbUsersTanksRepository = usersTanksRepository
|
||||
)
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ import ru.ulstu.`is`.pmu.tank.dao.RemoteKeysDao
|
||||
import ru.ulstu.`is`.pmu.tank.dao.TankDao
|
||||
import ru.ulstu.`is`.pmu.tank.dao.TankImageDao
|
||||
import ru.ulstu.`is`.pmu.tank.dao.UserDao
|
||||
import ru.ulstu.`is`.pmu.tank.dao.UsersTanksDao
|
||||
import ru.ulstu.`is`.pmu.tank.model.Level
|
||||
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||
import ru.ulstu.`is`.pmu.tank.model.RemoteKeys
|
||||
@ -46,10 +47,11 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun tankDao() : TankDao
|
||||
abstract fun userDao() : UserDao
|
||||
abstract fun tankImageDao() : TankImageDao
|
||||
abstract fun usersTanksDao(): UsersTanksDao
|
||||
abstract fun remoteKeysDao(): RemoteKeysDao
|
||||
|
||||
companion object {
|
||||
private const val DB_NAME: String = "21-db"
|
||||
private const val DB_NAME: String = "22-db"
|
||||
|
||||
@Volatile
|
||||
private var INSTANCE: AppDatabase? = null
|
||||
@ -118,17 +120,17 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
//Tanks
|
||||
val tankDao = database.tankDao()
|
||||
val tank1 = Tank(20L,"МС-1", 1000, PrepopulateStore.getProductMiniature(context, 1L), 1L, level1.uid, nation1.uid)
|
||||
val tank2 = Tank(21L, "Т-34-85", 960000, PrepopulateStore.getProductMiniature(context, 2L), 2L, level6.uid, nation1.uid)
|
||||
val tank10 = Tank(22L, "Pershing", 1260000, PrepopulateStore.getProductMiniature(context, 9L), 9L, level8.uid, nation3.uid)
|
||||
val tank6 = Tank(23L, "Ferdinand", 2500000, PrepopulateStore.getProductMiniature(context, 8L), 8L, level8.uid, nation2.uid)
|
||||
val tank3 = Tank(24L, "ИС-2", 1230000, PrepopulateStore.getProductMiniature(context, 3L), 3L, level7.uid, nation1.uid)
|
||||
val tank4 = Tank(25L, "ИСУ-152", 2350000, PrepopulateStore.getProductMiniature(context, 4L), 4L, level8.uid, nation1.uid)
|
||||
val tank5 = Tank(26L, "Tiger 1", 1430000,PrepopulateStore.getProductMiniature(context, 5L), 5L, level7.uid, nation2.uid)
|
||||
val tank7 = Tank(27L, "Tiger 2", 2500000, PrepopulateStore.getProductMiniature(context, 6L), 6L, level8.uid, nation2.uid)
|
||||
val tank8 = Tank(28L, "Panther", 1350000, PrepopulateStore.getProductMiniature(context, 7L), 7L, level7.uid, nation2.uid)
|
||||
val tank9 = Tank(29L, "M4A2E3", 990000, PrepopulateStore.getProductMiniature(context, 10L), 10L, level6.uid, nation3.uid)
|
||||
val tank11 = Tank(30L, "Hellcat", 940000, PrepopulateStore.getProductMiniature(context, 11L), 11L, level7.uid, nation3.uid)
|
||||
val tank1 = Tank(20L,"МС-1", 1000, PrepopulateStore.getProductMiniature(context, 1L), level1.uid, nation1.uid)
|
||||
val tank2 = Tank(21L, "Т-34-85", 960000, PrepopulateStore.getProductMiniature(context, 2L), level6.uid, nation1.uid)
|
||||
val tank10 = Tank(22L, "Pershing", 1260000, PrepopulateStore.getProductMiniature(context, 9L), level8.uid, nation3.uid)
|
||||
val tank6 = Tank(23L, "Ferdinand", 2500000, PrepopulateStore.getProductMiniature(context, 8L), level8.uid, nation2.uid)
|
||||
val tank3 = Tank(24L, "ИС-2", 1230000, PrepopulateStore.getProductMiniature(context, 3L), level7.uid, nation1.uid)
|
||||
val tank4 = Tank(25L, "ИСУ-152", 2350000, PrepopulateStore.getProductMiniature(context, 4L), level8.uid, nation1.uid)
|
||||
val tank5 = Tank(26L, "Tiger 1", 1430000,PrepopulateStore.getProductMiniature(context, 5L), level7.uid, nation2.uid)
|
||||
val tank7 = Tank(27L, "Tiger 2", 2500000, PrepopulateStore.getProductMiniature(context, 6L), level8.uid, nation2.uid)
|
||||
val tank8 = Tank(28L, "Panther", 1350000, PrepopulateStore.getProductMiniature(context, 7L), level7.uid, nation2.uid)
|
||||
val tank9 = Tank(29L, "M4A2E3", 990000, PrepopulateStore.getProductMiniature(context, 10L), level6.uid, nation3.uid)
|
||||
val tank11 = Tank(30L, "Hellcat", 940000, PrepopulateStore.getProductMiniature(context, 11L), level7.uid, nation3.uid)
|
||||
|
||||
tankDao.insert(tank1)
|
||||
tankDao.insert(tank2)
|
||||
|
@ -13,15 +13,6 @@ import ru.ulstu.`is`.pmu.tank.database.Converters
|
||||
|
||||
@Entity(
|
||||
tableName = "tanks",
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = TankImage::class,
|
||||
parentColumns = ["image_id"],
|
||||
childColumns = ["image_id"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
onUpdate = ForeignKey.RESTRICT
|
||||
)
|
||||
]
|
||||
)
|
||||
data class Tank(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ -31,8 +22,6 @@ data class Tank(
|
||||
@ColumnInfo(name = "price")
|
||||
val price: Int,
|
||||
val miniature: Bitmap,
|
||||
@ColumnInfo(name = "image_id", index = true)
|
||||
val imageId: Long,
|
||||
@ColumnInfo(name = "levelId", index = true)
|
||||
val levelId: Long?,
|
||||
@ColumnInfo(name = "nationId", index = true)
|
||||
@ -43,10 +32,9 @@ data class Tank(
|
||||
name: String,
|
||||
price: Int,
|
||||
miniature: Bitmap,
|
||||
imageId: Long,
|
||||
level: Level,
|
||||
nation: Nation
|
||||
) : this(null, name, price, miniature, imageId, level.uid, nation.uid)
|
||||
) : this(null, name, price, miniature, level.uid, nation.uid)
|
||||
|
||||
companion object {
|
||||
fun getTank(index: Long = 0): Tank {
|
||||
@ -55,7 +43,6 @@ data class Tank(
|
||||
"Первый танк",
|
||||
100000,
|
||||
miniature = getEmptyBitmap(),
|
||||
1L,
|
||||
1,
|
||||
1
|
||||
)
|
||||
@ -72,7 +59,6 @@ data class Tank(
|
||||
if (name != other.name) return false
|
||||
if (price != other.price) return false
|
||||
if (miniature != other.miniature) return false
|
||||
if (imageId != other.imageId) return false
|
||||
if (levelId != other.levelId) return false
|
||||
if (nationId != other.nationId) return false
|
||||
|
||||
|
@ -15,4 +15,13 @@ import org.jetbrains.annotations.NotNull
|
||||
data class UserTankCrossRef(
|
||||
val userId: Long,
|
||||
val tankId: Long
|
||||
){
|
||||
companion object {
|
||||
fun getEmpty(): UserTankCrossRef {
|
||||
return UserTankCrossRef(
|
||||
userId = 0,
|
||||
tankId = 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
|
||||
|
||||
interface NationRepository {
|
||||
suspend fun getAllNations(): List<Nation>
|
||||
suspend fun getAll(): Flow<PagingData<Nation>>
|
||||
fun getAll(): Flow<PagingData<Nation>>
|
||||
fun getSimpleNation(uid: Long): Flow<Nation?>
|
||||
fun getFullNation(uid: Long): Flow<NationWithTanks?>
|
||||
fun pagingSource(): PagingSource<Int, Nation>
|
||||
|
@ -9,7 +9,7 @@ import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
|
||||
|
||||
class OfflineNationRepository(private val nationDao: NationDao) : NationRepository {
|
||||
override suspend fun getAllNations(): List<Nation> = nationDao.getAll()
|
||||
override suspend fun getAll(): Flow<PagingData<Nation>> {
|
||||
override fun getAll(): Flow<PagingData<Nation>> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
|
@ -4,14 +4,16 @@ import android.graphics.Bitmap
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import ru.ulstu.`is`.pmu.tank.dao.TankDao
|
||||
import ru.ulstu.`is`.pmu.tank.dao.TankImageDao
|
||||
import ru.ulstu.`is`.pmu.tank.dao.UsersTanksDao
|
||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||
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
|
||||
|
||||
class OfflineTankRepository(
|
||||
private val tankDao: TankDao,
|
||||
private val tankImageDao: TankImageDao
|
||||
private val usersTanksDao: UsersTanksDao
|
||||
) : TankRepository {
|
||||
override suspend fun getAll(): List<Tank> = tankDao.getAll()
|
||||
|
||||
@ -22,14 +24,11 @@ class OfflineTankRepository(
|
||||
override suspend fun getUserTanks(uid: Long): List<TankWithNationAndLevel> = tankDao.getUserTanks(uid)
|
||||
|
||||
override suspend fun insertTank(tank: Tank, image: Bitmap) {
|
||||
val imageId = tankImageDao.insert(
|
||||
TankImage(
|
||||
id = null,
|
||||
data = image
|
||||
)
|
||||
)
|
||||
tankDao.insert(tank)
|
||||
}
|
||||
|
||||
tankDao.insert(tank.copy(imageId = imageId))
|
||||
override suspend fun buyTank(tankId: Long, userId: Long) {
|
||||
usersTanksDao.insert(UserTankCrossRef(userId, tankId))
|
||||
}
|
||||
|
||||
override suspend fun insertMany(tankList: List<Tank>) {
|
||||
@ -37,15 +36,7 @@ class OfflineTankRepository(
|
||||
}
|
||||
|
||||
override suspend fun updateTank(tank: Tank, image: Bitmap) {
|
||||
val imageId = tankImageDao.insert(
|
||||
TankImage(
|
||||
id = null,
|
||||
data = image
|
||||
)
|
||||
)
|
||||
|
||||
tankDao.update(tank.copy(imageId = imageId))
|
||||
tankImageDao.delete(tank.imageId)
|
||||
tankDao.update(tank.copy())
|
||||
}
|
||||
|
||||
override suspend fun deleteTank(tank: Tank) = tankDao.delete(tank)
|
||||
|
@ -8,7 +8,7 @@ import ru.ulstu.`is`.pmu.tank.model.User
|
||||
class OfflineUserRepository(private val userDao: UserDao) : UserRepository {
|
||||
override fun getAllUsers(): Flow<List<User>> = userDao.getAll()
|
||||
|
||||
override suspend fun getSimpleUser(email: String): User = userDao.getSimpleUserUid(email)
|
||||
override suspend fun getSimpleUser(userId: Long): User = userDao.getSimpleUserUid(userId)
|
||||
|
||||
override fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>> = userDao.getUserUid(uid)
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
package ru.ulstu.`is`.pmu.tank.repository
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import ru.ulstu.`is`.pmu.tank.dao.UsersTanksDao
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
|
||||
class OfflineUsersTanksRepository(
|
||||
private val usersTanksDao: UsersTanksDao
|
||||
) : UsersTanksRepository {
|
||||
override fun getAll(): List<UserTankCrossRef> {
|
||||
return usersTanksDao.getAll()
|
||||
}
|
||||
|
||||
override suspend fun getAllById(userId: Long): List<UserTankCrossRef> {
|
||||
return usersTanksDao.getAllById(userId)
|
||||
}
|
||||
|
||||
override suspend fun insertUserTank(userTankCrossRef: UserTankCrossRef) {
|
||||
return usersTanksDao.insert(userTankCrossRef)
|
||||
}
|
||||
|
||||
override suspend fun insertListUserTank(userTankCrossRefList: List<UserTankCrossRef>) {
|
||||
return usersTanksDao.insertMany(userTankCrossRefList)
|
||||
}
|
||||
|
||||
override suspend fun deleteUserTanks(userTankCrossRef: UserTankCrossRef) {
|
||||
return usersTanksDao.deleteAll()
|
||||
}
|
||||
}
|
@ -12,6 +12,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 insertMany(tankList: List<Tank>)
|
||||
suspend fun updateTank(tank: Tank, image: Bitmap)
|
||||
suspend fun deleteTank(tank: Tank)
|
||||
|
@ -6,7 +6,7 @@ import ru.ulstu.`is`.pmu.tank.model.User
|
||||
|
||||
interface UserRepository {
|
||||
fun getAllUsers(): Flow<List<User>>
|
||||
suspend fun getSimpleUser(email: String): User
|
||||
suspend fun getSimpleUser(userId: Long): User
|
||||
fun getFullUser(uid: Long): Flow<Map<User, List<TankWithNationAndLevel>>>
|
||||
suspend fun insertUser(user: User)
|
||||
suspend fun updateUser(user: User)
|
||||
|
@ -0,0 +1,14 @@
|
||||
package ru.ulstu.`is`.pmu.tank.repository
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
|
||||
import ru.ulstu.`is`.pmu.tank.model.User
|
||||
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
|
||||
|
||||
interface UsersTanksRepository {
|
||||
fun getAll(): List<UserTankCrossRef>
|
||||
suspend fun getAllById(userId: Long): List<UserTankCrossRef>
|
||||
suspend fun insertUserTank(userTankCrossRef: UserTankCrossRef)
|
||||
suspend fun insertListUserTank(userTankCrossRefList: List<UserTankCrossRef>)
|
||||
suspend fun deleteUserTanks(userTankCrossRef: UserTankCrossRef)
|
||||
}
|
@ -17,6 +17,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@ -46,6 +47,10 @@ fun Hangar(
|
||||
){
|
||||
viewModel.setUserId(100L)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.refreshUserTanksListState()
|
||||
}
|
||||
|
||||
//новый вызов основного списка
|
||||
Hangar(tankList = viewModel.usersTanksUiState.userTankList )
|
||||
}
|
||||
@ -82,7 +87,7 @@ private fun Hangar(
|
||||
) {
|
||||
var supportSizeRow = 1
|
||||
|
||||
if(n == supportCountRow && supportSizeRow % 2 != 0){
|
||||
if(n == supportCountRow && supportSizeRow % 2 != 0 && tankList.size != 2){
|
||||
supportSizeRow = 0
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ import ru.ulstu.`is`.pmu.tank.composeui.list.NationListViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.model.Nation
|
||||
import ru.ulstu.`is`.pmu.tanks.composeui.image.Dimensions
|
||||
import ru.ulstu.`is`.pmu.ui.AppViewModelProvider
|
||||
import androidx.compose.runtime.LaunchedEffect as LaunchedEffect
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
@ -46,13 +47,17 @@ fun NationList(
|
||||
navController: NavController,
|
||||
viewModel: NationListViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
||||
) {
|
||||
val nations = viewModel.nationPagingFlow.collectAsLazyPagingItems()
|
||||
val nations = viewModel.nationPagingFlow.flow.collectAsLazyPagingItems()
|
||||
|
||||
fun handleAddButtonClick() {
|
||||
val route = Screen.getEntityRoute(Screen.Constructor, 0)
|
||||
navController.navigate(route)
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.refresh()
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
@ -11,13 +11,17 @@ import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.UserEditViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.UsersTanksEditViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.list.NationListViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListViewModel
|
||||
|
||||
object AppViewModelProvider {
|
||||
val Factory = viewModelFactory {
|
||||
initializer {
|
||||
TankListViewModel(tankApplication().container.tankRestRepository)
|
||||
TankListViewModel(
|
||||
tankApplication().container.tankRestRepository,
|
||||
tankApplication().container.usersTanksRepository
|
||||
)
|
||||
}
|
||||
initializer {
|
||||
TankEditViewModel(
|
||||
@ -31,6 +35,12 @@ object AppViewModelProvider {
|
||||
tankApplication().container.userRestRepository
|
||||
)
|
||||
}
|
||||
initializer {
|
||||
UsersTanksEditViewModel(
|
||||
this.createSavedStateHandle(),
|
||||
tankApplication().container.usersTanksRepository
|
||||
)
|
||||
}
|
||||
initializer {
|
||||
LevelDropDownViewModel(tankApplication().container.levelRestRepository)
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user