mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-07 13:23:15 +00:00
Open Khoj Chat as a Pane instead of a Modal
- Allows having it open on the side as you traverse your Obsidian notes - Allow faster time to response, having responses visible for context - Enables ambient interactions
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import { App, MarkdownRenderer, Modal, request, requestUrl, setIcon } from 'obsidian';
|
import { ItemView, MarkdownRenderer, WorkspaceLeaf, request, requestUrl, setIcon } from 'obsidian';
|
||||||
import { KhojSetting } from 'src/settings';
|
import { KhojSetting } from 'src/settings';
|
||||||
|
|
||||||
|
export const KHOJ_CHAT_VIEW = "khoj-chat-view";
|
||||||
|
|
||||||
export interface ChatJsonResult {
|
export interface ChatJsonResult {
|
||||||
image?: string;
|
image?: string;
|
||||||
detail?: string;
|
detail?: string;
|
||||||
@@ -9,7 +11,7 @@ export interface ChatJsonResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class KhojChatModal extends Modal {
|
export class KhojChatView extends ItemView {
|
||||||
result: string;
|
result: string;
|
||||||
setting: KhojSetting;
|
setting: KhojSetting;
|
||||||
region: string;
|
region: string;
|
||||||
@@ -17,13 +19,13 @@ export class KhojChatModal extends Modal {
|
|||||||
countryName: string;
|
countryName: string;
|
||||||
timezone: string;
|
timezone: string;
|
||||||
|
|
||||||
constructor(app: App, setting: KhojSetting) {
|
constructor(leaf: WorkspaceLeaf, setting: KhojSetting) {
|
||||||
super(app);
|
super(leaf);
|
||||||
|
|
||||||
this.setting = setting;
|
this.setting = setting;
|
||||||
|
|
||||||
// Register Modal Keybindings to send user message
|
// Register Modal Keybindings to send user message
|
||||||
this.scope.register([], 'Enter', async () => { await this.chat() });
|
// this.scope.register([], 'Enter', async () => { await this.chat() });
|
||||||
|
|
||||||
|
|
||||||
fetch("https://ipapi.co/json")
|
fetch("https://ipapi.co/json")
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
@@ -39,6 +41,18 @@ export class KhojChatModal extends Modal {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getViewType(): string {
|
||||||
|
return KHOJ_CHAT_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDisplayText(): string {
|
||||||
|
return "Khoj";
|
||||||
|
}
|
||||||
|
|
||||||
|
getIcon(): string {
|
||||||
|
return "message-circle";
|
||||||
|
}
|
||||||
|
|
||||||
async chat() {
|
async chat() {
|
||||||
// Get text in chat input element
|
// Get text in chat input element
|
||||||
let input_el = <HTMLTextAreaElement>this.contentEl.getElementsByClassName("khoj-chat-input")[0];
|
let input_el = <HTMLTextAreaElement>this.contentEl.getElementsByClassName("khoj-chat-input")[0];
|
||||||
@@ -503,7 +517,7 @@ export class KhojChatModal extends Modal {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const transcribeButton = <HTMLButtonElement>this.contentEl.getElementsByClassName("khoj-transcribe")[0];
|
const transcribeButton = <HTMLButtonElement>this.contentEl.getElementsByClassName("khoj-transcribe")[0];
|
||||||
const chatInput = <HTMLTextAreaElement>this.contentEl.getElementsByClassName("khoj-chat-input")[0];
|
const chatInput = <HTMLTextAreaElement>this.contentEl.getElementsByClassName("khoj-chat-input")[0];
|
||||||
const sendButton = <HTMLButtonElement>this.modalEl.getElementsByClassName("khoj-chat-send")[0]
|
const sendButton = <HTMLButtonElement>this.contentEl.getElementsByClassName("khoj-chat-send")[0]
|
||||||
|
|
||||||
const generateRequestBody = async (audioBlob: Blob, boundary_string: string) => {
|
const generateRequestBody = async (audioBlob: Blob, boundary_string: string) => {
|
||||||
const boundary = `------${boundary_string}`;
|
const boundary = `------${boundary_string}`;
|
||||||
@@ -606,7 +620,7 @@ export class KhojChatModal extends Modal {
|
|||||||
clearTimeout(this.sendMessageTimeout);
|
clearTimeout(this.sendMessageTimeout);
|
||||||
|
|
||||||
// Revert to showing send-button and hide the stop-send-button
|
// Revert to showing send-button and hide the stop-send-button
|
||||||
let sendButton = <HTMLButtonElement>this.modalEl.getElementsByClassName("khoj-chat-send")[0];
|
let sendButton = <HTMLButtonElement>this.contentEl.getElementsByClassName("khoj-chat-send")[0];
|
||||||
setIcon(sendButton, "arrow-up-circle");
|
setIcon(sendButton, "arrow-up-circle");
|
||||||
let sendImg = <SVGElement>sendButton.getElementsByClassName("lucide-arrow-up-circle")[0]
|
let sendImg = <SVGElement>sendButton.getElementsByClassName("lucide-arrow-up-circle")[0]
|
||||||
sendImg.addEventListener('click', async (_) => { await this.chat() });
|
sendImg.addEventListener('click', async (_) => { await this.chat() });
|
||||||
@@ -637,7 +651,7 @@ export class KhojChatModal extends Modal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scrollChatToBottom() {
|
scrollChatToBottom() {
|
||||||
let sendButton = <HTMLButtonElement>this.modalEl.getElementsByClassName("khoj-chat-send")[0];
|
let sendButton = <HTMLButtonElement>this.contentEl.getElementsByClassName("khoj-chat-send")[0];
|
||||||
sendButton.scrollIntoView({ behavior: "auto", block: "center" });
|
sendButton.scrollIntoView({ behavior: "auto", block: "center" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Plugin } from 'obsidian';
|
import { Plugin, WorkspaceLeaf } from 'obsidian';
|
||||||
import { KhojSetting, KhojSettingTab, DEFAULT_SETTINGS } from 'src/settings'
|
import { KhojSetting, KhojSettingTab, DEFAULT_SETTINGS } from 'src/settings'
|
||||||
import { KhojSearchModal } from 'src/search_modal'
|
import { KhojSearchModal } from 'src/search_modal'
|
||||||
import { KhojChatModal } from 'src/chat_modal'
|
import { KhojChatView, KHOJ_CHAT_VIEW } from 'src/chat_view'
|
||||||
import { updateContentIndex, canConnectToBackend } from './utils';
|
import { updateContentIndex, canConnectToBackend } from './utils';
|
||||||
|
|
||||||
|
|
||||||
@@ -30,12 +30,14 @@ export default class Khoj extends Plugin {
|
|||||||
this.addCommand({
|
this.addCommand({
|
||||||
id: 'chat',
|
id: 'chat',
|
||||||
name: 'Chat',
|
name: 'Chat',
|
||||||
callback: () => { new KhojChatModal(this.app, this.settings).open(); }
|
callback: () => { this.activateView(KHOJ_CHAT_VIEW); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.registerView(KHOJ_CHAT_VIEW, (leaf) => new KhojChatView(leaf, this.settings));
|
||||||
|
|
||||||
// Create an icon in the left ribbon.
|
// Create an icon in the left ribbon.
|
||||||
this.addRibbonIcon('message-circle', 'Khoj', (_: MouseEvent) => {
|
this.addRibbonIcon('message-circle', 'Khoj', (_: MouseEvent) => {
|
||||||
new KhojChatModal(this.app, this.settings).open()
|
this.activateView(KHOJ_CHAT_VIEW);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a settings tab so the user can configure khoj
|
// Add a settings tab so the user can configure khoj
|
||||||
@@ -69,4 +71,24 @@ export default class Khoj extends Plugin {
|
|||||||
|
|
||||||
this.unload();
|
this.unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async activateView(viewType: string) {
|
||||||
|
const { workspace } = this.app;
|
||||||
|
|
||||||
|
let leaf: WorkspaceLeaf | null = null;
|
||||||
|
const leaves = workspace.getLeavesOfType(viewType);
|
||||||
|
|
||||||
|
if (leaves.length > 0) {
|
||||||
|
// A leaf with our view already exists, use that
|
||||||
|
leaf = leaves[0];
|
||||||
|
} else {
|
||||||
|
// Our view could not be found in the workspace, create a new leaf
|
||||||
|
// in the right sidebar for it
|
||||||
|
leaf = workspace.getRightLeaf(false);
|
||||||
|
await leaf.setViewState({ type: viewType, active: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Reveal" the leaf in case it is in a collapsed sidebar
|
||||||
|
workspace.revealLeaf(leaf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user