@@ -3,10 +3,7 @@ package app.opass.ccip.ui.schedule
3
3
import android.app.Application
4
4
import androidx.lifecycle.*
5
5
import app.opass.ccip.extension.debounce
6
- import app.opass.ccip.model.ConfSchedule
7
- import app.opass.ccip.model.Session
8
- import app.opass.ccip.model.SessionTag
9
- import app.opass.ccip.model.SessionType
6
+ import app.opass.ccip.model.*
10
7
import app.opass.ccip.util.PreferenceUtil
11
8
import com.google.gson.internal.bind.util.ISO8601Utils
12
9
import kotlinx.coroutines.Dispatchers
@@ -35,6 +32,7 @@ fun List<Session>.groupedByDate(): Map<String, List<Session>> =
35
32
private const val KEY_SHOW_STARRED_ONLY = " showStarredOnly"
36
33
private const val KEY_SELECTED_TAG_IDS = " selectedTagIds"
37
34
private const val KEY_SELECTED_TYPE_IDS = " selectedTypeIds"
35
+ private const val KEY_SELECTED_LANG_IDS = " selectedLangIds"
38
36
private const val KEY_SHOW_SEARCH_PANEL = " showSearchPanel"
39
37
40
38
class ScheduleViewModel (application : Application , stateHandle : SavedStateHandle ) : AndroidViewModel(application) {
@@ -46,24 +44,44 @@ class ScheduleViewModel(application: Application, stateHandle: SavedStateHandle)
46
44
}
47
45
val tags: LiveData <List <SessionTag >? > = schedule.map { schedule -> schedule?.tags }
48
46
val types: LiveData <List <SessionType >? > = schedule.map { schedule -> schedule?.sessionTypes }
47
+ val langList: LiveData <List <SessionLang >? > = schedule.map { schedule ->
48
+ val langList = schedule?.sessions?.mapNotNull { it.language }?.distinct()
49
+ if (langList.isNullOrEmpty()) {
50
+ null
51
+ } else {
52
+ langList.map { lang ->
53
+ SessionLang (lang, SessionLang .Zh (lang), SessionLang .En (lang))
54
+ }
55
+ }
56
+ }
49
57
50
58
val showStarredOnly = stateHandle.getLiveData(KEY_SHOW_STARRED_ONLY , false )
51
59
val selectedTagIds = stateHandle.getLiveData(KEY_SELECTED_TAG_IDS , emptyList<String >())
52
60
val selectedTypeIds = stateHandle.getLiveData(KEY_SELECTED_TYPE_IDS , emptyList<String >())
61
+ val selectedLangIds = stateHandle.getLiveData(KEY_SELECTED_LANG_IDS , emptyList<String >())
53
62
val shouldShowSearchPanel = stateHandle.getLiveData(KEY_SHOW_SEARCH_PANEL , false )
54
63
55
64
private val searchTerm: MutableLiveData <String > = MutableLiveData (" " )
56
65
private val filterConfig: LiveData <FilterConfig > = MediatorLiveData <FilterConfig >().apply {
57
66
val update = {
58
- value = FilterConfig (sessionsGroupedByDate.value, showStarredOnly.value!! , selectedTagIds.value!! , selectedTypeIds.value!! , searchTerm.value!! )
67
+ value = FilterConfig (
68
+ sessionsGroupedByDate.value,
69
+ showStarredOnly.value!! ,
70
+ selectedTagIds.value!! ,
71
+ selectedTypeIds.value!! ,
72
+ selectedLangIds.value!! ,
73
+ searchTerm.value!!
74
+ )
59
75
}
60
76
addSource(sessionsGroupedByDate) { update() }
61
77
addSource(showStarredOnly) { update() }
62
78
addSource(selectedTagIds) { update() }
63
79
addSource(selectedTypeIds) { update() }
80
+ addSource(selectedLangIds) { update() }
64
81
addSource(searchTerm) { update() }
65
82
}.debounce(100 )
66
- val groupedSessionsToShow: LiveData <Map <String , List <Session >>? > = filterConfig.switchMap { (sessions, starredOnly, selectedTagIds, selectedTypeIds, searchText) ->
83
+ val groupedSessionsToShow: LiveData <Map <String , List <Session >>? > = filterConfig.switchMap {
84
+ (sessions, starredOnly, selectedTagIds, selectedTypeIds, selectedLangIds, searchText) ->
67
85
liveData(viewModelScope.coroutineContext + Dispatchers .Default ) {
68
86
if (sessions == null ) {
69
87
emit(null )
@@ -87,6 +105,14 @@ class ScheduleViewModel(application: Application, stateHandle: SavedStateHandle)
87
105
}
88
106
}
89
107
108
+ if (selectedLangIds.isNotEmpty()) {
109
+ result = result.mapValues { (_, sessions) ->
110
+ sessions.filter { session ->
111
+ selectedLangIds.any { id -> session.language == id }
112
+ }
113
+ }
114
+ }
115
+
90
116
if (hasSearchTerm()) {
91
117
val searchResult = result.mapValues { (_, sessions) ->
92
118
sessions.filter { session ->
@@ -108,11 +134,13 @@ class ScheduleViewModel(application: Application, stateHandle: SavedStateHandle)
108
134
val starredOnly = showStarredOnly.value ? : false
109
135
val hasSelectedTags = selectedTagIds.value?.isNotEmpty() ? : false
110
136
val hasSelectedTypes = selectedTypeIds.value?.isNotEmpty() ? : false
111
- value = starredOnly || hasSelectedTags || hasSelectedTypes
137
+ val hasSelectedLangList = selectedLangIds.value?.isNotEmpty() ? : false
138
+ value = starredOnly || hasSelectedTags || hasSelectedTypes || hasSelectedLangList
112
139
}
113
140
addSource(showStarredOnly) { update() }
114
141
addSource(selectedTagIds) { update() }
115
142
addSource(selectedTypeIds) { update() }
143
+ addSource(selectedLangIds) { update() }
116
144
}
117
145
val shouldFilterSheetCollapse = MediatorLiveData <Boolean >().apply {
118
146
val update = {
@@ -129,12 +157,14 @@ class ScheduleViewModel(application: Application, stateHandle: SavedStateHandle)
129
157
val starredOnly = showStarredOnly.value ? : false
130
158
val hasSelectedTags = selectedTagIds.value?.isNotEmpty() ? : false
131
159
val hasSelectedTypes = selectedTypeIds.value?.isNotEmpty() ? : false
132
- value = scheduleReady && ! starredOnly && ! hasSelectedTags && ! hasSelectedTypes
160
+ val hasSelectedLangList = selectedLangIds.value?.isNotEmpty() ? : false
161
+ value = scheduleReady && ! starredOnly && ! hasSelectedTags && ! hasSelectedTypes && ! hasSelectedLangList
133
162
}
134
163
addSource(isScheduleReady) { update() }
135
164
addSource(showStarredOnly) { update() }
136
165
addSource(selectedTagIds) { update() }
137
166
addSource(selectedTypeIds) { update() }
167
+ addSource(selectedLangIds) { update() }
138
168
}
139
169
140
170
init {
@@ -160,13 +190,18 @@ class ScheduleViewModel(application: Application, stateHandle: SavedStateHandle)
160
190
types.value?.map(SessionType ::id)?.let { validTypeIds ->
161
191
selectedTypeIds.value = selectedTypeIds.value!! .filter { id -> validTypeIds.contains(id) }
162
192
}
193
+
194
+ langList.value?.map(SessionLang ::id)?.let { validLangIds ->
195
+ selectedLangIds.value = selectedLangIds.value!! .filter { id -> validLangIds.contains(id) }
196
+ }
163
197
}
164
198
}
165
199
166
200
fun clearFilter () {
167
201
showStarredOnly.value = false
168
202
selectedTagIds.value = emptyList()
169
203
selectedTypeIds.value = emptyList()
204
+ selectedLangIds.value = emptyList()
170
205
}
171
206
172
207
fun toggleFilterTag (idToToggle : String ) {
@@ -185,6 +220,14 @@ class ScheduleViewModel(application: Application, stateHandle: SavedStateHandle)
185
220
}
186
221
}
187
222
223
+ fun toggleLangType (idToToggle : String ) {
224
+ if (selectedLangIds.value!! .contains(idToToggle)) {
225
+ selectedLangIds.value = selectedLangIds.value!! .filterNot { id -> id == idToToggle }
226
+ } else {
227
+ selectedLangIds.value = selectedLangIds.value!! + idToToggle
228
+ }
229
+ }
230
+
188
231
fun toggleStarFilter () {
189
232
showStarredOnly.value = showStarredOnly.value!! .not ()
190
233
}
@@ -210,5 +253,6 @@ private data class FilterConfig(
210
253
val showStarredOnly : Boolean ,
211
254
val selectedTagIds : List <String >,
212
255
val selectedTypeIds : List <String >,
256
+ val selectedLangList : List <String >,
213
257
val searchTerm : String
214
258
)
0 commit comments