Inherit parent view options and sort for sub-folders (#2045)

## Description

This change applies only to subfolders that do not have their own saved
display settings.

When a subfolder has no saved settings, it now inherits the view type
and sort order from the closest ancestor with saved settings. Filter
settings are not inherited.

If the user changes the settings within a subfolder, those settings are
saved for that subfolder and take precedence over the inherited
settings.

### Related issues

Fixes #1768

### Testing

Tested an App Store flavor debug build on the following setup:

- Device: Xiaomi TV A Pro 43
- Jellyfin server version: 12.1
- Library: A hierarchical recording library stored on a NAS

I changed the view type and sort order at the top level of the library
and confirmed that both settings were inherited by untouched subfolders.

## Screenshots

N/A - no UI changes

## AI or LLM usage

Claude was used to write the changes in `CollectionFolderView.kt`.

I performed the testing on a physical Google TV device and verified the
behavior described above.

The commit also includes a `Co-Authored-By: Claude` trailer.

This description was written in Japanese and translated with an LLM.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mizuka123 2026-10-16 23:32:12 +09:00 • committed by GitHub
parent 9f557416ea
commit 55960c2462
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -89,6 +89,7 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.libraryApi
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
@ -168,15 +169,25 @@ class CollectionFolderViewModel
val id = collectionFilter.libraryDisplayInfoIdOverride ?: itemId
libraryDisplayInfoDao.getItem(user, id)
}
val ancestorDisplayInfo =
if (libraryDisplayInfo?.viewOptions == null && item != null) {
getAncestorDisplayInfo(item)
} else {
null
}
_state.update {
it.copy(
viewOptions = libraryDisplayInfo?.viewOptions ?: defaultViewOptions,
viewOptions =
libraryDisplayInfo?.viewOptions
?: ancestorDisplayInfo?.viewOptions
?: defaultViewOptions,
)
}
val sortAndDirection =
if (collectionFilter.useSavedLibraryDisplayInfo) {
libraryDisplayInfo?.sortAndDirection
?: ancestorDisplayInfo?.sortAndDirection
} else {
null
} ?: initialSortAndDirection ?: SortAndDirection.DEFAULT
@ -232,6 +243,25 @@ class CollectionFolderViewModel
}
}
/**
* For a sub-folder, returns the saved display info of the closest ancestor that has one
*/
private suspend fun getAncestorDisplayInfo(item: BaseItem): LibraryDisplayInfo? {
if (item.type != BaseItemKind.FOLDER || collectionFilter.libraryDisplayInfoIdOverride != null) {
return null
}
val user = serverRepository.currentUser ?: return null
return try {
api.libraryApi
.getAncestors(item.id, user.id)
.content
.firstNotNullOfOrNull { ancestor -> libraryDisplayInfoDao.getItem(user, ancestor.id) }
} catch (ex: Exception) {
Timber.w(ex, "Error getting ancestors for %s", item.id)
null
}
}
private fun saveLibraryDisplayInfo(
newFilter: GetItemsFilter = state.value.filter,
newSort: SortAndDirection = state.value.sortAndDirection,