## Description
- Add indicator to mark the chosen version on the choose version dialog
- Add an option for album's context menu to add it to the now playing
queue
- Fix how season cards refresh on the series detail page so the images
don't glitch
### Related issues
Related to #1220
### Testing
Emulator mostly
## Screenshots
The indicator shows which version will play, whether explicitly chosen
by the user or implicitly picked by Wholphin.

## AI or LLM usage
None
## Description
Adds context menu options for "Remove from continue watching" and
"Remove series from next up"
### Remove from continue watching
This marks the item as unplayed so it will not be shown on the Continue
Watching row anymore. It may still show on a Next Up or combined row
though.
### Remove series from next up
This first does the same as "Remove from continue watching" above. But
it also stores the series' ID in your display preferences as removed.
Wholphin will filter out this series from appearing in the Next Up row
until you watch _any_ episode in the series in the future.
This only works for Wholphin clients!
There's a dialog to view which series have been removed and to re-add
them manually. Settings->Customize Home->Settings->View removed next up
### Related issues
Closes#906
### Testing
Mostly emulator testing
## Screenshots
## AI or LLM usage
None
## Description
Adds a tab for Studios (TV networks) to TV libraries. This displays a
grid of all of the studios. Clicking one displays the series produced by
the studio.
Additionally, adds a filter to the library tab to filter by studio. You
can select multiple studios, but its not the best UX since there will
likely be many studios (I have almost 200).
Finally, you can add a home row for studios in a library.
### Related issues
Closes#1002
### Testing
Mostly manual testing via emulator
## Screenshots
### Studios tab for a library

### Filter drop down for studios

### Updates series details
Shows the studio above the genres

## AI or LLM usage
None
## Description
Instead of applying a code patch, this PR uses build time [product
flavors](https://developer.android.com/build/build-variants#product-flavors)
to define the existing default and an app store variant. This is more
robust than maintaining a patch file and making sure it is applied
before building.
The app store variant applies the same code changes (removing install
permission, requiring leanback, & setting `UpdateChecker.ACTIVE`), but
via manifest placeholders/merging and `BuildConfig` entries.
There are no user facing changes.
### Related issues
None
### Testing
Built the variants and verified manifest changes via aapt
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds a card at the end of the rows on the discover page/tab to view more
results. When clicking this card, it goes to a grid view of more results
starting focused on the next one.
### Dev notes
This PR modifies `ApiRequestPager` to move most of its functionality
into an abstract class, `RequestPager`. And then add a new concrete
class, `DiscoverRequestPager`, for Seerr API paging. `ApiRequestPager`
remains for Jellyfin paging.
### Related issues
Related to #1035
### Testing
Emulator
## Screenshots


## AI or LLM usage
None
## Description
When Wholphin is updated, it will show a short toast message. This works
for both app store and side loaded installs.
You can now click on the "Installed version" in settings to fetch the
release notes for the current version.
### Related issues
Closes#1058
### Testing
Emulator
## Screenshots

## AI or LLM usage
None
## Description
Fixes the list of supported audio types when playing music.
This fixes allows for playback of audio formats like ALAC, PCM/WAV,
Vorbis, etc.
### Related issues
Fixes#1168
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
A brain dump documenting many classes and functions throughout the app.
Definitely does not document everything, but covers most of the major
components. This should be useful for new contributors.
There is a small amount of code clean up too.
There are no user facing changes.
### Related issues
N/A
### Testing
N/A
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds better error handling when loading home page rows. For example,
this fixes loading errors if a playlist row is configured, but the
playlist is deleted.
Also fixes an issue from #1116 where changing users doesn't go the home
page.
### Related issues
Related to #1124
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
This fixes some issues restoring the app state after it is killed by the
system, such as to free up memory while the screensaver is showing.
### Dev notes
Reproduce:
1. Start playing media from beginning
2. Pause at 10 minute mark
3. Wait for screensaver to start
4. Press a button
5. Media starts from beginning
Note: It may take a few iterations of 2-4 before the OS destroys the
app.
If the app is killed during playback, ideally Wholphin restores state to
_previous_ page, not playback since restoring playback is complex.
Before this PR, the back stack was maintained by Compose's
`rememberSerializable` and would be restored _after_ the
`PlaybackLifecycleObserver` cleans up the playback destination.
This meant that the app would be restored, from scratch, to the playback
page. The `PlaybackViewModel` would be initialized from scratch as it
was originally called, ie play from beginning.
The fix is to save and restore the back stack outside of Compose.
### Related issues
Fixes#767
### Testing
Emulator & nvidia shield
## Screenshots
N/A
## AI or LLM usage
None
## Description
Fixes debug install updates from trying to install the release APK and
use debug ones instead.
### Related issues
Fixes#1098
### Testing
Unit tests
## Screenshots
N/A
## AI or LLM usage
None
## Description
This PR makes changes to how images are fetched for discover/Seerr
items.
If the discovered item is available on the Jellyfin server, the images
will be fetched from the Jellyfin server.
Then if the Seerr server has image caching enabled, the images will be
fetched from the Seerr server. Otherwise, images are fetched from TMDB .
TMDB was the previous behavior for all images.
### Dev notes
This PR also updates the Seerr server URLs stored in the database, so
it's not backwards compatible.
### Related issues
Fixes#1079
### Testing
Emulator against Jellyseer 2.7.3 & Seerr 3.0.1
## Screenshots
N/A
## AI or LLM usage
None
## Description
Fixes a race condition saving preferences. It would be triggered if you
have "Remember selected tabs" enabled and either: 1) changed settings
while on a library grid page or 2) changed settings on a page navigated
_from_ a library grid page and then returned to the grid
### Related issues
I think this will fix#1075
### Testing
Emulator following the steps above
## Screenshots
N/A
## AI or LLM usage
None
## Description
A few fixes
- Better crossfade for photo slideshow
- Fix "Go to" in context menu for photos
- Fix certain home video/photo libraries not working for photos
- Fix removing seerr server in some cases
### Related issues
Closes#835Fixes#1069
Addresses
https://github.com/damontecres/Wholphin/issues/634#issuecomment-4018580518
### Testing
Emulator mostly
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds a dialog to select individual seasons for a TV show when requesting
it via Discover/Jellyseerr
If a request is already pending, it can be updated. If there's more than
7 seasons, a second submit button is added at the bottom of the dialog
for easier access.
Also, adds a button from Jellyfin series details to its Discover
equivalent and added a request button for partially available series to
request more seasons.
### Related issues
Closes#961
### Testing
Emulator & Jellyseerr 2.7.3
## Screenshots

## AI or LLM usage
None
## Description
Fix a screensaver crash after the last item
Also adds some extra error checking
### Related issues
Fixes#1053
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
Unfortunately, there seem to be issues with switching to
`libass-android`, so reverting those changes so I can cut a release and
troubleshoot later.
Reverts damontecres/Wholphin#569
## Description
Add better ASS/SSA support to ExoPlayer by using
[`libass-android`](https://github.com/peerless2012/libass-android).
This is enabled with the "Use libass for ASS subtitles" advanced
settings for ExoPlayer. It is enabled by default.
### Related issues
Related to #22
## Description
This PR improves the logic used to choose a display mode when refresh
rate and resolution switching are enabled.
As before, matching the refresh rate is prioritized over picking the
resolution. For example, with the display modes of 1080@30 & 720@60 for
a 720@30 video, 1080@30 is used because the frame rate exactly matches.
### Related issues
Fixes#1036
### Testing
Unit tests, added test cases for more situations
## Screenshots
N/A
## AI or LLM usage
None
## Description
A follow up to #1014 to add the delete option in more context menus.
Also improves the "reaction" logic which updates previous pages from
deletions on later pages.
### Related issues
Addresses
https://github.com/damontecres/Wholphin/pull/1014#issuecomment-3987205355
Related to #104
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
Fixes some issues with Jellyseerr login. Also makes error message more
clear by showing the URLs that were tested and the error that occurred.
Also fixes an issue where you could not remove a Jellyseerr server if it
was previously configured but can no longer connect.
### Related issues
Fixes#1028
Should fix#1022
Related to #747
### Testing
Emulator, tested adding and removing valid & invalid IPs
## Screenshots
N/A
## AI or LLM usage
None
## Description
This PR is mostly a proof-of-concept for setting up automated UI
testing. The tests use Roboelectric so they can run without an emulator.
There is also a sample instrumented test for running on emulators or
devices for future tests.
It adds two basic automated UI tests for adding a server. These are sort
integration tests because they use the actual implementations for the
view model and services like `ServerRepository` and `JellyfinServerDao`.
Also, moves the bulk of `MainActivity`'s compose code into a function
for future tests.
### Related issues
N/A
### Testing
Local testing
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds a setting to enable "Media management" which adds a context menu
item to delete media. This is accessible using either the More button or
long clicking.
You can delete episodes, seasons, series and movies/videos.
If order for the option to appear the current user must have server-side
settings for "Allow media deletion from" enabled for the library and the
in-app setting under Settings->Advanced Settings->"Show media management
options".
### Related issues
Closes#104
### Testing
Emulator
## Screenshots
### Context menu

### Confirmation

## AI or LLM usage
None
## Description
- Aims to further optimize performance for the suggestions fetching
### Related issues
Fixes#833
### Testing
Android Emulator
NVIDIA Shield Pro 2019
## Screenshots
N/A
## AI or LLM usage
AI being used to assist with updating/creating unit tests
## Description
- Restores corner text for episode cards
- Always show end time on playback overlay instead of it being
controlled by the "Show Clock" setting
- Better logic to determine person's role in media
### Related issues
Fixes#1010Fixes#1004Fixes#975
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
- Catch network exceptions when querying to populate the nav drawer
- Perform screensaver work on IO thread
- Fix possible crash if screensaver service runs while regular activity
is destroyed
- Fix genre images & backdrop images not loading
This PR also adds an Jellyfin SDK `ApiClient` wrapper to push all
network calls onto the IO thread. And tries to use a more strict
network-on-main policy for debug builds.
### Related issues
Fixes#994Fixes#1001
Should fix#1003
### Testing
Emulator with simulated exception throws
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds both an optional in-app and Android TV OS (DreamService)
screensaver
Has settings for:
- Starting delay, options from 30s to 1 hour
- Duration to show each image, 30s to 2 minutes
- Show clock (separate from app-wide clock)
- Toggle animated zooming
- Set a max age rating to limit what content is shown
- Included media types: movies, tv shows, and/or photos
By default only Movies & TV Shows are included. But if you have like
family albums on your server, you could enable Photos too.
There's also an button to start the screensaver so you can see what it
looks like.
### Related issues
Closes#230
### Testing
Emulator, Onn 4k pro, nvidia shield using both in-app and OS
screensavers
## Screenshots

## AI or LLM usage
None
## Acknowledgements
Some of the skeleton code for setting up the `DreamService` with the
right lifecycle was copied and modified from the [official app's
implementation](https://github.com/jellyfin/jellyfin-androidtv/blob/master/app/src/main/java/org/jellyfin/androidtv/integration/dream/DreamServiceCompat.kt).
## Description
A few more home page fixes
* Focus issue between settings & preset buttons
* Fix default genre card size for "Wholphin Default" preset
* Cache genre image urls for 2 hours so that they don't change on every
refresh
### Related issues
Related to #399
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
Fixes clicking on a genre card added to the home page
### Related issues
Fixes#952
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
Show Jellyseerr connection errors in settings. If an error occurred
trying to login, in setting it will show "Server error" and clicking
gives more error info and option to remove the server.
### Related issues
Fixes#907
### Testing
Emulator with simulated errors
## Screenshots
N/A
## AI or LLM usage
None
## Description
Adds some metadata about playing media for consumption in remote control
apps such as Google Home or others.
### Related issues
Partially address #889, doesn't add explicit controls yet, but Google
Home works
### Testing
Nvidia shield + Google Home app
## Screenshots
iOS Google Home app:

## AI or LLM usage
None
## Description
Hopefully this is the last round of bug fixes for customizing the home
page!
Fixes a possible crash when scrolling after adding a row after resetting
to default or loading remote settings that have more rows than the
original settings
Fixes some incorrect titles
### Related issues
Related to #399 & #803
### Testing
Emulator & nvidia shield
## Screenshots
N/A
## AI or LLM usage
None
## Description
Fixes/improves thumb image handling by falling back to backdrop images
if available. Episodes without a parent thumb/backdrop will fall back to
their primary image.
Also fixes the nav drawer selected item not updating (bug introduced by
#886).
### Related issues
Fixes#642Fixes#914
### Testing
Emulator in various situations with missing thumbs
## Screenshots
N/A
## AI or LLM usage
None
## Description
Fixes several issues with home page customization such as
- Displaying wrong episode-specific display options
- Smaller text on cards without images
- Prefer fill scaling for posters, like the old home page
### Related issues
Related to #803
### Testing
Emulator
## Screenshots
N/A
## AI or LLM usage
None
## Description
An attempt to fix#769
1. Always fetch the `DisplayManager` when switching refresh rates
2. Use the Activity context instead of Application context
### Related issues
Fixes#769
### Testing
I still haven't reproduced #769 myself, but this change works fine on my
shield + LG C2
## Screenshots
N/A
## AI or LLM usage
None
## Description
Improves home page customization for Live TV & Recordings
- Add row for live tv channels
- Add row for "on now" programs
- Clicking on a TV channel or TV program starts playback
- Better name for "Recently recorded" instead of "Recently added in
Recordings"
Also fixes a back stack issue after adding rows
### Related issues
Follow up from #803
### Testing
Emulator
## Screenshots
<img width="663" height="190" alt="image"
src="https://github.com/user-attachments/assets/49d41953-42ab-4621-92f1-b7936aab7e97"
/>
## AI or LLM usage
None
## Description
Customizing the home page (#803) and nav drawer (#886) were developed
independently, so this PR just cleans up somethings so that those two
changes work together.
This PR restores the default home page when there is no customization to
be the same as before: continue watching/next up row(s) followed by the
order of the nav drawer libraries' recently added rows.
Finally gets rid of `NavDrawerIteRepository` and related functions which
all had weird, hard to follow code.
### Related issues
Related to #803 & #886
### Testing
Emulator testing
## Screenshots
N/A
## AI or LLM usage
None
## Description
Allows for reordering the items in the navigation drawer
This does not change the home page row order since #803 decouples the
nav drawer and home page rows.
The initial order will be the "Library Order" settings on the web under
Profile->Home. Making any changes locally in Wholphin will set the
order. If any new libraries are added or if Seerr integration is
enabled, these will added to the end of the "pinned" list.
### Related issues
Closes#822
Related to #399 & #803
### Testing
Tested on emulator
- Re-ordering
- Granting/Revoking user permission to a new library
## Screenshots
N/A, nav drawer is the same, just sorted differently
## AI or LLM usage
None
## Description
This PR adds the ability to customize the home page in-app
### Features
- Add, remove, & reorder rows
- Persist the configuration locally
- Save the configuration to the server, allowing to pull down on other
devices
- Adjust view options for rows such as card height, image type,
preferring series images, or aspect ratio (similar to libraries)
- Pull down the web client's home rows (no plugins are supported yet!)
- Preview of the home page which is usable & updated as changes are made
### Row options
These are row types that can be added in-app via the UI:
- Continue watching
- Next up
- Combined continue waiting & next up
- Recently added in a library
- Recently released in a library
- Genres in a library
- Suggestions for a library (movie & TV show libraries only)
- Favorite movies, tv shows, episodes, etc
Additionally, there are more row types that don't have a UI to add them
(yet):
- Simple query to get items from a parent ID such as a collection or
playlist
- Complex query to get arbitrary items via the `/Items` API endpoint
### Dev notes
Settings are loaded in order:
1. Locally saved
2. Remote saved
3. Fallback to default similar to Wholphin's original home rows
The remote saved settings are stored via the display preferences API.
I know some server admins would prefer to push a default setup to their
clients. This PR does not have that ability, but it does define a
straightforward API for defining the settings. Something like the
potential server plugin work started in #625 could be slimmed down to
expose a URL to be added in the load order.
I'm also investigating integration with popular home page plugins to
allow for further customization, but will take more time.
### Related issues
Closes#399Closes#361Closes#282
Related to #340
## Description
Fix a bug where movie suggestions would get stuck loading when the
on-disk cache file doesn't exist.
### Related issues
Fixes#876
### Testing
Ran unit tests locally.
## Screenshots
N/A
## AI or LLM usage
Used AI to add testing for this scenario to unit test
---------
Co-authored-by: Ray <154766448+damontecres@users.noreply.github.com>
## Description
A rewrite of the `SuggestionsCache` to simplify it as a read-through
cache. The downside of this is that updated suggestions won't be
reflected in the UI unless the user reloads the page, but I think that's
an okay trade off.
Also adds parallelism limits to fetching suggestions to reduce the
number of simultaneous API calls. And moved the combining logic to use
the `Default` dispatcher to free up an IO one.
Also adds an initial delay to both the suggestions & tv provider
workers, so a cold start of the app isn't starved.
### Related issues
Related to #849
### Testing
Emulator & unit testing
## Screenshots
N/A
## AI or LLM usage
None
## Description
Add a settings to set the maximum amount of time items can appear in
Next Up.
Options range from 7 days to a year, or no limit (current & default
behavior)
### Related issues
Closes#662
### Testing
Tested on the emulator and verified URLs, added unit tests
## Screenshots
N/A, just a new slider bar setting
## AI or LLM usage
None
## Description
Adds a item in the More menu to send information about the media item to
the server (and app logs).
This includes the "media sources" which is info about the files and
stream/tracks in the files. It also includes device info, the playback
preferences, and the device's transcoding profile. All of this info is
useful for debugging playback issues.
### Related issues
N/A
### Testing
Emulator testing
## Screenshots
N/A
## AI or LLM usage
None
## Description
Addresses suggestion logic oversight in recently merged suggestions fix,
and improve performance (especially app homepage startup time)
- Re-implements the logic that sorts/categorizes tailored suggestions
based on the seed items that are queried. This was implemented in the
original PR at first, but I overlooked moving that logic
- Removes `OneTimeWorkRequestBuilder` and replaces with trigger in
`PeriodicWorkRequest` to fire with a 30 seconds delay if cache is empty.
### Related issues
Fixes#833
### Testing
Will be testing in:
Android TV emulator in Android Studio
NVIDIA Shield TV Pro 2019
## AI or LLM usage
I will use AI to help with writing the tests/testing services.
## Description
This PR aims to fix#638 where the "Suggestions" row was mixing up
content from different libraries that shared the same library type. For
example you were in the Anime library, you'd see regular TV shows
showing up, as the TV Shows and Anime libraries would both be "Show"
libraries.
As @damontecres mentioned in the issue discussion, the
`/Items/Suggestions` endpoint Wholphin is using just returns random
items from the same library type, with no special logic or
recommendation algorithm.
I also looked at how the official WebUI handles this. It basically just
mixes "Resume," "Next Up," and "Latest Items" together. That felt a bit
redundant since we usually have dedicated rows for those things anyway;
I wanted to try something that helps discover new content.
I replaced the broken endpoint with a few custom `GetItemsRequest`
calls. These work correctly with the `ParentId` filter, so we only get
results from the library we are actually looking at. Additionally, I
added in some logic that takes into account what the user has been
watching to tailor the suggestions a little bit.
The new logic uses a 40/30/30 mix (this can of course be tweaked as
needed)
- Tailored (40%): Grabs your recently watched items from this library,
checks their genres, and returns items from the same genre.
- Random (30%): Random unwatched stuff from this library.
- New (30%): Recently added items.
This is implemented using only `GetItemsRequest` API calls using
filters, rather than any specialized endpoints like the
`/Items/Suggestions` endpoint. This means the feature should be
predictable and stable. If Jellyfin ever adds an actual recommendation
algorithm and endpoint to call it, I imagine we would want to switch to
that in the future though.
I also added some failsafe logic to make sure there will be diversity in
the "recently watched" items that get pulled, in case a user might have
recently binged a TV show. We wouldn't want every single recommendation
to be based off of that one show.
To fix this, I changed the query to fetch the last 20 history items
instead of just the top 3. Then, we filter that list client-side to find
unique Series IDs. If the user watched 10 episodes of One Piece in a
row, the logic collapses them into a single "One Piece" entry and moves
on to the next distinct show they watched. This guarantees we get
variety in the source material for recommendations.
This is a work in progress right now, mainly due to performance. For my
server it takes about 10-15 seconds to load the Suggestions row when I
tested. This is unacceptable in my opinion, especially if we ever intend
to add a Suggestions row like this to the home page like Plex does. I
have some ideas on how to improve performance, but I'm open to
suggestions.
### Related issues
Resolves#638
### Screenshots
Before:
<img width="1953" height="1162" alt="suggestions1"
src="https://github.com/user-attachments/assets/6e301c67-1a46-46b5-8184-3adb9e52b330"
/>
After:
<img width="1937" height="1108" alt="suggestions3"
src="https://github.com/user-attachments/assets/b9563865-4055-40b6-b452-f94c26c8b6e9"
/>
### AI/LLM usage
I used Claude Code to help write the Kotlin Coroutines so the API calls
run at the same time. I also used it to write the tests in
`TestSuggestionsLogic.kt`.
---------
Co-authored-by: Damontecres <damontecres@gmail.com>
## Description
Add support for viewing photos in photo albums
### Features
- Browse and view albums & photos
- View an album as a slideshow
- Show overlay with photo details and controls
- Rotate, zoom, & pan photos
- Apply basic filters to photos or albums such as contrast, saturation,
red/green/blue, etc
- Setting to include video clips during slideshows
### Controls
- D-Pad left or right: scroll between photos in album
- Hold D-Pad up or down: zoom in or out of the current photo
- D-Pad left/right/up/down, while zoomed: pan around photo
- Back, while zoomed: revert the zoom
- Otherwise: show photo overlay
### Related issues
Closes#458Closes#634
### Screenshots
#### Overlay

#### Applying filters

## Description
Can now configure a different subtitle style for HDR playback.
There is also a new setting to change the opacity/dim image based
subtitles. This is primarily for HDR to dim very bright PGS subtitles,
but the setting is available for SDR too.
Please remember that the styles only apply to unstyled text formats like
SRT.
I haven't been able to consistently get the preview to switch the
display into HDR mode, so the preview is not 100% accurate.
### Related issues
Closes#583
### Testing
Shield pro 2019 w/ LG C2
## AI or LLM usage
None