Сделал на 2 листа пагинацию, хохо
This commit is contained in:
parent
c7f73c4d5a
commit
68d533c81b
@ -0,0 +1,5 @@
|
||||
package com.example.myapplication.api
|
||||
|
||||
enum class ApiStatus {
|
||||
LOADING, ERROR, DONE
|
||||
}
|
@ -29,6 +29,7 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@ -55,11 +56,15 @@ fun BikeList(
|
||||
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
||||
) {
|
||||
var getUser by remember { mutableStateOf(currentUserViewModel.user) }
|
||||
val bikePagingItems = viewModel.bikePagingFlowState.flow.collectAsLazyPagingItems()
|
||||
|
||||
LaunchedEffect(getUser?.uid) {
|
||||
viewModel.refresh()
|
||||
}
|
||||
|
||||
// Проверяем, есть ли у пользователя uid
|
||||
if (getUser?.uid != null) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val bikePagingItems = viewModel.bikeListUiState.collectAsLazyPagingItems()
|
||||
|
||||
Scaffold(
|
||||
topBar = {},
|
||||
|
@ -1,17 +1,37 @@
|
||||
package com.example.myapplication.database.entities.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 androidx.paging.PagingData
|
||||
import androidx.paging.cachedIn
|
||||
import com.example.myapplication.database.entities.model.Bike
|
||||
import com.example.myapplication.database.entities.repository.BikeRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
|
||||
class BikeListViewModel(
|
||||
private val bikeRepository: BikeRepository
|
||||
) : ViewModel() {
|
||||
val bikeListUiState: Flow<PagingData<Bike>> = bikeRepository.getAllBikes()
|
||||
) : LoadingViewModel() {
|
||||
var bikePagingFlowState by mutableStateOf(BikePagingFlowState())
|
||||
private set
|
||||
|
||||
fun refresh() {
|
||||
runInScope(actionSuccess = {
|
||||
val pagingSource = bikeRepository.getAllBikes()
|
||||
bikePagingFlowState = BikePagingFlowState(pagingSource.cachedIn(viewModelScope))
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun deleteBike(bike: Bike) {
|
||||
runInScope(actionSuccess = {
|
||||
bikeRepository.deleteBike(bike)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
data class BikePagingFlowState(
|
||||
val flow: Flow<PagingData<Bike>> = emptyFlow(),
|
||||
)
|
@ -34,6 +34,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.example.myapplication.api.ApiStatus
|
||||
import com.example.myapplication.composeui.navigation.Screen
|
||||
import com.example.myapplication.database.entities.model.Bike
|
||||
|
||||
@ -50,7 +51,8 @@ fun BikeView(
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.refreshState()
|
||||
}
|
||||
|
||||
when (viewModel.apiStatus) {
|
||||
ApiStatus.DONE -> {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
@ -148,3 +150,12 @@ fun BikeView(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApiStatus.LOADING -> LoadingPage()
|
||||
else -> ErrorPage(
|
||||
message = viewModel.apiError,
|
||||
onBack = { navController.popBackStack() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import com.example.myapplication.database.entities.repository.BikeRepository
|
||||
|
||||
class BikeViewModel(
|
||||
savedStateHandle: SavedStateHandle, private val bikeRepository: BikeRepository
|
||||
) : ViewModel() {
|
||||
) : LoadingViewModel() {
|
||||
private val bikeUid: Int = checkNotNull(savedStateHandle["id"])
|
||||
|
||||
var bikeUiState by mutableStateOf(BikeUiState())
|
||||
@ -18,7 +18,11 @@ class BikeViewModel(
|
||||
|
||||
suspend fun refreshState() {
|
||||
if (bikeUid > 0) {
|
||||
runInScope(actionSuccess = {
|
||||
bikeUiState = BikeUiState(bikeRepository.getBike(bikeUid))
|
||||
}, actionError = {
|
||||
bikeUiState = BikeUiState()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ class CartViewModel(
|
||||
private val rentRepository: RentRepository,
|
||||
private val rentItemRepository: RentItemRepository,
|
||||
private val userRepository: UserRepository,
|
||||
) : ViewModel() {
|
||||
) : LoadingViewModel() {
|
||||
//private val userUid: Int = 1
|
||||
var cartUiState by mutableStateOf(CartUiState())
|
||||
private set
|
||||
|
@ -9,7 +9,7 @@ import com.example.myapplication.database.entities.model.User
|
||||
import com.example.myapplication.database.entities.repository.UserRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class CurrentUserViewModel(private val userRepository: UserRepository) : ViewModel(){
|
||||
class CurrentUserViewModel(private val userRepository: UserRepository) : LoadingViewModel(){
|
||||
val argument = mutableStateOf<String?>(null)
|
||||
private val userid = mutableStateOf<Int?>(null)
|
||||
var user by mutableStateOf<User?>(null)
|
||||
|
@ -9,7 +9,7 @@ import com.example.myapplication.database.entities.model.User
|
||||
import com.example.myapplication.database.entities.repository.UserRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class EntryUserViewModel(private val userRepository: UserRepository) : ViewModel() {
|
||||
class EntryUserViewModel(private val userRepository: UserRepository) : LoadingViewModel() {
|
||||
|
||||
var userList by mutableStateOf<List<User>>(emptyList())
|
||||
fun setUserList() {
|
||||
|
@ -10,7 +10,7 @@ import com.example.myapplication.database.entities.repository.UserItemRepository
|
||||
class ItemListViewModel(
|
||||
private val itemRepository: ItemRepository,
|
||||
private val userItemRepository: UserItemRepository
|
||||
) : ViewModel() {
|
||||
) : LoadingViewModel() {
|
||||
suspend fun deleteItem(item: ItemFromBike) {
|
||||
itemRepository.deleteItem(
|
||||
Item(
|
||||
|
@ -0,0 +1,64 @@
|
||||
package com.example.myapplication.database.entities.composeui
|
||||
|
||||
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.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.unit.TextUnit
|
||||
import androidx.compose.ui.unit.TextUnitType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.myapplication.R
|
||||
|
||||
@Composable
|
||||
fun LoadingPage() {
|
||||
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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ErrorPage(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))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.example.myapplication.database.entities.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 LoadingViewModel : ViewModel() {
|
||||
var apiStatus by mutableStateOf(ApiStatus.DONE)
|
||||
private set
|
||||
|
||||
var apiError by mutableStateOf("")
|
||||
private set
|
||||
|
||||
fun runInScope(
|
||||
actionSuccess: suspend () -> Unit,
|
||||
actionError: suspend () -> Unit,
|
||||
needLoadingScreen: Boolean = true,
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
if (needLoadingScreen)
|
||||
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 = {})
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ import com.example.myapplication.database.entities.model.User
|
||||
import com.example.myapplication.database.entities.repository.UserRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RegisterUserViewModel(private val userRepository: UserRepository) : ViewModel() {
|
||||
class RegisterUserViewModel(private val userRepository: UserRepository) : LoadingViewModel() {
|
||||
|
||||
private val _users = MutableLiveData<List<User>>()
|
||||
val users: LiveData<List<User>> get() = _users
|
||||
|
@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.flatMapLatest
|
||||
|
||||
class RentListViewModel(
|
||||
private val rentRepository: RentRepository
|
||||
) : ViewModel() {
|
||||
) : LoadingViewModel() {
|
||||
private val _userId = MutableStateFlow<Int?>(null)
|
||||
val userId: StateFlow<Int?> get() = _userId
|
||||
|
||||
|
@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
class RentViewModel(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val rentRepository: RentRepository
|
||||
) : ViewModel() {
|
||||
) : LoadingViewModel() {
|
||||
private val rentUid: Int = checkNotNull(savedStateHandle["id"])
|
||||
|
||||
val rentUiState: StateFlow<RentUiState> = flow{emit(rentRepository.getRent(rentUid))} .map {
|
||||
|
@ -15,7 +15,7 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class ReportViewModel(private val itemRespository: RestItemRepository): ViewModel() {
|
||||
class ReportViewModel(private val itemRespository: RestItemRepository): LoadingViewModel() {
|
||||
var reportPageUiState by mutableStateOf(ReportPageUiState())
|
||||
private set
|
||||
|
||||
|
@ -19,7 +19,10 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.example.myapplication.R
|
||||
import com.example.myapplication.api.ApiStatus
|
||||
import com.example.myapplication.database.entities.composeui.AppViewModelProvider
|
||||
import com.example.myapplication.database.entities.composeui.ErrorPage
|
||||
import com.example.myapplication.database.entities.composeui.LoadingPage
|
||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@ -29,7 +32,8 @@ fun BikeEdit(
|
||||
viewModel: BikeEditViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
when (viewModel.apiStatus) {
|
||||
ApiStatus.DONE -> {
|
||||
BikeEdit(
|
||||
bikeUiState = viewModel.bikeUiState,
|
||||
onClick = {
|
||||
@ -41,6 +45,13 @@ fun BikeEdit(
|
||||
onUpdate = viewModel::updateUiState,
|
||||
)
|
||||
}
|
||||
ApiStatus.LOADING -> LoadingPage()
|
||||
else -> ErrorPage(
|
||||
message = viewModel.apiError,
|
||||
onBack = { navController.popBackStack() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BikeEdit(
|
||||
|
@ -6,6 +6,7 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.myapplication.database.entities.composeui.LoadingViewModel
|
||||
import com.example.myapplication.database.entities.model.Bike
|
||||
import com.example.myapplication.database.entities.model.BikeWithItems
|
||||
import com.example.myapplication.database.entities.model.ItemFromBike
|
||||
@ -15,7 +16,7 @@ import kotlinx.coroutines.launch
|
||||
class BikeEditViewModel(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val bikeRepository: BikeRepository
|
||||
) : ViewModel() {
|
||||
) : LoadingViewModel() {
|
||||
var bikeUiState by mutableStateOf(BikeUiState())
|
||||
private set
|
||||
|
||||
@ -23,10 +24,15 @@ class BikeEditViewModel(
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
if (bikeUid > 0) {
|
||||
runInScope(
|
||||
actionSuccess = {
|
||||
bikeUiState = bikeRepository.getBike(bikeUid)
|
||||
.toUiState(true)
|
||||
},
|
||||
actionError = {
|
||||
bikeUiState = BikeUiState()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,12 +45,16 @@ class BikeEditViewModel(
|
||||
|
||||
suspend fun saveBike() {
|
||||
if (validateInput()) {
|
||||
runInScope(
|
||||
actionSuccess = {
|
||||
if (bikeUid > 0) {
|
||||
bikeRepository.updateBike(bikeUiState.bikeDetails.toBike(bikeUid))
|
||||
} else {
|
||||
bikeRepository.insertBike(bikeUiState.bikeDetails.toBike())
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateInput(uiState: BikeDetails = bikeUiState.bikeDetails): Boolean {
|
||||
|
@ -6,6 +6,7 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.myapplication.database.entities.composeui.LoadingViewModel
|
||||
import com.example.myapplication.database.entities.model.Item
|
||||
import com.example.myapplication.database.entities.repository.ItemRepository
|
||||
import kotlinx.coroutines.launch
|
||||
@ -14,7 +15,7 @@ import org.threeten.bp.LocalDateTime
|
||||
class ItemEditViewModel(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val itemRepository: ItemRepository
|
||||
) : ViewModel() {
|
||||
) : LoadingViewModel() {
|
||||
var itemUiState by mutableStateOf(ItemUiState())
|
||||
private set
|
||||
|
||||
|
@ -21,4 +21,6 @@
|
||||
<string name="item_bike_not_select">Велосипед не указан</string>
|
||||
<string name="size">Размер загруженного изображения: %1$dx%2$d</string>
|
||||
<string name="not_uploaded">Загрузите изображение</string>
|
||||
<string name="loading">Загрузка…</string>
|
||||
<string name="back">Назад</string>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user