diff --git a/LICENSE b/LICENSE index cf383b1..dd0b15b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 Epistemic Technology +Copyright (c) 2025-2026 Epistemic Technology Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/components/FolderSuggest.ts b/src/components/FolderSuggest.ts new file mode 100644 index 0000000..bdb2934 --- /dev/null +++ b/src/components/FolderSuggest.ts @@ -0,0 +1,31 @@ +import { AbstractInputSuggest, App, TFolder } from "obsidian"; + +export class FolderSuggest extends AbstractInputSuggest { + constructor(app: App, inputEl: HTMLInputElement) { + super(app, inputEl); + } + + getSuggestions(query: string): TFolder[] { + const lowerQuery = query.toLowerCase(); + const folders: TFolder[] = []; + for (const abstractFile of this.app.vault.getAllLoadedFiles()) { + if ( + abstractFile instanceof TFolder && + abstractFile.path.toLowerCase().contains(lowerQuery) + ) { + folders.push(abstractFile); + } + } + return folders; + } + + renderSuggestion(folder: TFolder, el: HTMLElement): void { + el.setText(folder.path); + } + + selectSuggestion(folder: TFolder): void { + (this as any).inputEl.value = folder.path; + (this as any).inputEl.trigger("input"); + this.close(); + } +} diff --git a/src/components/MarkdownView.tsx b/src/components/MarkdownView.tsx index 625738d..9580745 100644 --- a/src/components/MarkdownView.tsx +++ b/src/components/MarkdownView.tsx @@ -1,5 +1,5 @@ import { MarkdownRenderer, MarkdownRenderChild, Notice } from "obsidian"; -import { createEffect, onMount, useContext } from "solid-js"; +import { createEffect, onCleanup, onMount, useContext } from "solid-js"; import { AppContext, PluginContext } from "@/CoiChatApp"; interface MarkdownViewProps { @@ -12,6 +12,7 @@ export const MarkdownView = ({ sourcePath = "", }: MarkdownViewProps) => { let containerRef: HTMLDivElement | undefined; + let currentRenderChild: MarkdownRenderChild | undefined; const app = useContext(AppContext); const plugin = useContext(PluginContext); if (!app) { @@ -31,18 +32,22 @@ export const MarkdownView = ({ const renderMarkdown = async () => { if (containerRef && app && plugin) { + if (currentRenderChild) { + currentRenderChild.unload(); + } + while (containerRef.firstChild) { containerRef.removeChild(containerRef.firstChild); } try { - const renderChild = new MarkdownRenderChild(containerRef); + currentRenderChild = new MarkdownRenderChild(containerRef); await MarkdownRenderer.render( app, markdown, containerRef, sourcePath, - renderChild, + currentRenderChild, ); } catch (error) { new Notice("Error: failed to render markdown"); @@ -62,5 +67,11 @@ export const MarkdownView = ({ renderMarkdown(); }); + onCleanup(() => { + if (currentRenderChild) { + currentRenderChild.unload(); + } + }); + return
(containerRef = el)} />; }; diff --git a/src/components/ModelSelector.tsx b/src/components/ModelSelector.tsx index fc31473..aabf410 100644 --- a/src/components/ModelSelector.tsx +++ b/src/components/ModelSelector.tsx @@ -24,16 +24,16 @@ export const ModelSelector = ({ const hasModels = registry.availableModels.length > 0; return ( -
+
{showLabel ? ( -