Commit graph

9 commits

Author SHA1 Message Date
0b61007b3f Extract naturalCardBaseDp and scaledDensity helpers so tests bind to real code
resolvedCardHeight previously routed through a two-branch if(isWide)
hidden inside the composable extension, so the regression tests for
the global-slider reach bug only exercised the inner resolveCardHeight
(which was never broken). Lift the aspect -> natural base mapping
into a pure naturalCardBaseDp(AspectRatio) function with an exhaustive
when, and test that directly. SQUARE and FOUR_THREE rows piggyback on
the TALL global by design; the override branch still handles their
absolute heightDp values (Music presets at 100dp, etc.).

MainContent and DisplaySizePage's preview now both call a single
scaledDensity(base, percent) helper instead of inlining Density(...)
constructions. The double-fontScale-multiply regression has a real
guard now: tests assert scaledDensity(2.0, 1.0, 150) returns density
3.0 and fontScale 1.0 (not 1.5), and a third test confirms an
accessibility fontScale survives a UI scale change.

Pure refactor + test sharpening; no behaviour change.
2026-05-28 10:05:21 +02:00
71e74949b7 Fix global slider reach + UI-scale font math + per-type grid spacing
resolvedCardHeight now picks the row's natural base (128 for WIDE /
episode aspect, 172 for TALL / poster aspect) via HomeRowViewOptions
.aspectRatio and selects the matching scaled global (cardHeightDp or
episodeCardHeightDp) from InterfaceCustomization. Previously the
function always passed HEIGHT_2X3_DP as the natural base, so every
row storing heightDp = HEIGHT_EPISODE = 128 hit the override branch
and the global Card slider silently skipped episode-aspect home rows
(Favorite-Episode preset, genreDefault rows, etc.).

MainContent and DisplaySizePage's preview Density no longer multiply
fontScale by the UI-scale factor. sp rendering pipes through
density * fontScale, so scaling both produced factor^2 text size -
slider 150% rendered fonts at 2.25x while layouts rendered at 1.5x.
Scaling density alone makes both linear; the user's system fontScale
stays applied on top.

ItemGrid, CollectionFolderGrid, CollectionMixedGrid, and HomeRowGrid
now honor the per-type viewOptions.spacing base (16/24/16 for the
three view-options presets) the same way CollectionFolderList already
did - scaled by the global Spacing percent at the consumer site.
Before this fix only the list-mode consumer honored the per-type base
and grids fell back to a fixed 16dp baseline regardless of preset.

Also wires ViewMoreCard's default size into cardHeightDp and
QueueRowOverlay's queue-thumbnail height into episodeCardHeightDp so
those two surfaces scale too. Adds a Why: comment on the
migrateLegacyRowSpacing clamp (50..150 per-row range, intentionally
narrower than the global 25..175). Drops a couple of restating //
comments in DisplaySizePage and imports java.util.EnumSet at the top
of InterfaceHelpersTest. New unit tests cover resolveCardHeight's
episode-natural-base path, per-row override precedence over the
global, and the linear-density invariant guarding against the
fontScale bug regressing.
2026-05-28 10:05:21 +02:00
8fb301c2bb Add Display size customization page
Consolidates UI sizing into three percentage sliders surfaced through a
new Settings -> Interface -> Display size page: UI scale (50-150%),
Card size (50-150%), Spacing (25-175%). Each persists immediately via
DataStore; the rest of the app reflects them through
LocalInterfaceCustomization and a root-level LocalDensity override in
MainContent.

The page mirrors HomeSettingsPage's two-column shell: a fixed-width
settings panel on the left, HomePageContent rendering live preview rows
on the right. The page snapshots its own density on entry so the slider
rail stays fixed while UI scale changes the rest of the app.

Includes a one-shot AppUpgradeHandler migration block for installs at or
before 0.6.4-31-g0 that resets the three new percent fields to their
defaults.
2026-05-28 10:02:08 +02:00
Damontecres
366483599c
Customize which ratings to display (#1407)
## Description
Adds a setting, Settings->Advanced->"Customize which ratings to
display", which allows for toggling parental, community, or critic
ratings to be displayed in the quick details.

This doesn't apply to discover yet.

### Related issues
Related to #1020

### Testing
Emulator

## Screenshots

### Just community rating
<img width="1280" height="720" alt="ratings Large"
src="https://github.com/user-attachments/assets/d6f9ad8a-6cc5-4680-9d2f-66d16a44b41e"
/>


## AI or LLM usage
None
2026-05-20 12:40:58 -04:00
Damontecres
dbd17597b2
Show public users when switching users (#1358)
## Description
Show the public users (ie "Hide this user from login screens" is
unchecked) if the server has any. Previously, all users had to be
explicitly added by username or quick connect.

This PR also refactors the server & user pages to use modern state flows
and deletes some unused code.

### Related issues
Closes #600

### Testing
Emulator

## Screenshots
N/A

## AI or LLM usage
None
2026-05-10 08:50:08 -04:00
Ray
c92de3c33e
Fix some UI preference changes not being reflected immediately (#1146) 2026-03-25 21:55:00 -04:00
Ray
f9ff04c5b7
Fix issues when the system kills the app during playback (#1116)
## 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
2026-03-18 18:09:13 -04:00
Ray
ce44e9593b
Screensaver fixes (#1047)
## Description
Fixes a few issues with the in-app & OS screensavers

- Make sure clock is updating for in-app screensaver
- Fix crash if app is force quit before the OS screensaver starts

### Related issues
Fixes #1045 

### Testing
NVIDIA shield

## Screenshots
N/A

## AI or LLM usage
None
2026-03-06 08:46:47 -05:00
Ray
0004701296
Dev: add simple automated UI test setup (#1027)
## 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
2026-03-03 13:46:46 -05:00