From 462ed5c79a7a58ecb2ee1f363942e501552b2d3d Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 6 Jul 2024 21:04:48 +0530 Subject: [PATCH] Added loading indicator to playlist view --- .../newpipe/compose/playlist/Playlist.kt | 103 ++++++++++-------- 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/compose/playlist/Playlist.kt b/app/src/main/java/org/schabi/newpipe/compose/playlist/Playlist.kt index 429becb19..49e3def45 100644 --- a/app/src/main/java/org/schabi/newpipe/compose/playlist/Playlist.kt +++ b/app/src/main/java/org/schabi/newpipe/compose/playlist/Playlist.kt @@ -18,12 +18,16 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.fragment.app.FragmentActivity -import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData import androidx.paging.compose.collectAsLazyPagingItems +import kotlinx.coroutines.flow.Flow import my.nanihadesuka.compose.LazyColumnScrollbar import my.nanihadesuka.compose.LazyVerticalGridScrollbar import org.schabi.newpipe.DownloaderImpl +import org.schabi.newpipe.compose.status.LoadingIndicator import org.schabi.newpipe.compose.stream.StreamCardItem import org.schabi.newpipe.compose.stream.StreamGridItem import org.schabi.newpipe.compose.stream.StreamListItem @@ -31,24 +35,34 @@ import org.schabi.newpipe.compose.theme.AppTheme import org.schabi.newpipe.compose.util.determineItemViewMode import org.schabi.newpipe.extractor.NewPipe import org.schabi.newpipe.extractor.ServiceList +import org.schabi.newpipe.extractor.playlist.PlaylistInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.info_list.ItemViewMode -import org.schabi.newpipe.util.KEY_SERVICE_ID -import org.schabi.newpipe.util.KEY_URL +import org.schabi.newpipe.paging.PlaylistItemsSource import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.viewmodels.PlaylistViewModel @Composable fun Playlist(playlistViewModel: PlaylistViewModel = viewModel()) { - val playlistInfo by playlistViewModel.playlistInfo.collectAsState() - val streams = playlistViewModel.streamItems.collectAsLazyPagingItems() + Surface(color = MaterialTheme.colorScheme.background) { + val playlistInfo by playlistViewModel.playlistInfo.collectAsState() + playlistInfo?.let { + LoadedPlaylist(it, playlistViewModel.streamItems) + } ?: LoadingIndicator() + } +} + +@Composable +private fun LoadedPlaylist(playlistInfo: PlaylistInfo, flow: Flow>) { + val streams = flow.collectAsLazyPagingItems() + val mode = determineItemViewMode() + val context = LocalContext.current + val totalDuration by remember { derivedStateOf { streams.itemSnapshotList.sumOf { it!!.duration } } } - - val context = LocalContext.current val onClick = { stream: StreamInfoItem -> NavigationHelper.openVideoDetailFragment( context, (context as FragmentActivity).supportFragmentManager, @@ -56,42 +70,36 @@ fun Playlist(playlistViewModel: PlaylistViewModel = viewModel()) { ) } - playlistInfo?.let { - Surface(color = MaterialTheme.colorScheme.background) { - val mode = determineItemViewMode() + if (mode == ItemViewMode.GRID) { + val gridState = rememberLazyGridState() - if (mode == ItemViewMode.GRID) { - val gridState = rememberLazyGridState() - - LazyVerticalGridScrollbar(state = gridState) { - LazyVerticalGrid(state = gridState, columns = GridCells.Adaptive(250.dp)) { - item(span = { GridItemSpan(maxLineSpan) }) { - PlaylistHeader(playlistInfo = it, totalDuration = totalDuration) - } - - items(streams.itemCount) { - StreamGridItem(streams[it]!!, onClick) - } - } + LazyVerticalGridScrollbar(state = gridState) { + LazyVerticalGrid(state = gridState, columns = GridCells.Adaptive(250.dp)) { + item(span = { GridItemSpan(maxLineSpan) }) { + PlaylistHeader(playlistInfo, totalDuration) } - } else { - // Card or list views - val listState = rememberLazyListState() - LazyColumnScrollbar(state = listState) { - LazyColumn(state = listState) { - item { - PlaylistHeader(playlistInfo = it, totalDuration = totalDuration) - } + items(streams.itemCount) { + StreamGridItem(streams[it]!!, onClick) + } + } + } + } else { + // Card or list views + val listState = rememberLazyListState() - items(streams.itemCount) { - val stream = streams[it]!! - if (mode == ItemViewMode.CARD) { - StreamCardItem(stream, onClick) - } else { - StreamListItem(stream, onClick) - } - } + LazyColumnScrollbar(state = listState) { + LazyColumn(state = listState) { + item { + PlaylistHeader(playlistInfo, totalDuration) + } + + items(streams.itemCount) { + val stream = streams[it]!! + if (mode == ItemViewMode.CARD) { + StreamCardItem(stream, onClick) + } else { + StreamListItem(stream, onClick) } } } @@ -104,13 +112,18 @@ fun Playlist(playlistViewModel: PlaylistViewModel = viewModel()) { @Composable private fun PlaylistPreview() { NewPipe.init(DownloaderImpl.init(null)) - val params = - mapOf( - KEY_SERVICE_ID to ServiceList.YouTube.serviceId, - KEY_URL to "https://www.youtube.com/playlist?list=PLAIcZs9N4171hRrG_4v32Ca2hLvSuQ6QI", - ) + + val playlistInfo = PlaylistInfo.getInfo( + ServiceList.YouTube, + "https://www.youtube.com/playlist?list=PLAIcZs9N4171hRrG_4v32Ca2hLvSuQ6QI" + ) + val streams = Pager(PagingConfig(pageSize = 20, enablePlaceholders = false)) { + PlaylistItemsSource(playlistInfo) + }.flow AppTheme { - Playlist(PlaylistViewModel(SavedStateHandle(params))) + Surface(color = MaterialTheme.colorScheme.background) { + LoadedPlaylist(playlistInfo, streams) + } } }