mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
fix(home): swap Because-you-listened rail to AlbumRow under 696 px (#520)
* fix(home): swap Because-you-listened rail to AlbumRow under 696 px The hero-style BecauseCards are tuned for full-rail widths (3 cards at 1052 px+, 2 cards at 696-1051 px). Below that the cards stretched full-width with a fixed 160 px cover stuck on the left and centred text floating in a wide empty area — looked like three over-sized banners stacked vertically instead of a compact recommendation rail. A `ResizeObserver` on the rail wrapper now watches the container width and below 696 px renders a standard `AlbumRow` (which is already perf-tuned for narrow rails: artwork budget, viewport windowing, scroll paging). Wide layouts keep the unchanged hero card layout, so the mainstage view at full width is identical to before. * docs(changelog): add Because-you-listened narrow-layout fix entry
This commit is contained in:
committed by
GitHub
parent
268086ac74
commit
fec513b629
@@ -211,6 +211,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Fixed
|
||||
|
||||
### Home — Because-you-listened rail compact in narrow layouts
|
||||
|
||||
**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#520](https://github.com/Psychotoxical/psysonic/pull/520)**
|
||||
|
||||
* When the rail container drops below the 2-card threshold (≈ 696 px — sidebar + queue both open, mini, etc.), the home **Because-you-listened** section now switches to the standard `AlbumRow` layout instead of stretching the hero-style cards to full width. The narrow path inherits the rail's existing perf tuning (artwork budget, viewport windowing, scroll paging).
|
||||
* Wide layouts (>= 696 px) keep the existing 3-up hero cards with the "Similar to X" pill, album metadata, and album release-type pills — full-screen view is unchanged.
|
||||
* Detection runs through a single `ResizeObserver` on the rail wrapper. The wide path adds zero extra renders.
|
||||
|
||||
### Security — Tauri patch for IPC origin-confusion (GHSA-7gmj-67g7-phm9)
|
||||
|
||||
**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#509](https://github.com/Psychotoxical/psysonic/pull/509)**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { memo, useEffect, useMemo, useState } from 'react';
|
||||
import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Play, ListPlus, Music } from 'lucide-react';
|
||||
@@ -14,6 +14,7 @@ import CachedImage, { useCachedUrl } from './CachedImage';
|
||||
import { usePlayerStore, songToTrack } from '../store/playerStore';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { playAlbum } from '../utils/playAlbum';
|
||||
import AlbumRow from './AlbumRow';
|
||||
|
||||
const ANCHOR_HISTORY_KEY_PREFIX = 'psysonic_because_anchor_history:';
|
||||
const PICKS_HISTORY_KEY_PREFIX = 'psysonic_because_picks:';
|
||||
@@ -125,6 +126,24 @@ export default function BecauseYouLikeRail({
|
||||
);
|
||||
const [anchor, setAnchor] = useState<Anchor | null>(null);
|
||||
const [recs, setRecs] = useState<SubsonicAlbum[]>([]);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [narrow, setNarrow] = useState(false);
|
||||
|
||||
// 696px ≙ exactly 2 BecauseCards side-by-side (2*340 + 16 gap). Below that
|
||||
// the hero-style cards stretch full-width and dwarf the rest of the page,
|
||||
// so we swap in a standard AlbumRow which is already perf-tuned for narrow
|
||||
// rails (artwork budget, viewport windowing, scroll-paging).
|
||||
useEffect(() => {
|
||||
const el = containerRef.current;
|
||||
if (!el) return;
|
||||
const ro = new ResizeObserver(entries => {
|
||||
for (const entry of entries) {
|
||||
setNarrow(entry.contentRect.width < 696);
|
||||
}
|
||||
});
|
||||
ro.observe(el);
|
||||
return () => ro.disconnect();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
@@ -208,26 +227,36 @@ export default function BecauseYouLikeRail({
|
||||
return () => { cancelled = true; };
|
||||
}, [pool, activeServerId]);
|
||||
|
||||
if (!anchor || recs.length === 0) return null;
|
||||
if (!anchor || recs.length === 0) {
|
||||
return <div ref={containerRef} />;
|
||||
}
|
||||
|
||||
const sectionTitle = t('home.becauseYouLikeFor', { artist: anchor.name });
|
||||
|
||||
return (
|
||||
<section className="album-row-section because-you-like-rail">
|
||||
<div className="album-row-header">
|
||||
<h2 className="section-title" style={{ marginBottom: 0 }}>
|
||||
{t('home.becauseYouLikeFor', { artist: anchor.name })}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="because-card-grid">
|
||||
{recs.map(album => (
|
||||
<BecauseCard
|
||||
key={album.id}
|
||||
album={album}
|
||||
anchor={anchor.name}
|
||||
disableArtwork={disableArtwork}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
<div ref={containerRef}>
|
||||
{narrow ? (
|
||||
<AlbumRow title={sectionTitle} albums={recs} disableArtwork={disableArtwork} />
|
||||
) : (
|
||||
<section className="album-row-section because-you-like-rail">
|
||||
<div className="album-row-header">
|
||||
<h2 className="section-title" style={{ marginBottom: 0 }}>
|
||||
{sectionTitle}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="because-card-grid">
|
||||
{recs.map(album => (
|
||||
<BecauseCard
|
||||
key={album.id}
|
||||
album={album}
|
||||
anchor={anchor.name}
|
||||
disableArtwork={disableArtwork}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13916,7 +13916,7 @@ html[data-perf-disable-home-artwork-clip="true"] .home-lite-artwork .song-card-c
|
||||
/* Hide the 3rd card only inside the 2-column range, so:
|
||||
>= 1052px (3 cols) -> 3 cards in one row
|
||||
696-1051px (2 cols) -> 2 cards in one row, orphan dropped
|
||||
< 696px (1 col) -> 3 cards stacked, orphan welcome
|
||||
Below 696px the rail switches to a standard AlbumRow in JS — no layout here.
|
||||
Math: 3*340 + 2*16 = 1052 (3-col cutoff), 2*340 + 1*16 = 696 (2-col cutoff). */
|
||||
@container (min-width: 696px) and (max-width: 1051px) {
|
||||
.because-card-grid > :nth-child(n+3) {
|
||||
|
||||
Reference in New Issue
Block a user