/
CategoryFragmentViewModel.kt
118 lines (106 loc) 路 4.21 KB
/
CategoryFragmentViewModel.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Copyright 2016-2020 Open Food Facts
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package openfoodfacts.github.scrachx.openfood.features.categories.fragment
import android.util.Log
import android.view.View
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableInt
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.rx2.rxSingle
import openfoodfacts.github.scrachx.openfood.models.entities.category.Category
import openfoodfacts.github.scrachx.openfood.models.entities.category.CategoryName
import openfoodfacts.github.scrachx.openfood.repositories.ProductRepository
import openfoodfacts.github.scrachx.openfood.utils.LocaleManager
import java.net.UnknownHostException
import java.util.*
import javax.inject.Inject
@HiltViewModel
class CategoryFragmentViewModel @Inject constructor(
private val productRepository: ProductRepository,
private val localeManager: LocaleManager
) : ViewModel() {
private val allCategories = mutableListOf<CategoryName>()
val shownCategories = ObservableArrayList<CategoryName>()
val showProgress = ObservableInt(View.VISIBLE)
val showOffline = ObservableInt(View.GONE)
private val disposable = CompositeDisposable()
init {
refreshCategories()
}
override fun onCleared() {
super.onCleared()
disposable.dispose()
}
/**
* Generates a network call for showing categories in CategoryFragment
*/
fun refreshCategories() {
productRepository.getAllCategoriesByLanguageCode(localeManager.getLanguage())
.doOnSubscribe {
showOffline.set(View.GONE)
showProgress.set(View.VISIBLE)
}
.flatMap {
if (it.isEmpty()) {
productRepository.getAllCategoriesByDefaultLanguageCode()
} else Single.just(it)
}
.flatMap {
if (it.isEmpty()) {
rxSingle { extractCategoriesNames(productRepository.getCategories()) }
} else Single.just(it)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError {
Log.e(CategoryFragmentViewModel::class.simpleName, "Error loading categories", it)
if (it is UnknownHostException) {
showOffline.set(View.VISIBLE)
showProgress.set(View.GONE)
}
}
.subscribe { categoryList ->
allCategories += categoryList
shownCategories.clear()
shownCategories += categoryList
showProgress.set(View.GONE)
}.addTo(disposable)
}
/**
* Generate a new array which lists all the category names
*
* @param categories list of all the categories loaded using API
*/
private fun extractCategoriesNames(categories: List<Category>) = categories
.flatMap { it.names }
.filter { it.languageCode == localeManager.getLanguage() }
.sortedWith { o1, o2 -> o1.name!!.compareTo(o2.name!!) }
/**
* Search for all the category names that or equal to/start with a given string
*
* @param query string which is used to query for category names
*/
fun searchCategories(query: String) {
shownCategories.clear()
shownCategories += allCategories.filter { it.name?.lowercase(Locale.getDefault())?.startsWith(query) == true }
}
}