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

Career hub filter industry #120

Merged
merged 15 commits into from
Aug 20, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,36 @@ package ru.practicum.android.diploma.data.impl
import android.content.SharedPreferences
import com.google.gson.Gson
import ru.practicum.android.diploma.domain.SharedPrefsRepository
import ru.practicum.android.diploma.domain.models.Country
import ru.practicum.android.diploma.domain.models.Industries
import ru.practicum.android.diploma.domain.models.Region
import ru.practicum.android.diploma.domain.models.SaveFiltersSharedPrefs

class SharedPrefsRepositoryImpl(
private val sharedPreferences: SharedPreferences,
private val gson: Gson
) : SharedPrefsRepository {
override suspend fun readSharedPrefs(): SaveFiltersSharedPrefs? {
val json = sharedPreferences.getString(HISTORY, null) ?: return null
override suspend fun readSharedPrefs(): SaveFiltersSharedPrefs {
val json = sharedPreferences.getString(HISTORY, null) ?: return SaveFiltersSharedPrefs(
Industries("", "", false),
Country("", ""),
Region("", "", null),
"",
false
)
return gson.fromJson(json, SaveFiltersSharedPrefs::class.java)
}

override suspend fun writeSharedPrefs(filters: SaveFiltersSharedPrefs) {
sharedPreferences.edit().putString(HISTORY, gson.toJson(filters)).apply()
val oldShared = readSharedPrefs()
val newShared = oldShared.copy(
industries = filters.industries ?: oldShared.industries,
country = filters.country ?: oldShared.country,
region = filters.region ?: oldShared.region,
currency = filters.currency ?: oldShared.currency,
noCurrency = filters.noCurrency
)
sharedPreferences.edit().putString(HISTORY, gson.toJson(newShared)).apply()
}

override suspend fun clearSharedPrefs() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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.FilterIndustryViewModel
import ru.practicum.android.diploma.presentation.viewmodels.FilterPlaceOfWorkViewModel
import ru.practicum.android.diploma.presentation.viewmodels.FilterRegionViewModel
import ru.practicum.android.diploma.presentation.viewmodels.FilterViewModel
Expand Down Expand Up @@ -35,4 +36,7 @@ val viewModelModule = module {
viewModel<FilterRegionViewModel> {
FilterRegionViewModel(get())
}
viewModel<FilterIndustryViewModel> {
FilterIndustryViewModel(get())
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package ru.practicum.android.diploma.domain.models

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class Industries(
val id: String,
val name: String,
val isChecked: Boolean
)
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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.launch
import ru.practicum.android.diploma.domain.FilterInteractor
import ru.practicum.android.diploma.domain.models.Industries
import ru.practicum.android.diploma.domain.models.SaveFiltersSharedPrefs
import ru.practicum.android.diploma.util.ResponseData

class FilterIndustryViewModel(
private val interactor: FilterInteractor
) : ViewModel() {
private val _industries = MutableLiveData<List<Industries>>()
val industries: LiveData<List<Industries>>
get() = _industries

private val _hasSelected = MutableLiveData(false)
val hasSelected: LiveData<Boolean>
get() = _hasSelected

private val _selectedIndustry = MutableLiveData<Industries>()
val selectedIndustry: LiveData<Industries>
get() = _selectedIndustry

fun writeSharedPrefs() {
viewModelScope.launch {
interactor.writeSharedPrefs(
SaveFiltersSharedPrefs(
industries = _selectedIndustry.value,
null,
null,
null,
false
)
)
}
}

fun itemChecked(industries: Industries) {
val newList = ArrayList<Industries>()
_industries.value?.forEach { industry ->
if (industry.id == industries.id) {
newList.add(industry.copy(isChecked = !industry.isChecked))
_hasSelected.postValue(!industry.isChecked)
if (!industry.isChecked) _selectedIndustry.postValue(industry)
} else {
newList.add(industry.copy(isChecked = false))
}
}
_industries.postValue(newList)
}

fun updateListIndustries() {
viewModelScope.launch {
val industry = interactor.readSharedPrefs()?.industries
interactor.getIndustries().collect { list ->
when (list) {
is ResponseData.Data -> {
whenList(industry, list)
}

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

fun whenList(industry: Industries?, list: ResponseData.Data<List<Industries>>) {
if (industry != null) {
val newList = ArrayList<Industries>()
list.value.forEach { industryItem ->
if (industryItem.id == industry.id) {
newList.add(industryItem.copy(isChecked = true))
_selectedIndustry.postValue(industryItem)
_hasSelected.postValue(true)
} else {
newList.add(industryItem)
}
}
_industries.postValue(newList)
} else {
_industries.postValue(list.value)
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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.domain.models.SaveFiltersSharedPrefs
import ru.practicum.android.diploma.ui.state.PlaceOfWorkScreenState
import ru.practicum.android.diploma.util.ResponseData

Expand All @@ -17,6 +18,9 @@ class FilterPlaceOfWorkViewModel(
) : ViewModel() {

private val screenStateLiveData = MutableLiveData<PlaceOfWorkScreenState>()
private val _filtersSave = MutableLiveData<SaveFiltersSharedPrefs>()
val sharedPrefs: LiveData<SaveFiltersSharedPrefs>
get() = _filtersSave

fun render(): LiveData<PlaceOfWorkScreenState> {
return screenStateLiveData
Expand All @@ -42,6 +46,20 @@ class FilterPlaceOfWorkViewModel(
}
}

fun saveSharedPrefs(country: Country?, region: Region?) {
viewModelScope.launch {
filterInteractor.writeSharedPrefs(
SaveFiltersSharedPrefs(
industries = null,
country = country,
region = region,
currency = null,
noCurrency = false
)
)
}
}

fun saveFields(country: Country, region: Region) {
if (country.name.isEmpty()) {
getCountryName(region, true)
Expand Down Expand Up @@ -86,4 +104,10 @@ class FilterPlaceOfWorkViewModel(
private fun setState(state: PlaceOfWorkScreenState) {
screenStateLiveData.postValue(state)
}

fun readSharedPrefs() {
viewModelScope.launch {
_filtersSave.postValue(filterInteractor.readSharedPrefs())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import ru.practicum.android.diploma.domain.FilterInteractor
import ru.practicum.android.diploma.domain.models.SaveFiltersSharedPrefs
import ru.practicum.android.diploma.domain.models.Industries
import ru.practicum.android.diploma.ui.state.FilterScreenState

class FilterViewModel(
Expand All @@ -16,6 +17,9 @@ class FilterViewModel(

private val screenStateLiveData = MutableLiveData<FilterScreenState>()

private val _noCurrency = MutableLiveData<Boolean?>()
private val _industry = MutableLiveData<Industries?>()

fun render(): LiveData<FilterScreenState> {
return screenStateLiveData
}
Expand Down Expand Up @@ -67,7 +71,13 @@ class FilterViewModel(
} else {
setState(FilterScreenState.NoPlaceOfWork)
}
}

fun setNoCurrencySelected(answer: Boolean) {
_noCurrency.postValue(answer)
}

fun setIndustrySelected(industries: Industries?) {
_industry.postValue(industries)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import ru.practicum.android.diploma.domain.models.Industries
import ru.practicum.android.diploma.domain.models.Region
import ru.practicum.android.diploma.domain.models.SaveFiltersSharedPrefs
import ru.practicum.android.diploma.presentation.viewmodels.FilterViewModel
import ru.practicum.android.diploma.ui.fragments.FilterIndustryFragment.Companion.INDUSTRY_ITEM_KEY
import ru.practicum.android.diploma.ui.fragments.FilterIndustryFragment.Companion.INDUSTRY_KEY
import ru.practicum.android.diploma.ui.fragments.FilterPlaceOfWorkFragment.Companion.PLACE_OF_WORK_COUNTRY_KEY
import ru.practicum.android.diploma.ui.fragments.FilterPlaceOfWorkFragment.Companion.PLACE_OF_WORK_KEY
import ru.practicum.android.diploma.ui.fragments.FilterPlaceOfWorkFragment.Companion.PLACE_OF_WORK_REGION_KEY
Expand All @@ -43,7 +45,7 @@ class FilterFragment : Fragment() {

private val binding: FragmentFilterBinding by viewBinding(CreateMethod.INFLATE)
private val viewModel by viewModel<FilterViewModel>()

private var init = true
private var region = Region("", "", null)
private var country = Country("", "")
private var industries = Industries("", "", false)
Expand All @@ -65,6 +67,7 @@ class FilterFragment : Fragment() {
binding.salary.doOnTextChanged { text, _, _, _ ->
if (!text.isNullOrEmpty()) {
binding.btnGroup.isVisible = true
viewModel.saveFilter(makeFilterSettings())
} else {
checkFields()
}
Expand All @@ -89,13 +92,15 @@ class FilterFragment : Fragment() {
}

is FilterScreenState.Industry -> {
binding.industryTextInput.setText(state.industry)
setIndustryEndIcon()
}

FilterScreenState.NoIndustry -> {
binding.industryTextInput.text?.clear()
setNoIndustryEndIcon()
checkFields()
industries = Industries("", "", false)
}

FilterScreenState.NoPlaceOfWork -> {
Expand Down Expand Up @@ -160,6 +165,14 @@ class FilterFragment : Fragment() {
val countryName = setPlaceOfWorkName(country.name, region.name)
viewModel.setPlaceOfWork(countryName)
}
setFragmentResultListener(INDUSTRY_KEY) { _, bundle ->
val industryJson = bundle.getString(INDUSTRY_ITEM_KEY).toString()
val type = object : TypeToken<Industries>() {}.type
val industry = Gson().fromJson<Industries>(industryJson, type)
industries = industry
viewModel.setIndustry(industry.name)
viewModel.setIndustrySelected(industry)
}
}

private fun setPlaceOfWorkName(countryName: String, regionName: String): String {
Expand All @@ -179,6 +192,8 @@ class FilterFragment : Fragment() {
binding.clearButton.setOnClickListener { viewModel.clear() }
// Пример использования Checkbox, если включена опция показа только с зарплатой
binding.salaryFlagCheckbox.setOnCheckedChangeListener { _, isChecked -> //
viewModel.saveFilter(makeFilterSettings())
viewModel.setNoCurrencySelected(isChecked)
// viewModel.setSalaryOnlyCheckbox(isChecked)
}
binding.workTextInput.setOnClickListener {
Expand Down
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.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.navigation.fragment.findNavController
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.FragmentSelectIndustryBinding
import ru.practicum.android.diploma.presentation.viewmodels.FilterIndustryViewModel
import ru.practicum.android.diploma.util.adapter.industry.IndustryAdapter

class FilterIndustryFragment : Fragment() {

companion object {
const val INDUSTRY_KEY = "industryKey"
const val INDUSTRY_ITEM_KEY = "INDUSTRY_ITEM_KEY"
}

private val binding: FragmentSelectIndustryBinding by viewBinding(CreateMethod.INFLATE)
private val viewModel: FilterIndustryViewModel by viewModel()
private val adapter by lazy {
IndustryAdapter(
onClick = { industryList ->
viewModel.itemChecked(industryList)
}
)
}

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -24,10 +45,40 @@ class FilterIndustryFragment : Fragment() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.updateListIndustries()
binding.industryRecycleView.adapter = adapter

viewModel.industries.observe(viewLifecycleOwner) { list ->
adapter.industry = list
}

viewModel.hasSelected.observe(viewLifecycleOwner) {
binding.applyButton.isVisible = it
}

binding.industrySearchQuery.doOnTextChanged { text, start, before, count ->
if (binding.industrySearchQuery.text.isNotEmpty()) {
binding.searchIconLoupe.isVisible = false
binding.clearCrossIc.isVisible = true
} else {
binding.searchIconLoupe.isVisible = true
binding.clearCrossIc.isVisible = false
}
}

binding.clearCrossIc.setOnClickListener {
binding.industrySearchQuery.setText("")
}

binding.industryFilterToolbar.setNavigationOnClickListener {
findNavController().navigateUp()
}
}

binding.applyButton.setOnClickListener {
val json = Gson().toJson(viewModel.selectedIndustry.value)
setFragmentResult(INDUSTRY_KEY, bundleOf(INDUSTRY_ITEM_KEY to json))
viewModel.writeSharedPrefs()
findNavController().popBackStack()
}
}
}
Loading
Loading