feat: complete fuzzy search rebuild

This commit is contained in:
SethBurkart123
2025-04-01 13:51:45 +11:00
parent 8df138a374
commit 18441712c9
9 changed files with 725 additions and 116 deletions
+85 -12
View File
@@ -1,13 +1,13 @@
import type { Plugin } from '@/plugins/core/types';
import { BasePlugin } from '@/plugins/core/settings';
import { booleanSetting, defineSettings, Setting, stringSetting } from '@/plugins/core/settingsHelpers';
//import FlexSearch from 'flexsearch';
import renderSvelte from '@/interface/main';
import SearchBar from './SearchBar.svelte';
import styles from './styles.css?inline';
import { unmount } from 'svelte';
import { loadDynamicItems, type DynamicContentItem } from './dynamicSearch';
import { waitForElm } from '@/seqta/utils/waitForElm';
// Plugin settings
const settings = defineSettings({
searchHotkey: stringSetting({
default: 'ctrl+k',
@@ -18,7 +18,12 @@ const settings = defineSettings({
default: true,
title: 'Show Recent First',
description: 'Sort dynamic content by most recent first',
})
}),
transparencyEffects: booleanSetting({
default: true,
title: 'Transparency Effects',
description: 'Enable transparency effects for the search bar',
}),
});
class GlobalSearchPlugin extends BasePlugin<typeof settings> {
@@ -27,10 +32,62 @@ class GlobalSearchPlugin extends BasePlugin<typeof settings> {
@Setting(settings.showRecentFirst)
showRecentFirst!: boolean;
@Setting(settings.transparencyEffects)
transparencyEffects!: boolean;
}
const settingsInstance = new GlobalSearchPlugin();
const createSampleDynamicData = (): DynamicContentItem[] => {
const sampleMessages = [
{
id: 'message_1',
text: 'Assignment Discussion',
category: 'messages',
contentType: 'message' as const,
icon: '\uea6e',
content: 'Hey everyone, I was wondering if anyone could help me with the Physics assignment on circular motion. I\'m stuck on question 3 about centripetal force.',
dateAdded: Date.now() - 1000 * 60 * 60 * 2,
action: () => console.log('Open message 1'),
keywords: ['John Smith', 'message', 'chat'],
metadata: { author: 'John Smith'}
},
];
const sampleCourses = [
{
id: 'course_1',
text: 'Physics 101',
category: 'courses',
contentType: 'course' as const,
icon: '\uea67',
content: 'An introduction to mechanics, thermodynamics, and wave phenomena.',
dateAdded: Date.now() - 1000 * 60 * 60 * 24 * 5, // 5 days ago
action: () => console.log('Open Physics course'),
keywords: ['Dr. Richard Feynman', 'course', 'class'],
metadata: { teacher: 'Dr. Richard Feynman' }
},
];
const sampleAssessments = [
{
id: 'assessment_1',
text: 'Physics Lab Report',
category: 'assessments',
contentType: 'assessment' as const,
icon: '\uebb3',
content: 'Complete a lab report on the pendulum experiment.',
dateAdded: Date.now() - 1000 * 60 * 60 * 24, // 1 day ago
action: () => console.log('Open Physics assessment'),
keywords: ['Physics 101', 'assessment', 'homework'],
metadata: { dueDate: Date.now() + 1000 * 60 * 60 * 24 * 3 }
},
];
return [...sampleMessages, ...sampleCourses, ...sampleAssessments];
};
const globalSearchPlugin: Plugin<typeof settings> = {
id: 'global-search',
name: 'Global Search',
@@ -38,15 +95,19 @@ const globalSearchPlugin: Plugin<typeof settings> = {
version: '1.0.0',
settings: settingsInstance.settings,
disableToggle: true,
// Add some basic styles for our search UI
styles: styles,
run: async (api) => {
let app: any;
// Create search button
api.seqta.onMount('#title', (titleElement) => {
const dynamicData = createSampleDynamicData();
loadDynamicItems(dynamicData);
const mountSearchBar = (titleElement: Element) => {
if (titleElement.querySelector('.search-trigger')) {
return;
}
// Create search button
const searchButton = document.createElement('div');
searchButton.className = 'search-trigger';
@@ -68,17 +129,29 @@ const globalSearchPlugin: Plugin<typeof settings> = {
document.body.appendChild(searchRoot);
const searchRootShadow = searchRoot.attachShadow({ mode: 'open' });
// Mount Svelte component in shadow DOM
app = renderSvelte(SearchBar, searchRootShadow);
console.log('adding event listener to search button');
// Handle click on search button
searchButton.addEventListener('click', () => {
console.log('search button clicked');
// @ts-ignore
window.setCommandPalleteOpen(true);
});
});
// Mount Svelte component in shadow DOM
app = renderSvelte(SearchBar, searchRootShadow, {
transparencyEffects: api.settings.transparencyEffects,
});
}
const title = document.querySelector('#title');
if (title) {
mountSearchBar(title);
} else {
await waitForElm('#title', true, 100, 60);
mountSearchBar(document.querySelector('#title') as Element);
}
// Clean up
return () => {
const searchButton = document.querySelector('.search-trigger');
const searchRoot = document.querySelector('.global-search-root');