Skip to content

Instantly share code, notes, and snippets.

@OptIn(ExperimentalPagingApi::class)
class GithubRemoteMediator(
) : RemoteMediator<Int, Repo>() {
}
fun getSearchResultStream(query: String): Flow<PagingData<Repo>> {
val pagingSourceFactory = { database.reposDao().reposByName(dbQuery) }
@OptIn(ExperimentalPagingApi::class)
return Pager(
config = PagingConfig(
pageSize = NETWORK_PAGE_SIZE,
enablePlaceholders = false
@Dao
interface RepoDao {
@Query(
"SELECT * FROM repos WHERE " +
"name LIKE :queryString"
)
fun reposByName(queryString: String): PagingSource<Int, Repo>
}
private fun ActivitySearchRepositoriesBinding.bindState(
uiState: StateFlow<UiState>,
pagingData: Flow<PagingData<Repo>>,
uiActions: (UiAction) -> Unit
) {
val repoAdapter = ReposAdapter()
list.adapter = repoAdapter.withLoadStateHeaderAndFooter(
header = ReposLoadStateAdapter { repoAdapter.retry() },
footer = ReposLoadStateAdapter { repoAdapter.retry() }
)
private fun ActivitySearchRepositoriesBinding.bindList(
repoAdapter: ReposAdapter,
uiState: StateFlow<UiState>,
pagingData: Flow<PagingData<Repo>>,
) {
val notLoading = repoAdapter.loadStateFlow
// Only emit when REFRESH LoadState for the paging source changes.
.distinctUntilChangedBy { it.source.refresh }
private fun ActivitySearchRepositoriesBinding.bindList(
pagingData: Flow<PagingData<Repo>>,
) {
lifecycleScope.launch {
pagingData.collectLatest(repoAdapter::submitData)
}
}
// Before
// class ReposAdapter : ListAdapter<Repo, RepoViewHolder>(REPO_COMPARATOR) {
// …
// }
// After
class ReposAdapter : PagingDataAdapter<Repo, RepoViewHolder>(REPO_COMPARATOR) {
}
class SearchRepositoriesViewModel(
) : ViewModel() {
val state: StateFlow<UiState>
val pagingDataFlow: Flow<PagingData<Repo>>
init {
class SearchRepositoriesViewModel(
private val repository: GithubRepository,
) : ViewModel() {
private fun searchRepo(queryString: String): Flow<PagingData<Repo>> =
repository.getSearchResultStream(queryString)
}
data class UiState(
val query: String,
val searchResult: RepoSearchResult
)
sealed class RepoSearchResult {
data class Success(val data: List<Repo>) : RepoSearchResult()
data class Error(val error: Exception) : RepoSearchResult()
}