## Description
Fixes requesting additional seasons of a show if a previous request has
already been approved
Now if the previous request is already approved/completed/etc, a new
request will be created instead of trying to update the previous one.
Pending requests will still be updated as before instead of requesting a
new one.
### Related issues
Fixes#1702
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
Fixes an edge case where clicking on an episode to go to Series Overview
wouldn't scroll to the episode if there is a special (season 0) episodes
in the episode list.
Dev note: to simplify things, if the entire dataset is cached, then just
search with `indexOf`. Often the data is cached because 20 seasons or
100 episodes are fetched initially which covers many shows.
### Related issues
Follow up to #1708
### Testing
Emulator and unit tests
## Screenshots
N/A
## AI or LLM usage
None
## Description
Ensure that a playlist or collection's items are random sorted on the
home page, if applicable.
Previously, the request did sort by random then by sort name resulting
in only sorting by sort name.
However, there are still issues with random sorting in general, see
#1819
### Related issues
Technically fixes#1806
Further bugs in #1819
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
By default, Wholphin plays music with hardware audio offloading enabled.
This delegates audio decoding to the device's hardware DSP, making
playback stability highly dependent on the manufacturer's system audio
implementation. On certain hardware (such as my TCL TVs, e.g., the
Chinese Model Q9L Pro), this implementation causes music playback to
hang indefinitely at 0 seconds.
### Related issues
#1372
### Testing
Tested on a TCL TV (Q9L Pro):
- Some musics playback hangs at 0s with offloading enabled.
- Disabling audio offloading fixes the issues for all medias.
## Screenshots
<!-- Please include screenshots if the PR alters any UI elements -->
<img width="4284" height="5712" alt="IMG_9486"
src="https://github.com/user-attachments/assets/ddf95e68-6ebd-42f9-9565-568de4fbfc42"
/>
## AI or LLM usage
Developed in pair with Gemini and human-reviewed, tested.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
This PR has updates the Now Playing page.
Now only the song's backdrops and the song's artists' backdrops will
show. First, if the song has any backdrops (probably pretty uncommon),
they will be shuffled and shown, then if the song's artists have
backdrop, those are shuffled and shown. The backdrop changes every 2
minutes unless there's <15s left in the song to prevent rapid changes.
Note: album backdrops and album artists not directly linked to the
specific song are not included.
If a song has a lyrics and the user is scrolling through them, if the
user doesn't scroll for 5 seconds, the focus leaves the lyrics and they
scroll to the current line if available.
Dev note: Both backdrop & lyric updates are refactored to use `Flow`s to
trigger lookups
### Related issues
Fixes#1170
### Testing
Emulator, I need to test it longer term
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds an optional boolean parameter `shuffle` that is read for the
playback intent. When true, it will cause the resulting media to be
shuffled if applicable.
Something can be shuffled if the `itemId` is a grouping on media such as
a playlist, series, season, or even library.
### Related issues
Depends on #1756
### Testing
Emulator with the documented command
## Screenshots
N/A
## AI or LLM usage
None
## Description
When testing the new deep link feature from this PR
[#1688](https://github.com/damontecres/Wholphin/pull/1688)
I noticed that the back button would close the app. As in, all routes
are cleared and only the playback is in the nav stack.
I figured a more desirable behavior would be to create a nav stack,
always starting with the home screen, then also inserting the media
item's details page, if available.
To achieve this, I made the return Target.destinations a list of
destinations, and updated the other two uses in IntentService.
Open to implementation tweaks, or scrap it if this isn't how it should
work, haha.
### Testing
Tested deep links, which produced the following nav stacks:
- Movie view
- Home → Movie details
- Movie playback (with and without position)
- Home → Movie details → Playback
- Series view
- Home → Series details
- Season view
- Home → Season details
- Episode view
- Home → Episode details
- Episode playback (with and without position)
- Home → Episode details → Playback
- Trailer/extras playback (no details page available)
- Home → Playback
- TV channel view
- Home → Playback
- TV channel playback
- Home → Playback
## AI or LLM usage
AI was used to generate the initial code, debug and test, then manual
refactoring and cleanup was done.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## 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.
## Description
Fixes a bug where the external subtitle track would not be activated if
playback is transcoded
Also fixes a bug where external subtitles would cause MPV to incorrectly
switch to transcoding
### Related issues
Fixes#1778
### Testing
Emulator with files that have a variety of external SRT, embedded SRT &
ASS, & embedded PGS
## Screenshots
N/A
## AI or LLM usage
None
## Description
Removes the max height constraints for slider preferences and navigation
drawer preferences so that longer text (possibly in other languages or a
long library name) won't cut off any content
### Related issues
Fixes#1784
### Testing
Emulator with manual long text
## Screenshots
N/A, no significant change except sliders can be slightly taller if
needed
## AI or LLM usage
None
## 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>
## Description
#1654 broke playback for both live TV and recorded programs in `.ts`
format.
This PR fixes both issues! Jellyfin returns `NoCompatibleStream` for
live tv if the source ID is passed in, so that is now skipped for live
tv. `.ts` files may have IDs formatted with a slash instead of colon, so
the logic is updated to handle that plus fallbacks for potentially
unknown future formats.
### Related issues
Fixes#1767
### Testing
Emulator & nvidia shield, plus unit tests
## Screenshots
N/A
## AI or LLM usage
None
## Description
Another follow up to https://github.com/damontecres/Wholphin/pull/1764 &
#1772
Also adds `lint.xml` to mark the extra translations as just a warning
since they don't cause a problem in the final build.
### Related issues
#1764#1772
### Testing
N/A
## Screenshots
N/A
## AI or LLM usage
None