feat(settings): library card grid max columns in Appearance (4–12, default 6)

Persist libraryGridMaxColumns, wire useCardGridMetrics and card grid layout,
add i18n and settings search index; document performance hint in copy.
This commit is contained in:
Maxim Isaev
2026-05-15 02:19:20 +03:00
parent 7c6d3694d4
commit 0f5ece6d03
21 changed files with 169 additions and 16 deletions
+45 -1
View File
@@ -1,8 +1,12 @@
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { invoke } from '@tauri-apps/api/core';
import { Clock, Maximize2, Palette, Sliders, Type, ZoomIn } from 'lucide-react';
import { Clock, LayoutGrid, Maximize2, Palette, Sliders, Type, ZoomIn } from 'lucide-react';
import { useAuthStore } from '../../store/authStore';
import {
LIBRARY_GRID_MAX_COLUMNS_MAX,
LIBRARY_GRID_MAX_COLUMNS_MIN,
} from '../../store/authStoreDefaults';
import type { SeekbarStyle } from '../../store/authStoreTypes';
import { useFontStore, FontId } from '../../store/fontStore';
import { useThemeStore } from '../../store/themeStore';
@@ -108,6 +112,46 @@ export function AppearanceTab() {
</div>
</SettingsSubSection>
<SettingsSubSection
title={t('settings.libraryGridMaxColumnsTitle')}
icon={<LayoutGrid size={16} />}
>
<div className="settings-card">
<div className="settings-hint settings-hint-info" style={{ marginBottom: '0.75rem' }}>
{t('settings.libraryGridMaxColumnsPerfHint')}
</div>
<div className="form-group">
<label className="settings-label" htmlFor="library-grid-max-cols">
{t('settings.libraryGridMaxColumnsRangeLabel', {
min: LIBRARY_GRID_MAX_COLUMNS_MIN,
max: LIBRARY_GRID_MAX_COLUMNS_MAX,
})}
</label>
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem', marginTop: 8 }}>
<input
id="library-grid-max-cols"
type="range"
min={LIBRARY_GRID_MAX_COLUMNS_MIN}
max={LIBRARY_GRID_MAX_COLUMNS_MAX}
step={1}
value={auth.libraryGridMaxColumns}
onChange={e => auth.setLibraryGridMaxColumns(Number(e.target.value))}
style={{ flex: 1, maxWidth: 360 }}
aria-valuemin={LIBRARY_GRID_MAX_COLUMNS_MIN}
aria-valuemax={LIBRARY_GRID_MAX_COLUMNS_MAX}
aria-valuenow={auth.libraryGridMaxColumns}
/>
<span style={{ minWidth: 28, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>
{auth.libraryGridMaxColumns}
</span>
</div>
</div>
<p style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: '0.75rem', lineHeight: 1.45 }}>
{t('settings.libraryGridMaxColumnsDesc')}
</p>
</div>
</SettingsSubSection>
<SettingsSubSection
title={t('settings.visualOptionsTitle')}
icon={<Palette size={16} />}
+1
View File
@@ -46,6 +46,7 @@ export const SETTINGS_INDEX: SearchIndexEntry[] = [
{ tab: 'personalisation',titleKey: 'settings.artistLayoutTitle', keywords: 'artist page layout sections order' },
{ tab: 'personalisation',titleKey: 'settings.homeCustomizerTitle', keywords: 'home page customize sections' },
{ tab: 'personalisation',titleKey: 'settings.queueToolbarTitle', keywords: 'queue toolbar buttons reorder customize shuffle save load' },
{ tab: 'appearance', titleKey: 'settings.libraryGridMaxColumnsTitle', keywords: 'grid columns album artist playlist cards layout appearance performance scroll paint' },
{ tab: 'library', titleKey: 'settings.randomMixTitle', keywords: 'random mix blacklist genre keywords filter audiobook' },
{ tab: 'library', titleKey: 'settings.ratingsSectionTitle', keywords: 'ratings stars skip threshold manual' },
{ tab: 'storage', titleKey: 'settings.offlineDirTitle', keywords: 'offline library download directory folder cache' },