From 41e3a19cd429f291ec4793d28706641b97fa4e7d Mon Sep 17 00:00:00 2001 From: Damontecres Date: Thu, 2 Oct 2025 16:45:49 -0400 Subject: [PATCH] Use ApiRequestPager --- .../damontecres/dolphin/ui/detail/CardGrid.kt | 3 +- .../ui/detail/CollectionFolderDetails.kt | 10 +- .../dolphin/ui/detail/SeasonDetails.kt | 11 +- .../dolphin/ui/detail/SeriesDetails.kt | 16 +- .../damontecres/dolphin/util/ItemPager.kt | 142 ------------------ 5 files changed, 25 insertions(+), 157 deletions(-) delete mode 100644 app/src/main/java/com/github/damontecres/dolphin/util/ItemPager.kt diff --git a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CardGrid.kt b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CardGrid.kt index 43772834..8547bbba 100644 --- a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CardGrid.kt +++ b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CardGrid.kt @@ -52,7 +52,6 @@ import com.github.damontecres.dolphin.ui.playback.isForwardButton import com.github.damontecres.dolphin.ui.playback.isPlayKeyUp import com.github.damontecres.dolphin.ui.tryRequestFocus import com.github.damontecres.dolphin.util.ExceptionHandler -import com.github.damontecres.dolphin.util.ItemPager import kotlinx.coroutines.launch import timber.log.Timber import kotlin.math.max @@ -61,7 +60,7 @@ private const val DEBUG = false @Composable fun CardGrid( - pager: ItemPager, + pager: List, itemOnClick: (BaseItem) -> Unit, longClicker: (BaseItem) -> Unit, letterPosition: suspend (Char) -> Int, diff --git a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CollectionFolderDetails.kt b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CollectionFolderDetails.kt index bfeedede..ebdf223e 100644 --- a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CollectionFolderDetails.kt +++ b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/CollectionFolderDetails.kt @@ -16,8 +16,9 @@ import com.github.damontecres.dolphin.preferences.UserPreferences import com.github.damontecres.dolphin.ui.OneTimeLaunchedEffect import com.github.damontecres.dolphin.ui.nav.Destination import com.github.damontecres.dolphin.ui.nav.NavigationManager +import com.github.damontecres.dolphin.util.ApiRequestPager import com.github.damontecres.dolphin.util.ExceptionHandler -import com.github.damontecres.dolphin.util.ItemPager +import com.github.damontecres.dolphin.util.GetItemsRequestHandler import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.launch @@ -38,7 +39,7 @@ class CollectionFolderViewModel constructor( api: ApiClient, ) : ItemViewModel(api) { - val pager = MutableLiveData() + val pager = MutableLiveData?>() override fun init( itemId: UUID, @@ -81,7 +82,8 @@ class CollectionFolderViewModel sortOrder = listOf(SortOrder.ASCENDING), fields = listOf(ItemFields.PRIMARY_IMAGE_ASPECT_RATIO), ) - val newPager = ItemPager(api, request, viewModelScope) + val newPager = + ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope) newPager.init() pager.value = newPager } @@ -162,7 +164,7 @@ fun TVShowCollectionDetails( navigationManager: NavigationManager, library: Library, item: BaseItem, - pager: ItemPager, + pager: List, modifier: Modifier = Modifier, ) { val gridFocusRequester = remember { FocusRequester() } diff --git a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeasonDetails.kt b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeasonDetails.kt index b65623c3..8587e490 100644 --- a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeasonDetails.kt +++ b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeasonDetails.kt @@ -21,8 +21,9 @@ import com.github.damontecres.dolphin.preferences.UserPreferences import com.github.damontecres.dolphin.ui.cards.ItemRow import com.github.damontecres.dolphin.ui.nav.Destination import com.github.damontecres.dolphin.ui.nav.NavigationManager +import com.github.damontecres.dolphin.util.ApiRequestPager import com.github.damontecres.dolphin.util.ExceptionHandler -import com.github.damontecres.dolphin.util.ItemPager +import com.github.damontecres.dolphin.util.GetItemsRequestHandler import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.launch @@ -60,7 +61,13 @@ class SeasonViewModel fields = listOf(ItemFields.PRIMARY_IMAGE_ASPECT_RATIO, ItemFields.CHILD_COUNT), ) val pager = - ItemPager(api, request, viewModelScope, itemCount = item.data.childCount) + ApiRequestPager( + api, + request, + GetItemsRequestHandler, + viewModelScope, + itemCount = item.data.childCount, + ) pager.init() episodes.value = pager } diff --git a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt index 509dd65d..5867a6f8 100644 --- a/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt +++ b/app/src/main/java/com/github/damontecres/dolphin/ui/detail/SeriesDetails.kt @@ -15,13 +15,12 @@ import com.github.damontecres.dolphin.data.model.BaseItem import com.github.damontecres.dolphin.data.model.Video import com.github.damontecres.dolphin.preferences.UserPreferences import com.github.damontecres.dolphin.ui.cards.ItemRow -import com.github.damontecres.dolphin.ui.indexOfFirstOrNull import com.github.damontecres.dolphin.ui.nav.Destination import com.github.damontecres.dolphin.ui.nav.NavigationManager import com.github.damontecres.dolphin.util.ApiRequestPager import com.github.damontecres.dolphin.util.ExceptionHandler import com.github.damontecres.dolphin.util.GetEpisodesRequestHandler -import com.github.damontecres.dolphin.util.ItemPager +import com.github.damontecres.dolphin.util.GetItemsRequestHandler import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Deferred import kotlinx.coroutines.Job @@ -71,7 +70,13 @@ class SeriesViewModel ), ) val pager = - ItemPager(api, request, viewModelScope, itemCount = item.data.childCount) + ApiRequestPager( + api, + request, + GetItemsRequestHandler, + viewModelScope, + itemCount = item.data.childCount, + ) pager.init() seasons.value = pager Timber.v("Loaded ${pager.size} seasons for series ${item.id}") @@ -94,10 +99,7 @@ class SeriesViewModel viewModelScope.launch(ExceptionHandler()) { init(itemId, potential).join() season?.let { seasonNum -> - val targetSeasonPosition = - (seasons.value!! as ItemPager) - .toBlockingList() - .indexOfFirstOrNull { it.indexNumber == seasonNum } + // TODO map season number to index in list loadEpisodes(seasonNum) } } diff --git a/app/src/main/java/com/github/damontecres/dolphin/util/ItemPager.kt b/app/src/main/java/com/github/damontecres/dolphin/util/ItemPager.kt deleted file mode 100644 index d999155d..00000000 --- a/app/src/main/java/com/github/damontecres/dolphin/util/ItemPager.kt +++ /dev/null @@ -1,142 +0,0 @@ -package com.github.damontecres.dolphin.util - -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import com.github.damontecres.dolphin.data.model.BaseItem -import com.github.damontecres.dolphin.ui.DEFAULT_PAGE_SIZE -import com.google.common.cache.CacheBuilder -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import org.jellyfin.sdk.api.client.ApiClient -import org.jellyfin.sdk.api.client.extensions.itemsApi -import org.jellyfin.sdk.model.api.request.GetItemsRequest -import timber.log.Timber - -class ItemPager( - val api: ApiClient, - val request: GetItemsRequest, - private val scope: CoroutineScope, - private val pageSize: Int = DEFAULT_PAGE_SIZE, - itemCount: Int? = null, - cacheSize: Long = 8, -) : AbstractList() { - private var items by mutableStateOf(ItemList(0, pageSize, mapOf())) - private var totalCount by mutableIntStateOf(itemCount ?: -1) - private val mutex = Mutex() - private val cachedPages = - CacheBuilder - .newBuilder() - .maximumSize(cacheSize) - .build>() - - suspend fun init() { - if (totalCount < 0) { - val result = - api.itemsApi - .getItems( - request.copy( - startIndex = 0, - limit = 1, - enableTotalRecordCount = true, - ), - ).content - totalCount = result.totalRecordCount - } - } - - override operator fun get(index: Int): BaseItem? { - if (index in 0.. { - init() - return object : AbstractList() { - override val size: Int - get() = totalCount - - override fun get(index: Int): BaseItem = runBlocking { getBlocking(index)!! } - } - } - - companion object { - private const val DEBUG = false - } - - class ItemList( - val size: Int, - val pageSize: Int, - val pages: Map>, - ) { - operator fun get(position: Int): T? { - val page = position / pageSize - val data = pages[page] - if (data != null) { - val index = position % pageSize - if (index in data.indices) { - return data[index] - } else { - // This can happen when items are removed while scrolling - Timber.w( - "Index $index not in data: position=$position, data.size=${data.size}", - ) - return null - } - } else { - return null - } - } - } -}