diff --git a/CHANGELOG.md b/CHANGELOG.md index 573ca3f3..56723bba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Changed +### Settings — collapse-by-default cleanup, font picker without dropdown, OpenDyslexic at top + +**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#508](https://github.com/Psychotoxical/psysonic/pull/508)** + +* Every Settings sub-section now boots **collapsed**. Audio Device, Lyrics Sources, Last.fm, Sidebar, Random Mix, Offline Dir, Theme, Keybindings and Language used to auto-expand on first render — each tab felt like a wall of controls before the user had even looked for something specific. Click the section header to open what you actually need. +* **ThemePicker** no longer auto-expands the group containing the active theme. The blue dot in the group header already surfaces which group holds it. +* **Font picker** lost its inner dropdown button. Opening the Font sub-section now reveals the full font list directly; one click sets the font. +* **OpenDyslexic** moves to the top of the font list so dyslexic readers don't scroll past 14 sans-serifs to find their option. + ### Dependencies — npm / Cargo refresh and rodio 0.22 **By [@cucadmuh](https://github.com/cucadmuh), PR [#463](https://github.com/Psychotoxical/psysonic/pull/463)** diff --git a/src/components/ThemePicker.tsx b/src/components/ThemePicker.tsx index 85b21a10..b724ece0 100644 --- a/src/components/ThemePicker.tsx +++ b/src/components/ThemePicker.tsx @@ -180,8 +180,10 @@ interface Props { } export default function ThemePicker({ value, onChange }: Props) { - const initialOpen = THEME_GROUPS.find(g => g.themes.some(t => t.id === value))?.group ?? THEME_GROUPS[0].group; - const [openGroup, setOpenGroup] = useState(initialOpen); + // All groups collapsed on first render. The blue dot in the header surfaces + // which group holds the active theme, so auto-expanding it on mount just + // adds visual noise to a screen that already has a long sub-section list. + const [openGroup, setOpenGroup] = useState(null); const toggle = (group: string) => setOpenGroup(prev => prev === group ? null : group); diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 953cd5ac..3bd14269 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -1677,7 +1677,6 @@ export default function Settings() { const [devicesLoading, setDevicesLoading] = useState(false); const [showClearConfirm, setShowClearConfirm] = useState(false); const [clearing, setClearing] = useState(false); - const [fontPickerOpen, setFontPickerOpen] = useState(false); const [ndAdminAuth, setNdAdminAuth] = useState<{ token: string; serverUrl: string; username: string } | null>(null); const [ndAuthChecked, setNdAuthChecked] = useState(false); const addServerInviteAnchorRef = useRef(null); @@ -2269,7 +2268,6 @@ export default function Settings() { } - defaultOpen >
{IS_MACOS ? ( @@ -2698,7 +2696,6 @@ export default function Settings() { } - defaultOpen > @@ -2759,7 +2756,6 @@ export default function Settings() { } - defaultOpen >
{auth.lastfmSessionKey ? ( @@ -2958,7 +2954,6 @@ export default function Settings() { } - defaultOpen action={ - {fontPickerOpen && ( -
- {( - [ - { id: 'inter', label: 'Inter', stack: "'Inter Variable', sans-serif" }, - { id: 'outfit', label: 'Outfit', stack: "'Outfit Variable', sans-serif" }, - { id: 'dm-sans', label: 'DM Sans', stack: "'DM Sans Variable', sans-serif" }, - { id: 'nunito', label: 'Nunito', stack: "'Nunito Variable', sans-serif" }, - { id: 'rubik', label: 'Rubik', stack: "'Rubik Variable', sans-serif" }, - { id: 'space-grotesk', label: 'Space Grotesk', stack: "'Space Grotesk Variable', sans-serif" }, - { id: 'figtree', label: 'Figtree', stack: "'Figtree Variable', sans-serif" }, - { id: 'manrope', label: 'Manrope', stack: "'Manrope Variable', sans-serif" }, - { id: 'plus-jakarta-sans', label: 'Plus Jakarta Sans', stack: "'Plus Jakarta Sans Variable', sans-serif" }, - { id: 'lexend', label: 'Lexend', stack: "'Lexend Variable', sans-serif" }, - { id: 'geist', label: 'Geist', stack: "'Geist Variable', sans-serif" }, - { id: 'jetbrains-mono', label: 'JetBrains Mono', stack: "'JetBrains Mono Variable', monospace" }, - { id: 'golos-text', label: 'Golos Text', stack: "'Golos Text Variable', sans-serif" }, - { id: 'unbounded', label: 'Unbounded', stack: "'Unbounded Variable', sans-serif" }, - { id: 'opendyslexic', label: 'OpenDyslexic', stack: "'OpenDyslexic', sans-serif", hint: t('settings.fontHintOpenDyslexic') }, - ] as { id: FontId; label: string; stack: string; hint?: string }[] - ).map(f => ( - - ))} -
- )} +
+ {( + [ + // Accessibility-first: OpenDyslexic at the top so dyslexic + // readers don't have to scroll past 14 sans-serifs to find it. + { id: 'opendyslexic', label: 'OpenDyslexic', stack: "'OpenDyslexic', sans-serif", hint: t('settings.fontHintOpenDyslexic') }, + { id: 'inter', label: 'Inter', stack: "'Inter Variable', sans-serif" }, + { id: 'outfit', label: 'Outfit', stack: "'Outfit Variable', sans-serif" }, + { id: 'dm-sans', label: 'DM Sans', stack: "'DM Sans Variable', sans-serif" }, + { id: 'nunito', label: 'Nunito', stack: "'Nunito Variable', sans-serif" }, + { id: 'rubik', label: 'Rubik', stack: "'Rubik Variable', sans-serif" }, + { id: 'space-grotesk', label: 'Space Grotesk', stack: "'Space Grotesk Variable', sans-serif" }, + { id: 'figtree', label: 'Figtree', stack: "'Figtree Variable', sans-serif" }, + { id: 'manrope', label: 'Manrope', stack: "'Manrope Variable', sans-serif" }, + { id: 'plus-jakarta-sans', label: 'Plus Jakarta Sans', stack: "'Plus Jakarta Sans Variable', sans-serif" }, + { id: 'lexend', label: 'Lexend', stack: "'Lexend Variable', sans-serif" }, + { id: 'geist', label: 'Geist', stack: "'Geist Variable', sans-serif" }, + { id: 'jetbrains-mono', label: 'JetBrains Mono', stack: "'JetBrains Mono Variable', monospace" }, + { id: 'golos-text', label: 'Golos Text', stack: "'Golos Text Variable', sans-serif" }, + { id: 'unbounded', label: 'Unbounded', stack: "'Unbounded Variable', sans-serif" }, + ] as { id: FontId; label: string; stack: string; hint?: string }[] + ).map(f => ( + + ))} +
@@ -3948,7 +3914,6 @@ export default function Settings() { } - defaultOpen action={