Skip to content

Commit d791527

Browse files
committed
fix(palette): 2-stop gradient on phone layouts — secondary → theme bg
Drop the vibrant primary from the rendered gradient across MiniPlayer, player-view, album/artist/playlist-detail, and ExpandedPlayerView. The 3-stop bi-tone read as too busy on smaller screens. `primary` still extracts and is returned from `useImagePalette` for future tablet/ landscape layouts with more room.
1 parent ec9ce91 commit d791527

6 files changed

Lines changed: 58 additions & 44 deletions

File tree

src/components/ExpandedPlayerView.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,16 @@ export function ExpandedPlayerView({
120120
const { primary, secondary, gradientOpacity: extractedGradientOpacity } =
121121
useImagePalette(currentTrack?.coverArt);
122122

123-
// 3-stop diagonal gradient: extracted primary → extracted secondary (if any)
124-
// → a slightly-darkened theme background so the moodier "expanded player"
125-
// feel is preserved while the extracted colours dominate the hero area.
123+
// 2-stop diagonal gradient: extracted secondary (prefer) → a
124+
// slightly-darkened theme background. We drop the more-vibrant
125+
// `primary` from the render and use `secondary` as the calmer top
126+
// colour so the two extracted hues don't fight with each other
127+
// across the large hero area. `primary` still extracts and is
128+
// available in the hook for future bi-tone tablet layouts.
126129
const backgroundEnd = mixHexColors(colors.background, '#000000', 0.15);
127-
const gradientColors: readonly [string, string, ...string[]] = secondary
128-
? [primary ?? colors.background, secondary, backgroundEnd]
129-
: [primary ?? colors.background, backgroundEnd];
130-
const gradientLocations: readonly [number, number, ...number[]] = secondary ? [0, 0.3, 0.6] : [0, 0.6];
130+
const gradientTopColor = secondary ?? primary ?? colors.background;
131+
const gradientColors: readonly [string, string, ...string[]] = [gradientTopColor, backgroundEnd];
132+
const gradientLocations: readonly [number, number, ...number[]] = [0, 0.6];
131133

132134
// Right panel mode: queue (default), lyrics placeholder, or album info
133135
const [rightPanelMode, setRightPanelMode] = useState<'queue' | 'lyrics' | 'info'>('queue');

src/components/MiniPlayer.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,19 @@ export function MiniPlayer() {
7979
return `${hex}${a}`;
8080
};
8181

82-
// 3-stop vertical gradient: extracted primary at top → extracted
83-
// secondary (if any) in the middle → theme background at the bottom.
84-
// Preserves the previous "fade into tab bar" look while adding the
85-
// secondary colour as a mid-stop for more visual depth.
86-
const topColor = queueLoading ? PLACEHOLDER_BG : (primary ?? colors.card);
87-
const gradientColors: readonly [string, string, ...string[]] = secondary
88-
? [withAlpha(topColor, 0.65), withAlpha(secondary, 0.65), withAlpha(colors.background, 0.65)]
89-
: [withAlpha(topColor, 0.65), withAlpha(colors.background, 0.65)];
90-
const gradientLocations: readonly [number, number, ...number[]] = secondary ? [0, 0.5, 1] : [0, 1];
82+
// 2-stop vertical gradient: extracted secondary (prefer) → theme
83+
// background. On smaller screens the richer 3-stop bi-tone read as
84+
// too busy over the mini player, so we drop the more-vibrant `primary`
85+
// from the render and use `secondary` (the most-common hue distinct
86+
// from primary) as the calmer top colour. `primary` still extracts
87+
// and is available in the hook for future tablet/landscape layouts.
88+
const extractedTop = secondary ?? primary ?? colors.card;
89+
const topColor = queueLoading ? PLACEHOLDER_BG : extractedTop;
90+
const gradientColors: readonly [string, string, ...string[]] = [
91+
withAlpha(topColor, 0.65),
92+
withAlpha(colors.background, 0.65),
93+
];
94+
const gradientLocations: readonly [number, number, ...number[]] = [0, 1];
9195

9296
return (
9397
<View style={[styles.container, { backgroundColor: withAlpha(colors.card, 0.65) }]}>

src/screens/album-detail.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,15 @@ export function AlbumDetailScreen() {
335335
[colors.textPrimary, colors.textSecondary, t],
336336
);
337337

338-
// 3-stop gradient: extracted primary → extracted secondary (if any) →
339-
// theme background at the bottom. Keeps the dark/light theme colour at
340-
// the bottom of the hero area while using both extracted colours up top.
341-
const gradientColors: readonly [string, string, ...string[]] = secondary
342-
? [primary ?? colors.background, secondary, colors.background]
343-
: [primary ?? colors.background, colors.background];
344-
const gradientLocations: readonly [number, number, ...number[]] = secondary ? [0, 0.25, 0.5] : [0, 0.5];
338+
// 2-stop gradient: extracted secondary (prefer) → theme background.
339+
// On smaller screens the richer 3-stop bi-tone read as too busy over
340+
// the hero, so we drop the more-vibrant `primary` from the render and
341+
// use `secondary` (the most-common hue distinct from primary) as the
342+
// calmer top colour. `primary` still extracts and is available in the
343+
// hook for future tablet/landscape layouts with more room.
344+
const gradientTopColor = secondary ?? primary ?? colors.background;
345+
const gradientColors: readonly [string, string, ...string[]] = [gradientTopColor, colors.background];
346+
const gradientLocations: readonly [number, number, ...number[]] = [0, 0.5];
345347

346348
const gradientAnimatedStyle = useAnimatedStyle(() => ({
347349
opacity: gradientOpacity.value,

src/screens/artist-detail.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -199,13 +199,15 @@ export function ArtistDetailScreen() {
199199
const onRefresh = useCallback(() => fetchData(true), [fetchData]);
200200

201201
/* ---- Derived values ---- */
202-
// 3-stop gradient: extracted primary → extracted secondary (if any) →
203-
// theme background at the bottom. Keeps the dark/light theme colour at
204-
// the bottom of the hero area while using both extracted colours up top.
205-
const gradientColors: readonly [string, string, ...string[]] = secondary
206-
? [primary ?? colors.background, secondary, colors.background]
207-
: [primary ?? colors.background, colors.background];
208-
const gradientLocations: readonly [number, number, ...number[]] = secondary ? [0, 0.25, 0.5] : [0, 0.5];
202+
// 2-stop gradient: extracted secondary (prefer) → theme background.
203+
// On smaller screens the richer 3-stop bi-tone read as too busy over
204+
// the hero, so we drop the more-vibrant `primary` from the render and
205+
// use `secondary` (the most-common hue distinct from primary) as the
206+
// calmer top colour. `primary` still extracts and is available in the
207+
// hook for future tablet/landscape layouts with more room.
208+
const gradientTopColor = secondary ?? primary ?? colors.background;
209+
const gradientColors: readonly [string, string, ...string[]] = [gradientTopColor, colors.background];
210+
const gradientLocations: readonly [number, number, ...number[]] = [0, 0.5];
209211

210212
const gradientAnimatedStyle = useAnimatedStyle(() => ({
211213
opacity: gradientOpacity.value,

src/screens/player-view.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,15 @@ export function PlayerView() {
121121

122122
const { primary, secondary, gradientOpacity } = useImagePalette(currentTrack?.coverArt);
123123

124-
// 3-stop gradient: extracted primary → extracted secondary (if any) →
125-
// theme background. Keeps the dark/light theme background at the bottom
126-
// while letting the two extracted colours colour the top portion.
127-
const gradientColors: readonly [string, string, ...string[]] = secondary
128-
? [primary ?? colors.background, secondary, colors.background]
129-
: [primary ?? colors.background, colors.background];
130-
const gradientLocations: readonly [number, number, ...number[]] = secondary ? [0, 0.3, 0.6] : [0, 0.6];
124+
// 2-stop gradient: extracted secondary (prefer) → theme background. We
125+
// drop the more-vibrant `primary` from the render here because on small
126+
// phone screens it reads as too busy over the hero — `secondary` (the
127+
// most-common hue distinct from primary) is calmer. `primary` still
128+
// extracts and is available in the hook for future tablet/landscape
129+
// layouts that have more room for the richer bi-tone.
130+
const gradientTopColor = secondary ?? primary ?? colors.background;
131+
const gradientColors: readonly [string, string, ...string[]] = [gradientTopColor, colors.background];
132+
const gradientLocations: readonly [number, number, ...number[]] = [0, 0.6];
131133

132134
const offlineMode = offlineModeStore((s) => s.offlineMode);
133135

src/screens/playlist-detail.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -469,13 +469,15 @@ export function PlaylistDetailScreen() {
469469
[colors.textPrimary, colors.textSecondary, t],
470470
);
471471

472-
// 3-stop gradient: extracted primary → extracted secondary (if any) →
473-
// theme background at the bottom. Keeps the dark/light theme colour at
474-
// the bottom of the hero area while using both extracted colours up top.
475-
const gradientColors: readonly [string, string, ...string[]] = secondary
476-
? [primary ?? colors.background, secondary, colors.background]
477-
: [primary ?? colors.background, colors.background];
478-
const gradientLocations: readonly [number, number, ...number[]] = secondary ? [0, 0.25, 0.5] : [0, 0.5];
472+
// 2-stop gradient: extracted secondary (prefer) → theme background.
473+
// On smaller screens the richer 3-stop bi-tone read as too busy over
474+
// the hero, so we drop the more-vibrant `primary` from the render and
475+
// use `secondary` (the most-common hue distinct from primary) as the
476+
// calmer top colour. `primary` still extracts and is available in the
477+
// hook for future tablet/landscape layouts with more room.
478+
const gradientTopColor = secondary ?? primary ?? colors.background;
479+
const gradientColors: readonly [string, string, ...string[]] = [gradientTopColor, colors.background];
480+
const gradientLocations: readonly [number, number, ...number[]] = [0, 0.5];
479481

480482
const gradientAnimatedStyle = useAnimatedStyle(() => ({
481483
opacity: gradientOpacity.value,

0 commit comments

Comments
 (0)