Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Экраны стран и регионов #115

Merged
merged 8 commits into from
Aug 19, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package ru.practicum.android.diploma.di

import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
import ru.practicum.android.diploma.presentation.viewmodels.FilterCountryViewModel
import ru.practicum.android.diploma.presentation.viewmodels.FilterPlaceOfWorkViewModel
import ru.practicum.android.diploma.presentation.viewmodels.FilterRegionViewModel
import ru.practicum.android.diploma.presentation.viewmodels.FilterViewModel
import ru.practicum.android.diploma.presentation.viewmodels.SearchViewModel
import ru.practicum.android.diploma.presentation.viewmodels.VacancyViewModel
import ru.practicum.android.diploma.presentation.viewmodels.favourites.FavouritesFragmentViewModel
Expand All @@ -18,4 +22,17 @@ val viewModelModule = module {
viewModel<VacancyViewModel> {
VacancyViewModel(get(), get())
}

viewModel<FilterViewModel> {
FilterViewModel()
}
viewModel<FilterPlaceOfWorkViewModel> {
FilterPlaceOfWorkViewModel(get())
}
viewModel<FilterCountryViewModel> {
FilterCountryViewModel(get())
}
viewModel<FilterRegionViewModel> {
FilterRegionViewModel(get())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ru.practicum.android.diploma.presentation.viewmodels

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import ru.practicum.android.diploma.domain.FilterInteractor
import ru.practicum.android.diploma.ui.state.CountriesScreenState
import ru.practicum.android.diploma.util.ResponseData

class FilterCountryViewModel(
private val filterInteractor: FilterInteractor
) : ViewModel() {
private val countriesStateLiveData = MutableLiveData<CountriesScreenState>()

fun render(): LiveData<CountriesScreenState> {
return countriesStateLiveData
}

fun getCountries() {
viewModelScope.launch(Dispatchers.IO) {
setState(CountriesScreenState.Loading)
filterInteractor
.getCountries()
.collect { response ->
when (response) {
is ResponseData.Data -> {
val listOfCountries = response.value.sortedBy { it.id }
setState(CountriesScreenState.Success(listOfCountries))
}
is ResponseData.Error -> {
setState(CountriesScreenState.Error(response.error))
}
}
}
}
}

private fun setState(state: CountriesScreenState) {
countriesStateLiveData.postValue(state)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package ru.practicum.android.diploma.presentation.viewmodels

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import ru.practicum.android.diploma.domain.FilterInteractor
import ru.practicum.android.diploma.domain.models.Country
import ru.practicum.android.diploma.domain.models.Region
import ru.practicum.android.diploma.ui.state.PlaceOfWorkScreenState
import ru.practicum.android.diploma.util.ResponseData

class FilterPlaceOfWorkViewModel(
private val filterInteractor: FilterInteractor
) : ViewModel() {

private val screenStateLiveData = MutableLiveData<PlaceOfWorkScreenState>()

fun render(): LiveData<PlaceOfWorkScreenState> {
return screenStateLiveData
}

fun getCountryName(region: Region, isSaving: Boolean) {
viewModelScope.launch(Dispatchers.IO) {
filterInteractor
.getCountries()
.collect { response ->
when (response) {
is ResponseData.Data -> {
response.value.forEach {
if (it.id == region.parentId.toString()) {
setData(isSaving, it, region)
}
}
}

is ResponseData.Error -> {}
}
}
}
}

fun saveFields(country: Country, region: Region) {
if (country.name.isEmpty()) {
getCountryName(region, true)
} else {
setState(PlaceOfWorkScreenState.Saved(country, region))
}
}

private fun setData(isSaving: Boolean, country: Country, region: Region) {
if (isSaving) {
setState(PlaceOfWorkScreenState.Saved(country, region))
} else {
setState(PlaceOfWorkScreenState.CountryName(country))
}
}

fun setCountryName(country: Country) {
if (country.name.isNotEmpty()) {
setState(PlaceOfWorkScreenState.CountryName(country))
} else {
setState(PlaceOfWorkScreenState.NoCountryName)
}
}

fun setRegionName(regionName: String) {
if (regionName.isNotEmpty()) {
setState(PlaceOfWorkScreenState.RegionName(regionName))
} else {
setState(PlaceOfWorkScreenState.NoRegionName)
}
}

private fun setState(state: PlaceOfWorkScreenState) {
screenStateLiveData.postValue(state)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package ru.practicum.android.diploma.presentation.viewmodels

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import ru.practicum.android.diploma.domain.FilterInteractor
import ru.practicum.android.diploma.ui.state.RegionsScreenState
import ru.practicum.android.diploma.util.ResponseData

class FilterRegionViewModel(
private val filterInteractor: FilterInteractor
) : ViewModel() {

private val regionsStateLiveData = MutableLiveData<RegionsScreenState>()

fun render(): LiveData<RegionsScreenState> {
return regionsStateLiveData
}

private fun setState(state: RegionsScreenState) {
regionsStateLiveData.postValue(state)
}

fun getRegions(regionId: String) {
setState(RegionsScreenState.Loading)
viewModelScope.launch(Dispatchers.IO) {
if (regionId.isNotEmpty()) {
filterInteractor
.getRegions(regionId)
.collect { response ->
when (response) {
is ResponseData.Data -> {
val listOfRegions = response.value.sortedBy { it.name }
setState(RegionsScreenState.Success(listOfRegions))
}

is ResponseData.Error -> {
setState(RegionsScreenState.Error(response.error))
}
}
}
} else {
filterInteractor
.getAllRegions()
.collect { response ->
when (response) {
is ResponseData.Data -> {
val listOfRegions = response.value.sortedBy { it.name }
setState(RegionsScreenState.Success(listOfRegions))
}

is ResponseData.Error -> {
setState(RegionsScreenState.Error(response.error))
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ru.practicum.android.diploma.presentation.viewmodels

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import ru.practicum.android.diploma.ui.state.FilterScreenState

class FilterViewModel : ViewModel() {

private val screenStateLiveData = MutableLiveData<FilterScreenState>()

fun render(): LiveData<FilterScreenState> {
return screenStateLiveData
}

fun saveFilter() {
viewModelScope.launch(Dispatchers.IO) {
}
}

fun clear() {
setState(FilterScreenState.ClearState)
}

fun setIndustry(industry: String) {
if (industry.isNotEmpty()) {
setState(FilterScreenState.Industry(industry))
} else {
setState(FilterScreenState.NoIndustry)
}

}

private fun setState(state: FilterScreenState) {
screenStateLiveData.postValue(state)
}

fun setPlaceOfWork(country: String) {
if (country.isNotEmpty()) {
setState(FilterScreenState.PlaceOfWork(country))
} else {
setState(FilterScreenState.NoPlaceOfWork)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,36 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import by.kirich1409.viewbindingdelegate.CreateMethod
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.gson.Gson
import org.koin.androidx.viewmodel.ext.android.viewModel
import ru.practicum.android.diploma.databinding.FragmentSelectCountryBinding
import ru.practicum.android.diploma.domain.models.Country
import ru.practicum.android.diploma.presentation.viewmodels.FilterCountryViewModel
import ru.practicum.android.diploma.ui.state.CountriesScreenState
import ru.practicum.android.diploma.util.ResponseData
import ru.practicum.android.diploma.util.adapter.country.CountryAdapter

class FilterCountryFragment : Fragment() {

companion object {
const val COUNTRY_REQUEST_KEY = "COUNTRY_REQUEST_KEY"
const val COUNTRY_BUNDLE_KEY = "COUNTRY_BUNDLE_KEY"
}

private val binding: FragmentSelectCountryBinding by viewBinding(CreateMethod.INFLATE)
private val viewModel by viewModel<FilterCountryViewModel>()

private val adapter = CountryAdapter {
onItemClicked(it)
}

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -28,6 +49,80 @@ class FilterCountryFragment : Fragment() {
binding.selectCountryToolbar.setNavigationOnClickListener {
findNavController().navigateUp()
}
viewModel.render().observe(viewLifecycleOwner) { state ->
when (state) {
CountriesScreenState.Default -> {}
is CountriesScreenState.Error -> {
stopProgressBar()
when (state.error) {
ResponseData.ResponseError.NO_INTERNET -> {
setNoInternetState()
}

ResponseData.ResponseError.CLIENT_ERROR,
ResponseData.ResponseError.SERVER_ERROR -> {
setServerErrorState()
}

ResponseData.ResponseError.NOT_FOUND -> {
setNoListState()
}
}
}

CountriesScreenState.Loading -> {
removePlaceholders()
startProgressBar()
}

is CountriesScreenState.Success -> {
stopProgressBar()
adapter.setCountries(state.regions)
}
}

}
val countriesRecyclerView = binding.countryRecycleView
countriesRecyclerView.layoutManager = LinearLayoutManager(requireContext())
countriesRecyclerView.adapter = adapter
viewModel.getCountries()

}

private fun onItemClicked(country: Country) {
val json = Gson().toJson(country)
setFragmentResult(COUNTRY_REQUEST_KEY, bundleOf(COUNTRY_BUNDLE_KEY to json))
findNavController().navigateUp()
}

private fun startProgressBar() {
binding.progressBar.isVisible = true
}

private fun stopProgressBar() {
binding.progressBar.isVisible = false
}

private fun removePlaceholders() {
binding.placeholderGroup.isVisible = false
binding.noConnectionPlaceholder.isVisible = false
binding.noConnectionText.isVisible = false
binding.serverError.isVisible = false
binding.serverErrorText.isVisible = false
}

private fun setNoInternetState() {
binding.noConnectionPlaceholder.isVisible = true
binding.noConnectionText.isVisible = true
}

private fun setServerErrorState() {
binding.serverError.isVisible = true
binding.serverErrorText.isVisible = true
}

private fun setNoListState() {
binding.placeholderGroup.isVisible = true
}

}
Loading
Loading