mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-11-06 02:40:58 +01:00
Fix alphabet highlight for names starting with "The " (#1788)
## Description The alphabet scroll bar highlighted the letter of an item's *display* name while the grid sorted by the server's article-stripped `SortName`, so "The Beatles" sat under **B** but highlighted **T**. - **Artists:** the Artists tab never requested `SortName`, so the highlight silently fell back to `Name`. It now asks for `SlimItemFields` (which already includes `SORT_NAME`), matching the sibling `/Items` branch. The count-only query used for letter positions passes `fields = null`, since a `limit = 0` request has no use for them. - **Genres and studios:** these grids bucketed on the display name unconditionally. The sort-name fallback is extracted as `BaseItemDto.alphabetSortName` (`sortName ?: name ?: ""`) and carried onto the `Genre` and `Studio` grid items, so all three grids now derive the letter from one value. ### Related issues https://github.com/damontecres/Wholphin/issues/1787 ### Testing Two unit tests added: - `CollectionFolderViewModelTest` pins that the artist pager actually requests `SORT_NAME` — the field whose absence caused the bug. - `AlphabetSortNameTest` covers both branches of the `alphabetSortName` fallback. Manually: select a music library → Artists tab → put the cursor on an artist starting with "The " and confirm the highlighted letter matches the grid position. Same check on the genre and studio grids. ## AI or LLM usage I used Cursor for debugging and implementing the fix, and Claude Code for a follow-up cleanup pass over the diff.
This commit is contained in:
parent
454c0212b6
commit
a0966dd05a
6 changed files with 73 additions and 5 deletions
|
|
@ -54,7 +54,7 @@ data class BaseItem(
|
|||
get() = type.playable
|
||||
|
||||
override val sortName: String
|
||||
get() = data.sortName ?: data.name ?: ""
|
||||
get() = data.alphabetSortName
|
||||
|
||||
val type get() = data.type
|
||||
|
||||
|
|
@ -305,6 +305,9 @@ data class BaseItem(
|
|||
|
||||
val BaseItemDto.aspectRatioFloat: Float? get() = width?.let { w -> height?.let { h -> w.toFloat() / h.toFloat() } }
|
||||
|
||||
/** The server strips leading articles (eg "The ") from [BaseItemDto.sortName]. */
|
||||
val BaseItemDto.alphabetSortName: String get() = sortName ?: name ?: ""
|
||||
|
||||
@Immutable
|
||||
data class BaseItemUi(
|
||||
val episodeCornerText: String?,
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ class CollectionFolderViewModel
|
|||
GetArtistsRequest(
|
||||
parentId = item?.id,
|
||||
enableImageTypes = listOf(ImageType.PRIMARY, ImageType.THUMB),
|
||||
fields = SlimItemFields,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -477,6 +478,7 @@ class CollectionFolderViewModel
|
|||
GetArtistsHandler.countMatching(
|
||||
createGetArtistsRequest(filter).copy(
|
||||
enableImageTypes = null,
|
||||
fields = null,
|
||||
nameLessThan = letter.toString(),
|
||||
limit = 0,
|
||||
enableTotalRecordCount = true,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.damontecres.wholphin.data.ServerRepository
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.data.model.alphabetSortName
|
||||
import com.github.damontecres.wholphin.data.model.createGenreDestination
|
||||
import com.github.damontecres.wholphin.services.ImageUrlService
|
||||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
|
|
@ -104,7 +105,12 @@ class GenreViewModel
|
|||
.execute(api, request)
|
||||
.content.items
|
||||
.map {
|
||||
Genre(it.id, it.name ?: "", null)
|
||||
Genre(
|
||||
id = it.id,
|
||||
name = it.name ?: "",
|
||||
imageUrl = null,
|
||||
sortName = it.alphabetSortName,
|
||||
)
|
||||
}
|
||||
_state.update {
|
||||
it.copy(
|
||||
|
|
@ -243,10 +249,10 @@ data class Genre(
|
|||
val id: UUID,
|
||||
val name: String,
|
||||
val imageUrl: String?,
|
||||
override val sortName: String = name,
|
||||
) : CardGridItem {
|
||||
override val gridId: String get() = id.toString()
|
||||
override val playable: Boolean = false
|
||||
override val sortName: String get() = name
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.damontecres.wholphin.data.ServerRepository
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.data.model.alphabetSortName
|
||||
import com.github.damontecres.wholphin.data.model.createStudioDestination
|
||||
import com.github.damontecres.wholphin.services.ImageUrlService
|
||||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
|
|
@ -97,7 +98,12 @@ class StudioViewModel
|
|||
imageType = ImageType.THUMB,
|
||||
fillWidth = cardWidthPx,
|
||||
)
|
||||
Studio(it.id, it.name ?: "", imageUrl)
|
||||
Studio(
|
||||
id = it.id,
|
||||
name = it.name ?: "",
|
||||
imageUrl = imageUrl,
|
||||
sortName = it.alphabetSortName,
|
||||
)
|
||||
}
|
||||
_state.update {
|
||||
it.copy(
|
||||
|
|
@ -133,10 +139,10 @@ data class Studio(
|
|||
val id: UUID,
|
||||
val name: String,
|
||||
val imageUrl: String?,
|
||||
override val sortName: String = name,
|
||||
) : CardGridItem {
|
||||
override val gridId: String get() = id.toString()
|
||||
override val playable: Boolean = false
|
||||
override val sortName: String get() = name
|
||||
}
|
||||
|
||||
data class StudioGridState(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue