From f904aafd4a41827ff1c72de0e4646425507b0ef8 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sat, 27 Dec 2025 18:12:14 -0800 Subject: [PATCH] add isEnabled property for playback filters --- src/renderer/features/player/utils.ts | 1 + .../playback/player-filter-settings.tsx | 28 +++++++++++++++++++ src/renderer/store/settings.store.ts | 13 ++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/renderer/features/player/utils.ts b/src/renderer/features/player/utils.ts index bd77fec2d..3119bf704 100644 --- a/src/renderer/features/player/utils.ts +++ b/src/renderer/features/player/utils.ts @@ -407,6 +407,7 @@ export const filterSongsByPlayerFilters = (songs: Song[], filters: PlayerFilter[ // Filter out invalid filters (missing field, operator, or value) const validFilters = filters.filter( (filter) => + Boolean(filter.isEnabled) && filter.field && filter.operator && filter.value !== undefined && diff --git a/src/renderer/features/settings/components/playback/player-filter-settings.tsx b/src/renderer/features/settings/components/playback/player-filter-settings.tsx index b643a412e..0d6a7a802 100644 --- a/src/renderer/features/settings/components/playback/player-filter-settings.tsx +++ b/src/renderer/features/settings/components/playback/player-filter-settings.tsx @@ -21,6 +21,7 @@ import { } from '/@/shared/api/navidrome/navidrome-types'; import { ActionIcon } from '/@/shared/components/action-icon/action-icon'; import { Button } from '/@/shared/components/button/button'; +import { Checkbox } from '/@/shared/components/checkbox/checkbox'; import { DateInput } from '/@/shared/components/date-picker/date-picker'; import { Group } from '/@/shared/components/group/group'; import { NumberInput } from '/@/shared/components/number-input/number-input'; @@ -165,12 +166,14 @@ const getOperatorsForFieldType = ( }; const FilterValueInput = ({ + disabled, field, filterFields, onChange, operator, value, }: { + disabled?: boolean; field: PlayerFilterField; filterFields: FilterFieldConfig[]; onChange: (value: (number | string)[] | boolean | number | string) => void; @@ -203,6 +206,7 @@ const FilterValueInput = ({ { label: 'true', value: 'true' }, { label: 'false', value: 'false' }, ]} + disabled={disabled} onChange={(e) => onChange(e === 'true')} value={value?.toString() || 'false'} width="30%" @@ -215,6 +219,7 @@ const FilterValueInput = ({ onChange(date || '')} size="sm" @@ -226,6 +231,7 @@ const FilterValueInput = ({ } return ( onChange(e.currentTarget.value)} size="sm" value={(value as string) || ''} @@ -235,6 +241,7 @@ const FilterValueInput = ({ case 'number': return ( onChange(Number(e) || 0)} size="sm" value={value !== undefined && value !== null ? Number(value) : undefined} @@ -245,6 +252,7 @@ const FilterValueInput = ({ default: return ( onChange(e.currentTarget.value)} size="sm" value={(value as string) || ''} @@ -265,6 +273,7 @@ export const PlayerFilterSettings = () => { const newFilter: PlayerFilter = { field: 'name', id: nanoid(), + isEnabled: true, operator: 'is', value: '', }; @@ -322,6 +331,13 @@ export const PlayerFilterSettings = () => { [filters, setPlaybackFilters], ); + const handleToggleEnabled = useCallback( + (id: string, isEnabled: boolean) => { + setPlaybackFilters(filters.map((f) => (f.id === id ? { ...f, isEnabled } : f))); + }, + [filters, setPlaybackFilters], + ); + const fieldOptions = useMemo( () => filterFields.map((f) => ({ label: f.label, value: f.value })), [filterFields], @@ -344,8 +360,18 @@ export const PlayerFilterSettings = () => { return ( + + handleToggleEnabled( + filter.id, + e.currentTarget.checked, + ) + } + /> handleOperatorChange( filter.id, @@ -364,6 +391,7 @@ export const PlayerFilterSettings = () => { width="25%" /> diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index dd849bbac..adf93c780 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -476,6 +476,7 @@ const PlayerFilterOperatorSchema = z.enum([ const PlayerFilterSchema = z.object({ field: PlayerFilterFieldSchema, id: z.string(), + isEnabled: z.boolean().optional(), operator: PlayerFilterOperatorSchema, value: z.union([ z.string(), @@ -1792,10 +1793,20 @@ export const useSettingsStore = createWithEqualityFn()( } } + if (version <= 18) { + // Add isEnabled property to all existing player filters + if (state.playback?.filters && Array.isArray(state.playback.filters)) { + state.playback.filters = state.playback.filters.map((filter) => ({ + ...filter, + isEnabled: true, + })); + } + } + return persistedState; }, name: 'store_settings', - version: 18, + version: 19, }, ), );