Skip to content

Commit

Permalink
Cache paging data using the cachedIn() extension
Browse files Browse the repository at this point in the history
  • Loading branch information
Isira-Seneviratne committed Jul 3, 2024
1 parent 37d7d07 commit 8a97e45
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 48 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ dependencies {
implementation 'androidx.compose.material3:material3'
implementation 'androidx.activity:activity-compose'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.compose.ui:ui-text:1.7.0-beta03' // Needed for parsing HTML to AnnotatedString
implementation 'androidx.compose.ui:ui-text:1.7.0-beta04' // Needed for parsing HTML to AnnotatedString
implementation 'com.github.nanihadesuka:LazyColumnScrollbar:2.1.0'

// Paging
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
Expand All @@ -37,6 +38,7 @@ import androidx.compose.ui.unit.dp
import androidx.fragment.app.FragmentActivity
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import coil.compose.AsyncImage
import org.schabi.newpipe.R
import org.schabi.newpipe.compose.theme.AppTheme
Expand Down Expand Up @@ -141,13 +143,15 @@ fun Comment(comment: CommentsInfoItem) {

if (showReplies) {
ModalBottomSheet(onDismissRequest = { showReplies = false }) {
val flow = remember(comment) {
val coroutineScope = rememberCoroutineScope()
val flow = remember(coroutineScope) {
Pager(PagingConfig(pageSize = 20, enablePlaceholders = false)) {
CommentsSource(comment.serviceId, comment.url, comment.replies)
}.flow
.cachedIn(coroutineScope)
}

CommentSection(parentComment = comment, flow = flow)
CommentSection(parentComment = comment, commentsData = flow)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ import org.schabi.newpipe.paging.CommentsDisabledException
@Composable
fun CommentSection(
parentComment: CommentsInfoItem? = null,
flow: Flow<PagingData<CommentsInfoItem>>
commentsData: Flow<PagingData<CommentsInfoItem>>
) {
val replies = flow.collectAsLazyPagingItems()
val itemCount by remember { derivedStateOf { replies.itemCount } }
val comments = commentsData.collectAsLazyPagingItems()
val itemCount by remember { derivedStateOf { comments.itemCount } }

Surface(color = MaterialTheme.colorScheme.background) {
val refresh = replies.loadState.refresh
val refresh = comments.loadState.refresh
if (itemCount == 0 && refresh !is LoadState.Loading) {
NoCommentsMessage((refresh as? LoadState.Error)?.error)
} else {
Expand All @@ -58,7 +58,7 @@ fun CommentSection(
}

items(itemCount) {
Comment(comment = replies[it]!!)
Comment(comment = comments[it]!!)
}
}
}
Expand Down Expand Up @@ -113,7 +113,7 @@ private fun CommentSectionPreview(
@PreviewParameter(CommentDataProvider::class) pagingData: PagingData<CommentsInfoItem>
) {
AppTheme {
CommentSection(flow = flowOf(pagingData))
CommentSection(commentsData = flowOf(pagingData))
}
}

Expand All @@ -137,6 +137,6 @@ private fun CommentRepliesPreview() {
val flow = flowOf(PagingData.from(replies))

AppTheme {
CommentSection(parentComment = comment, flow = flow)
CommentSection(parentComment = comment, commentsData = flow)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import org.schabi.newpipe.compose.comment.CommentSection
import org.schabi.newpipe.compose.theme.AppTheme
import org.schabi.newpipe.paging.CommentsSource
Expand All @@ -29,14 +31,16 @@ class CommentsFragment : Fragment() {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val flow = remember(serviceId, url) {
val coroutineScope = rememberCoroutineScope()
val flow = remember(coroutineScope) {
Pager(PagingConfig(pageSize = 20, enablePlaceholders = false)) {
CommentsSource(serviceId, url, null)
}.flow
.cachedIn(coroutineScope)
}

AppTheme {
CommentSection(flow = flow)
CommentSection(commentsData = flow)
}
}
}
Expand Down
39 changes: 23 additions & 16 deletions app/src/main/java/org/schabi/newpipe/paging/CommentsSource.kt
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
package org.schabi.newpipe.paging

import androidx.paging.PagingSource
import androidx.paging.PagingState
import androidx.paging.rxjava3.RxPagingSource
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.schabi.newpipe.extractor.NewPipe
import org.schabi.newpipe.extractor.Page
import org.schabi.newpipe.extractor.comments.CommentsInfo
import org.schabi.newpipe.extractor.comments.CommentsInfoItem
import org.schabi.newpipe.util.ExtractorHelper
import org.schabi.newpipe.util.NO_SERVICE_ID

class CommentsSource(
private val serviceId: Int,
serviceId: Int,
private val url: String?,
private val repliesPage: Page?
) : RxPagingSource<Page, CommentsInfoItem>() {
override fun loadSingle(params: LoadParams<Page>): Single<LoadResult<Page, CommentsInfoItem>> {
) : PagingSource<Page, CommentsInfoItem>() {
init {
require(serviceId != NO_SERVICE_ID) { "serviceId is NO_SERVICE_ID" }
}
private val service = NewPipe.getService(serviceId)

override suspend fun load(params: LoadParams<Page>): LoadResult<Page, CommentsInfoItem> {
// repliesPage is non-null only when used to load the comment replies
val nextKey = params.key ?: repliesPage

return nextKey?.let {
ExtractorHelper.getMoreCommentItems(serviceId, url, it)
.subscribeOn(Schedulers.io())
.map { LoadResult.Page(it.items, null, it.nextPage) }
} ?: ExtractorHelper.getCommentsInfo(serviceId, url, false)
.subscribeOn(Schedulers.io())
.map {
if (it.isCommentsDisabled) {
return withContext(Dispatchers.IO) {
nextKey?.let {
val info = CommentsInfo.getMoreItems(service, url, it)
LoadResult.Page(info.items, null, info.nextPage)
} ?: run {
val info = CommentsInfo.getInfo(service, url)
if (info.isCommentsDisabled) {
LoadResult.Error(CommentsDisabledException())
} else {
LoadResult.Page(it.relatedItems, null, it.nextPage)
LoadResult.Page(info.relatedItems, null, info.nextPage)
}
}
}
}

override fun getRefreshKey(state: PagingState<Page, CommentsInfoItem>) = null
Expand Down
20 changes: 0 additions & 20 deletions app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.kiosk.KioskInfo;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
Expand Down Expand Up @@ -146,24 +144,6 @@ public static Single<InfoItemsPage<InfoItem>> getMoreChannelTabItems(
listLinkHandler, nextPage));
}

public static Single<CommentsInfo> getCommentsInfo(final int serviceId,
final String url,
final boolean forceLoad) {
checkServiceId(serviceId);
return checkCache(forceLoad, serviceId, url, InfoCache.Type.COMMENTS,
Single.fromCallable(() ->
CommentsInfo.getInfo(NewPipe.getService(serviceId), url)));
}

public static Single<InfoItemsPage<CommentsInfoItem>> getMoreCommentItems(
final int serviceId,
final String url,
final Page nextPage) {
checkServiceId(serviceId);
return Single.fromCallable(() ->
CommentsInfo.getMoreItems(NewPipe.getService(serviceId), url, nextPage));
}

public static Single<PlaylistInfo> getPlaylistInfo(final int serviceId,
final String url,
final boolean forceLoad) {
Expand Down

0 comments on commit 8a97e45

Please sign in to comment.