feat: button item + search storage reset

This commit is contained in:
SethBurkart123
2025-05-20 21:03:55 +10:00
parent 25623339f8
commit d8512e44cf
7 changed files with 79 additions and 16 deletions
-1
View File
@@ -59,7 +59,6 @@
if (!standalone) return; if (!standalone) return;
initializeSettingsState(); initializeSettingsState();
console.log('settingsState', $settingsState);
StandaloneStore.setStandalone(true); StandaloneStore.setStandalone(true);
}); });
</script> </script>
+11 -2
View File
@@ -12,7 +12,7 @@
import hideSensitiveContent from "@/seqta/ui/dev/hideSensitiveContent" import hideSensitiveContent from "@/seqta/ui/dev/hideSensitiveContent"
import { getAllPluginSettings } from "@/plugins" import { getAllPluginSettings } from "@/plugins"
import type { BooleanSetting, StringSetting, NumberSetting, SelectSetting } from "@/plugins/core/types" import type { BooleanSetting, StringSetting, NumberSetting, SelectSetting, ButtonSetting } from "@/plugins/core/types"
// Union type representing all possible settings // Union type representing all possible settings
type SettingType = type SettingType =
@@ -23,6 +23,10 @@
type: 'select', type: 'select',
id: string, id: string,
options: string[] options: string[]
}) |
(Omit<ButtonSetting, 'type'> & {
type: 'button',
id: string
}); });
interface Plugin { interface Plugin {
@@ -45,7 +49,7 @@
pluginSettingsValues[plugin.pluginId] = stored[storageKey] || {}; pluginSettingsValues[plugin.pluginId] = stored[storageKey] || {};
for (const [key, setting] of Object.entries(plugin.settings)) { for (const [key, setting] of Object.entries(plugin.settings)) {
if (pluginSettingsValues[plugin.pluginId][key] === undefined) { if (pluginSettingsValues[plugin.pluginId][key] === undefined && setting.type !== 'button') {
pluginSettingsValues[plugin.pluginId][key] = setting.default; pluginSettingsValues[plugin.pluginId][key] = setting.default;
} }
} }
@@ -241,6 +245,11 @@
label: opt.charAt(0).toUpperCase() + opt.slice(1) label: opt.charAt(0).toUpperCase() + opt.slice(1)
}))} }))}
/> />
{:else if setting.type === 'button'}
<Button
onClick={() => setting.trigger?.()}
text={setting.title}
/>
{/if} {/if}
</div> </div>
</div> </div>
@@ -2,6 +2,7 @@ import type { Plugin } from "@/plugins/core/types";
import { BasePlugin } from "@/plugins/core/settings"; import { BasePlugin } from "@/plugins/core/settings";
import { import {
booleanSetting, booleanSetting,
buttonSetting,
defineSettings, defineSettings,
Setting, Setting,
stringSetting, stringSetting,
@@ -34,6 +35,35 @@ const settings = defineSettings({
title: "Index on Page Load", title: "Index on Page Load",
description: "Run content indexing when SEQTA loads", description: "Run content indexing when SEQTA loads",
}), }),
resetIndex: buttonSetting({
title: "Reset Index",
description: "Reset the search index and storage",
trigger: async () => {
const confirmed = confirm("Are you sure you want to reset the search index and storage?");
if (confirmed) {
// Delete both 'embeddiaDB' and 'betterseqta-index' using native IndexedDB APIs
const deleteDb = (dbName: string) => {
return new Promise<void>((resolve, reject) => {
const req = indexedDB.deleteDatabase(dbName);
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
req.onblocked = () => {
alert(`Please close all other tabs using this app to reset the database: ${dbName}`);
reject(new Error('Delete blocked'));
};
});
};
try {
await deleteDb("embeddiaDB");
await deleteDb("betterseqta-index");
alert("Search index and storage have been reset.");
} catch (e) {
alert("Failed to reset one or more databases: " + String(e));
}
}
},
}),
}); });
class GlobalSearchPlugin extends BasePlugin<typeof settings> { class GlobalSearchPlugin extends BasePlugin<typeof settings> {
@@ -48,6 +78,9 @@ class GlobalSearchPlugin extends BasePlugin<typeof settings> {
@Setting(settings.runIndexingOnLoad) @Setting(settings.runIndexingOnLoad)
runIndexingOnLoad!: boolean; runIndexingOnLoad!: boolean;
@Setting(settings.resetIndex)
resetIndex!: () => void;
} }
const settingsInstance = new GlobalSearchPlugin(); const settingsInstance = new GlobalSearchPlugin();
@@ -210,8 +210,7 @@ export async function runIndexing(): Promise<void> {
let merged = mergeItems(stored, newItemsRaw); let merged = mergeItems(stored, newItemsRaw);
if (job.purge) merged = job.purge(merged); if (job.purge) merged = job.purge(merged);
console.log(merged); console.log(`[Indexer] ${job.label}: ${merged.length} items stored in '${jobId}' store (non-vector).`);
console.log(merged.length);
await setStoredItems(merged); await setStoredItems(merged);
await updateLastRunMeta(jobId); await updateLastRunMeta(jobId);
+11 -6
View File
@@ -5,6 +5,7 @@ import type {
PluginSettings, PluginSettings,
SelectSetting, SelectSetting,
StringSetting, StringSetting,
ButtonSetting,
} from "./types"; } from "./types";
import { createPluginAPI } from "./createAPI"; import { createPluginAPI } from "./createAPI";
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
@@ -190,26 +191,30 @@ export class PluginManager {
type: "select"; type: "select";
id: string; id: string;
options: Array<{ value: string; label: string }>; options: Array<{ value: string; label: string }>;
}); })
| (Omit<ButtonSetting, "type"> & { type: "button"; id: string; trigger?: () => void | Promise<void> });
}; };
}> { }> {
return Array.from(this.plugins.entries()).map(([id, plugin]) => { return Array.from(this.plugins.entries()).map(([id, plugin]) => {
const settingsEntries = Object.entries(plugin.settings).map( const settingsEntries = Object.entries(plugin.settings).map(
([key, setting]) => { ([key, setting]) => {
const settingObj = setting as any; const settingObj = setting as any;
// Create a copy of the setting object without any functions let result: any;
const result: any = Object.fromEntries( if (settingObj.type === "button") {
// For button, keep the trigger function
result = { ...settingObj };
} else {
// For others, strip functions
result = Object.fromEntries(
Object.entries(settingObj).filter( Object.entries(settingObj).filter(
([_, value]) => typeof value !== "function", ([_, value]) => typeof value !== "function",
), ),
); );
}
// Ensure required properties are present
result.id = key; result.id = key;
result.title = result.title || key; result.title = result.title || key;
result.description = result.description || ""; result.description = result.description || "";
result.defaultEnabled = plugin.defaultEnabled ?? true; result.defaultEnabled = plugin.defaultEnabled ?? true;
return [key, result]; return [key, result];
}, },
); );
+10
View File
@@ -1,5 +1,6 @@
import type { import type {
BooleanSetting, BooleanSetting,
ButtonSetting,
NumberSetting, NumberSetting,
SelectSetting, SelectSetting,
StringSetting, StringSetting,
@@ -41,6 +42,15 @@ export function selectSetting<T extends string>(
}; };
} }
export function buttonSetting(
options: Omit<ButtonSetting, "type">,
): ButtonSetting {
return {
type: "button",
...options,
};
}
export function defineSettings<T extends Record<string, any>>(settings: T): T { export function defineSettings<T extends Record<string, any>>(settings: T): T {
return settings; return settings;
} }
+9 -1
View File
@@ -34,11 +34,19 @@ export interface SelectSetting<T extends string> {
description?: string; description?: string;
} }
export interface ButtonSetting {
type: "button";
title: string;
description?: string;
trigger?: () => void | Promise<void>;
}
export type PluginSetting = export type PluginSetting =
| BooleanSetting | BooleanSetting
| StringSetting | StringSetting
| NumberSetting | NumberSetting
| SelectSetting<string>; | SelectSetting<string>
| ButtonSetting;
export type PluginSettings = { export type PluginSettings = {
[key: string]: PluginSetting; [key: string]: PluginSetting;