поиск и эдиты
This commit is contained in:
parent
55a0ac8581
commit
42c21b0ce7
17
.idea/deploymentTargetDropDown.xml
Normal file
17
.idea/deploymentTargetDropDown.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="deploymentTargetDropDown">
|
||||||
|
<runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<Target>
|
||||||
|
<type value="RUNNING_DEVICE_TARGET" />
|
||||||
|
<deviceKey>
|
||||||
|
<Key>
|
||||||
|
<type value="SERIAL_NUMBER" />
|
||||||
|
<value value="KFRSEQ6DTWWWQOE6" />
|
||||||
|
</Key>
|
||||||
|
</deviceKey>
|
||||||
|
</Target>
|
||||||
|
</runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<timeTargetWasSelectedWithDropDown value="2023-12-17T14:14:18.887820Z" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,3 @@
|
|||||||
|
package com.example.myapplication.api
|
||||||
|
|
||||||
|
enum class ApiStatus { LOADING, ERROR, DONE }
|
@ -1,13 +1,18 @@
|
|||||||
package com.example.myapplication.composeui
|
package com.example.myapplication.composeui
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import com.example.myapplication.database.entities.model.User
|
import com.example.myapplication.database.entities.model.User
|
||||||
import com.example.myapplication.database.entities.repository.UserRepository
|
import com.example.myapplication.database.entities.repository.UserRepository
|
||||||
|
|
||||||
class AuthenticatorViewModel(
|
class AuthenticatorViewModel(
|
||||||
private val userRepository: UserRepository
|
private val userRepository: UserRepository
|
||||||
) : ViewModel() {
|
) : MyViewModel() {
|
||||||
suspend fun findUserByLogin(login: String): User? {
|
suspend fun findUserByLogin(login: String): User? {
|
||||||
return userRepository.getUser(login)
|
var user: User? = null
|
||||||
|
runInScope(
|
||||||
|
actionSuccess = {
|
||||||
|
user = userRepository.getUser(login)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return user
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.example.myapplication.composeui
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.myapplication.api.ApiStatus
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import retrofit2.HttpException
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
open class MyViewModel : ViewModel() {
|
||||||
|
var apiStatus by mutableStateOf(ApiStatus.DONE)
|
||||||
|
private set
|
||||||
|
|
||||||
|
var apiError by mutableStateOf("")
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun runInScope(
|
||||||
|
actionSuccess: suspend () -> Unit,
|
||||||
|
actionError: suspend () -> Unit
|
||||||
|
) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
apiStatus = ApiStatus.LOADING
|
||||||
|
runCatching {
|
||||||
|
actionSuccess()
|
||||||
|
apiStatus = ApiStatus.DONE
|
||||||
|
apiError = ""
|
||||||
|
}.onFailure { e: Throwable ->
|
||||||
|
when (e) {
|
||||||
|
is IOException,
|
||||||
|
is HttpException -> {
|
||||||
|
actionError()
|
||||||
|
apiStatus = ApiStatus.ERROR
|
||||||
|
apiError = e.localizedMessage ?: e.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runInScope(actionSuccess: suspend () -> Unit) {
|
||||||
|
runInScope(actionSuccess, actionError = {})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.example.myapplication.composeui
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.TextUnit
|
||||||
|
import androidx.compose.ui.unit.TextUnitType
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.myapplication.R
|
||||||
|
import com.example.myapplication.ui.theme.PmudemoTheme
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ErrorPlaceholder(message: String, onBack: () -> Unit) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(10.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
fontSize = TextUnit(value = 20F, type = TextUnitType.Sp),
|
||||||
|
text = message,
|
||||||
|
color = Color(0xFFFF1744)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.padding(bottom = 10.dp))
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = { onBack() }
|
||||||
|
) {
|
||||||
|
Text(stringResource(id = R.string.back))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LoadingPlaceholder() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(10.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
fontSize = TextUnit(value = 25F, type = TextUnitType.Sp),
|
||||||
|
text = stringResource(id = R.string.loading)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 ErrorPlaceholderPreview() {
|
||||||
|
PmudemoTheme {
|
||||||
|
Surface(
|
||||||
|
color = MaterialTheme.colorScheme.background
|
||||||
|
) {
|
||||||
|
ErrorPlaceholder("Error", onBack = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 LoadingPlaceholderPreview() {
|
||||||
|
PmudemoTheme {
|
||||||
|
Surface(
|
||||||
|
color = MaterialTheme.colorScheme.background
|
||||||
|
) {
|
||||||
|
LoadingPlaceholder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,11 +3,11 @@ package com.example.myapplication.database.entities.composeui
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import androidx.paging.cachedIn
|
import androidx.paging.cachedIn
|
||||||
import com.example.myapplication.LiveStore
|
import com.example.myapplication.LiveStore
|
||||||
|
import com.example.myapplication.composeui.MyViewModel
|
||||||
import com.example.myapplication.database.entities.model.Cinema
|
import com.example.myapplication.database.entities.model.Cinema
|
||||||
import com.example.myapplication.database.entities.repository.CinemaRepository
|
import com.example.myapplication.database.entities.repository.CinemaRepository
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -15,14 +15,14 @@ import kotlinx.coroutines.flow.emptyFlow
|
|||||||
|
|
||||||
class CinemaListViewModel(
|
class CinemaListViewModel(
|
||||||
private val cinemaRepository: CinemaRepository
|
private val cinemaRepository: CinemaRepository
|
||||||
) : ViewModel() {
|
) : MyViewModel() {
|
||||||
var cinemaPagingFlow by mutableStateOf(ProductPagingFlowState())
|
var cinemaPagingFlow by mutableStateOf(CinemaPagingFlowState())
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
val name = "%${LiveStore.searchRequest.value}%"
|
val name = "%${LiveStore.searchRequest.value}%"
|
||||||
val pagingSource = cinemaRepository.getAllCinemas(name)
|
val pagingSource = cinemaRepository.getAllCinemas(name)
|
||||||
cinemaPagingFlow = ProductPagingFlowState(pagingSource.cachedIn(viewModelScope))
|
cinemaPagingFlow = CinemaPagingFlowState(pagingSource.cachedIn(viewModelScope))
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deleteCinema(cinema: Cinema) {
|
suspend fun deleteCinema(cinema: Cinema) {
|
||||||
@ -30,6 +30,6 @@ class CinemaListViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ProductPagingFlowState(
|
data class CinemaPagingFlowState(
|
||||||
val flow: Flow<PagingData<Cinema>> = emptyFlow(),
|
val flow: Flow<PagingData<Cinema>> = emptyFlow(),
|
||||||
)
|
)
|
@ -4,29 +4,32 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.ViewModel
|
import com.example.myapplication.composeui.MyViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.example.myapplication.database.entities.model.Cinema
|
import com.example.myapplication.database.entities.model.Cinema
|
||||||
import com.example.myapplication.database.entities.model.CinemaWithSessions
|
import com.example.myapplication.database.entities.model.CinemaWithSessions
|
||||||
import com.example.myapplication.database.entities.model.SessionFromCinema
|
import com.example.myapplication.database.entities.model.SessionFromCinema
|
||||||
import com.example.myapplication.database.entities.repository.CinemaRepository
|
import com.example.myapplication.database.entities.repository.CinemaRepository
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
class CinemaEditViewModel(
|
class CinemaEditViewModel(
|
||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
private val cinemaRepository: CinemaRepository
|
private val cinemaRepository: CinemaRepository
|
||||||
) : ViewModel() {
|
) : MyViewModel() {
|
||||||
var cinemaUiState by mutableStateOf(CinemaUiState())
|
var cinemaUiState by mutableStateOf(CinemaUiState())
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private val cinemaUid: Int = checkNotNull(savedStateHandle["id"])
|
private val cinemaUid: Int = checkNotNull(savedStateHandle["id"])
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
|
||||||
if (cinemaUid > 0) {
|
if (cinemaUid > 0) {
|
||||||
|
runInScope(
|
||||||
|
actionSuccess = {
|
||||||
cinemaUiState = cinemaRepository.getCinema(cinemaUid)
|
cinemaUiState = cinemaRepository.getCinema(cinemaUid)
|
||||||
.toUiState(true)
|
.toUiState(true)
|
||||||
|
},
|
||||||
|
actionError = {
|
||||||
|
cinemaUiState = CinemaUiState()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,12 +42,16 @@ class CinemaEditViewModel(
|
|||||||
|
|
||||||
suspend fun saveCinema() {
|
suspend fun saveCinema() {
|
||||||
if (validateInput()) {
|
if (validateInput()) {
|
||||||
|
runInScope(
|
||||||
|
actionSuccess = {
|
||||||
if (cinemaUid > 0) {
|
if (cinemaUid > 0) {
|
||||||
cinemaRepository.updateCinema(cinemaUiState.cinemaDetails.toCinema(cinemaUid))
|
cinemaRepository.updateCinema(cinemaUiState.cinemaDetails.toCinema(cinemaUid))
|
||||||
} else {
|
} else {
|
||||||
cinemaRepository.insertCinema(cinemaUiState.cinemaDetails.toCinema())
|
cinemaRepository.insertCinema(cinemaUiState.cinemaDetails.toCinema())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateInput(uiState: CinemaDetails = cinemaUiState.cinemaDetails): Boolean {
|
private fun validateInput(uiState: CinemaDetails = cinemaUiState.cinemaDetails): Boolean {
|
||||||
|
@ -4,17 +4,15 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.ViewModel
|
import com.example.myapplication.composeui.MyViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.example.myapplication.database.entities.model.Session
|
import com.example.myapplication.database.entities.model.Session
|
||||||
import com.example.myapplication.database.entities.repository.SessionRepository
|
import com.example.myapplication.database.entities.repository.SessionRepository
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.threeten.bp.LocalDateTime
|
import org.threeten.bp.LocalDateTime
|
||||||
|
|
||||||
class SessionEditViewModel(
|
class SessionEditViewModel(
|
||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
private val sessionRepository: SessionRepository
|
private val sessionRepository: SessionRepository
|
||||||
) : ViewModel() {
|
) : MyViewModel() {
|
||||||
var sessionUiState by mutableStateOf(SessionUiState())
|
var sessionUiState by mutableStateOf(SessionUiState())
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@ -22,11 +20,16 @@ class SessionEditViewModel(
|
|||||||
private val cinemaUid: Int = checkNotNull(savedStateHandle["cinemaId"])
|
private val cinemaUid: Int = checkNotNull(savedStateHandle["cinemaId"])
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
|
||||||
if (sessionUid > 0) {
|
if (sessionUid > 0) {
|
||||||
|
runInScope(
|
||||||
|
actionSuccess = {
|
||||||
sessionUiState = sessionRepository.getSession(sessionUid)
|
sessionUiState = sessionRepository.getSession(sessionUid)
|
||||||
.toUiState(true)
|
.toUiState(true)
|
||||||
|
},
|
||||||
|
actionError = {
|
||||||
|
sessionUiState = SessionUiState()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +42,8 @@ class SessionEditViewModel(
|
|||||||
|
|
||||||
suspend fun saveSession() {
|
suspend fun saveSession() {
|
||||||
if (validateInput()) {
|
if (validateInput()) {
|
||||||
|
runInScope(
|
||||||
|
actionSuccess = {
|
||||||
if (cinemaUid > 0)
|
if (cinemaUid > 0)
|
||||||
if (sessionUid > 0) {
|
if (sessionUid > 0) {
|
||||||
sessionRepository.updateSession(
|
sessionRepository.updateSession(
|
||||||
@ -53,6 +58,8 @@ class SessionEditViewModel(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateInput(uiState: SessionDetails = sessionUiState.sessionDetails): Boolean {
|
private fun validateInput(uiState: SessionDetails = sessionUiState.sessionDetails): Boolean {
|
||||||
|
@ -25,4 +25,6 @@
|
|||||||
<string name="err_03">Логин занят</string>
|
<string name="err_03">Логин занят</string>
|
||||||
<string name="err_04">Неверный логин или пароль</string>
|
<string name="err_04">Неверный логин или пароль</string>
|
||||||
<string name="err_05">Не совпадают пароли</string>
|
<string name="err_05">Не совпадают пароли</string>
|
||||||
|
<string name="back">Назад</string>
|
||||||
|
<string name="loading">Загрузка…</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user