Click on referenced notes by Khoj chat to open it in Obsidian vault

Allow opening Khoj chat references in Obsidian vault if the reference
is a heading or file in the current Obsidian vault
This commit is contained in:
Debanjum Singh Solanky 2024-05-26 18:04:20 +05:30
parent 0f796a79ec
commit e86899eec4
2 changed files with 37 additions and 8 deletions

View file

@ -1,7 +1,7 @@
import { MarkdownRenderer, WorkspaceLeaf, request, requestUrl, setIcon } from 'obsidian'; import { MarkdownRenderer, WorkspaceLeaf, request, requestUrl, setIcon } from 'obsidian';
import { KhojSetting } from 'src/settings'; import { KhojSetting } from 'src/settings';
import { KhojPaneView } from 'src/pane_view'; import { KhojPaneView } from 'src/pane_view';
import { KhojView, createCopyParentText, pasteTextAtCursor } from 'src/utils'; import { KhojView, createCopyParentText, getLinkToEntry, pasteTextAtCursor } from 'src/utils';
export interface ChatJsonResult { export interface ChatJsonResult {
image?: string; image?: string;
@ -249,14 +249,39 @@ export class KhojChatView extends KhojPaneView {
generateReference(messageEl: Element, referenceJson: any, index: number) { generateReference(messageEl: Element, referenceJson: any, index: number) {
let reference: string = referenceJson.hasOwnProperty("compiled") ? referenceJson.compiled : referenceJson; let reference: string = referenceJson.hasOwnProperty("compiled") ? referenceJson.compiled : referenceJson;
let referenceFile = referenceJson.hasOwnProperty("file") ? referenceJson.file : null;
// Get all markdown and PDF files in vault
const mdFiles = this.app.vault.getMarkdownFiles();
const pdfFiles = this.app.vault.getFiles().filter(file => file.extension === 'pdf');
// Escape reference for HTML rendering // Escape reference for HTML rendering
reference = reference.split('\n').slice(1).join('\n');
let escaped_ref = reference.replace(/"/g, """) let escaped_ref = reference.replace(/"/g, """)
// Generate HTML for Chat Reference // Generate HTML for Chat Reference
let short_ref = escaped_ref.slice(0, 100);
short_ref = short_ref.length < escaped_ref.length ? short_ref + "..." : short_ref;
let referenceButton = messageEl.createEl('button'); let referenceButton = messageEl.createEl('button');
referenceButton.textContent = short_ref;
if (referenceFile) {
// Find vault file associated with current reference
let linkToEntry = getLinkToEntry(mdFiles.concat(pdfFiles), referenceFile, reference);
let linkElement: Element;
linkElement = referenceButton.createEl('span');
linkElement.setAttribute('title', escaped_ref);
linkElement.textContent = referenceFile;
if (linkToEntry && linkToEntry) {
linkElement.classList.add("reference-link");
linkElement.addEventListener('click', (event) => {
event.stopPropagation();
this.app.workspace.openLinkText(linkToEntry, '');
});
}
}
let referenceText = referenceButton.createDiv();
referenceText.textContent = escaped_ref;
referenceButton.id = `ref-${index}`; referenceButton.id = `ref-${index}`;
referenceButton.classList.add("reference-button"); referenceButton.classList.add("reference-button");
referenceButton.classList.add("collapsed"); referenceButton.classList.add("collapsed");
@ -264,15 +289,12 @@ export class KhojChatView extends KhojPaneView {
// Add event listener to toggle full reference on click // Add event listener to toggle full reference on click
referenceButton.addEventListener('click', function() { referenceButton.addEventListener('click', function() {
console.log(`Toggling ref-${index}`)
if (this.classList.contains("collapsed")) { if (this.classList.contains("collapsed")) {
this.classList.remove("collapsed"); this.classList.remove("collapsed");
this.classList.add("expanded"); this.classList.add("expanded");
this.textContent = escaped_ref;
} else { } else {
this.classList.add("collapsed"); this.classList.add("collapsed");
this.classList.remove("expanded"); this.classList.remove("expanded");
this.textContent = short_ref;
} }
}); });

View file

@ -181,6 +181,13 @@ button.reference-button.expanded {
max-height: none; max-height: none;
white-space: pre-wrap; white-space: pre-wrap;
} }
button.reference-button.expanded > :nth-child(2) {
display: block;
}
button.reference-button.collapsed > :nth-child(2) {
display: none;
}
button.reference-button::before { button.reference-button::before {
content: "▶"; content: "▶";
margin-right: 5px; margin-right: 5px;
@ -214,7 +221,7 @@ a.inline-chat-link {
text-decoration: none; text-decoration: none;
border-bottom: 1px dotted #475569; border-bottom: 1px dotted #475569;
} }
a.reference-link { .reference-link {
color: var(--khoj-storm-grey); color: var(--khoj-storm-grey);
border-bottom: 1px dotted var(--khoj-storm-grey); border-bottom: 1px dotted var(--khoj-storm-grey);
} }