mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
feat: performance and visual improvements
This commit is contained in:
@@ -18,11 +18,9 @@
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
transparencyEffects,
|
transparencyEffects,
|
||||||
showRecentFirst,
|
|
||||||
searchHotkey: initialSearchHotkey
|
searchHotkey: initialSearchHotkey
|
||||||
} = $props<{
|
} = $props<{
|
||||||
transparencyEffects: boolean,
|
transparencyEffects: boolean,
|
||||||
showRecentFirst: boolean,
|
|
||||||
searchHotkey: string
|
searchHotkey: string
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@@ -170,10 +168,7 @@
|
|||||||
combinedResults = await doSearch(
|
combinedResults = await doSearch(
|
||||||
term,
|
term,
|
||||||
commandsFuse,
|
commandsFuse,
|
||||||
dynamicContentFuse,
|
|
||||||
commandIdToItemMap,
|
commandIdToItemMap,
|
||||||
dynamicIdToItemMap,
|
|
||||||
showRecentFirst
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
combinedResults = [];
|
combinedResults = [];
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
>
|
>
|
||||||
<div class="flex items-center w-full">
|
<div class="flex items-center w-full">
|
||||||
<div class="flex-none scale-90 w-8 h-8 text-xl font-IconFamily flex items-center justify-center text-white bg-gradient-to-br from-[#59aaf6] to-[#1b62c6] rounded-md">{item.metadata?.icon || '\uebe7'}</div>
|
<div class="flex-none scale-90 w-8 h-8 text-xl font-IconFamily flex items-center justify-center text-white bg-gradient-to-br from-[#59aaf6] to-[#1b62c6] rounded-md">{item.metadata?.icon || '\uebe7'}</div>
|
||||||
<span class="ml-4 text-lg truncate">
|
<span class="ml-4 text-lg truncate {item.metadata?.closed ? 'line-through opacity-80' : ''}">
|
||||||
<HighlightedText text={item.text} term={searchTerm} matches={matches} />
|
<HighlightedText text={item.text} term={searchTerm} matches={matches} />
|
||||||
</span>
|
</span>
|
||||||
<span class="flex-none ml-auto text-xs text-zinc-500 dark:text-zinc-400">
|
<span class="flex-none ml-auto text-xs text-zinc-500 dark:text-zinc-400">
|
||||||
|
|||||||
@@ -80,4 +80,8 @@ export const actionMap: Record<string, ActionHandler<any>> = {
|
|||||||
subjectcourse: ((item: IndexItem) => {
|
subjectcourse: ((item: IndexItem) => {
|
||||||
window.location.href = `/#?page=/courses/${item.metadata.programme}:${item.metadata.subjectId}`;
|
window.location.href = `/#?page=/courses/${item.metadata.programme}:${item.metadata.subjectId}`;
|
||||||
}) as ActionHandler<any>,
|
}) as ActionHandler<any>,
|
||||||
|
|
||||||
|
forum: ((item: IndexItem) => {
|
||||||
|
window.location.href = `/#?page=/forums/${item.metadata.forumId}`;
|
||||||
|
}) as ActionHandler<any>,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ export const forumsJob: Job = {
|
|||||||
forumId: forum.id,
|
forumId: forum.id,
|
||||||
owner: forum.owner,
|
owner: forum.owner,
|
||||||
title: forum.title,
|
title: forum.title,
|
||||||
|
closed: forum.closed,
|
||||||
},
|
},
|
||||||
actionId: "forum",
|
actionId: "forum",
|
||||||
renderComponentId: "forum",
|
renderComponentId: "forum",
|
||||||
@@ -60,9 +61,9 @@ export const forumsJob: Job = {
|
|||||||
return items;
|
return items;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Keep only forums from the last 2 years. */
|
/** Keep only forums from the last year. */
|
||||||
purge: (items) => {
|
purge: (items) => {
|
||||||
const twoYearsAgo = Date.now() - 2 * 365 * 24 * 60 * 60 * 1000;
|
const oneYearAgo = Date.now() - 365 * 24 * 60 * 60 * 1000;
|
||||||
return items.filter((i) => i.dateAdded >= twoYearsAgo);
|
return items.filter((i) => i.dateAdded >= oneYearAgo);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -27,7 +27,7 @@ export const subjectsJob: Job = {
|
|||||||
|
|
||||||
let score = 0;
|
let score = 0;
|
||||||
if (item.metadata.isActive) {
|
if (item.metadata.isActive) {
|
||||||
score += 1; // Boost for active subjects
|
score += 0.01; // Boost for active subjects
|
||||||
} else {
|
} else {
|
||||||
score -= 50; // Penalty for inactive subjects
|
score -= 50; // Penalty for inactive subjects
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,10 +130,7 @@ export function searchDynamicItems(
|
|||||||
export async function performSearch(
|
export async function performSearch(
|
||||||
query: string,
|
query: string,
|
||||||
commandsFuse: Fuse<StaticCommandItem>,
|
commandsFuse: Fuse<StaticCommandItem>,
|
||||||
dynamicContentFuse: Fuse<IndexItem>,
|
|
||||||
commandIdToItemMap: Map<string, StaticCommandItem>,
|
commandIdToItemMap: Map<string, StaticCommandItem>,
|
||||||
dynamicIdToItemMap: Map<string, IndexItem>,
|
|
||||||
showRecentFirst: boolean,
|
|
||||||
): Promise<CombinedResult[]> {
|
): Promise<CombinedResult[]> {
|
||||||
// Get all results first
|
// Get all results first
|
||||||
const commandResults = searchCommands(
|
const commandResults = searchCommands(
|
||||||
@@ -141,18 +138,11 @@ export async function performSearch(
|
|||||||
query,
|
query,
|
||||||
commandIdToItemMap,
|
commandIdToItemMap,
|
||||||
);
|
);
|
||||||
const dynamicResults = searchDynamicItems(
|
|
||||||
dynamicContentFuse,
|
|
||||||
query,
|
|
||||||
dynamicIdToItemMap,
|
|
||||||
10,
|
|
||||||
showRecentFirst,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get vector results in parallel
|
// Get vector results in parallel
|
||||||
let vectorResults: VectorSearchResult[] = [];
|
let vectorResults: VectorSearchResult[] = [];
|
||||||
try {
|
try {
|
||||||
vectorResults = await searchVectors(query, 10);
|
vectorResults = await searchVectors(query);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
// Create a map to store our final results, using ID as key to avoid duplicates
|
// Create a map to store our final results, using ID as key to avoid duplicates
|
||||||
@@ -164,35 +154,6 @@ export async function performSearch(
|
|||||||
// Process dynamic results and vector results together
|
// Process dynamic results and vector results together
|
||||||
const seenIds = new Set<string>();
|
const seenIds = new Set<string>();
|
||||||
|
|
||||||
// Add dynamic results first
|
|
||||||
dynamicResults.forEach((r) => {
|
|
||||||
seenIds.add(r.id);
|
|
||||||
|
|
||||||
if (r.type === "dynamic") {
|
|
||||||
const dynamicItem = r.item as IndexItem;
|
|
||||||
const job = jobs[dynamicItem.category];
|
|
||||||
if (job && typeof job.boostCriteria === 'function') {
|
|
||||||
const boost = job.boostCriteria(dynamicItem, query);
|
|
||||||
if (boost) {
|
|
||||||
r.score += boost; // Add the boost to the score
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const vectorMatch = vectorResults.find((v) => v.object.id === r.id);
|
|
||||||
if (vectorMatch) {
|
|
||||||
// If we found it in both searches, combine the scores
|
|
||||||
resultMap.set(r.id, {
|
|
||||||
...r,
|
|
||||||
score: r.score + vectorMatch.similarity * 0.6, // Boost exact matches
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// If only in Fuse results, keep as is
|
|
||||||
resultMap.set(r.id, r);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Now add any vector results we haven't seen yet
|
|
||||||
vectorResults.forEach((v) => {
|
vectorResults.forEach((v) => {
|
||||||
const id = v.object.id;
|
const id = v.object.id;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export interface VectorSearchResult extends SearchResult {
|
|||||||
|
|
||||||
export async function searchVectors(
|
export async function searchVectors(
|
||||||
query: string,
|
query: string,
|
||||||
topK: number = 10,
|
topK: number = 20,
|
||||||
): Promise<VectorSearchResult[]> {
|
): Promise<VectorSearchResult[]> {
|
||||||
if (!vectorIndex) await initVectorSearch();
|
if (!vectorIndex) await initVectorSearch();
|
||||||
|
|
||||||
@@ -32,7 +32,11 @@ export async function searchVectors(
|
|||||||
dedupeEntries: true,
|
dedupeEntries: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return results as VectorSearchResult[];
|
// filter results with a similarity below 0.81
|
||||||
|
const filteredResults = results.filter((r) => r.similarity > 0.81);
|
||||||
|
console.log("Vector search results", filteredResults);
|
||||||
|
|
||||||
|
return filteredResults as VectorSearchResult[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function refreshVectorCache() {
|
export async function refreshVectorCache() {
|
||||||
|
|||||||
Reference in New Issue
Block a user