Add implement for infinite scroll
This commit is contained in:
@@ -3,9 +3,9 @@ package org.libre.agosto.p2play
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.preference.PreferenceManager
|
||||
import org.libre.agosto.p2play.activities.MainActivity
|
||||
import org.libre.agosto.p2play.ajax.Auth
|
||||
import org.libre.agosto.p2play.helpers.TaskManager
|
||||
import org.libre.agosto.p2play.models.TokenModel
|
||||
|
@@ -35,9 +35,7 @@ class MainActivity : ComponentActivity() {
|
||||
) { innerPadding ->
|
||||
VideosView(
|
||||
modifier = Modifier.padding(innerPadding)
|
||||
) {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,8 @@
|
||||
package org.libre.agosto.p2play.components.lists
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
@@ -8,29 +11,69 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import org.libre.agosto.p2play.components.organisms.VideoItem
|
||||
import org.libre.agosto.p2play.models.VideoModel
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.libre.agosto.p2play.helpers.InfiniteScrollHandler
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun VideoList (videos: ArrayList<VideoModel>, header: @Composable (() -> Unit)?, onLoadMore: (() -> Unit)? = null) {
|
||||
fun VideoList (videos: List<VideoModel>, header: @Composable (() -> Unit)?, isLoading: Boolean = false, onRefresh: (() -> Unit)? = null, onLoadMore: (() -> Unit)? = null) {
|
||||
val videoList by remember { derivedStateOf { videos } }
|
||||
var isRefreshing by remember { mutableStateOf(false) }
|
||||
val lazyState = rememberLazyListState()
|
||||
|
||||
LazyColumn {
|
||||
if (header !== null) {
|
||||
item { header() }
|
||||
PullToRefreshBox(
|
||||
isRefreshing,
|
||||
{
|
||||
if (onRefresh !== null) {
|
||||
onRefresh()
|
||||
}
|
||||
}
|
||||
items (videos) {
|
||||
VideoItem(it)
|
||||
) {
|
||||
LazyColumn(state = lazyState) {
|
||||
if (header !== null) {
|
||||
item(key = "header") { header() }
|
||||
}
|
||||
items(videoList, key = { it.id }) {
|
||||
VideoItem(it)
|
||||
}
|
||||
if (isLoading) {
|
||||
item(key = "loading") {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 20.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (onLoadMore !== null) {
|
||||
LaunchedEffect(lazyState) {
|
||||
snapshotFlow { lazyState.layoutInfo.visibleItemsInfo }
|
||||
.collect { visibleItems ->
|
||||
if (visibleItems.isNotEmpty() &&
|
||||
visibleItems.last().index >= videos.size - 1) {
|
||||
onLoadMore()
|
||||
LaunchedEffect (isLoading) {
|
||||
snapshotFlow { isLoading }
|
||||
.collect {
|
||||
if (!it) {
|
||||
isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InfiniteScrollHandler(lazyState, 2) {
|
||||
onLoadMore()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -5,14 +5,17 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Star
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import org.libre.agosto.p2play.R
|
||||
import org.libre.agosto.p2play.ajax.Videos
|
||||
import org.libre.agosto.p2play.components.lists.VideoList
|
||||
@@ -23,9 +26,7 @@ import org.libre.agosto.p2play.models.VideoModel
|
||||
|
||||
@SuppressLint("MutableCollectionMutableState")
|
||||
@Composable
|
||||
fun VideosView (modifier: Modifier, click: (VideoModel) -> Unit) {
|
||||
val client: Videos = Videos()
|
||||
var videoFilter by rememberSaveable { mutableStateOf("trending") }
|
||||
fun VideosView (modifier: Modifier) {
|
||||
val chips = arrayListOf(
|
||||
object : ChipValues<String> {
|
||||
override val text = stringResource(R.string.nav_trending)
|
||||
@@ -53,11 +54,46 @@ fun VideosView (modifier: Modifier, click: (VideoModel) -> Unit) {
|
||||
override val icon = ImageVector.vectorResource(R.drawable.ic_home_black_24dp)
|
||||
}
|
||||
)
|
||||
var videos by rememberSaveable { mutableStateOf<ArrayList<VideoModel>>(arrayListOf<VideoModel>()) }
|
||||
val task = TaskManager<ArrayList<VideoModel>>()
|
||||
|
||||
task.runTask({ client.getLastVideos() }) {
|
||||
videos = it
|
||||
var videoFilter by rememberSaveable { mutableStateOf("trending") }
|
||||
val videos by rememberSaveable { mutableStateOf(mutableListOf<VideoModel>()) }
|
||||
var isLoading by rememberSaveable { mutableStateOf(true) }
|
||||
|
||||
LaunchedEffect(isLoading) {
|
||||
if (isLoading) {
|
||||
val task = TaskManager<List<VideoModel>>()
|
||||
task.runTask(
|
||||
{
|
||||
val client = Videos()
|
||||
when (videoFilter) {
|
||||
"trending" -> {
|
||||
client.getTrendingVideos(videos.size)
|
||||
}
|
||||
"popular" -> {
|
||||
client.getPopularVideos(videos.size)
|
||||
}
|
||||
"likes" -> {
|
||||
client.getMostLikedVideos(videos.size)
|
||||
}
|
||||
"recent" -> {
|
||||
client.getLastVideos(videos.size)
|
||||
}
|
||||
"local" -> {
|
||||
client.getLocalVideos(videos.size)
|
||||
}
|
||||
else -> {
|
||||
videoFilter = "trending"
|
||||
client.getTrendingVideos(videos.size)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
videos.addAll(it)
|
||||
isLoading = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Column (modifier) {
|
||||
@@ -66,6 +102,20 @@ fun VideosView (modifier: Modifier, click: (VideoModel) -> Unit) {
|
||||
header = {
|
||||
ChipSelector(chips, videoFilter) {
|
||||
videoFilter = it
|
||||
videos.clear()
|
||||
isLoading = true
|
||||
}
|
||||
},
|
||||
isLoading = isLoading,
|
||||
onRefresh = {
|
||||
if (!isLoading) {
|
||||
videos.clear()
|
||||
isLoading = true
|
||||
}
|
||||
},
|
||||
onLoadMore = {
|
||||
if (!isLoading) {
|
||||
isLoading = true
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@@ -0,0 +1,23 @@
|
||||
package org.libre.agosto.p2play.helpers
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
|
||||
@Composable
|
||||
fun InfiniteScrollHandler(
|
||||
lazyState: LazyListState,
|
||||
buffer: Int = 1,
|
||||
onLoadMore: () -> Unit
|
||||
) {
|
||||
LaunchedEffect(lazyState) {
|
||||
snapshotFlow { lazyState.layoutInfo.visibleItemsInfo }
|
||||
.collect { visibleItems ->
|
||||
val items = lazyState.layoutInfo.totalItemsCount
|
||||
if (visibleItems.isNotEmpty() && items > buffer && visibleItems.last().index >= items - 1) {
|
||||
onLoadMore()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user