Добрался до первого компонента.

This commit is contained in:
ElEgEv 2023-11-26 15:17:58 +04:00
parent 5b26f60938
commit 895fdee643
11 changed files with 272 additions and 5 deletions

View File

@ -0,0 +1,14 @@
package ru.ulstu.`is`.pmu
import android.app.Application
import ru.ulstu.`is`.pmu.tank.database.AppContainer
import ru.ulstu.`is`.pmu.tank.database.AppDataContainer
class TankApplication : Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}

View File

@ -36,15 +36,18 @@ 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 kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
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.Tank
import ru.ulstu.`is`.pmu.tank.model.getStudents
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.CustomRed
@ -52,7 +55,10 @@ import ru.ulstu.`is`.pmu.ui.theme.CustomYellow
import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme
@Composable
fun TankList(navController: NavController?) {
fun TankList(
navController: NavController?,
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val listIds = listOf(
R.string.ussr_list,
R.string.germany_list,

View File

@ -0,0 +1,46 @@
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.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import ru.ulstu.`is`.pmu.tank.model.Level
import ru.ulstu.`is`.pmu.tank.repository.LevelRepository
class LevelDropDownViewModel (
private val levelRepository: LevelRepository
) : ViewModel() {
var levelsListUiState by mutableStateOf(LevelsListUiState())
private set
var levelUiState by mutableStateOf(LevelUiState())
private set
init {
viewModelScope.launch {
levelsListUiState = LevelsListUiState(levelRepository.getAllLevels())
}
}
fun setCurrentLevel(levelId: Long) {
val level: Level? =
levelsListUiState.levelList.firstOrNull { level -> level.uid == levelId }
level?.let { updateUiState(it) }
}
fun updateUiState(level: Level) {
levelUiState = LevelUiState(
level = level
)
}
}
data class LevelsListUiState(val levelList: List<Level> = listOf())
data class LevelUiState(
val level: Level? = null
)
fun Level.toUiState() = LevelUiState(level = Level(uid = uid, level = level))

View File

@ -0,0 +1,46 @@
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.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import ru.ulstu.`is`.pmu.tank.model.Nation
import ru.ulstu.`is`.pmu.tank.repository.NationRepository
class NationDropDownViewModel(
private val nationRepository: NationRepository
) : ViewModel() {
var nationsListUiState by mutableStateOf(NationsListUiState())
private set
var nationUiState by mutableStateOf(NationUiState())
private set
init {
viewModelScope.launch {
nationsListUiState = NationsListUiState(nationRepository.getAllNations())
}
}
fun setCurrentNation(nationId: Long) {
val nation: Nation? =
nationsListUiState.nationList.firstOrNull { nation -> nation.uid == nationId }
nation?.let { updateUiState(it) }
}
fun updateUiState(nation: Nation) {
nationUiState = NationUiState(
nation = nation
)
}
}
data class NationsListUiState(val nationList: List<Nation> = listOf())
data class NationUiState(
val nation: Nation? = null
)
fun Nation.toUiState() = NationUiState(nation = Nation(uid = uid, nationName = nationName))

View File

@ -0,0 +1,93 @@
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.User
import ru.ulstu.`is`.pmu.tank.repository.UserRepository
class UserEditViewModel(
savedStateHandle: SavedStateHandle,
private val userRepository: UserRepository
) : ViewModel() {
var userUiState by mutableStateOf(UserUiState())
private set
private val userUid: Long = checkNotNull(savedStateHandle["id"])
init {
viewModelScope.launch {
if (userUid > 0) {
userUiState = userRepository.getSimpleUser(userUid)
.filterNotNull()
.first()
.toUiState(true)
}
}
}
fun updateUiState(userDetails: UserDetails) {
userUiState = UserUiState(
userDetails = userDetails,
isEntryValid = validateInput(userDetails)
)
}
suspend fun saveUser() {
if (validateInput()) {
if (userUid > 0) {
userRepository.updateUser(userUiState.userDetails.toUser(userUid))
} else {
userRepository.insertUser(userUiState.userDetails.toUser())
}
}
}
private fun validateInput(uiState: UserDetails = userUiState.userDetails): Boolean {
return with(uiState) {
nickname.isNotBlank()
&& email.isNotBlank()
&& password.isNotBlank()
&& balance > 0
}
}
}
data class UserUiState(
val userDetails: UserDetails = UserDetails(),
val isEntryValid: Boolean = false
)
data class UserDetails(
val nickname: String = "",
val email: String = "",
val password: String = "",
val balance: Int = 0,
)
fun UserDetails.toUser(uid: Long = 0): User = User(
userId = uid,
nickname = nickname,
email = email,
password = password,
balance = balance
)
fun User.toDetails(): UserDetails = UserDetails(
nickname = nickname,
email = email,
password = password,
balance = balance
)
fun User.toUiState(isEntryValid: Boolean = false): UserUiState = UserUiState(
userDetails = this.toDetails(),
isEntryValid = isEntryValid
)

View File

@ -0,0 +1,29 @@
package ru.ulstu.`is`.pmu.tank.composeui.list
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
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.repository.TankRepository
class TankListViewModel(
private val tankRepository: TankRepository
) : ViewModel() {
val tankListUiState: StateFlow<TankListUiState> = tankRepository.getAllTanks().map {
TankListUiState(it)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
initialValue = TankListUiState()
)
suspend fun deleteTank(tank: Tank) {
tankRepository.deleteTank(tank)
}
}
data class TankListUiState(val tankList: List<Tank> = listOf())

View File

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

View File

@ -5,7 +5,7 @@ import ru.ulstu.`is`.pmu.tank.model.Level
import ru.ulstu.`is`.pmu.tank.model.LevelWithTanks
interface LevelRepository {
fun getAllLevels(): Flow<List<Level>>
fun getAllLevels(): List<Level>
fun getSimpleLevel(uid: Long): Flow<Level?>
fun getFullLevel(uid: Long): Flow<LevelWithTanks?>
suspend fun insertLevel(level: Level)

View File

@ -5,7 +5,7 @@ import ru.ulstu.`is`.pmu.tank.model.Nation
import ru.ulstu.`is`.pmu.tank.model.NationWithTanks
interface NationRepository {
fun getAllNations(): Flow<List<Nation>>
fun getAllNations(): List<Nation>
fun getSimpleNation(uid: Long): Flow<Nation?>
fun getFullNation(uid: Long): Flow<NationWithTanks?>
suspend fun insertNation(nation: Nation)

View File

@ -6,7 +6,7 @@ import ru.ulstu.`is`.pmu.tank.model.Level
import ru.ulstu.`is`.pmu.tank.model.LevelWithTanks
class OfflineLevelRepository(private val levelDao: LevelDao) : LevelRepository {
override fun getAllLevels(): Flow<List<Level>> = levelDao.getAll()
override fun getAllLevels(): List<Level> = levelDao.getAll()
override fun getSimpleLevel(uid: Long): Flow<Level?> = levelDao.getSimpleLevelUid(uid)

View File

@ -0,0 +1,33 @@
package ru.ulstu.`is`.pmu.ui
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import ru.ulstu.`is`.pmu.TankApplication
import ru.ulstu.`is`.pmu.tank.composeui.edit.LevelDropDownViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
StudentListViewModel(tankApplication().container.studentRepository)
}
initializer {
StudentEditViewModel(
this.createSavedStateHandle(),
tankApplication().container.studentRepository
)
}
initializer {
LevelDropDownViewModel(tankApplication().container.levelRepository)
}
initializer {
NationDropDownViewModel(tankApplication().container.nationRepository)
}
}
}
fun CreationExtras.tankApplication(): TankApplication =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as TankApplication)