Правки

This commit is contained in:
ElEgEv 2023-11-12 00:39:21 +04:00
parent 976a08c596
commit 498aa7d955
15 changed files with 221 additions and 195 deletions

Binary file not shown.

View File

@ -23,7 +23,12 @@ import androidx.compose.material3.CardDefaults
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.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.key
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -32,8 +37,13 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.withContext
import ru.ulstu.`is`.pmu.R import ru.ulstu.`is`.pmu.R
import ru.ulstu.`is`.pmu.composeui.navigation.Screen import ru.ulstu.`is`.pmu.composeui.navigation.Screen
import ru.ulstu.`is`.pmu.tank.database.AppDatabase
import ru.ulstu.`is`.pmu.tank.model.Tank
import ru.ulstu.`is`.pmu.tank.model.getStudents import ru.ulstu.`is`.pmu.tank.model.getStudents
import ru.ulstu.`is`.pmu.ui.theme.CustomDark import ru.ulstu.`is`.pmu.ui.theme.CustomDark
import ru.ulstu.`is`.pmu.ui.theme.CustomOrange import ru.ulstu.`is`.pmu.ui.theme.CustomOrange
@ -57,6 +67,17 @@ fun TankList(navController: NavController?) {
fun ColumnItem( fun ColumnItem(
number: Int number: Int
) { ) {
val context = LocalContext.current
val tanks = remember { mutableStateListOf<Tank>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).tankDao().getAll().collect() { data ->
tanks.clear()
tanks.addAll(data)
tanks.reverse()
}
}
}
Column( Column(
modifier = Modifier.padding(0.dp, 10.dp) modifier = Modifier.padding(0.dp, 10.dp)
) { ) {
@ -85,56 +106,45 @@ fun ColumnItem(
modifier = Modifier.horizontalScroll(ScrollState(0)) modifier = Modifier.horizontalScroll(ScrollState(0))
) )
{ {
getStudents().forEachIndexed() { index, student -> tanks.forEach { tank ->
val studentId = Screen.StudentView.route.replace("{id}", index.toString()) key(tank.tankId) {
Card( //val studentId = Screen.StudentView.route.replace("{id}", index.toString())
colors = CardDefaults.cardColors( Card(
containerColor = CustomDark, colors = CardDefaults.cardColors(
), containerColor = CustomDark,
modifier = Modifier ),
.size(width = 200.dp, height = 250.dp)
.padding(all = 5.dp)
) {
var imageId = R.drawable.t_34_85
var textId = R.string.t_34_85
if(number == R.string.ussr_list){
//ничего
} else if (number == R.string.germany_list){
imageId = R.drawable.tiger_1
textId = R.string.tiger_1
} else if (number == R.string.usa_list) {
imageId = R.drawable.sherman
textId = R.string.sherman
}
Image(
painter = painterResource(id = imageId),
contentDescription = stringResource(id = R.string.tanks_main_title),
modifier = Modifier modifier = Modifier
.height(150.dp) .size(width = 200.dp, height = 250.dp)
.padding(all = 5.dp) .padding(all = 5.dp)
) ) {
Text( Image(
text = stringResource(id = textId), painter = painterResource(id = tank.image),
fontSize = 30.sp, contentDescription = stringResource(id = R.string.tanks_main_title),
fontWeight = FontWeight.Bold, modifier = Modifier
color = CustomOrange, .height(150.dp)
textAlign = TextAlign.Center, .padding(all = 5.dp)
modifier = Modifier.fillMaxWidth() )
) Text(
Button( text = tank.name,
modifier = Modifier fontSize = 30.sp,
.fillMaxWidth() fontWeight = FontWeight.Bold,
.padding(10.dp, 0.dp, 10.dp, 10.dp), color = CustomOrange,
colors = ButtonDefaults.buttonColors( textAlign = TextAlign.Center,
containerColor = CustomRed, modifier = Modifier.fillMaxWidth()
contentColor = CustomDark), )
onClick = { }) { Button(
//navController?.navigate(Screen.Hangar.route) modifier = Modifier
//navController?.navigate(studentId) .fillMaxWidth()
//"${student.firstName} ${student.lastName}" .padding(10.dp, 0.dp, 10.dp, 10.dp),
Text(text = stringResource(id = R.string.purchase_button)) colors = ButtonDefaults.buttonColors(
containerColor = CustomRed,
contentColor = CustomDark),
onClick = { }) {
//navController?.navigate(Screen.Hangar.route)
//navController?.navigate(studentId)
//"${student.firstName} ${student.lastName}"
Text(text = stringResource(id = R.string.purchase_button))
}
} }
} }
} }

View File

@ -14,7 +14,7 @@ import ru.ulstu.`is`.pmu.tank.model.User
@Dao @Dao
interface LevelDao { interface LevelDao {
@Query("select * from levels order by level collate nocase asc") @Query("select * from levels")
fun getAll(): Flow<List<Level>> fun getAll(): Flow<List<Level>>
//получить уровни с танками //получить уровни с танками

View File

@ -13,7 +13,7 @@ import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
@Dao @Dao
interface NationDao { interface NationDao {
@Query("select * from nations order by name collate nocase asc") @Query("select * from nations")
fun getAll(): Flow<List<Nation>> fun getAll(): Flow<List<Nation>>
//получить нации с танками //получить нации с танками

View File

@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.Flow
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
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.UserWithTanks import ru.ulstu.`is`.pmu.tank.model.UserWithTanks
@Dao @Dao
@ -19,19 +20,16 @@ interface UserDao {
fun getAll(): Flow<List<User>> fun getAll(): Flow<List<User>>
//получить нации с танками //получить нации с танками
@Transaction
@Query("SELECT * FROM users") @Query("SELECT * FROM users")
fun getUsersWithTanks(): LiveData<List<UserWithTanks>> fun getUsersWithTanks(): LiveData<List<UserWithTanks>>
//получить конкретную нацию //получить конкретного пользователя
@Transaction
@Query("select * from users where users.userId = :uid") @Query("select * from users where users.userId = :uid")
suspend fun getUserUid(uid: Long): UserWithTanks suspend fun getUserUid(uid: Long): UserWithTanks
//добавить танк в ангар пользователя //добавить танк в ангар пользователя
@Transaction @Insert
@Query("INSERT INTO UserTankCrossRef (userId, tankId) VALUES (:uid, :tid)") suspend fun insert(userWithTanks: UserWithTanks) : Long
suspend fun addTankToClient(uid: Long?, tid: Long?)
@Insert @Insert
suspend fun insert(user: User) suspend fun insert(user: User)

View File

@ -8,6 +8,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ru.ulstu.`is`.pmu.R
import ru.ulstu.`is`.pmu.tank.dao.LevelDao import ru.ulstu.`is`.pmu.tank.dao.LevelDao
import ru.ulstu.`is`.pmu.tank.dao.NationDao import ru.ulstu.`is`.pmu.tank.dao.NationDao
import ru.ulstu.`is`.pmu.tank.dao.TankDao import ru.ulstu.`is`.pmu.tank.dao.TankDao
@ -17,6 +18,7 @@ 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.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
//тут, собственно говоря, всё и мутится с БД :))) //тут, собственно говоря, всё и мутится с БД :)))
@Database(entities = [Nation::class, Level::class, Tank::class, User::class, UserTankCrossRef::class], version = 1, exportSchema = false) @Database(entities = [Nation::class, Level::class, Tank::class, User::class, UserTankCrossRef::class], version = 1, exportSchema = false)
@ -84,17 +86,17 @@ abstract class AppDatabase : RoomDatabase() {
//Tanks //Tanks
val tankDao = database.tankDao() val tankDao = database.tankDao()
val tank1 = Tank("МС-1", 1000, level1, nation1) val tank1 = Tank("МС-1", 1000, R.drawable.t_34_85, level1, nation1)
val tank2 = Tank("Т-34-85", 960000, level6, nation1) val tank2 = Tank("Т-34-85", 960000, R.drawable.t_34_85, level6, nation1)
val tank3 = Tank("ИС-2", 1230000, level7, nation1) val tank3 = Tank("ИС-2", 1230000, R.drawable.t_34_85, level7, nation1)
val tank4 = Tank("ИСУ-152", 2350000, level8, nation1) val tank4 = Tank("ИСУ-152", 2350000, R.drawable.t_34_85, level8, nation1)
val tank5 = Tank("Tiger 1", 1430000, level7, nation2) val tank5 = Tank("Tiger 1", 1430000, R.drawable.tiger_1, level7, nation2)
val tank6 = Tank("Ferdinand", 2500000, level8, nation2) val tank6 = Tank("Ferdinand", 2500000, R.drawable.tiger_1, level8, nation2)
val tank7 = Tank("Tiger 2", 2500000, level8, nation2) val tank7 = Tank("Tiger 2", 2500000, R.drawable.tiger_1, level8, nation2)
val tank8 = Tank("Panther", 1350000, level7, nation2) val tank8 = Tank("Panther", 1350000, R.drawable.tiger_1, level7, nation2)
val tank9 = Tank("M4A2E3", 990000, level6, nation3) val tank9 = Tank("M4A2E3", 990000, R.drawable.sherman, level6, nation3)
val tank10 = Tank("Pershing", 1260000, level8, nation3) val tank10 = Tank("Pershing", 1260000, R.drawable.sherman, level8, nation3)
val tank11 = Tank("Hellcat", 940000, level7, nation3) val tank11 = Tank("Hellcat", 940000, R.drawable.sherman, level7, nation3)
tankDao.insert(tank1) tankDao.insert(tank1)
tankDao.insert(tank2) tankDao.insert(tank2)
@ -111,13 +113,10 @@ abstract class AppDatabase : RoomDatabase() {
//Users //Users
val userDao = database.userDao() val userDao = database.userDao()
val user = User("3tankista73", "egor@mail.ru", "12032003", 10000000) val user = User("3tankista73", "egor@mail.ru", "12032003", 10000000)
val newObj1 = UserWithTanks(user, listOf(tank1, tank3, tank5, tank7, tank9))
userDao.insert(user) userDao.insert(user)
userDao.addTankToClient(user.userId, tank1.tankId) userDao.insert(newObj1)
userDao.addTankToClient(user.userId, tank3.tankId)
userDao.addTankToClient(user.userId, tank5.tankId)
userDao.addTankToClient(user.userId, tank7.tankId)
userDao.addTankToClient(user.userId, tank9.tankId)
} }
} }

View File

@ -15,6 +15,8 @@ data class Tank(
val name: String, val name: String,
@ColumnInfo(name = "price") @ColumnInfo(name = "price")
val price: Int, val price: Int,
@ColumnInfo(name="image")
val image: Int,
@ColumnInfo(name = "levelId", index = true) @ColumnInfo(name = "levelId", index = true)
val levelId: Long?, val levelId: Long?,
@ColumnInfo(name = "nationId", index = true) @ColumnInfo(name = "nationId", index = true)
@ -24,9 +26,10 @@ data class Tank(
constructor( constructor(
name: String, name: String,
price: Int, price: Int,
image: Int,
level: Level, level: Level,
nation: Nation nation: Nation
) : this(null, name, price, level.uid, nation.uid) ) : this(null, name, price, image, level.uid, nation.uid)
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true

View File

@ -1,10 +1,29 @@
package ru.ulstu.`is`.pmu.tank.model package ru.ulstu.`is`.pmu.tank.model
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey
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(primaryKeys = ["userId", "tankId"],
foreignKeys = [
ForeignKey(
entity = User::class,
parentColumns = ["userId"],
childColumns = ["userId"],
onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT
),
ForeignKey(
entity = Tank::class,
parentColumns = ["tankId"],
childColumns = ["tankId"],
onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT
)
]
)
data class UserTankCrossRef( data class UserTankCrossRef(
val userId: Long, val userId: Long,
val tankId: Long val tankId: Long

View File

@ -18,10 +18,15 @@ 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.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateListOf
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.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -32,8 +37,15 @@ import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import ru.ulstu.`is`.pmu.R import ru.ulstu.`is`.pmu.R
import ru.ulstu.`is`.pmu.composeui.navigation.Screen import ru.ulstu.`is`.pmu.composeui.navigation.Screen
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.UserWithTanks
import ru.ulstu.`is`.pmu.ui.theme.CustomDark import ru.ulstu.`is`.pmu.ui.theme.CustomDark
import ru.ulstu.`is`.pmu.ui.theme.CustomYellow import ru.ulstu.`is`.pmu.ui.theme.CustomYellow
import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme
@ -45,130 +57,115 @@ fun Hangar(navController: NavController){
val currentDestination = navBackStackEntry?.destination val currentDestination = navBackStackEntry?.destination
val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }
val context = LocalContext.current
val users = remember { mutableStateListOf<UserWithTanks>() }
val nations = remember { mutableStateListOf<Nation>() }
val levels = remember { mutableStateListOf<Level>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).userDao().getUsersWithTanks().value?.forEach() { data ->
users.clear()
users.add(data)
}
AppDatabase.getInstance(context).nationDao().getAll().collect { data ->
nations.clear()
nations.addAll(data)
}
AppDatabase.getInstance(context).levelDao().getAll().collect { data ->
levels.clear()
levels.addAll(data)
}
}
}
Column( Column(
verticalArrangement = Arrangement.spacedBy(15.dp) verticalArrangement = Arrangement.spacedBy(15.dp)
) { ) {
for(n in 1..3){ users.forEach { user ->
Row( key(user.user.userId) {
verticalAlignment = Alignment.CenterVertically, val countRows = user.tanks.size / 2
horizontalArrangement = Arrangement.SpaceAround,
modifier = Modifier //проверяем на то, что не всё поместилось в ряды по 2 элемента
.fillMaxWidth() val oneLastElem = user.tanks.size % 2
.padding(10.dp, 0.dp, 10.dp, 0.dp)
) { var index = 0
Column(
modifier = Modifier.background(CustomYellow) var supportCountRow = countRows
) {
Box( for(n in 1 .. supportCountRow){
Modifier Row(
.background(CustomYellow) verticalAlignment = Alignment.CenterVertically,
.height(260.dp), horizontalArrangement = Arrangement.SpaceAround,
) modifier = Modifier
{ .fillMaxWidth()
Card( .padding(10.dp, 0.dp, 10.dp, 0.dp)
colors = CardDefaults.cardColors( ) {
containerColor = CustomYellow, //цикл для заполнения строки карточек
), for (m in 0 .. 1){
modifier = Modifier Column(
.size(width = 170.dp, height = 250.dp) modifier = Modifier.background(CustomYellow)
.padding(10.dp, 0.dp, 10.dp, 0.dp) ) {
) { Box(
Image( Modifier
painter = painterResource(id = R.drawable.t_34_85), .background(CustomYellow)
contentDescription = stringResource(id = R.string.tanks_main_title), .height(260.dp),
modifier = Modifier )
.height(130.dp) {
) Card(
Text( colors = CardDefaults.cardColors(
text = stringResource(id = R.string.t_34_85), containerColor = CustomYellow,
fontSize = 20.sp, ),
fontWeight = FontWeight.Bold, modifier = Modifier
color = Color.Black, .size(width = 170.dp, height = 250.dp)
textAlign = TextAlign.Center, .padding(10.dp, 0.dp, 10.dp, 0.dp)
modifier = Modifier.fillMaxWidth() ) {
) Image(
Text( painter = painterResource(id = user.tanks[index].image),
text = "Нация: СССР", contentDescription = stringResource(id = R.string.tanks_main_title),
fontSize = 17.sp, modifier = Modifier
fontWeight = FontWeight.Bold, .height(130.dp)
color = Color.Black, )
textAlign = TextAlign.Center, Text(
modifier = Modifier.fillMaxWidth() text = user.tanks[index].name,
) fontSize = 20.sp,
Text( fontWeight = FontWeight.Bold,
text = "Уровень: 6", color = Color.Black,
fontSize = 17.sp, textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold, modifier = Modifier.fillMaxWidth()
color = Color.Black, )
textAlign = TextAlign.Center, Text(
modifier = Modifier.fillMaxWidth() text = "Нация: " + nations.find{ it.uid == user.tanks[index].nationId }.toString(),
) fontSize = 17.sp,
Text( fontWeight = FontWeight.Bold,
text = "Стоимость: 965000", color = Color.Black,
fontSize = 17.sp, textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold, modifier = Modifier.fillMaxWidth()
color = Color.Black, )
textAlign = TextAlign.Center, Text(
modifier = Modifier.fillMaxWidth() text = "Уровень: " + levels.find{ it.uid == user.tanks[index].levelId }.toString(),
) fontSize = 17.sp,
} fontWeight = FontWeight.Bold,
} color = Color.Black,
} textAlign = TextAlign.Center,
Column( modifier = Modifier.fillMaxWidth()
modifier = Modifier.background(CustomYellow) )
) { Text(
Box( text = "Стоимость: " + user.tanks[index].price.toString(),
Modifier fontSize = 17.sp,
.background(CustomYellow) fontWeight = FontWeight.Bold,
.height(260.dp), color = Color.Black,
) textAlign = TextAlign.Center,
{ modifier = Modifier.fillMaxWidth()
Card( )
colors = CardDefaults.cardColors( }
containerColor = CustomYellow, }
), }
modifier = Modifier index++
.size(width = 170.dp, height = 250.dp)
.padding(10.dp, 0.dp, 10.dp, 0.dp) //если надо будет допечатать ещё один элемент
) { if(n == supportCountRow && oneLastElem != 0){
Image( supportCountRow = oneLastElem
painter = painterResource(id = R.drawable.tiger_1), }
contentDescription = stringResource(id = R.string.tanks_main_title),
modifier = Modifier
.height(130.dp)
)
Text(
text = stringResource(id = R.string.tiger_1),
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Text(
text = "Нация: Германия",
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Text(
text = "Уровень: 7",
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Text(
text = "Стоимость: 1350000",
fontSize = 17.sp,
fontWeight = FontWeight.Bold,
color = Color.Black,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
} }
} }
} }