offload to files

This commit is contained in:
EthanHealy01 2025-09-24 12:34:18 +01:00
parent cd94584278
commit 0f74dcda6c
5 changed files with 104 additions and 72 deletions

View File

@ -11,7 +11,7 @@ import { useNavigationActions, useNavigationState } from './NavigationContext';
import { ToolId, isValidToolId } from '../types/toolId';
import { useNavigationUrlSync } from '../hooks/useUrlSync';
import { getDefaultWorkbench } from '../types/workbench';
import { idToWords, scoreMatch, minScoreForQuery } from '../utils/fuzzySearch';
import { filterToolRegistryByQuery } from '../utils/toolSearch';
// State interface
interface ToolWorkflowState {
@ -219,54 +219,10 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) {
setReaderMode(true);
}, [setReaderMode]);
// Filter tools based on search query with fuzzy matching (name and description)
// Filter tools based on search query with fuzzy matching (name, description, id, synonyms)
const filteredTools = useMemo(() => {
if (!toolRegistry) return [];
const entries = Object.entries(toolRegistry);
if (!state.searchQuery.trim()) {
// Return in the new format even when not searching
return entries.map(([id, tool]) => ({ item: [id, tool] as [string, ToolRegistryEntry] }));
}
const threshold = minScoreForQuery(state.searchQuery);
const results: Array<{ item: [string, ToolRegistryEntry]; matchedText?: string; score: number }> = [];
for (const [id, tool] of entries) {
let best = 0;
let matchedText = '';
const candidates: string[] = [
idToWords(id),
tool.name || '',
tool.description || ''
];
for (const value of candidates) {
if (!value) continue;
const s = scoreMatch(state.searchQuery, value);
if (s > best) {
best = s;
matchedText = value;
}
}
if (Array.isArray(tool.synonyms)) {
for (const synonym of tool.synonyms) {
if (!synonym) continue;
const s = scoreMatch(state.searchQuery, synonym);
if (s > best) {
best = s;
matchedText = synonym;
}
}
}
if (best >= threshold) {
results.push({ item: [id, tool] as [string, ToolRegistryEntry], matchedText, score: best });
}
}
results.sort((a, b) => b.score - a.score);
return results.map(({ item, matchedText }) => ({ item, matchedText }));
return filterToolRegistryByQuery(toolRegistry as Record<string, ToolRegistryEntry>, state.searchQuery);
}, [toolRegistry, state.searchQuery]);
const isPanelVisible = useMemo(() =>

View File

@ -12,6 +12,7 @@ import RemoveBlanks from "../tools/RemoveBlanks";
import RemovePages from "../tools/RemovePages";
import RemovePassword from "../tools/RemovePassword";
import { SubcategoryId, ToolCategoryId, ToolRegistry } from "./toolsTaxonomy";
import { mergeSynonyms } from "../utils/toolSynonyms";
import AddWatermark from "../tools/AddWatermark";
import Merge from '../tools/Merge';
import Repair from "../tools/Repair";
@ -146,31 +147,6 @@ export const CONVERT_SUPPORTED_FORMATS = [
"pdf",
];
// Helper function to get translated synonyms for a tool
const getTranslatedSynonyms = (t: any, toolId: string): string[] => {
try {
const tagsKey = `${toolId}.tags`;
const tags = t(tagsKey);
// If the translation key doesn't exist or returns the key itself, return empty array
if (!tags || tags === tagsKey) {
return [];
}
// Split by comma and clean up the tags
return tags.split(',').map((tag: string) => tag.trim()).filter((tag: string) => tag.length > 0);
} catch (error) {
console.warn(`Failed to get translated synonyms for tool ${toolId}:`, error);
return [];
}
};
// Helper function to merge translated synonyms with existing synonyms
const mergeSynonyms = (t: any, toolId: string, existingSynonyms: string[] = []): string[] => {
const translatedSynonyms = getTranslatedSynonyms(t, toolId);
return [...translatedSynonyms, ...existingSynonyms];
};
// Hook to get the translated tool registry
export function useFlatToolRegistry(): ToolRegistry {
const { t } = useTranslation();

View File

@ -96,6 +96,9 @@ export function rankByFuzzy<T>(items: T[], query: string, getters: Array<(item:
best = s;
matchedText = value;
}
if (best >= 95) {
break;
}
}
if (best >= threshold) results.push({ item, score: best, matchedText });
}

View File

@ -0,0 +1,61 @@
import { ToolRegistryEntry } from "../data/toolsTaxonomy";
import { idToWords, scoreMatch, minScoreForQuery } from "./fuzzySearch";
export interface RankedToolItem {
item: [string, ToolRegistryEntry];
matchedText?: string;
}
export function filterToolRegistryByQuery(
toolRegistry: Record<string, ToolRegistryEntry>,
query: string
): RankedToolItem[] {
const entries = Object.entries(toolRegistry);
if (!query.trim()) {
return entries.map(([id, tool]) => ({ item: [id, tool] as [string, ToolRegistryEntry] }));
}
const threshold = minScoreForQuery(query);
const results: Array<{ item: [string, ToolRegistryEntry]; matchedText?: string; score: number }> = [];
for (const [id, tool] of entries) {
let best = 0;
let matchedText = '';
const candidates: string[] = [
idToWords(id),
tool.name || '',
tool.description || ''
];
for (const value of candidates) {
if (!value) continue;
const s = scoreMatch(query, value);
if (s > best) {
best = s;
matchedText = value;
}
if (best >= 95) break;
}
if (Array.isArray(tool.synonyms)) {
for (const synonym of tool.synonyms) {
if (!synonym) continue;
const s = scoreMatch(query, synonym);
if (s > best) {
best = s;
matchedText = synonym;
}
if (best >= 95) break;
}
}
if (best >= threshold) {
results.push({ item: [id, tool] as [string, ToolRegistryEntry], matchedText, score: best });
}
}
results.sort((a, b) => b.score - a.score);
return results.map(({ item, matchedText }) => ({ item, matchedText }));
}

View File

@ -0,0 +1,36 @@
import { TFunction } from 'i18next';
// Helper function to get translated synonyms for a tool
export const getTranslatedSynonyms = (t: TFunction, toolId: string): string[] => {
try {
const tagsKey = `${toolId}.tags`;
const tags = t(tagsKey) as unknown as string;
// If the translation key doesn't exist or returns the key itself, return empty array
if (!tags || tags === tagsKey) {
return [];
}
// Split by comma and clean up the tags
return tags
.split(',')
.map((tag: string) => tag.trim())
.filter((tag: string) => tag.length > 0);
} catch (error) {
// eslint-disable-next-line no-console
console.warn(`Failed to get translated synonyms for tool ${toolId}:`, error);
return [];
}
};
// Helper function to merge translated synonyms with existing synonyms
export const mergeSynonyms = (
t: TFunction,
toolId: string,
existingSynonyms: string[] = []
): string[] => {
const translatedSynonyms = getTranslatedSynonyms(t, toolId);
return [...translatedSynonyms, ...existingSynonyms];
};