fix(settings): improve in-page search matching and coverage (#968)

* fix(settings): improve in-page search matching and coverage

Index AudioMuse and individual shortcut rows, tighten fuzzy matching so
junk queries return no hits, and scroll to the parent subsection when a
shortcut result is selected.

* docs: note PR #968 in changelog and settings credits
This commit is contained in:
cucadmuh
2026-06-03 23:56:54 +03:00
committed by GitHub
parent cd47a4b0fa
commit e8962c21ab
7 changed files with 131 additions and 26 deletions
+54
View File
@@ -0,0 +1,54 @@
import type { TFunction } from 'i18next';
import { GLOBAL_SHORTCUT_ACTIONS, IN_APP_SHORTCUT_ACTIONS } from '../../config/shortcutActions';
import { SETTINGS_INDEX, matchScore, type Tab } from './settingsTabs';
export type SettingsSearchHit = {
tab: Tab;
title: string;
focusTitle: string;
score: number;
key: string;
};
export function searchSettings(query: string, activeTab: Tab, t: TFunction): SettingsSearchHit[] {
const q = query.trim();
if (!q) return [];
const hits: SettingsSearchHit[] = [];
for (const entry of SETTINGS_INDEX) {
const title = t(entry.titleKey as any);
const hay = entry.keywords ? `${title} ${entry.keywords}` : title;
const score = matchScore(hay, q);
if (score <= 0) continue;
const focusTitle = entry.focusTitleKey ? t(entry.focusTitleKey as any) : title;
hits.push({ tab: entry.tab, title, focusTitle, score, key: entry.titleKey });
}
const inAppSection = t('settings.inputKeybindingsTitle');
for (const { id, getLabel } of IN_APP_SHORTCUT_ACTIONS) {
const title = getLabel(t);
const hay = `${title} ${inAppSection} shortcut hotkey keyboard in-app ${id.replace(/-/g, ' ')}`;
const score = matchScore(hay, q);
if (score <= 0) continue;
hits.push({ tab: 'input', title, focusTitle: inAppSection, score, key: `in-app:${id}` });
}
const globalSection = t('settings.globalShortcutsTitle');
for (const { id, getLabel } of GLOBAL_SHORTCUT_ACTIONS) {
const title = getLabel(t);
const hay = `${title} ${globalSection} shortcut hotkey global media ${id.replace(/-/g, ' ')}`;
const score = matchScore(hay, q);
if (score <= 0) continue;
hits.push({ tab: 'input', title, focusTitle: globalSection, score, key: `global:${id}` });
}
hits.sort((a, b) => {
const aCurrent = a.tab === activeTab ? 1 : 0;
const bCurrent = b.tab === activeTab ? 1 : 0;
if (aCurrent !== bCurrent) return bCurrent - aCurrent;
return b.score - a.score;
});
return hits;
}