Commit graph

414 commits

Author SHA1 Message Date
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
Justin Caveda
bcc7e660ea
Allow debug builds to to be installed alongside the stable app (#565)
## Description

This PR updates the debug build config to allow side by side
installation with the mainline/stable release by changing the app name
and app ID.

This is a convenience change to allow contributors to test debug builds
on their personal devices without overwriting the existing stable
version of the app
2025-12-24 13:31:06 -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
Amar Sandhu
fd260f2709
Add "Ends at" time display. (#475)
Addresses #441 .

---------

Co-authored-by: Damontecres <damontecres@gmail.com>
2025-12-18 15:52:27 -05:00
Ray
1855c4666b
Always show video as Dolby Vision if it has DoVi title (#502)
## Description
Always show the "Dolby Vision" label instead of just HDR if the video
has a Dolby Vision title. This matches the behavior of the official app.

### Related issues
Fixes #491
2025-12-18 14:28:22 -05:00
Ray
644bf51aff
Fix backdrop not clearing between tabs (#500)
## Description
Follow up to #476 to clear the backdrop when switching tabs

### Related issues
Fixes #499
2025-12-18 14:01:21 -05:00
Ray
8b40e89b8a
Update MPV playback threading model (#481)
There's no user facing changes in this PR

This PR updates `MpvPlayer` to use a threading model more similar to
[ExoPlayer's
model](https://developer.android.com/reference/androidx/media3/exoplayer/ExoPlayer#threading-model).

There's now a dedicated thread looper message queue between the UI
interactions on the main thread and calls to `libmpv`. This is necessary
because previously, the main thread would make the calls into `libmpv`.
`libmpv` uses internal mutex locking for some operations which meant
that the main thread would be blocked momentarily.

Now, the UI issues a command (eg seek to X position) and the command is
added to the thread looper queue and processed on that separate thread.
This uses the standard Android Handler/Looper mechanisms.

Related to #235
2025-12-17 18:24:25 -05:00
Ray
8c0defb772
Add translations as of 2025-12-17 (#495)
Adds another batch of translated strings.

Thank you to all of the contributors!

---------

Co-authored-by: Priit Jõerüüt <jrtcdbrg@noreply.codeberg.org>
Co-authored-by: ymir <ymir@noreply.codeberg.org>
Co-authored-by: ianvm <ianvm@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@noreply.codeberg.org>
Co-authored-by: American_Jesus <american_jesus@noreply.codeberg.org>
Co-authored-by: Vistaus <vistaus@noreply.codeberg.org>
Co-authored-by: Geekice <geekice@noreply.codeberg.org>
Co-authored-by: opakholis <opakholis@noreply.codeberg.org>
Co-authored-by: RabSsS <rabsss@noreply.codeberg.org>
Co-authored-by: arcker95 <arcker95@noreply.codeberg.org>
Co-authored-by: Rand0mB0y <rand0mb0y@noreply.codeberg.org>
Co-authored-by: SimonHung <simonhung@noreply.codeberg.org>
Co-authored-by: efko <efko@noreply.codeberg.org>
Co-authored-by: DragoWing <dragowing@noreply.codeberg.org>
Co-authored-by: oyvhov <oyvhov@noreply.codeberg.org>
2025-12-17 17:01:08 -05:00
Ray
8479d8621d
Bump dependency versions, notably media3 (#496)
## Description
Bumps dependency versions, notably media3/ExoPlayer to `1.9.0`

### Related issues

Fixes #108
Fixes #355
Fixes #479
2025-12-17 17:00:15 -05:00
Ray
7581b05b97
Move time tracking into a CompositionLocal (#493)
## Description
Creates a `CompositionLocal` which tracks the current time in a single
place and is usable anywhere in the app.

Can be used such as:
```kotlin
val now = LocalClock.current.now
val details = remember(item, now) {
  // Create detail strings based the item and current time
  // This will be recomposed/updated whenever the time changes
}
```

### Related issues
Related to #475
2025-12-17 13:25:36 -05:00
YogiBear12
2908f539e2
Redesign alphabet picker to fit all letters on screen (#480)
- Switch to tv.material3.Button with ButtonDefaults for better styling
- Add opacity changes based on focus (0.85f focused, 0.2f unfocused)
- Keep selected letter fully visible when picker is unfocused
- Reduce button size from 24.dp to 14.dp to fit all letters
- Reduce spacing between letters (1.1.dp vertical, 2.dp horizontal)
- Use transparent backgrounds for unfocused letters
- Use border color for selected letter when focused, tertiary when
unfocused
- Add Box with CircleShape clip to prevent focus indicator overflow
- Reduce font size by 15%
- Add 16.dp end padding to push picker away from screen edge

When using the 'Show details' view option, the alphabet picker will
still overflow the bottom edge of the screen. I find this an acceptable
option though, as the backdrop pushes the card grid further down the
page.

Closes https://github.com/damontecres/Wholphin/issues/386

>[!NOTE]
> AI was used in the making of this PR

---------

Co-authored-by: Damontecres <damontecres@gmail.com>
2025-12-17 12:16:46 -05:00
YogiBear12
801ff5e67b
Redesign Select Server and Select User screens (#478)
Redesign Select Server and Select User screens with horizontal card
layout, similar to traditional streaming services

- Replace vertical lists with horizontal list of icons
- Center align text in Quick Connect and Username/Password modals
- Display Jellyfin profile images
- Fallback to first letter of username if no image is available
- Filter out duplicate server entries in the auto-discovery list

---------

Co-authored-by: Damontecres <damontecres@gmail.com>
2025-12-17 11:56:19 -05:00
Ray
bbfbc13532
Backdrop improvements (#476)
## Description

The backdrop image shown on most pages is now configurable in advanced
settings:
* Image w/ dynamic color - Shows the backdrop with dynamic color filling
the entire space (new default)
* Image only - Shows only the backdrop image (current Wholphin behavior)
* None - Don't show any backdrops

Additionally, the backdrop is retained between page loads for the same
items.

## Acknowledgements

Big thanks to @YogiBear12 from which the idea and implementation for the
dynamic color was adapted from!

Code adapted from
https://github.com/YogiBear12/Halfin/blob/main/COLOR_EXTRACTION_AND_BACKDROP.md#backdrop-fading-and-transitions

## Issues

Closes #221
Closes #461
Closes #442



https://github.com/user-attachments/assets/1acbc487-c697-44d7-89ed-e7e4c9169360
2025-12-17 11:18:57 -05:00
Damontecres
f77d345abf
Allow null ItemTrackModification from DB 2025-12-16 13:52:44 -05:00
damontecres
d5a55ce4ad
Fix trickplay image scaling (#477)
Fix to #467 to scale the tiles by the actual calculated ratio based on
the server's fixed width and our target width instead of using the
general density scaling

I verified this on 1080p & 4k with 4:3, 16:9, & 2.35:1 videos.

Fixes
https://github.com/damontecres/Wholphin/issues/432#issuecomment-3657381461
2025-12-15 16:53:06 -05:00
damontecres
ebfc00c016
Always save series audio & subtitle preferences regardless of preferred languages (#473)
## Description

This PR adjust the logic for audio & subtitle track selection for TV
series. Instead of only saving for future episodes if the newly selected
track is a different language than the user's preferred, always save it.

Basically this means if you change the audio or subtitle language for an
episode, the same audio or subtitle language will be used for future
episodes (if available).

Also, fixes the "default" subtitle mode to take the user's preferred
language into consideration.

## Issues
Follow up to https://github.com/damontecres/Wholphin/issues/378 &
https://github.com/damontecres/Wholphin/issues/427

Fixes #469
2025-12-15 12:15:17 -05:00
damontecres
ab8bbf2bd7
MPV: Adjust subtitle delay/offset (#470)
**This is for MPV playback backend only!** Since this only works in MPV
for now, the option is not shown if using ExoPlayer.

Adds a setting (the gear icon during playback) to adjust the subtitle
delay.

A negative delay shows subtitles sooner. A positive delay shows them
later. For example, if a subtitle is supposed to show between
1000ms-2000ms, a negative 250ms delay will show it at 750ms-1750ms
instead.

The delay is persisted between plays of the same media & subtitle track.

Ref: #12 


![subtitle_delay](https://github.com/user-attachments/assets/824e3a28-650a-4619-9535-b67addaabf1e)
2025-12-15 10:06:36 -05:00
damontecres
7ab39eba57
Improve trickplay image preview speed (#467)
Moves the clipping of trickplay images from the image loading layer to
the composition/graphics layer.

Effectively, this PR loads and renders the entire trickplay image which
is then moved around to the right position and finally is clipped so
only a single tile is shown. Since moving the image around on screen
plsu clipping is 1) very fast and 2) done during recompositions, this
means it is _much_ faster at rendering each trickplay tile image and
Coil only has to load the image once.

Fixes #432
2025-12-14 19:04:01 -05:00
damontecres
ff43f8b1b5
Use sdk provided device name (#457)
Use the SDK to get the device name since it handles older Android
versions and has a fallback.

This should not change the device ID or name if the device was working
before this change.

Maybe related to #454
2025-12-14 10:07:46 -05:00
damontecres
43703436c5
Switch back to older text input (#459)
Revert some of the changes to input text fields from #327. This PR
switches back to using the `value/onValueChange` variants for single
line input.

Fixes #413
2025-12-13 21:03:41 -05:00
damontecres
a386028b6b
Fix possible NPE during refresh rate switch (#448)
Use current thread's looper or fallback to the main looper for the
display change callback.

This is the behavior in newer versions of Android whereas older versions
assumed a non-null looper.

Fixes #446
2025-12-13 17:58:30 -05:00
damontecres
d2e1c4683d
Only use server provided aspect ratios if >0 (#453)
Fixes #451
2025-12-13 16:43:49 -05:00
damontecres
6edcfb1067
Customize TV guide display (#443)
Adds a view options button for the TV guide to allow some basic
customization:
* Show details header
* Adjust how channels are sorted
* Toggle color coding for programs

Related to #250 
Closes #288 
Fixes #439
2025-12-12 22:05:01 -05:00
damontecres
0d8800863b
Prefetch trickplay images (#445)
Prefetch trickplay images and cache them so that quick scrolling doesn't
require network calls and images will appear significantly faster

Fixes #432
2025-12-12 22:04:52 -05:00
Damontecres
652becd685
Disable pin check 2025-12-12 19:16:43 -05:00
Amar Sandhu
c3f6fd7f60
Add media information dialog. (#416)
Addresses #414

---------

Co-authored-by: Damontecres <damontecres@gmail.com>
2025-12-12 11:49:30 -05:00
damontecres
e381df0295
Add batch of translations (#425)
Update translations from
https://translate.codeberg.org/projects/wholphin/

---------

Co-authored-by: damontecres <damontecres@noreply.codeberg.org>
Co-authored-by: n8llcaster <n8llcaster@noreply.codeberg.org>
Co-authored-by: RabSsS <rabsss@noreply.codeberg.org>
Co-authored-by: Vistaus <vistaus@noreply.codeberg.org>
Co-authored-by: Priit Jõerüüt <jrtcdbrg@noreply.codeberg.org>
Co-authored-by: sarjona98 <sarjona98@noreply.codeberg.org>
Co-authored-by: SimonHung <simonhung@noreply.codeberg.org>
Co-authored-by: arcker95 <arcker95@noreply.codeberg.org>
Co-authored-by: streamyfinchris <streamyfinchris@noreply.codeberg.org>
Co-authored-by: opakholis <opakholis@noreply.codeberg.org>
Co-authored-by: Tellos <tellos@noreply.codeberg.org>
Co-authored-by: SuperCool <supercool@noreply.codeberg.org>
Co-authored-by: Pawsi <pawsi@noreply.codeberg.org>
Co-authored-by: American_Jesus <american_jesus@noreply.codeberg.org>
Co-authored-by: ictu <ictu@noreply.codeberg.org>
Co-authored-by: adambibor <adambibor@noreply.codeberg.org>
2025-12-11 13:03:27 -05:00
damontecres
2403a44c18
Add view option for hiding card titles (#422)
Adds a view option for grids to show/hide titles. It is enabled by
default.

Closes #403
2025-12-11 13:03:16 -05:00
damontecres
c5c0dff705
Fix subtitle smart mode to check chosen audio language (#420)
Fixes how the smart subtitle mode logic works

Fixes #406
2025-12-11 12:52:21 -05:00
damontecres
319b46983f
Play item directly when clicking play button on remote (#424)
On the home page or any grid, if focused on a "playable" item (movie,
episode, etc), pressing the Play or Play-Pause button on the remote will
immediately start playback.

Dev note: Also guards against an edge case where an item passed into
playback doesn't have media sources due to more limited item fields in
the query.
2025-12-11 12:52:13 -05:00
damontecres
c97553f82a
Support login for users without passwords (#421)
Just requires a username to be entered to enable the login button.

Fixes #419
2025-12-11 10:40:32 -05:00