mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
2d27428056
Adds a new sub-section under Settings → Personalisation (Advanced) that
hides individual controls in the player bar: Star rating, Favorite
(heart), Last.fm love, Equalizer, Mini player. Last.fm love still only
renders when a Last.fm session exists; the overflow row in the player
collapses when both Equalizer and Mini player are hidden.
- New `playerBarLayoutStore` (Zustand + persist, items[{id, visible}] +
rehydrate sanitize) following the queueToolbar / playlistLayout
pattern; defaults to all visible.
- New `PlayerBarLayoutCustomizer` reuses the same row + toggle pattern
as the other personalisation customisers.
- Gates threaded through `PlayerTrackInfo` (3 controls), `PlayerBar`
(EQ + Mini buttons), and `PlayerOverflowMenu` (EQ + Mini in the
overflow row, with row-level conditional).
- `PersonalisationTab`: added as the last advanced sub-section so it
only appears when the global Advanced Mode toggle is on.
- Settings search index gets entries for both Playlist page layout and
Player bar (playlist row was missing).
- New i18n keys `settings.playerBar*` in all 9 locales.
Reuses kveld9's design from PR #627; not merged because the locale
split and the Advanced Mode refactor landed afterwards. Credited via
Co-Authored-By trailer + a new line in settingsCredits.ts under the
existing kveld9 entry.
Co-authored-by: Kveld. <kveld912@proton.me>
53 lines
2.1 KiB
TypeScript
53 lines
2.1 KiB
TypeScript
import React from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { Heart, PictureInPicture2, SlidersVertical, Star } from 'lucide-react';
|
|
import LastfmIcon from '../LastfmIcon';
|
|
import {
|
|
usePlayerBarLayoutStore,
|
|
type PlayerBarLayoutItemId,
|
|
} from '../../store/playerBarLayoutStore';
|
|
|
|
const PLAYER_BAR_LAYOUT_LABEL_KEYS: Record<PlayerBarLayoutItemId, string> = {
|
|
starRating: 'settings.playerBarStarRating',
|
|
favorite: 'settings.playerBarFavorite',
|
|
lastfmLove: 'settings.playerBarLastfmLove',
|
|
equalizer: 'settings.playerBarEqualizer',
|
|
miniPlayer: 'settings.playerBarMiniPlayer',
|
|
};
|
|
|
|
const PLAYER_BAR_LAYOUT_ICONS: Record<PlayerBarLayoutItemId, React.ReactNode> = {
|
|
starRating: <Star size={16} style={{ color: 'var(--text-muted)', flexShrink: 0 }} />,
|
|
favorite: <Heart size={16} style={{ color: 'var(--text-muted)', flexShrink: 0 }} />,
|
|
lastfmLove: (
|
|
<span style={{ color: 'var(--text-muted)', display: 'inline-flex', flexShrink: 0 }} aria-hidden>
|
|
<LastfmIcon size={16} />
|
|
</span>
|
|
),
|
|
equalizer: <SlidersVertical size={16} style={{ color: 'var(--text-muted)', flexShrink: 0 }} />,
|
|
miniPlayer: <PictureInPicture2 size={16} style={{ color: 'var(--text-muted)', flexShrink: 0 }} />,
|
|
};
|
|
|
|
export function PlayerBarLayoutCustomizer() {
|
|
const { t } = useTranslation();
|
|
const items = usePlayerBarLayoutStore(s => s.items);
|
|
const toggleItem = usePlayerBarLayoutStore(s => s.toggleItem);
|
|
|
|
return (
|
|
<div className="settings-card" style={{ padding: '4px 0' }}>
|
|
{items.map((it) => {
|
|
const label = t(PLAYER_BAR_LAYOUT_LABEL_KEYS[it.id]);
|
|
return (
|
|
<div key={it.id} className="sidebar-customizer-row">
|
|
{PLAYER_BAR_LAYOUT_ICONS[it.id]}
|
|
<span style={{ flex: 1, fontSize: 14, opacity: it.visible ? 1 : 0.45 }}>{label}</span>
|
|
<label className="toggle-switch" aria-label={label}>
|
|
<input type="checkbox" checked={it.visible} onChange={() => toggleItem(it.id)} />
|
|
<span className="toggle-track" />
|
|
</label>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|