@@ -14,11 +14,17 @@ import kotlinx.coroutines.flow.asStateFlow
1414import kotlinx.coroutines.launch
1515import kotlinx.coroutines.withContext
1616import org.wordpress.android.R
17+ import org.wordpress.android.fluxc.Dispatcher
18+ import org.wordpress.android.fluxc.generated.TaxonomyActionBuilder
1719import org.wordpress.android.fluxc.model.SiteModel
20+ import org.wordpress.android.fluxc.model.TermModel
21+ import org.wordpress.android.fluxc.model.TermsModel
1822import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider
1923import org.wordpress.android.fluxc.store.AccountStore
24+ import org.wordpress.android.fluxc.store.TaxonomyStore
2025import org.wordpress.android.fluxc.store.TaxonomyStore.DEFAULT_TAXONOMY_CATEGORY
2126import org.wordpress.android.fluxc.store.TaxonomyStore.DEFAULT_TAXONOMY_TAG
27+ import org.wordpress.android.fluxc.store.TaxonomyStore.FetchTermsResponsePayload
2228import org.wordpress.android.fluxc.utils.AppLogWrapper
2329import org.wordpress.android.modules.IO_THREAD
2430import org.wordpress.android.modules.UI_THREAD
@@ -31,10 +37,10 @@ import org.wordpress.android.ui.mysite.SelectedSiteRepository
3137import org.wordpress.android.util.AppLog
3238import org.wordpress.android.util.NetworkUtilsWrapper
3339import rs.wordpress.api.kotlin.WpRequestResult
34- import uniffi.wp_api.TermEndpointType
35- import uniffi.wp_api.TermListParams
3640import uniffi.wp_api.AnyTermWithEditContext
3741import uniffi.wp_api.TermCreateParams
42+ import uniffi.wp_api.TermEndpointType
43+ import uniffi.wp_api.TermListParams
3844import uniffi.wp_api.TermUpdateParams
3945import uniffi.wp_api.WpApiParamOrder
4046import uniffi.wp_api.WpApiParamTermsOrderBy
@@ -74,6 +80,8 @@ class TermsViewModel @Inject constructor(
7480 private val wpApiClientProvider : WpApiClientProvider ,
7581 private val appLogWrapper : AppLogWrapper ,
7682 private val selectedSiteRepository : SelectedSiteRepository ,
83+ private val taxonomyStore : TaxonomyStore ,
84+ private val fluxCDispatcher : Dispatcher , // Used to include FluxC in the flow (local terms store)
7785 accountStore : AccountStore ,
7886 @Named(UI_THREAD ) mainDispatcher : CoroutineDispatcher ,
7987 sharedPrefs : SharedPreferences ,
@@ -112,6 +120,7 @@ class TermsViewModel @Inject constructor(
112120 fun initialize (taxonomySlug : String , isHierarchical : Boolean ) {
113121 this .taxonomySlug = taxonomySlug
114122 this .isHierarchical = isHierarchical
123+ taxonomyStore.onRegister()
115124 initialize()
116125 }
117126
@@ -197,6 +206,20 @@ class TermsViewModel @Inject constructor(
197206 _termDetailState .value = null
198207 }
199208
209+ override fun getLocalData (): List <DataViewItem > = when (val site = selectedSiteRepository.getSelectedSite()) {
210+ null -> emptyList()
211+ else -> {
212+ val terms = taxonomyStore.getTermsForSite(site, this .taxonomySlug)
213+ terms.map { term ->
214+ convertToDataViewItem(
215+ terms,
216+ term,
217+ isHierarchical
218+ )
219+ }
220+ }
221+ }
222+
200223 override fun getSupportedSorts (): List <DataViewDropdownItem > = if (isHierarchical) {
201224 listOf ()
202225 } else {
@@ -232,6 +255,11 @@ class TermsViewModel @Inject constructor(
232255 allTerms
233256 }
234257
258+ // Store terms when they are not filtered
259+ if (sortedTerms.isNotEmpty() && filter == null ) {
260+ storeTerms(selectedSite, sortedTerms)
261+ }
262+
235263 // Convert to DataViewItems and return
236264 sortedTerms.map { term ->
237265 // Do not use hierarchical indentation when the user is searching terms
@@ -267,6 +295,30 @@ class TermsViewModel @Inject constructor(
267295 return result
268296 }
269297
298+ private suspend fun storeTerms (site : SiteModel , terms : List <AnyTermWithEditContext >) = withContext(ioDispatcher) {
299+ val termsResponsePayload = FetchTermsResponsePayload (
300+ TermsModel (
301+ terms.map { term ->
302+ TermModel (
303+ term.id.toInt(),
304+ site.id,
305+ term.id,
306+ taxonomySlug,
307+ term.name,
308+ term.slug,
309+ term.description,
310+ term.parent ? : 0 ,
311+ term.parent != null ,
312+ term.count.toInt()
313+ )
314+ },
315+ ),
316+ site,
317+ taxonomySlug
318+ )
319+ fluxCDispatcher.dispatch(TaxonomyActionBuilder .newFetchedTermsAction(termsResponsePayload))
320+ }
321+
270322 fun saveTerm () {
271323 viewModelScope.launch {
272324 val selectedSite = selectedSiteRepository.getSelectedSite()
@@ -395,6 +447,32 @@ class TermsViewModel @Inject constructor(
395447 )
396448 }
397449
450+ private fun convertToDataViewItem (
451+ allTerms : List <TermModel >,
452+ term : TermModel ,
453+ useHierarchicalIndentation : Boolean
454+ ): DataViewItem {
455+ val indentation = if (useHierarchicalIndentation) {
456+ getHierarchicalIndentation(allTerms, term)
457+ } else {
458+ 0
459+ }
460+ return DataViewItem (
461+ id = term.remoteTermId,
462+ image = null ,
463+ title = term.name,
464+ fields = listOf (
465+ DataViewItemField (
466+ value = context.resources.getString(R .string.term_count, term.postCount),
467+ valueType = DataViewFieldType .TEXT ,
468+ )
469+ ),
470+ skipEndPositioning = true ,
471+ data = term,
472+ indentation = (indentation * INDENTATION_IN_DP ).dp
473+ )
474+ }
475+
398476
399477 /* *
400478 * Returns an integer representation of the hierarchical indentation for the given term.
@@ -419,6 +497,29 @@ class TermsViewModel @Inject constructor(
419497 return indentation
420498 }
421499
500+ /* *
501+ * Returns an integer representation of the hierarchical indentation for the given term.
502+ */
503+ private fun getHierarchicalIndentation (
504+ allTerms : List <TermModel >,
505+ term : TermModel ?
506+ ): Int {
507+ if (term == null ) return 0
508+
509+ val termsById = allTerms.associateBy { it.remoteTermId }
510+ var indentation = 0
511+ var currentParentId = term.parentRemoteId
512+
513+ while (currentParentId > 0 ) {
514+ val parent = termsById[currentParentId]
515+ if (parent == null ) break
516+ indentation++
517+ currentParentId = parent.parentRemoteId
518+ }
519+
520+ return indentation
521+ }
522+
422523 private suspend fun getTermsList (
423524 site : SiteModel ,
424525 page : Int ,
0 commit comments