Skip to content

Commit 3d4b0c7

Browse files
fix: unexpected requests under certain conditions
1 parent 0beb199 commit 3d4b0c7

4 files changed

Lines changed: 53 additions & 52 deletions

File tree

library/src/commonMain/kotlin/project/pipepipe/app/ui/list/CommentList.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,16 @@ fun CommentList(
5555
) {
5656
val uniqueItems = remember(comments) { comments.distinctBy { it.url } }
5757

58-
LaunchedEffect(listState, hasMoreComments, isLoading) {
58+
LaunchedEffect(listState, hasMoreComments, uniqueItems) {
5959
snapshotFlow {
60-
val layoutInfo = listState.layoutInfo
61-
val lastVisibleIndex = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1
62-
val totalItemsCount = layoutInfo.totalItemsCount
63-
lastVisibleIndex to totalItemsCount
60+
val actualItems = listState.layoutInfo.visibleItemsInfo.filter { it.key is String? }.map { it.key }
61+
val lastVisible = actualItems.lastOrNull()
62+
lastVisible to uniqueItems.lastOrNull()
6463
}
6564
.distinctUntilChanged()
66-
.collect { (lastVisibleIndex, totalItemsCount) ->
67-
val isAtBottom = totalItemsCount > 0 && lastVisibleIndex == totalItemsCount - 1
65+
.collect { (lastVisible, lastItem) ->
66+
val lastItemUrl = lastItem?.url
67+
val isAtBottom = lastVisible == lastItemUrl
6868
if (isAtBottom && hasMoreComments && !isLoading) {
6969
onLoadMore()
7070
}

library/src/commonMain/kotlin/project/pipepipe/app/ui/screens/ChannelScreen.kt

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ fun ChannelScreen(
309309
gridState = liveGridState,
310310
items = uiState.liveTab.itemList,
311311
isLoading = uiState.common.isLoading,
312-
hasMore = uiState.liveTab.nextPageUrl != null,
312+
nextPageUrl = uiState.liveTab.nextPageUrl,
313313
onLoadMore = { viewModel.loadLiveTabMoreItems(serviceId) },
314314
getUrl = { it.url },
315315
onItemClick = { item ->
@@ -328,7 +328,7 @@ fun ChannelScreen(
328328
gridState = shortsGridState,
329329
items = uiState.shortsTab.itemList,
330330
isLoading = uiState.common.isLoading,
331-
hasMore = uiState.shortsTab.nextPageUrl != null,
331+
nextPageUrl = uiState.shortsTab.nextPageUrl,
332332
onLoadMore = { viewModel.loadShortsTabMoreItems(serviceId) },
333333
getUrl = { it.url },
334334
onItemClick = { item ->
@@ -347,7 +347,7 @@ fun ChannelScreen(
347347
gridState = videoGridState,
348348
items = uiState.videoTab.itemList,
349349
isLoading = uiState.common.isLoading,
350-
hasMore = uiState.videoTab.nextPageUrl != null,
350+
nextPageUrl = uiState.videoTab.nextPageUrl,
351351
onLoadMore = { viewModel.loadMainTabMoreItems(serviceId) },
352352
getUrl = { it.url },
353353
onItemClick = { item ->
@@ -366,7 +366,7 @@ fun ChannelScreen(
366366
gridState = remember { LazyGridState() },
367367
items = uiState.playlistTab.itemList,
368368
isLoading = uiState.common.isLoading,
369-
hasMore = uiState.playlistTab.nextPageUrl != null,
369+
nextPageUrl = uiState.playlistTab.nextPageUrl,
370370
onLoadMore = { viewModel.loadPlaylistTabMoreItems(serviceId) },
371371
getUrl = { it.url },
372372
onItemClick = { item -> navController.navigate(
@@ -383,7 +383,7 @@ fun ChannelScreen(
383383
gridState = remember { LazyGridState() },
384384
items = uiState.albumTab.itemList,
385385
isLoading = uiState.common.isLoading,
386-
hasMore = uiState.albumTab.nextPageUrl != null,
386+
nextPageUrl = uiState.albumTab.nextPageUrl,
387387
onLoadMore = { viewModel.loadAlbumTabMoreItems(serviceId) },
388388
getUrl = { it.url },
389389
onItemClick = { item -> navController.navigate(
@@ -541,7 +541,7 @@ private fun <T: Info> TabContent(
541541
gridState: LazyGridState,
542542
items: List<T>,
543543
isLoading: Boolean,
544-
hasMore: Boolean,
544+
nextPageUrl: String?,
545545
onLoadMore: () -> Unit,
546546
getUrl: (T) -> String,
547547
onItemClick: (T) -> Unit,
@@ -552,32 +552,32 @@ private fun <T: Info> TabContent(
552552
val uniqueItems = remember(items) { items.distinctBy { getUrl(it) } }
553553
val loadMoreInvoker = rememberUpdatedState(onLoadMore)
554554

555-
LaunchedEffect(listState, gridState, hasMore, isLoading, uniqueItems) {
555+
LaunchedEffect(listState, gridState, nextPageUrl,uniqueItems) {
556556
if (isGridEnabled) {
557557
snapshotFlow {
558-
val layoutInfo = gridState.layoutInfo
559-
val lastVisibleIndex = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1
560-
val totalItemsCount = layoutInfo.totalItemsCount
561-
lastVisibleIndex to totalItemsCount
558+
val actualItems = gridState.layoutInfo.visibleItemsInfo.filter { it.key is String? }.map { it.key }
559+
val lastVisible = actualItems.lastOrNull()
560+
lastVisible to uniqueItems.lastOrNull()
562561
}
563562
.distinctUntilChanged()
564-
.collect { (lastVisibleIndex, totalItemsCount) ->
565-
val isAtBottom = totalItemsCount > 0 && lastVisibleIndex == totalItemsCount - 1
566-
if (isAtBottom && hasMore && !isLoading) {
563+
.collect { (lastVisible, lastItem) ->
564+
val lastItemUrl = lastItem?.let { getUrl(it) }
565+
val isAtBottom = lastVisible == lastItemUrl
566+
if (isAtBottom && nextPageUrl != null && !isLoading) {
567567
loadMoreInvoker.value.invoke()
568568
}
569569
}
570570
} else {
571571
snapshotFlow {
572-
val layoutInfo = listState.layoutInfo
573-
val lastVisibleIndex = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1
574-
val totalItemsCount = layoutInfo.totalItemsCount
575-
lastVisibleIndex to totalItemsCount
572+
val actualItems = listState.layoutInfo.visibleItemsInfo.filter { it.key is String? }.map { it.key }
573+
val lastVisible = actualItems.lastOrNull()
574+
lastVisible to uniqueItems.lastOrNull()
576575
}
577576
.distinctUntilChanged()
578-
.collect { (lastVisibleIndex, totalItemsCount) ->
579-
val isAtBottom = totalItemsCount > 0 && lastVisibleIndex == totalItemsCount - 1
580-
if (isAtBottom && hasMore && !isLoading) {
577+
.collect { (lastVisible, lastItem) ->
578+
val lastItemUrl = lastItem?.let { getUrl(it) }
579+
val isAtBottom = lastVisible == lastItemUrl
580+
if (isAtBottom && nextPageUrl != null && !isLoading) {
581581
loadMoreInvoker.value.invoke()
582582
}
583583
}

library/src/commonMain/kotlin/project/pipepipe/app/ui/screens/SearchScreen.kt

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -172,39 +172,37 @@ fun SearchScreen(
172172
}
173173

174174
if (isGridLayout) {
175-
LaunchedEffect(gridState, uiState.list.nextPageUrl, uiState.common.isLoading) {
175+
LaunchedEffect(gridState, uiState.list.nextPageUrl) {
176176
snapshotFlow {
177-
val layoutInfo = gridState.layoutInfo
178-
val lastVisible = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1
179-
lastVisible to layoutInfo.totalItemsCount
177+
val actualItems = gridState.layoutInfo.visibleItemsInfo.filter { it.key is String? }.map { it.key }
178+
val lastVisible = actualItems.lastOrNull()
179+
lastVisible to uiState.list.itemList.lastOrNull()
180180
}
181181
.distinctUntilChanged()
182-
.collect { (lastVisible, totalCount) ->
182+
.collect { (lastVisible, lastItemInList) ->
183183
val hasNextPage = uiState.list.nextPageUrl != null
184184
val canLoadMore = !uiState.common.isLoading && hasNextPage
185-
val atBottom = totalCount > 0 && lastVisible == totalCount - 1
186-
185+
val atBottom = lastVisible == lastItemInList?.url
187186
if (canLoadMore && atBottom) {
188-
val serviceId = uniqueItems.firstOrNull()?.serviceId ?: return@collect
187+
val serviceId = lastItemInList!!.serviceId ?: return@collect
189188
viewModel.loadMoreResults(serviceId)
190189
}
191190
}
192191
}
193192
} else {
194-
LaunchedEffect(listState, uiState.list.nextPageUrl, uiState.common.isLoading) {
193+
LaunchedEffect(listState) {
195194
snapshotFlow {
196-
val layoutInfo = listState.layoutInfo
197-
val lastVisible = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1
198-
lastVisible to layoutInfo.totalItemsCount
195+
val actualItems = listState.layoutInfo.visibleItemsInfo.filter { it.key is String? }.map { it.key }
196+
val lastVisible = actualItems.lastOrNull()
197+
lastVisible to uiState.list.itemList.lastOrNull()
199198
}
200199
.distinctUntilChanged()
201-
.collect { (lastVisible, totalCount) ->
200+
.collect { (lastVisible, lastItemInList) ->
202201
val hasNextPage = uiState.list.nextPageUrl != null
203202
val canLoadMore = !uiState.common.isLoading && hasNextPage
204-
val atBottom = totalCount > 0 && lastVisible == totalCount - 1
205-
203+
val atBottom = lastVisible == lastItemInList?.url
206204
if (canLoadMore && atBottom) {
207-
val serviceId = uniqueItems.firstOrNull()?.serviceId ?: return@collect
205+
val serviceId = lastItemInList!!.serviceId ?: return@collect
208206
viewModel.loadMoreResults(serviceId)
209207
}
210208
}

library/src/commonMain/kotlin/project/pipepipe/app/ui/screens/playlistdetail/PlaylistDetailScreen.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,27 +99,30 @@ fun PlaylistDetailScreen(
9999
}
100100
}
101101

102-
LaunchedEffect(listState, gridState, uiState.displayItems.size) {
102+
LaunchedEffect(listState, gridState, uiState.list.nextPageUrl) {
103103
val isGridEnabled = SharedContext.settingsManager.getBoolean("grid_layout_enabled_key", false)
104104

105-
val lastVisibleIndexFlow = if (isGridEnabled) {
105+
val lastVisibleKeyFlow = if (isGridEnabled) {
106106
snapshotFlow {
107-
gridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index
107+
val actualItems = gridState.layoutInfo.visibleItemsInfo.filter { it.key is String? }.map { it.key }
108+
actualItems.lastOrNull()
108109
}
109110
} else {
110111
snapshotFlow {
111-
listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index
112+
val actualItems = listState.layoutInfo.visibleItemsInfo.filter { it.key is String? }.map { it.key }
113+
actualItems.lastOrNull()
112114
}
113115
}
114116

115-
lastVisibleIndexFlow.collect { lastVisibleIndex ->
116-
if (lastVisibleIndex != null &&
117+
lastVisibleKeyFlow.collect { lastVisibleKey ->
118+
if (lastVisibleKey != null &&
117119
uiState.playlistType in listOf(PlaylistType.REMOTE, PlaylistType.TRENDING) &&
118120
!uiState.common.isLoading &&
119121
uiState.list.nextPageUrl != null) {
120122

121-
val totalItems = uiState.displayItems.size
122-
if (lastVisibleIndex >= totalItems - 5) {
123+
val lastItem = uiState.displayItems.lastOrNull()
124+
val lastItemKey = lastItem?.joinId ?: lastItem?.url
125+
if (lastVisibleKey == lastItemKey) {
123126
viewModel.loadRemotePlaylistMoreItems(serviceId!!)
124127
}
125128
}

0 commit comments

Comments
 (0)