Commit graph

363 commits

Author SHA1 Message Date
Damontecres
6906813bbc
Fix mpv error with MediaSession 2026-01-07 14:03:28 -05:00
Ray
4df17e41cd
Fix timing issues with segments (#648)
## Description
Processing segments happens in a separate coroutine which wasn't
cancelled until _after_ playback of the next item begins. So in some
cases the outro from a previous item might be triggered during the very
beginning of the newly starting item.

So this PR instead cancels segment processing immediately when starting
the process for playback of an item. Additionally, the processing also
now checks that the current segment is for the current playback item as
an additional safeguard.

### Related issues
I believe this should fix both of these issues:

Fixes #369
Fixes #647
2026-01-07 13:23:55 -05:00
Ray
49740c47cf
Create media session during playback allowing for external control (#640)
## Description
Creates a `MediaSession` during playback which allows for external
control such as via smart speakers, Google Home app, etc

Note: one limitation is that seeking previous/next items in the playlist
isn't supported. This is because Wholphin manages that independent of
the `Player`, so additional dev work is needed for this.

### Related issues
Closes #622
Might help with #415
2026-01-07 12:49:43 -05:00
Ray
356a93310f
MPV: Handle resolution switch (#635)
## Description
When switching resolution (and possibly refresh rate less frequently),
the initial surface is not always valid. This means, the MPV playback
treated it as detaching the surface and would never update.

This PR instead subscribes to the `SurfaceHolder`'s callbacks which will
provide a new, valid surface once the switch is ready. Then the surface
is attached and queued commands execute to start playback.

Also temporarily disables content scale options for MPV since the
compose implementation conflicts with MPV rendering.

### Related issues
Fixes #626
2026-01-05 15:38:36 -05:00
Ray
4f1c730736
Don't process reqeued MPV commands (#633)
## Description
This is an embarrassing bug... In #619, a change was made to avoid a
race condition and wait for the video output surface to be ready by
re-enqueuing commands. Except I missed cancelling executing the current
command.

This meant the command would both be executed and queued again. So, if
attaching the video surface takes a while, such as needing to wait for a
refresh rate change, _a lot_ of commands could have been added to the
queue and trigger a constant start-stop playback loop.

I think technically it would eventually resolve itself, but can take a
while.

### Related issues
Should fix #626
2026-01-04 17:25:43 -05:00
Ray
02d6a98ba8
More subtitle selection fixes (#630)
## Description
Fixes more subtitle selection issues, primarily fixes the sort order of
subtitle streams. But also prefer default subtitle in some cases

Adds test cases for the described situations below

Also adds an option in the More dialog to clear track selections made on
an item/series.

### Related issues
Addresses
https://github.com/damontecres/Wholphin/issues/570#issuecomment-3707255647
&
https://github.com/damontecres/Wholphin/issues/570#issuecomment-3707292928
2026-01-04 17:06:54 -05:00
joshjryan
3d4b06db44
Guard against navigating to a non-existant tab (#629)
Just make sure we don't crash if the selectedTabIndex isn't a positive
int. Fixes #628.

---------

Co-authored-by: Damontecres <damontecres@gmail.com>
2026-01-03 18:38:07 -05:00
Ray
9345d0a698
Fix home header not updating & row movement (#627)
## Description
Removes an incorrect optimization for showing the home page header

Separates logic for focusing on rows on the home page

### Related issues
Fixes #624 
Fixes #620
2026-01-03 18:09:40 -05:00
Ray
4d9e3cb6de
Fix MPV race condition causing no video output (#619)
## Description
Fixes a race condition where `libmpv` is beginning playback before it
has been attached to the output video surface.

The solution is for the handler to re-enqueue commands if MPV is either
not initialized or not attached yet. Once `libmpv` is ready, the
commands will be processed.

### Related issues
Should fix #576
2026-01-02 14:13:03 -05:00
Ray
0fe8e5d988
Show button for trailers instead of card row (#618)
## Description
On both movie & series detail pages, show a button to play trailers
instead of the row of cards below.

The button works like this:
- If no trailers, the button shows "No trailers" and is
disabled/non-clickable
- If only a single trailer, the button shows "Play trailer" and clicking
it plays the trailer
- Otherwise, shows "Trailers" and clicking displays a dialog to choose
one

Local trailers are shown first in the list. Then there is an attempt to
sort the trailers for the dialog so that names with "Official Trailer"
or "Official Theatrical Trailer" are listed first and "Teaser" is listed
last. This isn't perfect and doesn't work for non-English, but there's
no other metadata to use.

### Related issues
Closes #408
2026-01-02 13:50:45 -05:00
Damontecres
b8e8a1d913
Fix yet another focus problem 2026-01-02 11:50:23 -05:00
Ray
83a543ad7d
Fix some crashes due to bad UI state (#617)
## Description
Fixes two possible crashes:
- When saving view options for a favorite page tab
- When there are no results on a grid page/tab
2026-01-02 00:24:17 -05:00
Ray
0958578082
Fixes websocket subscription, date invalidation, & theme music (#616)
## Description
Makes sure the `ServerEventListener` and `DatePlayedInvalidationService`
are injected so that they run. This was broken in #538.

Also fixes the a delayed stopping of theme music

Also fixes for detecting a non-seamless refresh rate switch

### Related issues
Fixes #615
Fixes #568
2026-01-01 22:19:36 -05:00
Ray
977db0474a
Small bug fixes (#614)
## Description
Fixes the screen showing endless loading when toggling on automatic sign
in

Ports a bug fix to the device profile from the official app
(https://github.com/jellyfin/jellyfin-androidtv/pull/5268)
2026-01-01 15:07:32 -05:00
Ray
3c11d4ba12
Fix some issues with restoring focus between pages (#613)
## Description
Yet more focus issue fixes:
- Restore focus when going back to home page from a later row
- Don't jump to episode row when going back to series overview (such as
from a person page)

This PR also changes how backgrounding the app during playback works.
Now the only goes back to the previous page when the app comes back to
the foreground. This helps with focusing back on the page properly.
There's also a bit more clean up performed.
2026-01-01 14:37:32 -05:00
Ray
26a913b05e
Support resolution switching (#597)
## Description
Adds a settings for automatic resolution switching. When enabled, the
app tries to output content at the video stream's resolution.

For example, if playing 1080p content on a 4K TV, the actual output by
the Android TV device will be 1080p.

This works in hand-in-hand with automatic refresh rate switching. So
enabling both allows for the output to match both refresh rate and
content resolution. Outputting the best refresh rate is preferred over
best resolution.

Also, shows the current display mode in the playback debug info.

### Related issues
Closes #428 
Fixes #531
2025-12-31 17:11:30 -05:00
Ray
38697b011d
Switch from synchronized mutations to copy-on-write (#609)
## Description
Instead of synchronizing all access to event observers, use a
`CopyOnWriteArrayList`. This means sending events doesn't need to lock.
2025-12-31 16:10:29 -05:00
Ray
a5a7ed97b7
A few more UI tweaks (#603)
## Description
- Use series poster for seasons without a poster
- Larger logo on playback overlay
- Fix an issue where corner text on card on the home page would not
properly update

### Related issues
Closes #590
Closes #601
Fixes
https://github.com/damontecres/Wholphin/pull/586#issuecomment-3698613927
2025-12-30 18:39:48 -05:00
Ray
e3fa45d12f
Trigger tv guide scroll animation during key presses (#595)
## Description
Instead of triggering the tv guide scroll animation during composition,
do it during key presses. This fixes an edge case that crashes the main
thread when returning the guide but the underlying UI data structures
haven't been updated.

### Related issues
Fixes #592
2025-12-29 15:39:07 -05:00
Ray
243e08b635
Some minor optimizations to improve UI speed (#593)
## Description
Many tiny changes that improve UI rendering speed and reduces
recompositions

Still plenty of room for improvement though.
2025-12-29 15:36:05 -05:00
Ray
622a99631b
Fix movie page library & collection tabs not updating (#594)
## Description
Ensures the tabs on movie page use separate view models so the data
isn't shared between them.

### Related issues
Fixes #591
2025-12-29 15:35:42 -05:00
Ray
aa194f5a2d
Fix duplicates being added to Android TV watch next channel (#588)
## Description
Fixes the logic for determining which items need to be added to the
watch next channel row

Also adds some code to clean up existing duplicates. This code can be
removed around the next release.

Adds a channel to the home screen for recently added media. This is
needed to ensure full integration with the OS to allow toggling off any
of the Wholphin channels including watch next.

### Related issues
#372 introduced the bug
Fixes #587
2025-12-28 17:14:14 -05:00
Ray
ad64f9a136
Minor UI tweaks (#586)
## Description
- Show unwatched counts on the cards in the latest rows instead of child
count, which is more in line with the web UI & official app
- Show exact runtime on the overview dialog for each version
- Don't show controls after clicking up next

### Related issues
Closes #431
2025-12-27 15:59:51 -05:00
Ray
9ae4965c2a
Add resume/continue watching items to Android TV watch next row (#372)
## Details

Adds resume and continue watching items for the logged in user to the
Android TV OS level watch next "channel"
(https://developer.android.com/training/tv/discovery/watch-next-add-programs).

## Issues
Closes #206
Related to #581
2025-12-27 15:40:45 -05:00
Ray
639ce0de71
Don't flash previous app content when resuming app & auto sign-in is off (#585)
## Description
When the app is put into the background with auto sign-in disabled, it
will remove the current page and show a loading indicator. This way when
the app is resumed, the previous content won't flash on screen for a
split second.

The above should technically fix #584 on its own, but as additional safe
guide, this PR also makes sure the `ApiClient` is configured before
trying to create image URLs.

### Related issues
Fixes #584
2025-12-27 15:13:45 -05:00
Ray
494ff07b72
Fix smart & default subtitle selection logic (#579)
## Description
Fixes the logic for subtitle selection when using `Smart` or `Default`
server modes. Also takes into account unknown languages.

This is heavily inspired by [the server selection
logic](https://github.com/jellyfin/jellyfin/blob/release-10.11.z/Emby.Server.Implementations/Library/MediaStreamSelector.cs).
For better or for worse, Wholphin implements this client side.

### Related issues
Fixes #570
2025-12-27 14:22:40 -05:00
Ray
fd1feddab3
Improvements to overview/media info dialog (#580)
## Description
* Splits video details into two columns
* Show index number if multiple streams of the same type
* Different font color for media section titles
* Adjustments to spacing
* Add hearing impaired flag to & remove AVC from subtitle info

### Related issues
Closes #549
2025-12-27 12:47:01 -05:00
Ray
a797bd8267
Further improvements to resuming the app (#577)
## Description
Fixes issues when the app is resumed, such as after the screensaver is
dismissed.

For example, if you pause during playback and the screensaver starts,
Wholphin will stop playback and go back to the previous page. But with
this PR, instead of focus being lost and defaulting to teh nav drawer,
focus will restore on the play button or episode card.

### Related issues
Related to #552 &
https://github.com/damontecres/Wholphin/issues/552#issuecomment-3690614491
2025-12-26 15:40:52 -05:00
Ray
bdec72752d
Use backdrop images for genre cards (#578)
## Description
Uses backdrop instead of thumb images for the genre cards since the
backdrops tend to have little text to distract from the card title

### Related issues
Closes #574
2025-12-26 15:40:43 -05:00
Damontecres
5d1f4b6154
Merge branch 'release/v0.3.9' 2025-12-25 08:57:20 -05:00
Damontecres
c00c7b8aa9
Catch exceptions during app startup 2025-12-25 08:49:57 -05:00
Damontecres
72f910582f
Only clear backdrop on home for full reloads 2025-12-25 08:49:33 -05:00
Damontecres
13370db48d
Only clear backdrop on home for full reloads 2025-12-24 18:15:17 -05:00
Ray
2ecc3f262d
Optimize series data loading speed (#567)
## Description
Optimizes how both series pages are loaded. If the series has a lot of
seasons and/or lots of episodes per season, the pages load much faster.

This is a combination of reducing queried information, optimizing
finding the right data to display first, and lazy loading seasons.

Note: Series that don't have episode numbers, like daily TV shows, are
not as optimized yet

### Rough speed-ups
These numbers are from my (beefy) server, so it will vary based on your
server

Series details page (one with seasons row) w/ ~50 seasons: 5s->300ms,
~13x faster

Series overview page (one with episode row) w/ ~50 seasons & 25
episodes: 6s->1.1s, ~5x faster

### Related issues
Related to #562
2025-12-24 16:47:17 -05:00
Ray
b671e14826
Better restoration for auto sign in (#566)
## Description
Improves how the app restores state when auto sign in is enabled. If
auto sign in is enabled, the app will restore back to the last page.

#538 altered the app start up logic. This caused the app to reset state
more often when it goes into the background.

### Related issues
Related to #552
2025-12-24 16:44:41 -05:00
Ray
2b53a53155
Prevent quick details from using more veritical space if not enough horizontal space (#544)
## Description
Prevents the quick details (the dot separated details) from using more
vertical space if there is not enough horizontal space. Instead, the row
will be clipped at the total width.

This PR also gives more horizontal space to the details header on grid
pages. This matches the home page now.

### Related issues
Fixes #542
2025-12-22 19:16:12 -05:00
Ray
9a08cf3f25
Don't use saved library info for genre grids (#540)
## Description
The filtering & sorting for the genre results grid is now independent
from the actual library.

This prevents having a filter saved on the actual library that conflicts
with the Genre grid.

Also shows the genre name in the title of the page

### Related issues
Fixes #536
2025-12-22 15:44:08 -05:00
Ray
af54e777dc
Fix settings changes requiring an app restart (#539)
## Description
- Ensures settings changes take effect immediately instead of requiring
an app restart
- Add conditional & catch when checking for app updates

### Related issues
Fixes issues introduced in #538
2025-12-22 15:28:21 -05:00
Ray
eb4e9b93be
Add setting to toggle automatic sign in (#538)
## Description
The major user facing change in this PR is adding back the setting to
toggle automatic sign in on or off. This controls whether to restore the
app to where you left off or go the user selection page.

If enabled: re-opening the app will restore the previous user's session

If disabled: re-opening the app will always start with the user
selection page for the most recent server, or if there isn't a recent
server, the server selection page

This also separate this setting from the PIN protection settings in
previous PRs.

### Dev changes

This PR refactors the "setup" UI (server & user selection) to be
separate from the "app" UI (the actually app content). There is now a
`NavDisplay` for the setup flow which ends with displaying the
`ApplicationContent`'s `NavDisplay`. Most of the logic is moved out of
Compose code and into a `ViewModel`.

This means to switch users/server, the `SetupNavigationManager` must be
used instead of `NavigationManager`.


### Related issues
Closes #396
Fixes #376
2025-12-22 14:52:09 -05:00
Ray
20fe5e2626
Move MPV init & destroy to looper thread (#534)
## Description
No user facing changes in this PR

This is a continuation of #481 to move initializing and tearing down
`libmpv` onto the looper thread to prevent main thread blocking.

~The only function left that runs on the main thread is
`setVideoSurfaceView`. Since this has to directly interact with the UI,
I need to read the docs and ExoPlayer code a bit more to see how this
can safely done multi-threaded.~ It is safe/correct to attach on another
thread.
2025-12-22 10:40:42 -05:00
Ray
60838c2a86
Fixes a few bugs (#535)
## Description

A few minor bug fixes across the app

- Fix the language not showing after search on the subtitle search &
download dialog
- Clear the backdrop whenever the home page is reloading from scratch
- Enable pressing a remote's play (or play/pause) button on the series
page to play the focused episode

### Related issues
Play button follow up from #424
2025-12-21 21:31:01 -05:00
Ray
925a4b9d82
Add multi-part videos to playback queue (#520)
## Description
When playing media with multiple parts, the additional parts will be
added to the playback queue. This means a multi-part movie or episode
will be play all of the parts in order before the next item in the
queue.

This only affects the playback queue. There's no UI changes and no
indication that a movie or episode has multiple parts. I'll work on that
in a separate PR.

### Related issues
Related to #455
2025-12-21 21:30:00 -05:00
Ray
6df89fe8c9
Apply combined continue/next up, if enabled, on library recommended tabs (#533)
## Description
Respect the combine Continue Watching & Next Up setting on TV Show
library recommended tabs.

This uses the same implementation on the home screen, but only includes
items for that particular tv show library.

### Related issues
Fixes #532
2025-12-21 19:00:59 -05:00
Ray
11dda19b8a
TV Guide UI followup to #517 (#521)
## Description
- Instead of just replacing newline characters, collapse white-space
into single space characters which is roughly how the web UI does it
with CSS's `white-space: nowrap;`
- Use an actual arrow indicator instead of a `<` character for when a
program begins before the guide start

### Related issues
#517
https://github.com/damontecres/Wholphin/issues/434
https://github.com/damontecres/Wholphin/issues/435
https://github.com/damontecres/Wholphin/issues/436

### Screenshots
<img width="605" height="316" alt="image"
src="https://github.com/user-attachments/assets/6a5227b5-9960-4c6d-a086-a4a9867ea60b"
/>
2025-12-20 14:47:28 -05:00
Ray
a65b93e064
Enforce a minimum aspect ratio (#519)
## Description
When using a server provided aspect, force a minimum value (.666) in
case the server returns unusable data like zero.

Note: I have not been able to reproduce the errors in #451 to verify
that this PR will fix it. And it's not clear to me why #453 did not fix
it either. However, this PR shouldn't impact anything if the server is
sending valid aspect ratios and should at least prevent the crash on the
UI side.

### Related issues
Follow up to #453
Hopefully fixes #451
2025-12-20 14:39:59 -05:00
Ray
13d70e7623
Rework internals of ApiRequestPager (#518)
## Description
Changes how `init()` works for `ApiRequestPager` so that it 1) always
forces updating the total count if needed and 2) propagates errors
during the initial fetch up to the original caller

This means if an error occurs during the initialization of the pager
data, it won't be quietly logged and ignored. Instead, ViewModel code
will catch it and display an error in the UI.

### Related issues
Should fix #492
2025-12-20 14:39:48 -05:00
Ray
5c5db4c1ef
TV Guide title clean up & align start to half hours (#517)
## Description
- Cleans up program titles & subtitles by removing newline characters
- Align the start of the guide to half hour, rounded down, ie 9:52->9:30
or 11:05->11:00
- Add some visual indication that a program has started before the guide
start time
- This is done by adding a `<` prefix to the title and using sharp 90
degree corners at the start instead of rounded

### Related issues
Closes #434
Closes #435
Closes #436
2025-12-20 11:54:41 -05:00
Ray
693398536e
Better images for genre grid (#501)
## Description
Overhauls the genre cards for Movies & TV Show libraries.

Now the cards use a semi-transparent, consistent, generated color using
the same logic as in #478. And a random item from the library with that
genre is show in the background. This is heavily inspired from Plex.

If there are not applicable items for the genre, then just the colored
card is shown.

### Related issues
Fixes #490
2025-12-19 10:46:57 -05:00
Justin Caveda
e60748a0d0
[UI] Add playback overlay dark gradient background (#505)
## Description

This PR adds a background dimming effect behind the playback controls to
fix readability issues against bright video content. It implements a
full-screen vertical gradient that ensures white text and buttons remain
legible.

I added a vertical gradient fading from transparent at the top to ~95%
black at the bottom which adds contrast for UI elements without
obscuring the center of the video.

### Related issues

Solves [#485](https://github.com/damontecres/Wholphin/issues/485)

### Screenshots


<img width="1948" height="1112" alt="playback"
src="https://github.com/user-attachments/assets/f671072c-e37a-491d-b82f-fb6f888a42c7"
/>

<img width="1918" height="1081" alt="no_gradient"
src="https://github.com/user-attachments/assets/30bc2fee-ef5a-4d63-87a6-953e401cd84b"
/>


### AI/LLM usage

This change was developed with the assistance of AI, but was not wholly
generated by AI.

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Damontecres <damontecres@gmail.com>
Co-authored-by: Ray <154766448+damontecres@users.noreply.github.com>
2025-12-19 10:42:34 -05:00
Ray
c5214d886e
Fix backdrop not clearing on favorite tab changes (#507)
## Description
Fixes the backdrop not being cleared when switching tabs on the
favorites page by ensuring each has a unique view model.

Also clears the backdrop if the view option to show details is turned
off.

### Related issues
#476 
#499
2025-12-18 16:20:24 -05:00