Commit graph

664 commits

Author SHA1 Message Date
Ray
3f0dedd71e
Fix error pages overlapping with nav drawer (#887)
## Description
As of #842, if an error occurred on some pages that display a generic
error message, it would be shown under the nav drawer making it
difficult to read.

This PR fixes that by passing the `modifier` into the `ErrorMessage`
composables ensuring it has proper offset & padding. Also, for
consistency, passes it the `LoadingPage`s.

### Related issues
Caused by #842

### Testing
Threw an exception during home page loading to observe the issue and fix
on the emulator

## Screenshots
N/A

## AI or LLM usage
None
2026-02-12 19:21:16 -05:00
Justin Caveda
11fd780b31
Fix suggestions cache miss handling for missing files (#880)
## 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>
2026-02-12 18:27:59 -05:00
Ray
4161ea418c
Fixes the skip segment button appearance behavior (#884)
## Description
Fixes the segment (intro, credits, etc) skip button appearance behavior

For the button shown on the video: if the button for a given segment is
clicked, dismissed by the back button, or times out after 10 seconds, it
will never appear again even if you rewind the video.

However, the current non-ignored segment will always show a button on
the playback controls though so it's possible to still use it.

### Related issues
Fixes #875

### Testing
Tested a bunch of scenarios on the emulator

## Screenshots
N/A

## AI or LLM usage
None
2026-02-11 20:06:15 -05:00
voc0der
028553dc91
Add Quick Connect authorization to Settings (#820)
## Description
- Adding `Quick Connect` drawer to the Settings under the Seer
integration, and before Additional options.
- When interacted with, A inline-dialog appears (after internally
resetting itself), with gutter options Cancel / OK, like existing
dialogs, and when that is completed, where it completes the other side
of `Quick Connect`, e.g. login to your phone Jellyfin app by using
Wholphin.
- Failure and success both are indicated to the user and if success, it
closes the window.

### Related issues
Related to #819 
Closes #819

### Testing
Tested on development build from my repo on a Nvidia Shield 2019.
Performed several logout/login, both success and fail to observe dialog
state and function.

## AI or LLM usage
Used Claude Sonnet 4.5 for most of the code, ChatGPT, reviewed it, then
I reviewed it, made a few tweaks.
2026-02-11 20:06:03 -05:00
Ray
83e5a44f37
Fixes glitches when scrolling on the home page (#882)
## Description
Fixes the possible glitch on some devices when scrolling left-right on
rows on the home page

### Related issues
Fixes #367
Fixes #872

### Testing
Emulator & shield 2019

## Screenshots
N/A

## AI or LLM usage
None
2026-02-11 16:07:22 -05:00
Ray
6e676b9474
Fixes overscrolling on recommended tabs (#881)
## Description
If the continue watching row is empty on recommended pages, it would
scroll to the first successfully loaded row even if previous ones are
still pending.

This PR fixes that so the page waits until the right first row is ready.

### Related issues
Fixes #839

### Testing
Emulator & shield 2019

## Screenshots
N/A

## AI or LLM usage
None
2026-02-11 16:05:11 -05:00
Damontecres
073f030d20
Fix spanish plurals 2026-02-10 15:14:08 -05:00
American_Jesus
9f2ca8ca18
Translated using Weblate (Portuguese)
Currently translated at 100.0% (387 of 387 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/pt/
2026-02-10 19:59:42 +00:00
Outbreak2096
f539f69bb6
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (387 of 387 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-02-10 19:59:42 +00:00
Fjuro
2cfd130853
Translated using Weblate (Czech)
Currently translated at 100.0% (384 of 384 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/cs/
2026-02-10 19:59:42 +00:00
Outbreak2096
c01235d183
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (384 of 384 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-02-10 19:59:42 +00:00
arcker95
bdebe38b60
Translated using Weblate (Italian)
Currently translated at 100.0% (384 of 384 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-02-10 19:59:42 +00:00
opakholis
b51052acbb
Translated using Weblate (Indonesian)
Currently translated at 100.0% (384 of 384 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/id/
2026-02-10 19:59:42 +00:00
Lorixx
05bc8b67d1
Translated using Weblate (German)
Currently translated at 92.1% (354 of 384 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/de/
2026-02-10 19:59:41 +00:00
Bliiitz
cd540c621b
Translated using Weblate (French)
Currently translated at 99.7% (382 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/fr/
2026-02-10 19:59:41 +00:00
Priit Jõerüüt
70ea593bd9
Translated using Weblate (Estonian)
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/et/
2026-02-10 19:59:41 +00:00
Priit Jõerüüt
a62b34d372
Translated using Weblate (Estonian)
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/et/
2026-02-10 19:59:41 +00:00
idezentas
21010df2aa
Translated using Weblate (Turkish)
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/tr/
2026-02-10 19:59:41 +00:00
Fjuro
0f33f14972
Translated using Weblate (Czech)
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/cs/
2026-02-10 19:59:41 +00:00
Sathen
bdac869402
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/uk/
2026-02-10 19:59:41 +00:00
Outbreak2096
03f57f4679
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-02-10 19:59:41 +00:00
arcker95
a96b0b428d
Translated using Weblate (Italian)
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-02-10 19:59:41 +00:00
SimonHung
f5e0607ae9
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (383 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hant/
2026-02-10 19:59:41 +00:00
idezentas
735d413a74
Translated using Weblate (Turkish)
Currently translated at 94.2% (361 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/tr/
2026-02-10 19:59:41 +00:00
efko
eea6003ffb
Translated using Weblate (Greek)
Currently translated at 46.7% (179 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/el/
2026-02-10 19:59:41 +00:00
ictu
a8ac91ecd1
Translated using Weblate (Polish)
Currently translated at 63.1% (242 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/pl/
2026-02-10 19:59:41 +00:00
SimonHung
24cd367204
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 94.7% (363 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hant/
2026-02-10 19:59:41 +00:00
oyvhov
01bc279ecf
Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.2% (319 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/nb_NO/
2026-02-10 19:59:41 +00:00
damontecres
2a264f31e6
Translated using Weblate (Spanish)
Currently translated at 94.2% (361 of 383 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/es/
2026-02-10 19:59:41 +00:00
Outbreak2096
231dc4e6df
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (364 of 364 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-02-10 19:59:41 +00:00
arcker95
dd61bab8d1
Translated using Weblate (Italian)
Currently translated at 100.0% (364 of 364 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-02-10 19:59:41 +00:00
idezentas
47f12b8735
Translated using Weblate (Turkish)
Currently translated at 100.0% (362 of 362 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/tr/
2026-02-10 19:59:41 +00:00
subatomic9345
4b8ee5f5de
Translated using Weblate (German)
Currently translated at 94.4% (342 of 362 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/de/
2026-02-10 19:59:41 +00:00
idezentas
1a4daf8078
Added translation using Weblate (Turkish) 2026-02-10 19:59:40 +00:00
opakholis
4155556c05
Translated using Weblate (Indonesian)
Currently translated at 100.0% (362 of 362 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/id/
2026-02-10 19:59:40 +00:00
SimonHung
1c9afd0408
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (362 of 362 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hant/
2026-02-10 19:59:40 +00:00
danyrd92
4dd6e3a6c0
Translated using Weblate (Spanish)
Currently translated at 100.0% (362 of 362 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/es/
2026-02-10 19:59:40 +00:00
damontecres
8605fcafa8
Translated using Weblate (Spanish)
Currently translated at 100.0% (362 of 362 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/es/
2026-02-10 19:59:40 +00:00
haldq
404a883eb4
Translated using Weblate (German)
Currently translated at 94.1% (341 of 362 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/de/
2026-02-10 19:59:40 +00:00
Damontecres
f7efbf9f87
Don't show directed by line if director is unknown 2026-02-10 14:59:27 -05:00
Ray
6954d821ed
Fix two UI issues (#856)
## Description
Fixes UI issues:
- Showing unplayed corner text on multi-part movies
- Fix duplicate or missing rating info on discover movie & series pages

### Related issues
N/A

### Testing
Emulator

## Screenshots
N/A

## AI or LLM usage
None
2026-02-09 18:27:10 -05:00
Ray
b06761eaa5
Rewrite SuggestionsCache & limit parallelism (#851)
## 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
2026-02-09 17:39:40 -05:00
Ray
e7da5ca007
Add settings for max days in next up (#850)
## 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
2026-02-09 15:36:20 -05:00
Ray
63b37ef3f4
Fix glitchy nav drawer scrolling when opening (#848)
## Description
The nav drawer would always glitch a little when it gained focus due it
to trying to keep the selected page in view. #842 made this even worst.

This PR fixes that issue by hoisting the list scroll state up higher
which ensures it is remembered between recompositions. This change also
eliminates the need for workarounds to try and scroll it
programmatically which is also a tiny performance boost.

### Related issues
Follow up to #842 

### Testing
Emulator & nvidia shield

## Screenshots
N/A

## AI or LLM usage
None
2026-02-08 16:21:38 -05:00
Ray
72e5e6ae86
Add option to send relevant media info to server for bug reports (#840)
## 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
2026-02-08 13:38:09 -05:00
Ray
d5602aa88c
Navigation drawer improvements (#842)
## Description
This updates the navigation drawer with better behavior and UI. It is
also a bit more optimized and is slightly faster.

- When open, content is pushed to the right instead of being covered
- When open, it uses the same background colors from the dynamic
background
- The icons no longer shift as the drawer opens & closes
- The open drawer is not as wide
- Focus highlight on items is less circular, now matching the other
menus in the app
- The animation is a bit faster too

Dev notes:
- This PR copies & modifies `tv-material` code, so there's a customized
`ModalNavigationDrawer` implementation now
- There are fewer `AnimatedVisibility` composables which improves
performance
- Icons are exactly sized
- Content pages generally shouldn't add start/end padding anymore, the
padding is now added by the nav drawer
(b4f1b111edcd7e7ec05edc1100402b2851721fcd) and is consistent across
every page

### Related issues
Closes #699
Closes #384

### Testing
Tested on the emulator, nvidia shield, & google sabrina

## Screenshots
![nav_drawer_closed
Large](https://github.com/user-attachments/assets/9047eb45-6025-4992-8740-3430f0a8f2a9)
![nav_drawer_open_backdrop_dim
Large](https://github.com/user-attachments/assets/880f24a5-8018-469e-805d-18060c641dc5)



## AI or LLM usage
None
2026-02-08 13:03:43 -05:00
Justin Caveda
8e9a6799f5
Fix: suggestions logic/re-implement logic into worker and address performance issues (#834)
## 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.
2026-02-07 20:38:26 -05:00
Ray
abf5ec8004
Take playback speed into account when calculating the video end time (#843)
## Description
Small change so that the "Ends" time on the playback overlay takes the
current playback speed into account.

### Related issues
Closes #836

### Testing
Emulator

## Screenshots
N/A

## AI or LLM usage
None
2026-02-07 13:03:10 -05:00
Justin Caveda
aeaecc0f59
Fix suggestions mixing content from different libraries and update recommendation logic (#644)
## 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>
2026-02-04 20:50:29 -05:00
Ray
d9d5ab02e8
Add support for viewing photos in photo albums (#703)
## 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 #458
Closes #634

### Screenshots
#### Overlay
![photo_overlay
Large](https://github.com/user-attachments/assets/b44ed876-d8bd-4f75-aa1e-4106c2edb2f7)

#### Applying filters
![photo_filters
Large](https://github.com/user-attachments/assets/1379978a-b27c-47ac-80af-f7bb6a2177df)
2026-02-04 20:04:46 -05:00