Commit graph

642 commits

Author SHA1 Message Date
arcker95
1984f0e47a
Translated using Weblate (Italian)
Currently translated at 100.0% (329 of 329 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-01-19 16:39:36 +00:00
ymir
6f9a5e7bdc
Translated using Weblate (French)
Currently translated at 100.0% (329 of 329 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/fr/
2026-01-19 16:39:36 +00:00
Priit Jõerüüt
111f88b929
Translated using Weblate (Estonian)
Currently translated at 100.0% (329 of 329 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/et/
2026-01-19 16:39:36 +00:00
Outbreak2096
3eab616bf7
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.3% (327 of 329 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-01-19 16:39:36 +00:00
arcker95
ba233d4642
Translated using Weblate (Italian)
Currently translated at 100.0% (327 of 327 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-01-19 16:39:36 +00:00
RabSsS
2ee432e812
Translated using Weblate (French)
Currently translated at 99.6% (326 of 327 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/fr/
2026-01-19 16:39:36 +00:00
lazigeri
a2c6f12f8b
Translated using Weblate (Hungarian)
Currently translated at 100.0% (327 of 327 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/hu/
2026-01-19 16:39:36 +00:00
lazigeri
950ce06669
Translated using Weblate (Hungarian)
Currently translated at 99.6% (325 of 326 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/hu/
2026-01-19 16:39:36 +00:00
subatomic9345
b38e962633
Translated using Weblate (German)
Currently translated at 89.3% (286 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/de/
2026-01-19 16:39:36 +00:00
texxlan
3236bf5978
Translated using Weblate (German)
Currently translated at 89.3% (286 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/de/
2026-01-19 16:39:36 +00:00
oyvhov
a0eecf9917
Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (320 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/nb_NO/
2026-01-19 16:39:36 +00:00
Outbreak2096
4f0f8cb39d
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (320 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-01-19 16:39:36 +00:00
SimonHung
8100d0b166
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 99.6% (319 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hant/
2026-01-19 16:39:36 +00:00
arcker95
930fe834a6
Translated using Weblate (Italian)
Currently translated at 100.0% (320 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-01-19 16:39:36 +00:00
ymir
f0ba9da5bc
Translated using Weblate (French)
Currently translated at 100.0% (320 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/fr/
2026-01-19 16:39:36 +00:00
Priit Jõerüüt
16bf015ad9
Translated using Weblate (Estonian)
Currently translated at 100.0% (320 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/et/
2026-01-19 16:39:36 +00:00
American_Jesus
68cea647f0
Translated using Weblate (Portuguese)
Currently translated at 100.0% (320 of 320 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/pt/
2026-01-19 16:39:36 +00:00
lazigeri
87ac139f9f
Translated using Weblate (Hungarian)
Currently translated at 100.0% (319 of 319 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/hu/
2026-01-19 16:39:36 +00:00
Outbreak2096
65b0e1fdf0
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (319 of 319 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-01-19 16:39:36 +00:00
lazigeri
667008ec31
Translated using Weblate (Hungarian)
Currently translated at 100.0% (319 of 319 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/hu/
2026-01-19 16:39:36 +00:00
arcker95
bed45814d6
Translated using Weblate (Italian)
Currently translated at 100.0% (319 of 319 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-01-19 16:39:36 +00:00
Priit Jõerüüt
7ec36917db
Translated using Weblate (Estonian)
Currently translated at 100.0% (319 of 319 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/et/
2026-01-19 16:39:36 +00:00
lazigeri
05bb2d4c65
Translated using Weblate (Hungarian)
Currently translated at 100.0% (316 of 316 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/hu/
2026-01-19 16:39:36 +00:00
SimonHung
ca48d59b07
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (316 of 316 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hant/
2026-01-19 16:39:36 +00:00
Outbreak2096
8f0b620435
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (316 of 316 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/zh_Hans/
2026-01-19 16:39:36 +00:00
lazigeri
a2b8ab5918
Translated using Weblate (Hungarian)
Currently translated at 100.0% (316 of 316 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/hu/
2026-01-19 16:39:36 +00:00
arcker95
c64b09d891
Translated using Weblate (Italian)
Currently translated at 100.0% (316 of 316 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/it/
2026-01-19 16:39:35 +00:00
Priit Jõerüüt
449185b9c3
Translated using Weblate (Estonian)
Currently translated at 100.0% (316 of 316 strings)

Translation: Wholphin/Wholphin
Translate-URL: https://translate.codeberg.org/projects/wholphin/wholphin/et/
2026-01-19 16:39:35 +00:00
Ray
0f52616d21
Add user PIN protection (#719)
## Description
Adds (back) the ability to set a per-user PIN. This is required to
switch to the user. If the user has a PIN, this overrides and ignores
the "Sign in automatically" setting for that user.

The PIN consists of any combination of D-Pad directional buttons. If you
forget the PIN, you can click the button to login via the server instead
(ie QuickConnect or username/password) which will also remove the PIN so
you can set a new one if desired.

### Related issues
Closes #268 
Replaces #398
Related to #321 & #356

### Screenshots
![enter_pin
Large](https://github.com/user-attachments/assets/aa25364d-1266-410d-846e-8dc32c56a794)
2026-01-19 11:39:29 -05:00
Ray
946043342a
Use the user's profile image on nav drawer (#723)
## Description
Replaces the generic user icon with the user's profile image on the nav
drawer

If there's no image it will fall back to the generated color & first
letter just like on the user list page.

### Related issues
Closes #631

### Screenshots
<img width="54" height="160" alt="image"
src="https://github.com/user-attachments/assets/bee21e56-104a-420f-bb7d-aae717f8aeb0"
/>
2026-01-19 11:39:21 -05:00
Ray
4dd44b935c
Add optional AV1 software decoding via dav1d for ExoPlayer (#721)
## Description
Adds the [`dav1d` decoder
module](https://github.com/androidx/media/tree/release/libraries/decoder_av1)
for ExoPlayer as an option. It can be enabled in advanced settings.

Performance will vary between devices.

### Related issues
Closes #103

### Dev notes

As with the ffmpeg module, this one is not required to build the entire
app so it's easier for developers to get started.

This also introduces a customized `DefaultRenderersFactory` for
ExoPlayer, but its largely copied from the super class's implementation.
2026-01-18 18:35:41 -05:00
Damontecres
a0329b2c1d
Fix episode row focus 2026-01-17 22:51:28 -05:00
Ray
08355bf24b
Fixes focusing issues on many rows (#718)
## Description
Fixes focus jumping back a few cards on rows when returning to a page

I think some behavior changes occurred in a recent compose release.
`requestFocus` doesn't throw an exception anymore for example. Focus in
compose has always been finicky.

This PR basically adds some delegating parent focus down its to
children. Also, most rows now maintain an internal position state to
track where the focus requester is applied.

### Related issues
Closes #632
2026-01-17 18:09:17 -05:00
Ray
154713d3f1
Several small bug fixes (#717)
## Description
- Fixes a copy-paste error where checking if Seerr support 4K for TV
accidently used the movie 4K value
- Always show the loading indicator while waiting for playback to begin
- This has the side effect of fixing MPV playback not starting until the
UI changes (recomposes). That's a hacky fix, but should work while I try
to figure out the real cause

### Related issues
Fixes #715
2026-01-17 18:09:05 -05:00
Ray
bbeb42dab9
Keep grid controls accessible if error occurs (#714)
## Description
If an error occurs while fetching data for the grid, leave the controls
accessible. This is useful in case a particular sort or filter causes an
error because the app remembers those values between page loads.

Essentially the error message is shown in place of the grid content
instead of the entire tab.

### Related issues
Fixes #712
2026-01-16 17:15:16 -05:00
Damontecres
88de065fe0
Another cancel button fix 2026-01-16 14:38:16 -05:00
Ray
03b332e4c4
Fixes a few discover page UI bugs (#710)
## Description
- Fixes when to show/hide Request & Cancel buttons
- Removes the More button
- Uses a larger 16x9 backdrop so that the fade is better
- Fix reloading the backdrop on series pages

### Related issues
Fixes #706
2026-01-16 13:43:59 -05:00
Damontecres
ccd8c80d5e
Fix not showing some multiple versions in labels 2026-01-14 18:33:15 -05:00
Ray
c9d1244057
Optimize quick details UI (#674)
## Description
This PR optimizes the rendering of "quick details" in headers. That's
the dot separated row of Season/Episode/Date/Runtime, etc

The UI is slightly different because I moved the "Ends at" part to the
end of the row. The dots & spacing is also slightly different.

In testing this on my CCwGTV HD, a pretty low powered device, the PR
improved the time to render by over 3x (59.42ms->17.72ms). Note: these
times are during profiling and are not real world performance, but the
relative change should be applicable in the real world.

### Dev details
- Changes the dot separated row of multiple Text & Box composables into
a row of two Texts
- The text is an `AnnotatedString` which is created on the IO thread
when `BaseItem` is created
- A separate composable creates the "Ends at" to prevent recompositions
of the other strings
2026-01-14 17:07:17 -05:00
Ray
3215326515
Fixes "Pause with one click" for MPV (#701)
## Description
Fixes "Pause with one click" so the desired behavior isn't reversed and
now shows the controls when pausing.

This bug happened because MPV commands are async, so there is a tiny
delay before the pausing occurs and the playback state is updated.
However, the logic to decided whether to show the controls or not checks
the playback state immediately.

### Related issues
Fixes #697
2026-01-14 17:06:40 -05:00
Justin Caveda
d725821011
[FEAT] Add voicesearch button to search page (#637)
## Description
This PR is a rewrite of a previously submitted PR for this same feature.
It implements native Voice Search for Android TV using Android's
SpeechRecognizer API.

Key Changes

  New Files:
- VoiceInputManager.kt - Handles SpeechRecognizer lifecycle, permission
management, and audio level normalization
- VoiceSearchButton.kt - Composable button with audio-reactive pulse and
full-screen listening dialog

  UI/UX:
  - Audio-reactive microphone button that pulses based on input volume
  - Full-screen listening overlay with animated states:
- Listening - Pulsing bubble with ripple rings, shows partial
transcription
    - Processing - Animated dots while waiting for final result
- Error - Red bubble with localized error message, auto-dismisses after
3s

### Related issues
Resolves https://github.com/damontecres/Wholphin/issues/515

### AI/LLM usage
The initial draft of this change from the prior PR was created with the
assistance of Claude Code, which was heavily leaned on for the overlay.
I have taken the initial draft, gone through it, and re-implemented by
hand to clean it up, narrow the scope (AI loves to touch and change
things unrelated to what you're working on) and make it more readable.
AI was used in the last stage to assist with finding any logic
errors/bugs I may have missed (by looking through code and also by
looking over ADB logs from testing on Nvidia Shield).. AI was also used
to create the tests found in TestVoiceInputManager.kt. Lastly, I fed the
diffs to an AI to help summarize the changes for this PR in an easy to
read manner.

---------

Co-authored-by: Damontecres <damontecres@gmail.com>
2026-01-14 17:06:22 -05:00
Ray
c4e64c3367
Fixes to genre grids (#693)
## Description
Use only TV series genres for a TV library's genre tab. This ensures
only series are shown, not episodes, which removes some of the seemingly
empty genres.

Also fixes the image filtering to ensure an item with a backdrop is
always used if available.

### Related issues
Fixes #689
Fixes #690
2026-01-13 16:05:09 -05:00
Justin Caveda
18e4877736
Fix wrong dialog showing after Seerr login (#688)
**Description**

Fixes a race condition in the Seerr integration.

When you added a new Seerr server and logged in successfully, the app
would immediately show the "Disable Seerr?" dialog instead of a success
message. The state was getting mixed up during recomposition and
thinking you wanted to remove the server you just added.

Fixed by being more explicit about what mode the dialog is in (adding vs
removing) so it can't get confused by background state changes. Also
added a success toast when login works.

**AI/LLM usage**

Used Claude Code to analyze the issue.
2026-01-13 15:32:29 -05:00
Ray
7c018f9a37
Use circular cards for people (#691)
## Description
Clips person images to a circle. The rectangle is still used in grid
pages like favorite people.

This PR also updates the fallback image to use a person icon if there is
no image for that person

Also adds role/job to discover pages' people rows

### Related issues
Closes #682 

### Screenshots

![Image](https://github.com/user-attachments/assets/9ca5c25b-5ba0-49d9-a680-6520804b0ace)
2026-01-13 14:16:49 -05:00
Ray
5cb3662995
Fix jumping to a letter for many grids (#687)
## Description
On any grid that wasn't showing movies, tv shows, or videos, the jump to
letter functionality did not work correctly.

This PR fixes jumping for other media types, eg collections or episodes.
Additionally, the jump now also takes filters into account, so if
filtering Movies, it will jump to the right place now within the
available movies.

### Related issues
Fixes #683
2026-01-12 22:47:35 -05:00
Ray
80670c3e0f
Support requesting 4k media in discover (#685)
## Description
If the server support it and the user has permission, allows for
requesting 4K media

### Related issues
A follow up to #558
2026-01-12 21:55:50 -05:00
Ray
4c7c465c67
Add integration with Jellyseerr/Seerr (#558)
## Description
This PR add the ability to integrate with a [Jellyseerr/Seerr
server](https://github.com/seerr-team/seerr).

### Features
- Login to the Seerr server using API Key, Jellyfin credentials, or
local Seerr credentials
    - Separate Seerr logins per user profile
- Search Seerr from the search page
- Discover media from Seerr on the nav drawer `Discover` page
    - Also from movie, series, or person pages
- Seamless integration with existing media, i.e. selecting media found
from Seerr that already exists on the Jellyfin server, will go directly
to the regular media page
- Mostly consistent UI between Jellyfin media & Seerr media
- Submit requests to Seerr
- Cancel submitted requests

### Screenshots

![discover](https://github.com/user-attachments/assets/f830b48f-e2f1-43f4-9680-9c6d4e071765)

### Related issues
Closes #54

## Acknowledgements

The `app/src/main/seerr/seerr-api.yml` file is copied & modified from
https://github.com/seerr-team/seerr/blob/develop/seerr-api.yml. I hope
to try to upstream some of the changes in the future.
2026-01-12 16:35:27 -05:00
Ray
230b937048
Bug fixes (#680)
## Description
Gathering a couple final bug fixes

- Fixes the audio change dialog copy-paste error
2026-01-12 15:53:09 -05:00
Justin Caveda
8111f8bab2
Fix season numbers not appearing when scrolling (#679)
**Description**

Fixes a regression where season numbers in the tab strip were invisible
when scrolling through long series (15+ seasons).

**Related issues**

Fixes #677

**AI/LLM usage**

Used Claude Code to analyze diffs from recent commits in order to find
which commit caused the regression.

---------

Co-authored-by: Damontecres <damontecres@gmail.com>
2026-01-12 15:33:02 -05:00
Ray
d5192abf62
Return focus to the tabs if a grid has no results (#676)
## Description
Previously, if you clicked on a tab and the resulting grid had no
results, the nav drawer would open and focus which is not good.

This PR fixes that and instead returns focus back to the tab row.

### Related issues
Fixes #543
2026-01-11 21:36:24 -05:00