Fix the alphabet buttons scroll bar on the Artists tab (#1775)
## Description positionOfLetter counted through /Items no matter which endpoint the grid was actually paging. A music library's Artists tab pages /Artists, so the index it returned had counted every album and song before the letter - an order of magnitude more rows than the artist grid holds - and every letter jumped to the last row. Count through the same endpoint createPager builds its pager from: /Artists for the ARTIST override, /Items for NONE. The artist request is now built once in createGetArtistsRequest and shared by both, so the two cannot drift apart. GetPersonsRequest has neither nameLessThan nor startIndex, so /Persons cannot be counted up to a letter at all; the PERSON override returns null, which the call sites already map to the "no jump" sentinel. That path is unreachable today - the only PERSON tab sorts by ItemSortBy.DEFAULT, so showLetterButtons is never true there and AlphabetButtons is never composed. ### Related issues https://github.com/damontecres/Wholphin/issues/1774 ### Testing Select a music library -> Go to Artist tab -> Select a letter on the right side alphabet scroll bar ## AI or LLM usage I used Cursor and Claude Code for planning, implementation and code review. --------- Co-authored-by: Damontecres <damontecres@gmail.com>
This commit is contained in:
parent
6ad96865e7
commit
d7d63f52c3
3 changed files with 259 additions and 33 deletions
|
|
@ -71,6 +71,7 @@ import com.github.damontecres.wholphin.util.GetArtistsHandler
|
|||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.GetPersonsHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.RequestHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.github.damontecres.wholphin.util.successValue
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -378,26 +379,30 @@ class CollectionFolderViewModel
|
|||
}
|
||||
|
||||
GetItemsFilterOverride.ARTIST -> {
|
||||
val item = state.value.item.successValue
|
||||
val request =
|
||||
filter.applyTo(
|
||||
GetArtistsRequest(
|
||||
parentId = item?.id,
|
||||
enableImageTypes = listOf(ImageType.PRIMARY, ImageType.THUMB),
|
||||
),
|
||||
)
|
||||
val newPager =
|
||||
ApiRequestPager(
|
||||
api,
|
||||
request,
|
||||
GetArtistsHandler,
|
||||
viewModelScope,
|
||||
useSeriesForPrimary = useSeriesForPrimary,
|
||||
)
|
||||
newPager
|
||||
ApiRequestPager(
|
||||
api,
|
||||
createGetArtistsRequest(filter),
|
||||
GetArtistsHandler,
|
||||
viewModelScope,
|
||||
useSeriesForPrimary = useSeriesForPrimary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared with [positionOfLetter] so that the alphabet jump counts the same artists that are
|
||||
* actually paged through
|
||||
*/
|
||||
private fun createGetArtistsRequest(filter: GetItemsFilter): GetArtistsRequest {
|
||||
val item = state.value.item.successValue
|
||||
return filter.applyTo(
|
||||
GetArtistsRequest(
|
||||
parentId = item?.id,
|
||||
enableImageTypes = listOf(ImageType.PRIMARY, ImageType.THUMB),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createGetItemsRequest(
|
||||
sortAndDirection: SortAndDirection,
|
||||
recursive: Boolean,
|
||||
|
|
@ -460,26 +465,57 @@ class CollectionFolderViewModel
|
|||
filterOption,
|
||||
)
|
||||
|
||||
/**
|
||||
* The count must come from the same endpoint that [createPager] pages through, otherwise
|
||||
* the index refers to a different result set and lands past the end of the list.
|
||||
*/
|
||||
suspend fun positionOfLetter(letter: Char): Int? =
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
val sort = state.value.sortAndDirection
|
||||
val filter = state.value.filter
|
||||
val request =
|
||||
createGetItemsRequest(
|
||||
sortAndDirection = sort,
|
||||
recursive = recursive,
|
||||
filter = filter,
|
||||
).copy(
|
||||
enableImageTypes = null,
|
||||
fields = null,
|
||||
nameLessThan = letter.toString(),
|
||||
limit = 0,
|
||||
enableTotalRecordCount = true,
|
||||
)
|
||||
val result by GetItemsRequestHandler.execute(api, request)
|
||||
result.totalRecordCount
|
||||
when (filter.override) {
|
||||
GetItemsFilterOverride.ARTIST -> {
|
||||
GetArtistsHandler.countMatching(
|
||||
createGetArtistsRequest(filter).copy(
|
||||
enableImageTypes = null,
|
||||
nameLessThan = letter.toString(),
|
||||
limit = 0,
|
||||
enableTotalRecordCount = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// GetPersonsRequest has no nameLessThan or startIndex, so /Persons cannot be
|
||||
// counted up to a letter at all
|
||||
GetItemsFilterOverride.PERSON -> {
|
||||
null
|
||||
}
|
||||
|
||||
GetItemsFilterOverride.NONE -> {
|
||||
GetItemsRequestHandler.countMatching(
|
||||
createGetItemsRequest(
|
||||
sortAndDirection = state.value.sortAndDirection,
|
||||
recursive = recursive,
|
||||
filter = filter,
|
||||
).copy(
|
||||
enableImageTypes = null,
|
||||
fields = null,
|
||||
nameLessThan = letter.toString(),
|
||||
limit = 0,
|
||||
enableTotalRecordCount = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [request] must ask for the count, ie `limit = 0` and `enableTotalRecordCount = true`
|
||||
*/
|
||||
private suspend fun <T> RequestHandler<T>.countMatching(request: T): Int {
|
||||
val result by execute(api, request)
|
||||
return result.totalRecordCount
|
||||
}
|
||||
|
||||
override fun setWatched(
|
||||
position: Int,
|
||||
itemId: UUID,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue