## Description
The Music / Artists view currently appears to use the artist metadata
from individual tracks. While at a track level this makes perfect sense,
it can result in a very noisy and fragmented artists view.
For example, an album by Eminem might contain tracks with artists such
as:
- Eminem
- Eminem feat. 50 Cent
- Eminem ft. Rihanna
- Eminem & Dr. Dre
Each of these seem to appear as a separate artist entry (even though
they are all tracks from the same album by Eminem)
This becomes particularly noticeable in large music libraries, where
featured artists, collaborations, remixes, and slightly different artist
metadata ends up resulting in a large number of sparsely populated or
duplicate / strange looking artist entries.
This PR adds an option / toggle to determine which metadata field is
used to populate the artists view. This option sits neatly within the
current artist view settings e.g. Music > Artists > View options >
Artist source
- Artist (current behavior)
- Album Artist (use the album artist metadata instead)
That Artist setting stays as the default choice (so nobody sees a change
unless they pick it) but now gives the option to filter down only to
Album Artists if desired - this choice is saved per library and applies
immediately.
### Related issues
Closes#1868
### Testing
I've tested it extensively on an Amazon Fire TV Cube Gen 2 (using the
firetv debug variant) the following manual tests were performed:
- The list changes when you pick Album artist and importantly the
selection survives a full app restart
- It was tested on a large library and can confirm only the Album
Artists remained (e.g. only one Eminem entry remained)
Automated checks were run (testFiretvDebugUnitTest & pre-commit) As well
as two new tests being added to the CollectionFolderViewModelTest.kt:
- For letter counting its checking via the album artist endpoint (and
not the standard one) when the source is set as ALBUM_ARTIST
- When the source is changed via the saveViewOptions its triggering a
load from the album artist endpoint
## Screenshots
Please see the screenshots below showing the UI impact / modification:
<img width="4624" height="3472" alt="1"
src="https://github.com/user-attachments/assets/6b53575e-ad15-4f66-b9c0-074657128a1d"
/>
<img width="4624" height="3472" alt="2"
src="https://github.com/user-attachments/assets/528c5766-44d8-43d3-8519-778f5aab7441"
/>
<img width="4624" height="3472" alt="3"
src="https://github.com/user-attachments/assets/5de2fb6d-173d-4ac3-ad1b-e08f27f4dafd"
/>
## AI or LLM usage
The code was written / supported with Claude - the approach (e.g. design
/ storing the choice in ViewOptions) endpoint research etc was done by
myself - I reviewed the approaches / refactoring and than deployed a
debug.apk to my local device to confirm everything was working as
expected.
I've reviewed each line and can explain it / the thinking to approaches
/ logic etc and am comfortable submitting the PR.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
**On Amlogic boxes (S905X4 and similar) Dolby Vision Profile 7 does not
play as Dolby Vision.**
The server transcodes it, or, with "Direct play Dolby Vision Profile 7"
switched on by hand, the
decoder answers `NoSupport` and fallback ends in HDR10. Devices with a
native Profile 7 decoder,
such as the Shield, are not affected and nothing changes for them.
This PR converts Profile 7 to 8.1 on the fly. It has two halves and one
decision.
The preference `convertDolbyVisionProfile7` is proto field 6 in the
experimental settings, off by
default. In `WholphinRenderersFactory` the filter comes first in the
list, followed by the HDR10+
masking from #1876.
**What this PR does not do.** The enhancement layer is dropped; that is
the price of the
conversion, which is why devices with a native Profile 7 decoder are
left alone.
`BlockAdditional` (an enhancement layer outside the stream) is not read
— like the rest of
Wholphin today — so such a file stays HDR10, as it is now.
### Related issues
Closes#244
Builds on #1876 (the `BitstreamFilter` list). Related to #1540. @fanni42
asked for exactly this on
an S905X4 in #1876.
### Testing
**Hardware** — a debug build of this branch, Homatics box (Amlogic
S905X4, Android 14) + LG BX,
Jellyfin 12.1.0, a Profile 7 FEL remux with the enhancement layer in
band, played from the start
for 39 seconds. Only the new preference was switched on; manual "Direct
play Dolby Vision
Profile 7" was **off**:
* `DolbyVisionProfile7FilterTest` (14) — a fake rewriter on a direct
buffer: offset ≠ 0,
position/limit untouched, every "bytes stay as they were" branch,
three-byte start codes,
`UnsatisfiedLinkError` tried once;
* `DolbyVisionProfile7ExtractorsFactoryTest` (5, mockk) — only the video
track is rewritten;
* `DolbyVisionProfile7ConversionTest` (6) — codec strings, DRM, `dvh1`.
CI in my fork ran on this branch plus a debug signing commit:
`pre-commit`,
`testDefaultDebugUnitTest` and `assembleDefaultDebug` are all green. The
hardware measurement
above is that build.
## Screenshots
The only UI change is one toggle in the experimental settings.
## AI or LLM usage
The code was written with Claude (Claude Code): the filter, the
extractor wrapper, the condition
and the tests. I reviewed every line and can explain it. It was tested
with the unit tests and
the hardware measurement above. This description was written by me in
Russian and translated
into English with the same assistant.
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
https://github.com/damontecres/jellyfin-plugin-wholphin/pull/3 added a
new endpoint for Seerr configuration in Wholphin server plugin.
This PR adds support for reading that configuration and either
pre-filling the URL or automatically logging in.
Some code was copied from #1418 (thanks @matschi95!), but that PR worked
by inserting a DB record for the plugin provided server. Since the local
DB was preferred, this meant plugin config changes wouldn't be reflected
in the client. This PR instead attempts the connection and only updates
the in-memory connection state, so user switching and app restarts will
re-fetch from the plugin.
If the server plugin is not installed or no Seerr server is configured,
nothing in Wholphin changes.
### Related issues
#598
This PR replaces #1418
### Testing
Emulator with different scenarios
## Screenshots
N/A
## AI or LLM usage
None
## Description
Now that Jellyfin 12 has been out for over six weeks, it's time to start
considering dropping support for Jellyfin 10 & 11 as part of #1640.
This PR adds a warning message on the switch server, switch user, &
preferences pages if the current server version is <12.
### Related issues
See https://github.com/damontecres/Wholphin/discussions/1640 for further
discussion!
### Testing
Emulator w/ faked data
## Screenshots
N/A, reuses the same error message space
## AI or LLM usage
None
## Description
Rename music "Top Rated Unwatched" row to "Top Rated"
### Related issues
Typo.
### Testing
Android TV
## Screenshots
<!-- Please include screenshots if the PR alters any UI elements -->
<img width="1920" height="1080" alt="pr2-music-recommended-top-rated"
src="https://github.com/user-attachments/assets/3978bc9b-a020-4ee7-ae35-feb19e19ebae"
/>
## AI or LLM usage
Claude wrote the code, I reviewed, deploed a -debug.apk to my device and
tested live.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
## Description
PR to add support for a Wholphin server plugin:
https://github.com/damontecres/jellyfin-plugin-wholphin
Note: The plugin is not required to use Wholphin. It adds features the
server admin can use to set default settings like the home page or
eventually Seerr connection info.
### Changes
Wholphin will use the home page settings in order of:
1. Saved on the device locally
2. Saved on the server in the user's profile settings (display
preferences)
3. Provided by `jellyfin-plugin-wholphin`
4. Default fallback: combined continue watching & recently added in
libraries
Under customize home page, you can now see the "source" of the home
settings. This also allows to pick a different source
Finally, instead of the home customization being saved in the background
only locally, if there are any changes, a dialog is shown with options
to save locally, server-side user profile, or discard.
So overall, it's more clear where the home page settings are from and
where the user wants to save them.
### Install
[See instructions
here](https://github.com/damontecres/Wholphin/releases/tag/develop-server-plugin)
### Related issues
Related to #598
### Testing
WIP
## Screenshots
N/A
## AI or LLM usage
None
---------
Co-authored-by: Mario Reisinger <marioreisinger95@gmail.com>
## Description
This PR overhauls how audio and subtitle track persistence works for
series! Previously, when you chose an audio or subtitle track for an
episode, only the language was saved and used for subsequent episodes.
This meant aspects about why that choice were lost such as a forced or
hearing impaired track.
This PR changes the persistence to include more details about the chosen
track. Additionally, the persistence is saved at both the season and
series levels.
## How it works
Selecting the track uses the first success option:
1. Episode specific - User has explicitly chosen an audio/subtitle track
for this episode
2. Season specific - User has chosen the track for another episode in
this season
3. Series specific - User has chosen the track for another episode in
this series
4. User preferences - User has _not_ chosen a track for the episode,
season, nor series, so determine track based on the preferred audio
language, preferred subtitle language, and subtitle mode
Additionally, the season or series specific choices use a scoring
algorithm to find the best suited track. For example, if the chosen
tracks for an episode in the season had the forced flag, this will be
preferred for subsequent episodes. Same for SDH/hearing impaired or
title, etc. This means that the common case, where a season has
substantially identical tracks, will use the same ones across all
episodes (after choosing for one, otherwise falling back to the series
or user preferences).
Finally, this also means that users that prefer SDH/hearing impaired
subtitles can be prioritized now, though there is no global preference
for this yet.
The previous track language choices are migrated to the new algorithm.
They lack the additional context, but this makes for a seamless
transition.
## UI changes
The context menu for choosing audio or subtitle tracks now displays why
that track was chosen.
### Related issues
Fixes#1795
Maybe fixes#1783
Related to #1136 & #1798Closes#1470
### Testing
Previous unit tests for track selection all pass, plus there are a few
additional unit tests. I've done some testing on the emulator and it
seems to work well. But I think real world testing will be needed.
## AI or LLM usage
None
Description
Adding per-format HDR override preferences (HDR10, HDR10+, Dolby Vision
Profile 5/7/8) to control device compatibility information sent to the
Jellyfin server, so users can force specific formats on or off
independently instead of disabling Dolby Vision as a whole.
Related issues
This is a common problem across the Jellyfin ecosystem, but there isn't
a specific issue for Wholphin. My experience is the issue is FireTV
(model and generation) + TV dependent + media dependent. I tested videos
from
https://kodi.wiki/view/Samples with the same DOVIWithHDR10 flag that
worked while other movies I have with It is a very frustrating user
experience and the current workaround of setting the bitrate really low
to force a transcode is sub-optimal IMO as it lowers the video quality.
This allows the user to maintain full quality while disabling only the
specific format(s) causing problems.
https://github.com/jellyfin/jellyfin-androidtv/issues/4021https://github.com/jellyfin/jellyfin-androidtv/issues/4892https://github.com/nova-video-player/aos-AVP/issues/1503https://www.reddit.com/r/jellyfin/comments/12jqoxh/dolby_vision_video_not_working_on_fire_stick_4k/
Testing
<!-- Describe how this change was tested and on what device(s) -->
FireTV 4K (gen 1) + Vizio
FireTV 4K Max (gen 1) + LG
FireTV 4K Max (gen 2) + Vizio
FireTV (gen 1) + Olevia
AI or LLM usage
Claude code assisted and wrote much of the code in this PR. I've
reviewed it all and run the pre-commit linting and formatting.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
Adds a new setting to pick a maximum resolution (by height). Any
playback that has a larger resolution will be transcoded down to the
maximum resolution.
Playback equal or less than the maximum resolution will not be affected
and will direct play if otherwise able. This setting is also independent
of the maximum bitrate (ie if max resolution is 4K and max bitrate is
2mbps, playing 4K will transcode).
This setting is pretty much equivalent to the Web UI setting "Maximum
Allowed Video Transcoding Resolution" with "Limit maximum supported
video resolution" enabled.
Note: this setting does not affect which version is chosen by default
### Related issues
Closes#756Closes#1594
### Testing
Manual emulator testing
## Screenshots
N/A
## AI or LLM usage
None
## Description
Updates the home page header & card text when a Season type is shown,
such as in recently added for a TV Show library.
The title or logo for the series is shown with the season name as the
title. The "quick details" has the year of the season. The card shows
the unplayed count of episodes.
### Related issues
Closes#1958
### Testing
Emulator over a few days to see different seasons
## Screenshots
<img width="313" height="153" alt="image"
src="https://github.com/user-attachments/assets/c41e9edd-9f2a-4f62-b76d-e452e83dd8bf"
/>
## AI or LLM usage
None
## Description
Adds a "Prefer Dolby Vision over HDR10+" switch (off by default) under
Experimental settings. That screen only shows up once "Experimental
settings" is enabled under Advanced, and until then the switch is read
as off: it goes through `experimentalPreferences.get {}`, so nothing is
wrapped and the playback path is untouched.
Most current 4K web releases carry both Dolby Vision (profile 8.1) RPUs
and HDR10+ dynamic metadata in the same HEVC stream. Some MediaTek based
devices (Philips and TCL TVs, some Fire TV models) latch onto the HDR10+
metadata on those files and never engage Dolby Vision, even though a
Dolby Vision decoder is selected.
I isolated this on my Philips 55OLED810 by playing the same episode
three ways, direct play in all three cases:
| | Stream | TV shows |
|---|---|---|
| A | MKV with DV 8.1 + HDR10+ | HDR10+ |
| B | Same MKV with the HDR10+ metadata removed using
[hdr10plus_tool](https://github.com/quietvoid/hdr10plus_tool), DV
untouched | Dolby Vision |
| C | Same stream remuxed to MP4, both kinds of metadata present |
HDR10+ |
The container doesn't matter and the Dolby Vision signaling is picked up
correctly. The only thing the app can do is keep the HDR10+ metadata
away from the decoder.
When the switch is on, and only when a Dolby Vision decoder was actually
selected, the HDR10+ SEI messages (SMPTE ST 2094-40, recognized by their
ITU-T T.35 header `B5 003C 0001`) are masked in each access unit before
it is queued to MediaCodec. The SEI payload type byte is overwritten
with an unused value (254), so the decoder skips the message. That is
one byte rewritten in place per message: the masking filter returns the
size it was given, so the access unit is queued exactly as long as it
came out of the extractor, which is what makes it safe with both the
synchronous and asynchronous MediaCodec adapters. media3 does the same
thing for HAGC metadata in `HevcSeiUtil`; this filter only targets ST
2094-40, so other T.35 SEI such as CEA-708 captions are not affected.
The filter was written from the H.265 spec, no Kodi or media3 code was
copied.
The hook is generic rather than HDR10+ specific, as asked in the thread.
`BitstreamFilteringCodecAdapterFactory` wraps the codec adapter with a
`List<BitstreamFilter>`, and a filter is `(ByteBuffer, offset, size) ->
Int` where the returned `Int` is the new size of the access unit: the
adapter queues the size the chain reports, and hands each filter the
size the previous one reported. A filter which only overwrites bytes
returns the size unchanged, which is what the HDR10+ masking does; a
filter which drops NAL units compacts what it keeps and reports the
shorter size. A reported size which is negative or larger than the one
the filter was given is ignored rather than queued. That is what lets
the Dolby Vision profile 7 to 8.1 conversion of #244 arrive later as one
more filter instead of a second copy of the adapter plumbing.
When the switch is off, the playback path is unchanged. On a device
without a Dolby Vision decoder (or a display without DV support) the
wrapper is never installed, so HDR10+ only devices keep their metadata.
Encrypted samples, codec config buffers and empty buffers are passed
through untouched.
Kodi has an equivalent option for the same reason: xbmc/xbmc@032cbfeb
and xbmc/xbmc@e2c54e7f.
### Related issues
Implements what was requested in #1855. The filter list is what #244
(Dolby Vision profile 7 direct play) needs, so that conversion can be
added as another filter. #1895 implemented the same masking
independently and was closed in favour of this PR; the device profile
part of it was not carried over, see the note under Testing. Upstream:
androidx/media#1895, where the maintainers say the bug is in the device
codecs and that they don't plan a workaround in ExoPlayer itself.
## AI or LLM usage
The implementation (bitstream filter, MediaCodecAdapter wiring, unit
tests) were written with AI assistance (Claude). I reviewed the changes
and validated the behavior myself on a real MediaTek TV (Philips
55OLED810), with the setting on and off, on hybrid and DV-only content.
---------
Co-authored-by: Jycreyn <github.2ilp7@passmail.com>
## Description
Collection of minor bug fixes for `v1.0.7`
- Fixes a possible race condition crash when navigating to the search
page
- Uses friendlier error message when login fails due to parental
restrictions (based on
[`jellyfin-web`](https://github.com/jellyfin/jellyfin-web/blob/v10.11.11/src/controllers/session/login/index.js#L38-L41))
- Don't re-sort search results by name, just by relevance scoring
- Consume the key event when dim is active (ie if the screen is dimmed,
pressing a key will un-dim and not perform another action)
### Related issues
Fixes#1922Fixes#1951
Related to #1848 (search sorting)
### Testing
Emulator & nvidia shield
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds support to remove items from a playlist and move items within a
playlist
The remove option is in the context menu. Moving has buttons on the
right side. The buttons are available if the user has edit permissions
and the playlist is sorted by "Default" (the playlist order). Remove
from playlist option is available if the user has edit permissions.
Also, thumb images are now preferred instead of primary/poster images
since the layout is much wider than tall.
### Related issues
Closes#1881
### Testing
Emulator with both a user with & without permissions to edit
## Screenshots
### With move buttons
<img width="1280" height="720" alt="playlist_buttons Large"
src="https://github.com/user-attachments/assets/ce7880c3-b823-4b69-9ad4-cfc9e7ee5fd5"
/>
### Without move buttons
<img width="1280" height="720" alt="playlist_no_buttons Large"
src="https://github.com/user-attachments/assets/f2027052-4628-4d44-8257-6c2a5e8c3af4"
/>
## AI or LLM usage
None
## Description
Added localized formatting for season/episode numbers across the UI
because it was in English-only in every UI language.
### Related issues
None
### Testing
Tested on a physical Google TV Streamer 4K device. Checked manually
relevant screens while browsing and during playback.
## Screenshots
No frontend changes are visible in English and new translations will be
contributed through Weblate for other languages later, as usual.
## AI or LLM usage
Generated initial code with AI, then manually passed over it while
cleaning and refactoring where needed.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
This PR adds many more data types as tabs to the favorites page.
Additionally, only tabs for the types the user has favorites for will
appear. For example, if you have no favorited music videos, that tab
will not show.
Added types:
- Collections
- TV Channels
- Music albums
- Music artists
- Music videos
- Songs
- Home videos
- Photos
- Photo albums
Dev note: The tabs are implemented using keys instead of indexes which
could be useful for the series overview season tabs. Plus it maybe even
be adapted for the episode list to eliminate the terrible index search
logic. A major difference is that the possible favorites tabs are
known/static list where seasons/episodes are queried & paginated.
### Related issues
Closes#1041Closes#1844
### Testing
Manually on emulator, plus unit tests
## Screenshots
N/A
## AI or LLM usage
None
## Description
This PR adds several more data types to search. It also adds a setting
(per use profile) to choose which types to include/exclude when
searching. The combined results now uses the same types instead of a
separate list.
A user can only search for types that they have access to. For example,
they need Live TV access for TV channels/programs or need access to a
movies-type library to search movies.
Added types to search:
- Photos & Photo albums
- Playlists
- People
- TV channels
- Live TV programs
Clicking a TV channel will play it. Clicking a TV program shows the
program dialog allowing for recording or watching live if it's currently
airing.
On the main search page you can also toggle whether to search Seerr or
not. This does not apply to the discover search tab.
Dev note: Some minor refactoring to move setting up/canceling live tv
recordings into a new service so it can be shared between with the live
tv & search pages. Also search related files are moved into the same
package now.
### Related issues
Closes#409Closes#646Closes#1668Closes#1750
### Testing
Emulator using users with different permissions and library access
## Screenshots
<img width="475" height="584" alt="image"
src="https://github.com/user-attachments/assets/ebcff697-07ba-4ddd-8c26-57f147cfa02a"
/>
## AI or LLM usage
None
## Description
Adds a new sceensaver setting to add dimming. A larger value is darker
This works with or without the in-app screensaver. If dimming is
enabled, the screen be will be dimmed after inactivity. If both dimming
and the in-app screensaver are enabled, the screensaver will show dimmed
after inactivity.
### Related issues
Closes#1179
### Testing
Emulator
## Screenshots
N/A, it's just darker
## 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
Another collection of small individual fixes that don't warrant a full
PR:
- Better error handling for series and collection detail pages
- Better error handling on Discover search tab
- Fix issues when changing view options on card grid without reloading
the page
- Better error handling when changing the refresh rate or resolution
- Fix some nav drawer items disappearing briefly when restarting the app
- Fix that the discover search row would not clear when the query is
cleared
And some UI tweaks:
- Use consistent padding for the different customize home page sections
- Convert the "Continue watching click behavior" setting from a toggle
to choice dialog (the options & behaviors have not changed)
### Related issues
I think the error handling when changing the refresh rate might help
with #1737
### Testing
Emulator mostly
## Screenshots
N/A, UI changes are minor
## AI or LLM usage
None
## Description
Fixes an incorrect query for an artist's albums (thanks @StefanBS for
reporting & fixing in #1761!)
Additionally, another album row for "Appears on" is added. This is
definitely necessary because Wholphin only has a tab for all artists
which includes artists featured on albums attributed to a different
artist. So those albums will now show in the "Appears on" similar to the
web UI instead of an empty artist page.
Finally, the long-click context menu is added for music videos on an
artist's page.
### Related issues
Fixes#1760
Replaced #1761
### Testing
Emulator, particularly with artists who are not album artists
Also, verified the query fix against the web UI dev console
## Screenshots
N/A
## AI or LLM usage
None, but the fix included from #1761 did use some AI
---------
Co-authored-by: Stefan Bullones <stefan.bullones@gmail.com>
## Description
On the switch server page, display error message at the bottom for the
focused server. This includes unsupported server version.
### Related issues
Jellyfin 10.11/12.0 support discussion: #1640
### Testing
Emulator
## Screenshots
<img width="1280" height="720" alt="server_error Large"
src="https://github.com/user-attachments/assets/1227e7e7-a364-48d9-9a77-cb3f78d134a1"
/>
## AI or LLM usage
None
## Description
Adds a third option for d-pad seeking to not show any seek bar which
only shows the skip indicator and not the seek bar along the bottom
### Related issues
Original work to add other mode in #1650Closes#1520
### Testing
Emulator testing
## Screenshots
<img width="546" height="347" alt="image"
src="https://github.com/user-attachments/assets/2872566e-4598-4284-92cb-95a45b307835"
/>
## AI or LLM usage
None
## Description
Adds a setting to allow the user to choose between the current D-Pad
skip functionality, and a new simple trickplay overlay.
The setting is added in Advanced, under the Playback section, called
"D-Pad seek mode". The options are "Skip time" and "Trickplay previews".
I left the default as "Skip time" since that's how it operates now, and
nothing would change for users after this option is added unless they go
and set it.
When "Trickplay previews" is enabled, it shows an simple overlay when
using the D-Pad to seek (without the full overlay open). The new simple
overlay is the same implementation of the components in the full
overlay: seekbar, trickplay images, current playhead time, remaining
time. The components were pulled from the full overlay's inline UI code
into their own reusable components, now used in both the full overlay
and the simple overlay.
#### Notes
I could see there being an adjustment for the overlay hide delay. It's
currently hard coded to 1.5s.
This could be the default method, but it seems like preference is split
as to whether people want this, or the minimalistic skipped seconds only
version.
### Related issues
This is directly in response to this issue, as well as my own desire for
the feature :)
https://github.com/damontecres/Wholphin/discussions/1084
It's also loosely related to this issue, in that it would solve it since
it shows the playhead and remaining times.
https://github.com/damontecres/Wholphin/discussions/1122
### Testing
Built and tested on an Amazon Fire TV Stick 4K Max. I wouldn't
anticipate and compatibility or performance changes since it's a simple
settings/UI change involving already-used UI components.
## Screenshots
<img width="1920" height="1080" alt="wholphin-20260630-155708"
src="https://github.com/user-attachments/assets/52046cc2-7413-4f66-89dd-355464fa0f91"
/>
<img width="1920" height="1080" alt="wholphin-20260630-155723"
src="https://github.com/user-attachments/assets/57a4a271-9e44-4d2a-bea3-ce5c9cdc731a"
/>
<img width="1920" height="1080" alt="wholphin-20260630-153825"
src="https://github.com/user-attachments/assets/2cf664ff-3db5-4a2e-8626-10219946669c"
/>
## AI or LLM usage
AI was used to generate the change, automate some testing, and provide
information surrounding the change. I manually did some refactoring and
cleanup to keep it clean and consistent with the rest of the code
conventions.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
Switches to use the Artists API instead of Items API when fetching the
list of artists in a library.
Enables fetching artists, albums, and music videos in a collection.
Also adds titles for the remaining `BaseItemKind` types for future
proofing even if they aren't used anywhere in the app.
### Related issues
Fixes#1733Fixes#1734Fixes#1735
### Testing
Emulator, created a new collection with the above. Also verified the
artist query against the web UI
## Screenshots
N/A
## AI or LLM usage
None
## Description
Changes to searching & downloading subtitles:
- Activating newly downloaded subtitles more reliably
- Better audio index adjustment checks after downloading subtitles
- Sort subtitle downloadable options by whether the file hash matches
first
- Update the UI for subtitle downloadable options
Also, some improvements to the subtitle choice dialog:
- It now loops from top to bottom (and vice versa)
- It now focuses initially on current choice
### Dev notes
This PR now the selected tracks from `state.currentItemPlayback` to
`state.currentPlayback`. `currentItemPlayback` now only reflects the
user's choices saved in the database instead of a combination of DB and
"actual" state. `currentPlayback` stores the actual, resolved track
indexes regardless of how they were derived.
This means the indexes values in `state.currentItemPlayback` and
`state.currentPlayback` may be different. For example, if the user has
chosen "Only forced", `state.currentItemPlayback==-3` but
`state.currentPlayback` might be an actual forced track index.
### Related issues
Fixes#1549Fixes#1718Closes#1723
Fixes bug reported in
https://github.com/damontecres/Wholphin/issues/1498#issuecomment-5019965271
### Testing
Emulator
## Screenshots
Now shows SDH & hash matching
<img width="779" height="280" alt="image"
src="https://github.com/user-attachments/assets/4c33e5af-c9a1-4c9c-8217-6bc2ab3fcd27"
/>
## AI or LLM usage
None
## Description
Gathering several small bug fixes:
- Clear the backdrop when manually reloading the home page
- Convert the "# years old" string resource to plural
- Fix a spelling error in the source English strings
- Ensure #1680 is respected when searching for subtitles to download
- Slightly adjust padding for the header in collection details to match
other headers
### Related issues
Fixes string issues reported in
https://github.com/damontecres/Wholphin/issues/1705#issuecomment-4982909931
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds settings under the "User profile settings" section which allows for
specifying preferred languages for audio and subtitles and the preferred
subtitle mode.
By default (matching existing Wholphin behavior), the preferred
languages and subtitle mode are derived from the user's profile settings
provided by the server which can be set on the WebUI:
User->Settings->Playback or Subtitles. However, this isn't well
understood and Wholphin doesn't display these values anywhere, so many
users were confused.
The preferred languages and subtitle mode can now be configured from
within Wholphin. Setting these will **not** update the server. The
settings are **only** used locally.
### Related issues
Related to #319Closes#790
### Testing
Emulator manually changing some settings, added additional unit tests to
ensure the overrides are respected when choosing tracks
## Screenshots
### Settings page
<img width="1280" height="720" alt="settings_01 Large"
src="https://github.com/user-attachments/assets/28cc2f6b-3a60-42a4-b268-48695086d566"
/>
### Clicking into "More user profile settings"
<img width="1280" height="720" alt="settings_02 Large"
src="https://github.com/user-attachments/assets/6c3be3aa-c177-4d44-8060-b76d15fb10d7"
/>
### Language choice dialog
Can filter languages by typing in the search box at the top
<img width="1280" height="720" alt="settings_03 Large"
src="https://github.com/user-attachments/assets/c014d0ba-8d5b-4201-a6ee-4876b478148c"
/>
## AI or LLM usage
None
## Description
Adds an experimental setting to prefer transcoding audio with more than
2 channels to AC3. Stereo audio does not transcode.
This is basically a workaround for HDMI ARC (not eARC) or optical audio
devices because instead of 2 uncompressed PCM channels, 6 AC3 channels
(ie 5.1) is possible.
An downside of enabling this is that embedded subtitles be burned in
causing a video transcode as well.
### Related issues
Fixes#255
Incorporates some code from #1410
### Testing
Just on the emulator so far to observe if the settings trigger the
transcode or not
## Screenshots
N/A
## AI or LLM usage
None
---------
Co-authored-by: darkflame91 <darkflame91@gmail.com>
## Description
Start testing against Seerr `3.3.0` which has been out for over a month.
The only significant change is that the new "blocklisted" status is
added, but it uses the same code as the previous "deleted" status. So
generally, Seerr `3.2.0` will still work.
This starts work on supporting Seerr's blocklist which, unfortunately,
is expected to be enforced on the client side. For now, blocklisted
items still show, but the request button is disabled and shows
"Unavailable" instead.
Finally, some Seerr parent permissions I missed in #1631 are added.
### Related issues
Related to #1626
### Testing
Emulator testing
## Screenshots
N/A
## AI or LLM usage
None
## Description
Instead of using English-only duration format (e.g. `HHh MMm SSs`) in
various places, I've added a format function that is based on several
new localized resources keys.
That includes:
1. Media runtime in Item view
2. Time remaining in Item view
3. End time in Player view
4. Time passed and time remained in Player view
### Related issues
None
### Testing
I installed the app on my Google TV Streamer, switched to my language,
browsed all item views that I could think of to see that the duration
labels are all localized in my language. I didn't commit those strings,
I will do it through the Weblate after it will get merged. I also played
a few items and saw that the labels there are localized as well.
## Screenshots
It looks the same in English as before, currently no other language has
custom resources for it yet.
## AI or LLM usage
Used Claude Sonnet to detect places that I missed that are related to
this localization change. Also it helped me to get access to my format
function from various places in the code.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
This PR introduces the concept of "experimental" settings or features.
These may cause instabilities or may need further testing. They may be
changed or removed any time. Also, the developers won't provide lots of
support for them.
The goal is expose some specialized settings that might only apply to a
small subset of users or test out tweaks to playback.
The first experimental feature is a toggle to enable [video
tunneling](https://developer.android.com/media/media3/exoplayer/track-selection#tunneling).
### Related issues
Related to #1283
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
This PR moves the separated HDR subtitle style behind a toggle. This
means users must now opt-in to using separated SDR vs HDR subtitle
styles. This is a better UX for users who want to customize the style
but use the same styles for both.
Users who have changed the HDR subtitles previously will have the toggle
enabled automatically. If the user hasn't changed HDR style or their SDR
& HDR styles are the the same, the toggle will be disabled.
Also, fixes a bug where when playback switched between SDR or HDR, the
subtitle styles might not be updated.
### Related issues
Closes#1603
### Testing
Emulator & unit tests for migration
## Screenshots
N/A
## AI or LLM usage
None
## Description
This PR adds sort & filter options for the discover grid pages.
Sort options:
- Popularity
- Release date
- "Community rating" (TMDB user vote)
- Name
Filter options:
- Genre
- Studio/Network
- "Community rating" (TMDB user vote)
- Parental rating
- Production status (TV only)
Also, two more tabs are added to the discover page for browsing movies
and TV. These are essentially the same as clicking "View more" on the
respective rows on the Discover tab.
### Limitations
This PR hardcodes the region used for studio listing and filtering to
"United States". I'll work on a follow up PR to enable users to specify
this.
The sort & filters are not persisted. I think they should be on the two
new tabs, but not elsewhere, but this will be a follow up PR.
### Related issues
Related to #702
Implements some of #1511
Rewrites the filter logic in #1610
### Testing
Emulator, but needs further testing
## Screenshots
<img width="1280" height="720" alt="discover_filters Large"
src="https://github.com/user-attachments/assets/cdefb95c-c4b7-4e06-9bac-b535d372ba03"
/>
## AI or LLM usage
None
## Description
Adds option to select the quality profile and/or root folder when
requesting from Seerr.
The user needs "Advanced Requests" permission to use this feature. If
not, the options won't show.
### Related issues
Closes#863
Related to #702
### Testing
Emulator w/ different user permissions and different request
configurations
## Screenshots
<img width="1280" height="720" alt="request_movie Large"
src="https://github.com/user-attachments/assets/2665dcbb-e6c3-4d26-857c-b465edff6a02"
/>
## AI or LLM usage
None
## Description
Ensures that all string & plural resource keys are unique. This should
help make sure all of the strings are shown in weblate's translation.
### Related issues
Related to #1551
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds a few enhancements to home page customization:
- Add option to combined continue watching & next up to split it
- Add option to continue watching and next up rows to combine them
- Add option for sorting playlist or collections
- Show suggestions (recently updated) when searching for a playlist or
collection to add
- Better handling for loading vs unsupported types for suggestions
Also, the old toggle for combining continue watching & next up in
advanced settings is removed. Now by default the rows will be combined
unless changed in the home page customization settings.
### Related issues
Closes#340Closes#1383Closes#1350
### Testing
Just on the emulator so far
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds an option to display libraries in a list layout
The list can be regular showing 6-7 items or compact showing ~11 items.
Can also toggle showing the details on the left side. Movies, tv shows,
& albums have type-specific layouts and other types like videos, music
videos, etc use a generic one similar to movies.
Another change is that showing the backdrop is now a separate toggle
from showing details for both grid & list layouts.
Sorting, filtering, & jumping to a letter all work as expected!
### Related issues
Closes#1101
### Testing
Emulator mostly
## Screenshots
<details><summary>Click for screenshots</summary>
<p>
### TV shows list
<img width="1280" height="720" alt="series_list Large"
src="https://github.com/user-attachments/assets/f8f9b801-e537-4cdf-b992-f2f1259457fa"
/>
### TV shows compact list
<img width="1280" height="720" alt="series_list_compact Large"
src="https://github.com/user-attachments/assets/747e5929-90d7-4d59-a179-bc3210ac01b9"
/>
### Movie list
<img width="1280" height="720" alt="movie_list Large"
src="https://github.com/user-attachments/assets/ee3e1c6c-fb25-438a-a11e-522d30fbaabf"
/>
### Album list
<img width="1280" height="720" alt="music_list Large"
src="https://github.com/user-attachments/assets/9b1f59ec-c237-4ab2-9b51-6cb519f5327c"
/>
</p>
</details>
## AI or LLM usage
None
## Description
Adds a setting to configure the app's language/locale. It is configured
per user. This settings has no impact on audio or subtitles language
choices.
Only languages Wholphin has translations for can be used. If you would
like to contribute new translations, check out
https://translate.codeberg.org/projects/wholphin/!
Dev notes: This doesn't exactly follow Android's recommendations because
the [guidelines are for
per-app](https://developer.android.com/guide/topics/resources/app-languages)
and not users within the app.
### Related issues
Closes#513Closes#669
### Testing
- Emulator API 34
- Nvidia shield API 30
- Fire TV OS 7 API 28
## Screenshots
<img width="1280" height="720" alt="language Large"
src="https://github.com/user-attachments/assets/bf1c0962-8a36-4012-aed9-eab564fc1114"
/>
## AI or LLM usage
None
## Description
Adds a "Show voice search button" toggle to the search page's view
options dialog, alongside the existing "Combined search results" toggle.
When disabled, the voice search button is hidden from the search row,
taking it out of the D-pad focus path.
The new field `show_voice_search_button` is added to `SearchPreferences`
(default `true`). The serializer applies the default for new installs,
and a new entry in `AppUpgradeHandler` sets it to `true` for users
upgrading from earlier versions so existing behaviour is preserved.
### Related issues
Discussion: https://github.com/damontecres/Wholphin/discussions/1419
### Testing
Tested on an Android TV (1080p) AVD running API 34:
- Toggle on (default): voice search button visible at the top of the
search row.
- Toggle off: button disappears; only the search text field remains.
- Toggle back on: button reappears.
- Upgrade handler verified by spoofing `version.current.name` to an
older value in SharedPreferences and force-restarting the app; after
`needUpgrade()` fired, the toggle was on as expected.
The upgrade-handler entry currently uses `0.6.4-8-g0` (based on current
`main` HEAD); happy to bump this if you'd prefer a different target
version on merge.
## Screenshots
<img width="1920" height="1080" alt="pr1-01-home"
src="https://github.com/user-attachments/assets/0d5cdad0-5547-44f3-b4a5-5d15f71dddc0"
/>
<img width="1920" height="1080" alt="pr1-02-toggled-off"
src="https://github.com/user-attachments/assets/1e574229-0838-487d-b943-83d394a8193d"
/>
## AI or LLM usage
I used Claude to scaffold the proto/serializer/upgrade-handler/dialog
changes, mirroring the existing `combined_search_results` pattern. I
reviewed each diff before committing and tested the toggle manually on
the emulator, including the upgrade-handler simulation.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
Adds a setting, Settings->Advanced->"Customize which ratings to
display", which allows for toggling parental, community, or critic
ratings to be displayed in the quick details.
This doesn't apply to discover yet.
### Related issues
Related to #1020
### Testing
Emulator
## Screenshots
### Just community rating
<img width="1280" height="720" alt="ratings Large"
src="https://github.com/user-attachments/assets/d6f9ad8a-6cc5-4680-9d2f-66d16a44b41e"
/>
## AI or LLM usage
None
## Description
This PR adds a new method of protecting a user profile when switching to
it: server login. When enabled, switching to the user requires
authenticating with the server again via Quick Connect or username &
password. This is basically the same as the official client.
### Related issues
Closes#321
Related to #1330 - might cause merge conflicts
Related to #1287 - definitely causes merge conflicts
### Testing
Emulator with various uses cases including auto sign-in, switching
between server login & PIN protection, and removing the protection
## Screenshots
N/A, the login looks identical as adding a new user
## AI or LLM usage
None
## Description
Adds an option under Settings->Customize home page->Settings, "Continue
watching/Next up click behavior":
- When disabled (the default), clicking goes to the item's details page
- When enabled, clicking starts playback for the item from its resume
position
This only applies to the continue watching, next up, or combined rows.
All other rows go to the details page no matter what.
### Related issues
Closes#1007
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
Improves how search results are displayed:
- Reorders search categories to Movies → TV Shows → Episodes →
Collections, surfacing the most commonly searched content types at the
top.
- Adds a new "Combined search results" preference in Advanced settings →
Search. When enabled, shows all results in a single list instead of
separate categories.
- When Seerr is active, adds Library/Discover tabs to switch between
local library results and Seerr discovery results.
- Hides empty result categories instead of showing "No results"
placeholders.
### Screenshots
<img width="1935" height="1100" alt="Screenshot_20260116_113656"
src="https://github.com/user-attachments/assets/1e29aa3a-3ba2-4f86-ab61-fed683490474"
/>
<img width="1934" height="1095" alt="image"
src="https://github.com/user-attachments/assets/8b93fa38-d4c9-4e72-a997-caa82b4949f0"
/>
<img width="1921" height="1094" alt="image"
src="https://github.com/user-attachments/assets/82aed1a5-810c-413f-a266-6d78490a1534"
/>
### AI/LLM usage
Code auditing and PR description drafting with Claude Code. Also used
Claude Code for the regex.