Feat: adding filter and 'All' button to processors
This commit is contained in:
@ -23,8 +23,8 @@
|
||||
savePitchLockFrequency,
|
||||
loadExpandedCategories,
|
||||
saveExpandedCategories,
|
||||
loadEnabledProcessorCategories,
|
||||
saveEnabledProcessorCategories,
|
||||
loadSelectedProcessorCategory,
|
||||
saveSelectedProcessorCategory,
|
||||
} from "./lib/utils/settings";
|
||||
import {
|
||||
cropAudio,
|
||||
@ -68,8 +68,8 @@
|
||||
let canUndo = $state(false);
|
||||
let sidebarOpen = $state(false);
|
||||
let expandedCategories = $state<Set<string>>(loadExpandedCategories());
|
||||
let enabledProcessorCategories = $state<Set<ProcessorCategory>>(
|
||||
loadEnabledProcessorCategories() as Set<ProcessorCategory>
|
||||
let selectedProcessorCategory = $state<ProcessorCategory | 'All'>(
|
||||
loadSelectedProcessorCategory()
|
||||
);
|
||||
|
||||
const showDuration = $derived(engineType !== "sample");
|
||||
@ -111,7 +111,7 @@
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
saveEnabledProcessorCategories(enabledProcessorCategories as Set<string>);
|
||||
saveSelectedProcessorCategory(selectedProcessorCategory);
|
||||
});
|
||||
|
||||
// Group engines by category
|
||||
@ -137,14 +137,8 @@
|
||||
expandedCategories = newSet;
|
||||
}
|
||||
|
||||
function toggleProcessorCategory(category: ProcessorCategory) {
|
||||
const newSet = new Set(enabledProcessorCategories);
|
||||
if (newSet.has(category)) {
|
||||
newSet.delete(category);
|
||||
} else {
|
||||
newSet.add(category);
|
||||
}
|
||||
enabledProcessorCategories = newSet;
|
||||
function selectProcessorCategory(category: ProcessorCategory | 'All') {
|
||||
selectedProcessorCategory = category;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
@ -714,8 +708,8 @@
|
||||
<div onmouseenter={keepPopupOpen} onmouseleave={scheduleHidePopup}>
|
||||
<ProcessorPopup
|
||||
onselect={applyProcessor}
|
||||
enabledCategories={enabledProcessorCategories}
|
||||
ontogglecategory={toggleProcessorCategory}
|
||||
selectedCategory={selectedProcessorCategory}
|
||||
onselectcategory={selectProcessorCategory}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
|
||||
interface Props {
|
||||
onselect: (processor: AudioProcessor) => void;
|
||||
enabledCategories: Set<ProcessorCategory>;
|
||||
ontogglecategory: (category: ProcessorCategory) => void;
|
||||
selectedCategory: ProcessorCategory | 'All';
|
||||
onselectcategory: (category: ProcessorCategory | 'All') => void;
|
||||
}
|
||||
|
||||
let { onselect, enabledCategories, ontogglecategory }: Props = $props();
|
||||
let { onselect, selectedCategory, onselectcategory }: Props = $props();
|
||||
|
||||
const allProcessors = getAllProcessors();
|
||||
|
||||
@ -24,22 +24,40 @@
|
||||
'Utility'
|
||||
];
|
||||
|
||||
const categoryCountsMap = $derived.by(() => {
|
||||
const counts = new Map<ProcessorCategory, number>();
|
||||
for (const processor of allProcessors) {
|
||||
const category = processor.getCategory();
|
||||
counts.set(category, (counts.get(category) || 0) + 1);
|
||||
}
|
||||
return counts;
|
||||
});
|
||||
|
||||
const filteredProcessors = $derived(
|
||||
allProcessors
|
||||
.filter(p => enabledCategories.has(p.getCategory()))
|
||||
.sort((a, b) => a.getName().localeCompare(b.getName()))
|
||||
selectedCategory === 'All'
|
||||
? allProcessors.sort((a, b) => a.getName().localeCompare(b.getName()))
|
||||
: allProcessors
|
||||
.filter(p => p.getCategory() === selectedCategory)
|
||||
.sort((a, b) => a.getName().localeCompare(b.getName()))
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="processor-popup">
|
||||
<div class="popup-sidebar">
|
||||
<button
|
||||
class="category-filter"
|
||||
class:active={selectedCategory === 'All'}
|
||||
onclick={() => onselectcategory('All')}
|
||||
>
|
||||
All ({allProcessors.length})
|
||||
</button>
|
||||
{#each allCategories as category}
|
||||
<button
|
||||
class="category-filter"
|
||||
class:active={enabledCategories.has(category)}
|
||||
onclick={() => ontogglecategory(category)}
|
||||
class:active={selectedCategory === category}
|
||||
onclick={() => onselectcategory(category)}
|
||||
>
|
||||
{category}
|
||||
{category} ({categoryCountsMap.get(category) || 0})
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@ -9,7 +9,7 @@ const STORAGE_KEYS = {
|
||||
PITCH_LOCK_ENABLED: 'pitchLockEnabled',
|
||||
PITCH_LOCK_FREQUENCY: 'pitchLockFrequency',
|
||||
EXPANDED_CATEGORIES: 'expandedCategories',
|
||||
ENABLED_PROCESSOR_CATEGORIES: 'enabledProcessorCategories',
|
||||
SELECTED_PROCESSOR_CATEGORY: 'selectedProcessorCategory',
|
||||
} as const;
|
||||
|
||||
export function loadVolume(): number {
|
||||
@ -65,19 +65,11 @@ export function saveExpandedCategories(categories: Set<string>): void {
|
||||
localStorage.setItem(STORAGE_KEYS.EXPANDED_CATEGORIES, JSON.stringify(Array.from(categories)));
|
||||
}
|
||||
|
||||
export function loadEnabledProcessorCategories(): Set<string> {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.ENABLED_PROCESSOR_CATEGORIES);
|
||||
if (stored) {
|
||||
try {
|
||||
const parsed = JSON.parse(stored);
|
||||
return new Set(Array.isArray(parsed) ? parsed : []);
|
||||
} catch {
|
||||
return new Set(['Amplitude', 'Filter', 'Time', 'Space', 'Pitch', 'Modulation', 'Distortion', 'Spectral', 'Utility']);
|
||||
}
|
||||
}
|
||||
return new Set(['Amplitude', 'Filter', 'Time', 'Space', 'Pitch', 'Modulation', 'Distortion', 'Spectral', 'Utility']);
|
||||
export function loadSelectedProcessorCategory(): string {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.SELECTED_PROCESSOR_CATEGORY);
|
||||
return stored || 'All';
|
||||
}
|
||||
|
||||
export function saveEnabledProcessorCategories(categories: Set<string>): void {
|
||||
localStorage.setItem(STORAGE_KEYS.ENABLED_PROCESSOR_CATEGORIES, JSON.stringify(Array.from(categories)));
|
||||
export function saveSelectedProcessorCategory(category: string): void {
|
||||
localStorage.setItem(STORAGE_KEYS.SELECTED_PROCESSOR_CATEGORY, category);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user