mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
d49424e95b
* feat(ui): prototype compact hero and toolbar buttons (Large/Small appearance setting) * feat(settings): rename action-button size toggle to "Compact buttons" Promote the hero-button prototype to a real, app-wide setting. - rename heroButtonSize → buttonSize, data-hero-buttons → data-button-size, hero-action-bar/hero-btn-label → compact-action-bar/compact-btn-label - relabel "Hero buttons" → "Compact buttons" and broaden the description (action + toolbar buttons across detail pages and browse views) in all 11 locales - move the feature CSS out of cover-lightbox.css into its own compact-buttons.css - add tests: themeStore buttonSize toggle, SelectionToggleButton * docs(changelog): compact buttons appearance toggle (#1189) * docs(credits): compact buttons appearance toggle (#1189)
62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
import React from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { Play, RefreshCw } from 'lucide-react';
|
|
|
|
interface Props {
|
|
selectedGenre: string | null;
|
|
loading: boolean;
|
|
genreMixLoading: boolean;
|
|
genreMixComplete: boolean;
|
|
genreMixSongsLength: number;
|
|
filteredSongsLength: number;
|
|
randomMixSize: number;
|
|
onRefresh: () => void;
|
|
onPlayAll: () => void;
|
|
}
|
|
|
|
export default function RandomMixHeader({
|
|
selectedGenre, loading, genreMixLoading, genreMixComplete,
|
|
genreMixSongsLength, filteredSongsLength, randomMixSize,
|
|
onRefresh, onPlayAll,
|
|
}: Props) {
|
|
const { t } = useTranslation();
|
|
const isGenreLoading = selectedGenre && !genreMixComplete;
|
|
const isPlayDisabled = loading
|
|
|| (selectedGenre ? !genreMixComplete || genreMixSongsLength === 0 : filteredSongsLength === 0);
|
|
|
|
return (
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '2rem' }}>
|
|
<h1 className="page-title">{t('randomMix.title')}</h1>
|
|
|
|
<div className="compact-action-bar" style={{ display: 'flex', gap: '0.5rem' }}>
|
|
<button
|
|
className="btn btn-surface"
|
|
onClick={onRefresh}
|
|
disabled={selectedGenre ? genreMixLoading : loading}
|
|
aria-label={selectedGenre ? t('randomMix.remixGenre', { genre: selectedGenre }) : t('randomMix.remix')}
|
|
data-tooltip={selectedGenre
|
|
? t('randomMix.remixTooltipGenre', { genre: selectedGenre })
|
|
: t('randomMix.remixTooltip')
|
|
}
|
|
>
|
|
<RefreshCw size={18} className={(selectedGenre ? genreMixLoading : loading) ? 'spin' : ''} />
|
|
<span className="compact-btn-label">{selectedGenre ? t('randomMix.remixGenre', { genre: selectedGenre }) : t('randomMix.remix')}</span>
|
|
</button>
|
|
<button
|
|
className={`btn ${isGenreLoading ? 'btn-surface' : 'btn-primary'}`}
|
|
onClick={onPlayAll}
|
|
disabled={isPlayDisabled}
|
|
aria-label={t('randomMix.playAll')}
|
|
data-tooltip={t('randomMix.playAll')}
|
|
>
|
|
{isGenreLoading ? (
|
|
<><div className="spinner" style={{ width: 14, height: 14, borderWidth: 2 }} /> <span className="compact-btn-label">{Math.min(genreMixSongsLength, randomMixSize)} / {randomMixSize}</span></>
|
|
) : (
|
|
<><Play size={18} fill="currentColor" /> <span className="compact-btn-label">{t('randomMix.playAll')}</span></>
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|