mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-26 22:42:17 +00:00
ref: catalog screen to remember scroll state
This commit is contained in:
parent
bfed3b4cd8
commit
9d2fe291e8
5 changed files with 92 additions and 9 deletions
|
|
@ -11,3 +11,8 @@ data class CatalogUiState(
|
|||
val canLoadMore: Boolean
|
||||
get() = nextSkip != null
|
||||
}
|
||||
|
||||
data class CatalogScrollPosition(
|
||||
val firstVisibleItemIndex: Int = 0,
|
||||
val firstVisibleItemScrollOffset: Int = 0,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ object CatalogRepository {
|
|||
|
||||
private var activeJob: Job? = null
|
||||
private var activeRequest: CatalogRequest? = null
|
||||
private val scrollPositions = linkedMapOf<CatalogRequest, CatalogScrollPosition>()
|
||||
|
||||
fun load(
|
||||
manifestUrl: String,
|
||||
|
|
@ -34,7 +35,7 @@ object CatalogRepository {
|
|||
supportsPagination: Boolean = false,
|
||||
force: Boolean = false,
|
||||
) {
|
||||
val request = CatalogRequest(
|
||||
val request = catalogRequest(
|
||||
manifestUrl = manifestUrl,
|
||||
type = type,
|
||||
catalogId = catalogId,
|
||||
|
|
@ -62,9 +63,36 @@ object CatalogRepository {
|
|||
fun clear() {
|
||||
activeJob?.cancel()
|
||||
activeRequest = null
|
||||
scrollPositions.clear()
|
||||
_uiState.value = CatalogUiState()
|
||||
}
|
||||
|
||||
fun scrollPosition(
|
||||
manifestUrl: String,
|
||||
type: String,
|
||||
catalogId: String,
|
||||
genre: String? = null,
|
||||
supportsPagination: Boolean = false,
|
||||
): CatalogScrollPosition =
|
||||
scrollPositions[catalogRequest(manifestUrl, type, catalogId, genre, supportsPagination)]
|
||||
?: CatalogScrollPosition()
|
||||
|
||||
fun saveScrollPosition(
|
||||
manifestUrl: String,
|
||||
type: String,
|
||||
catalogId: String,
|
||||
genre: String? = null,
|
||||
supportsPagination: Boolean = false,
|
||||
firstVisibleItemIndex: Int,
|
||||
firstVisibleItemScrollOffset: Int,
|
||||
) {
|
||||
val request = catalogRequest(manifestUrl, type, catalogId, genre, supportsPagination)
|
||||
scrollPositions[request] = CatalogScrollPosition(
|
||||
firstVisibleItemIndex = firstVisibleItemIndex,
|
||||
firstVisibleItemScrollOffset = firstVisibleItemScrollOffset,
|
||||
)
|
||||
}
|
||||
|
||||
private fun fetchInternalLibrary(request: CatalogRequest) {
|
||||
activeJob?.cancel()
|
||||
_uiState.value = _uiState.value.copy(
|
||||
|
|
@ -127,7 +155,7 @@ object CatalogRepository {
|
|||
catalogId = request.catalogId,
|
||||
genre = request.genre,
|
||||
skip = requestedSkip.takeIf { it > 0 },
|
||||
).withUnreleasedFilter()
|
||||
).withUnreleasedFilter(request.hideUnreleasedContent)
|
||||
}.fold(
|
||||
onSuccess = { page ->
|
||||
if (activeRequest != request) return@fold
|
||||
|
|
@ -159,10 +187,26 @@ object CatalogRepository {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun catalogRequest(
|
||||
manifestUrl: String,
|
||||
type: String,
|
||||
catalogId: String,
|
||||
genre: String? = null,
|
||||
supportsPagination: Boolean = false,
|
||||
): CatalogRequest =
|
||||
CatalogRequest(
|
||||
manifestUrl = manifestUrl,
|
||||
type = type,
|
||||
catalogId = catalogId,
|
||||
genre = genre,
|
||||
supportsPagination = supportsPagination,
|
||||
hideUnreleasedContent = HomeCatalogSettingsRepository.snapshot().hideUnreleasedContent,
|
||||
)
|
||||
}
|
||||
|
||||
private fun CatalogPage.withUnreleasedFilter(): CatalogPage {
|
||||
if (!HomeCatalogSettingsRepository.snapshot().hideUnreleasedContent) return this
|
||||
private fun CatalogPage.withUnreleasedFilter(hideUnreleasedContent: Boolean): CatalogPage {
|
||||
if (!hideUnreleasedContent) return this
|
||||
val filteredItems = items.filterReleasedItems(CurrentDateProvider.todayIsoDate())
|
||||
return if (filteredItems.size == items.size) this else copy(items = filteredItems)
|
||||
}
|
||||
|
|
@ -173,4 +217,5 @@ private data class CatalogRequest(
|
|||
val catalogId: String,
|
||||
val genre: String?,
|
||||
val supportsPagination: Boolean,
|
||||
val hideUnreleasedContent: Boolean,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -86,7 +86,26 @@ fun CatalogScreen(
|
|||
WatchedRepository.ensureLoaded()
|
||||
WatchedRepository.uiState
|
||||
}.collectAsStateWithLifecycle()
|
||||
val gridState = rememberLazyGridState()
|
||||
val initialScrollPosition = remember(
|
||||
manifestUrl,
|
||||
type,
|
||||
catalogId,
|
||||
genre,
|
||||
supportsPagination,
|
||||
homeCatalogSettingsUiState.hideUnreleasedContent,
|
||||
) {
|
||||
CatalogRepository.scrollPosition(
|
||||
manifestUrl = manifestUrl,
|
||||
type = type,
|
||||
catalogId = catalogId,
|
||||
genre = genre,
|
||||
supportsPagination = supportsPagination,
|
||||
)
|
||||
}
|
||||
val gridState = rememberLazyGridState(
|
||||
initialFirstVisibleItemIndex = initialScrollPosition.firstVisibleItemIndex,
|
||||
initialFirstVisibleItemScrollOffset = initialScrollPosition.firstVisibleItemScrollOffset,
|
||||
)
|
||||
var headerHeightPx by remember { mutableIntStateOf(0) }
|
||||
var observedOfflineState by remember { mutableStateOf(false) }
|
||||
|
||||
|
|
@ -97,10 +116,25 @@ fun CatalogScreen(
|
|||
catalogId = catalogId,
|
||||
genre = genre,
|
||||
supportsPagination = supportsPagination,
|
||||
force = true,
|
||||
)
|
||||
}
|
||||
|
||||
LaunchedEffect(gridState, manifestUrl, type, catalogId, genre, supportsPagination, homeCatalogSettingsUiState.hideUnreleasedContent) {
|
||||
snapshotFlow { gridState.firstVisibleItemIndex to gridState.firstVisibleItemScrollOffset }
|
||||
.distinctUntilChanged()
|
||||
.collect { (index, offset) ->
|
||||
CatalogRepository.saveScrollPosition(
|
||||
manifestUrl = manifestUrl,
|
||||
type = type,
|
||||
catalogId = catalogId,
|
||||
genre = genre,
|
||||
supportsPagination = supportsPagination,
|
||||
firstVisibleItemIndex = index,
|
||||
firstVisibleItemScrollOffset = offset,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(gridState, uiState.canLoadMore, uiState.isLoading) {
|
||||
snapshotFlow { gridState.layoutInfo }
|
||||
.map { layoutInfo ->
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ internal actual fun CollectionCardRemoteImage(
|
|||
|
||||
UIKitView(
|
||||
modifier = modifier,
|
||||
interactive = false,
|
||||
factory = {
|
||||
UIImageView().apply {
|
||||
contentMode = UIViewContentMode.UIViewContentModeScaleAspectFill
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ androidx-appcompat = "1.7.1"
|
|||
androidx-core = "1.17.0"
|
||||
androidx-core-splashscreen = "1.0.1"
|
||||
androidx-espresso = "3.7.0"
|
||||
androidx-lifecycle = "2.11.0-alpha03"
|
||||
androidx-lifecycle = "2.11.0-beta01"
|
||||
androidx-work = "2.10.3"
|
||||
androidx-testExt = "1.3.0"
|
||||
composeMultiplatform = "1.11.0-beta03"
|
||||
composeMultiplatform = "1.11.1"
|
||||
coil = "3.5.0-beta01"
|
||||
kermit = "2.0.5"
|
||||
junit = "4.13.2"
|
||||
|
|
|
|||
Loading…
Reference in a new issue