Skip to content

Commit

Permalink
Distinct fap items by id in paging sources (#881)
Browse files Browse the repository at this point in the history
**Background**

Right now sometimes the server can return repetitive application items

**Changes**

Check unique of item

**Test plan**

Try launch app with broken offsets and limit on server (mock for
example)
  • Loading branch information
LionZXY authored Jun 25, 2024
1 parent 8973286 commit f3bdf0c
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# 1.7.2 - In Progress

- [FIX] Distinct fap items by id in paging sources

# 1.7.1

- Fix for a vulnerability causing write access to internal application files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package com.flipperdevices.core.pager
import androidx.paging.LoadState
import androidx.paging.LoadStates
import androidx.paging.PagingData
import androidx.paging.filter
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map

fun <T : Any> loadingPagingDataFlow(): Flow<PagingData<T>> {
return flowOf(
Expand All @@ -18,3 +20,12 @@ fun <T : Any> loadingPagingDataFlow(): Flow<PagingData<T>> {
)
)
}

fun <T : Any, K> Flow<PagingData<T>>.distinctBy(selector: (T) -> K): Flow<PagingData<T>> {
val set = HashSet<K>()
return map { pageData ->
pageData.filter { element ->
set.add(selector(element))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.flipperdevices.bridge.dao.api.FapHubHideItemApi
import com.flipperdevices.core.pager.distinctBy
import com.flipperdevices.core.pager.loadingPagingDataFlow
import com.flipperdevices.core.preference.pb.Settings
import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel
Expand Down Expand Up @@ -57,7 +58,7 @@ class FapsListViewModel @Inject constructor(
) {
FapsPagingSource(fapNetworkApi, sortType, target, hiddenItems)
}.flow
}.flatMapLatest { it }.cachedIn(viewModelScope)
}.flatMapLatest { it }.distinctBy { it.id }.cachedIn(viewModelScope)

fun getFapsFlow(): Flow<PagingData<FapItemShort>> = faps

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.flipperdevices.bridge.dao.api.FapHubHideItemApi
import com.flipperdevices.core.pager.distinctBy
import com.flipperdevices.core.pager.loadingPagingDataFlow
import com.flipperdevices.core.preference.pb.Settings
import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel
Expand Down Expand Up @@ -34,10 +35,9 @@ class FapHubCategoryViewModel @AssistedInject constructor(
private val sortStateFlow = MutableStateFlow(SortType.UPDATE_AT_DESC)

init {
dataStoreSettings.data
.onEach {
sortStateFlow.emit(it.selectedCatalogSort.toSortType())
}.launchIn(viewModelScope)
dataStoreSettings.data.onEach {
sortStateFlow.emit(it.selectedCatalogSort.toSortType())
}.launchIn(viewModelScope)
}

fun getSortTypeFlow() = sortStateFlow.asStateFlow()
Expand All @@ -55,16 +55,14 @@ class FapHubCategoryViewModel @AssistedInject constructor(
) {
FapsCategoryPagingSource(fapNetworkApi, category, sortType, target, hiddenItems)
}.flow
}.flatMapLatest { it }.cachedIn(viewModelScope)
}.flatMapLatest { it }.distinctBy { it.id }.cachedIn(viewModelScope)

fun getFapsFlow() = faps

fun onSelectSortType(sortType: SortType) {
viewModelScope.launch {
dataStoreSettings.updateData {
it.toBuilder()
.setSelectedCatalogSort(sortType.toSelectedSortType())
.build()
it.toBuilder().setSelectedCatalogSort(sortType.toSelectedSortType()).build()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.flipperdevices.bridge.dao.api.FapHubHideItemApi
import com.flipperdevices.core.pager.distinctBy
import com.flipperdevices.core.pager.loadingPagingDataFlow
import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel
import com.flipperdevices.faphub.dao.api.FapNetworkApi
Expand Down Expand Up @@ -33,7 +34,7 @@ class FapHubSearchViewModel @Inject constructor(
Pager(PagingConfig(pageSize = FAPS_PAGE_SIZE)) {
FapsSearchPagingSource(fapNetworkApi, searchRequest, target, hiddenItems)
}.flow
}.flatMapLatest { it }.cachedIn(viewModelScope)
}.flatMapLatest { it }.distinctBy { it.id }.cachedIn(viewModelScope)

fun getSearchRequest() = searchRequestFlow.asStateFlow()

Expand Down

0 comments on commit f3bdf0c

Please sign in to comment.