Repository: Automattic/pocket-casts-android
File: modules/services/repositories/src/main/java/au/com/shiftyjelly/pocketcasts/repositories/categories/CategoriesManager.kt (Kotlin)

Code before:
                            .sortedBy { rowInfo.popularCategoryIds.indexOf(it.id) },
                    )
                }
            }.ifEmpty {
                categories
            }.take(FEATURED_CATEGORY_COUNT).mapIndexed { index, item ->
                item.copy(featuredIndex = index)
            }
            State.Idle(
                featuredCategories = featuredCategories,
                allCategories = categories.map { it.copy(isSponsored = rowInfo.sponsoredCategoryIds.contains(it.id)) },
                areAllCategoriesShown = areAllShown,
            )
        }
    }.stateIn(scope, SharingStarted.Eagerly, State.Empty)

    val selectedCategory = state.map { state ->
        when (state) {
            is State.Selected -> state.selectedCategory
            is State.Idle -> null
        }
    }.distinctUntilChanged()

    val availableInterestCategories = discoverCategories.asStateFlow()
        .map { categories ->
            categories.filter { it.popularity != null }
                .sortedBy { it.popularity }
        }

    fun loadCategories(url: String) {
        if (discoverCategories.value.isEmpty() || areCategoriesStale()) {
            scope.launch {
                try {
                    val userVisits = userCategoryVisitsDao.getCategoryVisitsOrdered()
                    discoverCategories.value = listRepository.getCategoriesList(url).map { category ->
                        category.copy(
                            totalVisits = userVisits.find { it.categoryId == category.id }?.totalVisits ?: 0,
                        )
                    }
                    lastUpdate = TimeSource.Monotonic.markNow()
                } catch (e: Throwable) {
                    Timber.e(e, "Failed to fetch categories under $url")
                }
            }
        }
    }

    fun setRowInfo(popularCategoryIds: List<Int>, sponsoredCategoryIds: List<Int>) {
        discoverRowInfo.value = DiscoverRowInfo(
            popularCategoryIds = popularCategoryIds,
            sponsoredCategoryIds = sponsoredCategoryIds,

Review comment (suggestion):
`.asStateFlow()` is unnecessary here since the flow is being later mapped and loses its State type. If you want/need to keep it as State it can be `discoverCategories.map().stateIn(scope, /* appropriate configuration */)`

Code after:
                }
            }.ifEmpty {
                categories
            }.take(FEATURED_CATEGORY_COUNT).mapIndexed { index, item ->
                item.copy(featuredIndex = index)
            }
            State.Idle(
                featuredCategories = featuredCategories,
                allCategories = categories.map { it.copy(isSponsored = rowInfo.sponsoredCategoryIds.contains(it.id)) },
                areAllCategoriesShown = areAllShown,
            )
        }
    }.stateIn(scope, SharingStarted.Eagerly, State.Empty)

    val selectedCategory = state.map { state ->
        when (state) {
            is State.Selected -> state.selectedCategory
            is State.Idle -> null
        }
    }.distinctUntilChanged()

    val availableInterestCategories = discoverCategories
        .map { categories ->
            categories.filter { it.popularity != null }
                .sortedBy { it.popularity }
        }

    fun loadCategories(url: String) {
        if (discoverCategories.value.isEmpty() || areCategoriesStale()) {
            scope.launch {
                try {
                    val userVisits = userCategoryVisitsDao.getCategoryVisitsOrdered()
                    discoverCategories.value = listRepository.getCategoriesList(url).map { category ->
                        category.copy(
                            totalVisits = userVisits.find { it.categoryId == category.id }?.totalVisits ?: 0,
                        )
                    }
                    lastUpdate = TimeSource.Monotonic.markNow()
                } catch (e: Throwable) {
                    Timber.e(e, "Failed to fetch categories under $url")
                }
            }
        }
    }

    fun setRowInfo(popularCategoryIds: List<Int>, sponsoredCategoryIds: List<Int>) {
        discoverRowInfo.value = DiscoverRowInfo(
            popularCategoryIds = popularCategoryIds,
            sponsoredCategoryIds = sponsoredCategoryIds,
        )
    }