Работаем над конструктором.
This commit is contained in:
parent
bf6f3fd2e4
commit
ba4be87c09
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -72,18 +72,6 @@ fun ColumnItem(
|
||||
number: Int,
|
||||
tanks: List<Tank>
|
||||
) {
|
||||
/*
|
||||
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(
|
||||
modifier = Modifier.padding(0.dp, 10.dp)
|
||||
) {
|
||||
@ -223,7 +211,10 @@ fun TankEmptyListPreview() {
|
||||
Surface(
|
||||
color = CustomDark
|
||||
) {
|
||||
TankList(numbers = listOf(1, 2, 3), listTanks = listOf())
|
||||
TankList(
|
||||
numbers = listOf(1, 2, 3),
|
||||
listTanks = listOf()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package ru.ulstu.`is`.pmu.tank.composeui.edit
|
||||
|
||||
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.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.ulstu.`is`.pmu.tank.model.Tank
|
||||
import ru.ulstu.`is`.pmu.tank.repository.TankRepository
|
||||
|
||||
class TankEditViewModel(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val tankRepository: TankRepository
|
||||
) : ViewModel() {
|
||||
var tankUiState by mutableStateOf(TankUiState())
|
||||
private set
|
||||
|
||||
private val tankUid: Long = checkNotNull(savedStateHandle["id"])
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
if (tankUid > 0) {
|
||||
tankUiState = tankRepository.getTank(tankUid)
|
||||
.filterNotNull()
|
||||
.first()
|
||||
.toUiState(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateUiState(tankDetails: TankDetails) {
|
||||
tankUiState = TankUiState(
|
||||
tankDetails = tankDetails,
|
||||
isEntryValid = validateInput(tankDetails)
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun saveTank() {
|
||||
if (validateInput()) {
|
||||
if (tankUid > 0) {
|
||||
tankRepository.updateTank(tankUiState.tankDetails.toTank(tankUid))
|
||||
} else {
|
||||
tankRepository.insertTank(tankUiState.tankDetails.toTank())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateInput(uiState: TankDetails = tankUiState.tankDetails): Boolean {
|
||||
return with(uiState) {
|
||||
name.isNotBlank()
|
||||
&& price > 0
|
||||
&& image > 0
|
||||
&& levelId!! > 0
|
||||
&& nationId!! > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class TankUiState(
|
||||
val tankDetails: TankDetails = TankDetails(),
|
||||
val isEntryValid: Boolean = false
|
||||
)
|
||||
|
||||
data class TankDetails(
|
||||
val name: String = "",
|
||||
val price: Int = 0,
|
||||
val image: Int = 0,
|
||||
val levelId: Long? = 0,
|
||||
val nationId: Long? = 0,
|
||||
)
|
||||
|
||||
fun TankDetails.toTank(uid: Long = 0): Tank = Tank(
|
||||
tankId = uid,
|
||||
name = name,
|
||||
price = price,
|
||||
image = image,
|
||||
levelId = levelId,
|
||||
nationId = levelId
|
||||
)
|
||||
|
||||
fun Tank.toDetails(): TankDetails = TankDetails(
|
||||
name = name,
|
||||
price = price,
|
||||
image = image,
|
||||
levelId = levelId,
|
||||
nationId = nationId
|
||||
)
|
||||
|
||||
fun Tank.toUiState(isEntryValid: Boolean = false): TankUiState = TankUiState(
|
||||
tankDetails = this.toDetails(),
|
||||
isEntryValid = isEntryValid
|
||||
)
|
@ -27,6 +27,13 @@ data class Level(
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DEMO_LEVEL = Level(
|
||||
0,
|
||||
1
|
||||
)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return (uid ?: -1) as Int
|
||||
}
|
||||
|
@ -28,6 +28,13 @@ data class Nation(
|
||||
override fun hashCode(): Int {
|
||||
return (uid ?: -1) as Int
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DEMO_NATION = Nation(
|
||||
0,
|
||||
"СССР"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getNations(): List<Nation> {
|
||||
|
@ -4,6 +4,7 @@ import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import ru.ulstu.`is`.pmu.R
|
||||
|
||||
@Entity(
|
||||
tableName = "tanks"
|
||||
@ -31,6 +32,19 @@ data class Tank(
|
||||
nation: Nation
|
||||
) : this(null, name, price, image, level.uid, nation.uid)
|
||||
|
||||
companion object {
|
||||
fun getTank(index: Long = 0): Tank {
|
||||
return Tank(
|
||||
index,
|
||||
"Первый танк",
|
||||
100000,
|
||||
R.drawable.t_34_85,
|
||||
1,
|
||||
1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
@ -23,6 +23,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
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
|
||||
@ -33,25 +34,78 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
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
|
||||
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.LevelDropDownViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.LevelUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.LevelsListUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankDetails
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.edit.toUiState
|
||||
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListViewModel
|
||||
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.getLevels
|
||||
import ru.ulstu.`is`.pmu.tank.model.getNations
|
||||
import ru.ulstu.`is`.pmu.ui.AppViewModelProvider
|
||||
import ru.ulstu.`is`.pmu.ui.theme.CustomDark
|
||||
import ru.ulstu.`is`.pmu.ui.theme.CustomOrange
|
||||
import ru.ulstu.`is`.pmu.ui.theme.CustomYellow
|
||||
import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme
|
||||
|
||||
@Composable
|
||||
fun Constructor(
|
||||
navController: NavController,
|
||||
tankEditViewModel: TankEditViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
levelDropDownViewModel: LevelDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
nationDropDownViewModel: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
||||
){
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
levelDropDownViewModel.setCurrentLevel(tankEditViewModel.tankUiState.tankDetails.levelId ?: 1)
|
||||
nationDropDownViewModel.setCurrentNation(tankEditViewModel.tankUiState.tankDetails.nationId ?: 1)
|
||||
|
||||
Constructor(
|
||||
tankUiState = tankEditViewModel.tankUiState,
|
||||
levelUiState = levelDropDownViewModel.levelUiState,
|
||||
levelsListUiState = levelDropDownViewModel.levelsListUiState,
|
||||
onLevelUpdate = levelDropDownViewModel::updateUiState,
|
||||
nationUiState = nationDropDownViewModel.nationUiState,
|
||||
nationsListUiState = nationDropDownViewModel.nationsListUiState,
|
||||
onNationUpdate = nationDropDownViewModel::updateUiState,
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
tankEditViewModel.saveTank()
|
||||
navController.popBackStack()
|
||||
}
|
||||
},
|
||||
onUpdate = tankEditViewModel::updateUiState
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class)
|
||||
@Composable
|
||||
fun Constructor(navController: NavController) {
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentDestination = navBackStackEntry?.destination
|
||||
val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }
|
||||
|
||||
private fun Constructor(
|
||||
tankUiState: TankUiState,
|
||||
levelUiState: LevelUiState,
|
||||
levelsListUiState: LevelsListUiState,
|
||||
onLevelUpdate: (Level) -> Unit,
|
||||
nationUiState: NationUiState,
|
||||
nationsListUiState: NationsListUiState,
|
||||
onNationUpdate: (Nation) -> Unit,
|
||||
onClick: () -> Unit,
|
||||
onUpdate: (TankDetails) -> Unit
|
||||
) {
|
||||
var nationName by remember { mutableStateOf("") }
|
||||
var price by remember { mutableStateOf("") }
|
||||
|
||||
@ -69,7 +123,9 @@ fun Constructor(navController: NavController) {
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth().background(CustomYellow)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(CustomYellow)
|
||||
){
|
||||
Column {
|
||||
Row(
|
||||
@ -98,7 +154,7 @@ fun Constructor(navController: NavController) {
|
||||
TextField(
|
||||
value = nationName,
|
||||
placeholder = { Text(text = "Название", color = CustomDark) },
|
||||
onValueChange = { nationName = it },
|
||||
onValueChange = { onUpdate(tankUiState.tankDetails.copy(name = it)) },
|
||||
modifier = Modifier
|
||||
.width(200.dp),
|
||||
)
|
||||
@ -108,7 +164,7 @@ fun Constructor(navController: NavController) {
|
||||
expanded = expandedLevels,
|
||||
onExpandedChange = {
|
||||
expandedLevels = !expandedLevels
|
||||
}
|
||||
},
|
||||
) {
|
||||
// textfield
|
||||
TextField(
|
||||
@ -136,6 +192,7 @@ fun Constructor(navController: NavController) {
|
||||
text = { Text(selectionOption.level.toString()) },
|
||||
onClick = {
|
||||
selectedLevel = selectionOption.level
|
||||
onLevelUpdate(selectionOption)
|
||||
expandedLevels = false
|
||||
},
|
||||
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
|
||||
@ -177,6 +234,7 @@ fun Constructor(navController: NavController) {
|
||||
text = { Text(selectionOption.nationName) },
|
||||
onClick = {
|
||||
selectedNation = selectionOption.nationName
|
||||
onNationUpdate(selectionOption)
|
||||
expandedNation = false
|
||||
},
|
||||
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
|
||||
@ -188,7 +246,7 @@ fun Constructor(navController: NavController) {
|
||||
TextField(
|
||||
value = price,
|
||||
placeholder = { Text(text = "Стоимость", color = CustomDark) },
|
||||
onValueChange = { price = it },
|
||||
onValueChange = { onUpdate(tankUiState.tankDetails.copy(price = it.toInt())) },
|
||||
modifier = Modifier
|
||||
.width(200.dp),
|
||||
)
|
||||
@ -196,7 +254,9 @@ fun Constructor(navController: NavController) {
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(10.dp, 10.dp)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp, 10.dp)
|
||||
){
|
||||
Button(
|
||||
modifier = Modifier
|
||||
@ -208,14 +268,16 @@ fun Constructor(navController: NavController) {
|
||||
),
|
||||
onClick = { }) {
|
||||
//"${student.firstName} ${student.lastName}"
|
||||
Text(text = stringResource(id = R.string.create_account_button), fontSize = 20.sp, fontWeight = FontWeight.Bold)
|
||||
Text(text = stringResource(id = R.string.save_account_button), fontSize = 20.sp, fontWeight = FontWeight.Bold)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth().background(CustomYellow)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(CustomYellow)
|
||||
){
|
||||
Column {
|
||||
Row(
|
||||
@ -246,7 +308,9 @@ fun Constructor(navController: NavController) {
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(10.dp, 10.dp)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp, 10.dp)
|
||||
){
|
||||
Button(
|
||||
modifier = Modifier
|
||||
@ -265,7 +329,9 @@ fun Constructor(navController: NavController) {
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth().background(CustomYellow)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(CustomYellow)
|
||||
){
|
||||
Column {
|
||||
Row(
|
||||
@ -296,7 +362,9 @@ fun Constructor(navController: NavController) {
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(10.dp, 10.dp)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp, 10.dp)
|
||||
){
|
||||
Button(
|
||||
modifier = Modifier
|
||||
@ -320,13 +388,23 @@ fun Constructor(navController: NavController) {
|
||||
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
fun ConstructorPreview() {
|
||||
fun ConstructorEditPreview() {
|
||||
PmudemoTheme {
|
||||
Surface(
|
||||
color = CustomDark
|
||||
) {
|
||||
val navController = rememberNavController()
|
||||
Constructor(navController)
|
||||
Constructor(
|
||||
tankUiState = Tank.getTank().toUiState(true),
|
||||
levelUiState = Level.DEMO_LEVEL.toUiState(),
|
||||
levelsListUiState = LevelsListUiState(listOf()),
|
||||
onLevelUpdate = { },
|
||||
nationUiState = Nation.DEMO_NATION.toUiState(),
|
||||
nationsListUiState = NationsListUiState(listOf()),
|
||||
onNationUpdate = { },
|
||||
onClick = { },
|
||||
onUpdate = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -170,15 +170,12 @@ private fun Hangar(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index++
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(20.dp))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,8 +187,20 @@ fun HangarPreview() {
|
||||
Surface(
|
||||
color = CustomDark
|
||||
) {
|
||||
val navController = rememberNavController()
|
||||
Hangar(navController)
|
||||
Hangar(tankList = listOf())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
fun HangarEmptyPreview() {
|
||||
PmudemoTheme {
|
||||
Surface(
|
||||
color = CustomDark
|
||||
) {
|
||||
Hangar(tankList = listOf())
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user