Исправил вывод в Ангаре и запрос к БД.

This commit is contained in:
ElEgEv 2023-11-27 20:54:27 +04:00
parent 434cb03cac
commit bf6f3fd2e4
11 changed files with 74 additions and 50 deletions

View File

@ -8,10 +8,12 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
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.repository.TankRepository
class TankListViewModel(
private val tankRepository: TankRepository
private val tankRepository: TankRepository,
private var userId: Long = 100L
) : ViewModel() {
val tankListUiState: StateFlow<TankListUiState> = tankRepository.getAll().map {
TankListUiState(it)
@ -21,9 +23,23 @@ class TankListViewModel(
initialValue = TankListUiState()
)
val usersTanksUiState: StateFlow<UserTankListUiState> = tankRepository.getUserTanks(userId).map {
UserTankListUiState(it)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
initialValue = UserTankListUiState()
)
suspend fun deleteTank(tank: Tank) {
tankRepository.deleteTank(tank)
}
fun setUserId(uid: Long){
userId = uid
}
}
data class TankListUiState(val tankList: List<Tank> = listOf())
data class TankListUiState(val tankList: List<Tank> = listOf())
data class UserTankListUiState(val userTankList: List<TankWithNationAndLevel> = listOf())

View File

@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.Flow
import ru.ulstu.`is`.pmu.tank.model.LevelWithTanks
import ru.ulstu.`is`.pmu.tank.model.Nation
import ru.ulstu.`is`.pmu.tank.model.Tank
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
@Dao
interface TankDao {
@ -20,6 +21,16 @@ interface TankDao {
@Query("select * from tanks where tanks.tankId = :uid")
fun getTankUid(uid: Long): Flow<Tank?>
//получаем все танки пользователя по его Id
@Query(
"SELECT t.tankId, t.name, t.price, t.image, l.level, n.nationName FROM UserTankCrossRef AS ut " +
"LEFT JOIN tanks as t on ut.tankId = t.tankId " +
"LEFT JOIN levels as l on t.levelId = l.uid " +
"LEFT JOIN nations as n on t.nationId = n.uid " +
"WHERE ut.userId = :uid"
)
fun getUserTanks(uid: Long): Flow<List<TankWithNationAndLevel>>
@Insert
suspend fun insert(tank: Tank)

View File

@ -3,12 +3,15 @@ package ru.ulstu.`is`.pmu.tank.repository
import kotlinx.coroutines.flow.Flow
import ru.ulstu.`is`.pmu.tank.dao.TankDao
import ru.ulstu.`is`.pmu.tank.model.Tank
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
class OfflineTankRepository(private val tankDao: TankDao) : TankRepository {
override fun getAll(): Flow<List<Tank>> = tankDao.getAll()
override fun getTank(uid: Long): Flow<Tank?> = tankDao.getTankUid(uid)
override fun getUserTanks(uid: Long): Flow<List<TankWithNationAndLevel>> = tankDao.getUserTanks(uid)
override suspend fun insertTank(tank: Tank) = tankDao.insert(tank)
override suspend fun updateTank(tank: Tank) = tankDao.update(tank)

View File

@ -2,10 +2,12 @@ package ru.ulstu.`is`.pmu.tank.repository
import kotlinx.coroutines.flow.Flow
import ru.ulstu.`is`.pmu.tank.model.Tank
import ru.ulstu.`is`.pmu.tank.model.TankWithNationAndLevel
interface TankRepository {
fun getAll(): Flow<List<Tank>>
fun getTank(uid: Long): Flow<Tank?>
fun getUserTanks(uid: Long): Flow<List<TankWithNationAndLevel>>
suspend fun insertTank(tank: Tank)
suspend fun updateTank(tank: Tank)
suspend fun deleteTank(tank: Tank)

View File

@ -20,6 +20,7 @@ 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.runtime.key
import androidx.compose.runtime.mutableStateListOf
@ -36,6 +37,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
@ -46,64 +48,53 @@ 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.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.UserWithTanks
import ru.ulstu.`is`.pmu.ui.AppViewModelProvider
import ru.ulstu.`is`.pmu.ui.theme.CustomDark
import ru.ulstu.`is`.pmu.ui.theme.CustomYellow
import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme
@Composable
fun Hangar(
navController: NavController?,
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory)
){
viewModel.setUserId(100L)
val userTankListUiState by viewModel.usersTanksUiState.collectAsState()
//новый вызов основного списка
Hangar(tankList = userTankListUiState.userTankList )
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Hangar(navController: NavController) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }
val context = LocalContext.current
val (users, setUsers) = remember { mutableStateOf<UserWithTanks?>(null) }
val nations = remember { mutableStateListOf<Nation>() }
val levels = remember { mutableStateListOf<Level>() }
fun getData(): Flow<UserWithTanks> {
return flow {
AppDatabase.getInstance(context).userDao().getUserUid(100L).collect() { data ->
emit(data.firstNotNullOf {
UserWithTanks(
user = it.key,
tanks = it.value
)
})
}
}
}
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
getData().collect() {
setUsers(it)
}
}
}
private fun Hangar(
tankList: List<TankWithNationAndLevel>
) {
Column(
verticalArrangement = Arrangement.spacedBy(15.dp)
) {
val startIndex = 0
if(users != null){
val countRows = users.tanks.size / 2
//проверяем на то, что не всё поместилось в ряды по 2 элемента
val oneLastElem = users.tanks.size % 2
if(tankList.isNotEmpty()){
val countRows = tankList.size / 2
var index = 0
var supportCountRow = countRows
for (n in 1..(supportCountRow ?: 1)) {
//проверяем на то, что не всё поместилось в ряды по 2 элемента
if(tankList.size % 2 == 1){
supportCountRow++
}
for (n in 1..supportCountRow) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceAround,
@ -111,8 +102,14 @@ fun Hangar(navController: NavController) {
.fillMaxWidth()
.padding(10.dp, 0.dp, 10.dp, 0.dp)
) {
var supportSizeRow = 1
if(n == supportCountRow && supportSizeRow % 2 != 0){
supportSizeRow = 0
}
//цикл для заполнения строки карточек
for (m in 0..1) {
for (m in 0..supportSizeRow) {
Column(
modifier = Modifier.background(CustomYellow)
) {
@ -132,14 +129,14 @@ fun Hangar(navController: NavController) {
) {
Image(
painter = painterResource(
id = users.tanks[index].image
id = tankList[index].image
),
contentDescription = stringResource(id = R.string.tanks_main_title),
modifier = Modifier
.height(130.dp)
)
Text(
text = users.tanks[index].name,
text = tankList[index].name,
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
@ -147,7 +144,7 @@ fun Hangar(navController: NavController) {
modifier = Modifier.fillMaxWidth()
)
Text(
text = "Нация: " + users.tanks[index].nationName,
text = "Нация: " + tankList[index].nationName,
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
@ -155,7 +152,7 @@ fun Hangar(navController: NavController) {
modifier = Modifier.fillMaxWidth()
)
Text(
text = "Уровень: " + users.tanks[index].level.toString(),
text = "Уровень: " + tankList[index].level.toString(),
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
@ -163,7 +160,7 @@ fun Hangar(navController: NavController) {
modifier = Modifier.fillMaxWidth()
)
Text(
text = "Стоимость: " + users.tanks[index].price.toString(),
text = "Стоимость: " + tankList[index].price.toString(),
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
@ -175,11 +172,6 @@ fun Hangar(navController: NavController) {
}
index++
//если надо будет допечатать ещё один элемент
if (n == supportCountRow && oneLastElem != 0) {
supportCountRow = oneLastElem
}
}
}
Spacer(Modifier.height(20.dp))