поиск и эдиты

This commit is contained in:
dasha 2023-12-17 18:16:41 +04:00
parent 55a0ac8581
commit 42c21b0ce7
9 changed files with 228 additions and 43 deletions

View 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>

View File

@ -0,0 +1,3 @@
package com.example.myapplication.api
enum class ApiStatus { LOADING, ERROR, DONE }

View File

@ -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
} }
} }

View File

@ -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 = {})
}
}

View File

@ -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()
}
}
}

View File

@ -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(),
) )

View File

@ -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 {

View File

@ -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 {

View File

@ -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>