From a14fdac85232b3f4a5f2e8b319461f02031fdf65 Mon Sep 17 00:00:00 2001 From: Ray <154766448+damontecres@users.noreply.github.com> Date: Tue, 24 Feb 2026 12:37:21 -0500 Subject: [PATCH] A few more home page fixes (#967) ## Description A few more home page fixes * Focus issue between settings & preset buttons * Fix default genre card size for "Wholphin Default" preset * Cache genre image urls for 2 hours so that they don't change on every refresh ### Related issues Related to #399 ### Testing Emulator ## Screenshots N/A ## AI or LLM usage None --- .../wholphin/services/HomeSettingsService.kt | 3 +++ .../wholphin/ui/components/GenreCardGrid.kt | 26 +++++++++++++++++++ .../wholphin/ui/main/HomeViewModel.kt | 3 +++ .../ui/main/settings/HomeRowPresets.kt | 3 +-- .../ui/main/settings/HomeSettingsRowList.kt | 2 +- .../ui/main/settings/HomeSettingsViewModel.kt | 1 + 6 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt index 2fe5a6cc..b8a850ef 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt @@ -569,6 +569,7 @@ class HomeSettingsService userDto: UserDto, libraries: List, limit: Int = prefs.maxItemsPerRow, + isRefresh: Boolean, ): HomeRowLoadingState = when (row) { is HomeRowConfig.ContinueWatching -> { @@ -649,12 +650,14 @@ class HomeSettingsService val genreImages = getGenreImageMap( api = api, + userId = serverRepository.currentUser.value?.id, scope = scope, imageUrlService = imageUrlService, genres = genreIds, parentId = row.parentId, includeItemTypes = null, cardWidthPx = null, + useCache = isRefresh, ) val library = libraries diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt index e64f1824..e1e28f0c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt @@ -35,6 +35,7 @@ import com.github.damontecres.wholphin.util.GetGenresRequestHandler import com.github.damontecres.wholphin.util.GetItemsRequestHandler import com.github.damontecres.wholphin.util.LoadingExceptionHandler import com.github.damontecres.wholphin.util.LoadingState +import com.mayakapps.kache.InMemoryKache import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -55,8 +56,10 @@ import org.jellyfin.sdk.model.api.ItemFields import org.jellyfin.sdk.model.api.ItemSortBy import org.jellyfin.sdk.model.api.request.GetGenresRequest import org.jellyfin.sdk.model.api.request.GetItemsRequest +import timber.log.Timber import java.util.UUID import java.util.concurrent.ConcurrentHashMap +import kotlin.time.Duration.Companion.hours @HiltViewModel(assistedFactory = GenreViewModel.Factory::class) class GenreViewModel @@ -110,6 +113,7 @@ class GenreViewModel val genreToUrl = getGenreImageMap( api = api, + userId = serverRepository.currentUser.value?.id, scope = viewModelScope, imageUrlService = imageUrlService, genres = genres.map { it.id }, @@ -141,15 +145,35 @@ class GenreViewModel } } +data class GenreCacheKey( + val userId: UUID?, + val parentId: UUID, +) + +private val genreCache by lazy { + InMemoryKache>(8) { + expireAfterWriteDuration = 2.hours + } +} + suspend fun getGenreImageMap( api: ApiClient, + userId: UUID?, scope: CoroutineScope, imageUrlService: ImageUrlService, genres: List, parentId: UUID, includeItemTypes: List?, cardWidthPx: Int?, + useCache: Boolean = true, ): Map { + val key = GenreCacheKey(userId, parentId) + if (useCache) { + genreCache.getIfAvailable(key)?.let { + Timber.v("Got cached entry") + return it + } + } val genreToUrl = ConcurrentHashMap() val semaphore = Semaphore(4) genres @@ -161,6 +185,7 @@ suspend fun getGenreImageMap( .execute( api, GetItemsRequest( + userId = userId, parentId = parentId, recursive = true, limit = 1, @@ -189,6 +214,7 @@ suspend fun getGenreImageMap( } } }.awaitAll() + genreCache.put(key, genreToUrl) return genreToUrl } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt index 4471194e..a8ce7fd9 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt @@ -78,6 +78,8 @@ class HomeViewModel // Refreshing if a load has already occurred and the rows haven't significantly changed val refresh = state.loadingState == LoadingState.Success && state.settings == settings + Timber.v("refresh=$refresh, state.loadingState=${state.loadingState}") + _state.update { it.copy(settings = settings) } val semaphore = Semaphore(4) @@ -102,6 +104,7 @@ class HomeViewModel userDto = userDto, libraries = libraries, limit = prefs.maxItemsPerRow, + isRefresh = refresh, ) } catch (ex: Exception) { Timber.e(ex, "Error on row %s", row) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowPresets.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowPresets.kt index 815c343a..eaf44d81 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowPresets.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowPresets.kt @@ -19,7 +19,6 @@ import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.data.model.HomeRowViewOptions import com.github.damontecres.wholphin.preferences.PrefContentScale import com.github.damontecres.wholphin.ui.AspectRatio -import com.github.damontecres.wholphin.ui.Cards import com.github.damontecres.wholphin.ui.components.ViewOptionImageType import com.github.damontecres.wholphin.ui.tryRequestFocus import org.jellyfin.sdk.model.api.CollectionType @@ -81,7 +80,7 @@ data class HomeRowPresets( contentScale = PrefContentScale.FIT, ), liveTv = HomeRowViewOptions.liveTvDefault, - genreSize = Cards.HEIGHT_2X3_DP, + genreSize = HomeRowViewOptions.genreDefault.heightDp, ) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt index 5a0ac965..9eadc615 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt @@ -137,7 +137,7 @@ fun HomeSettingsRowList( position = 2 onClickPresets.invoke() }, - modifier = Modifier.focusRequester(focusRequesters[1]), + modifier = Modifier.focusRequester(focusRequesters[2]), ) } item { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt index 9110af12..67b57e28 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt @@ -133,6 +133,7 @@ class HomeSettingsViewModel userDto = userDto, libraries = state.libraries, limit = limit, + isRefresh = false, ) } }