Improve Khoj server status check in Khoj Obsidian client

- Update server connection status on every edit of khoj url, api key in
  settings instead of only on plugin load

  The error message was stale if connection fixed after changes in
  Khoj plugin settings to URL or API key, like on plugin install

- Show better welcome message on first plugin install.
  Include API key setup instruction

- Show logged in user email on Khoj settings page
This commit is contained in:
Debanjum Singh Solanky 2024-01-17 13:12:14 +05:30
parent 870af19ba4
commit aab75a6ead
3 changed files with 79 additions and 29 deletions

View file

@ -1,8 +1,8 @@
import { Notice, Plugin, request } from 'obsidian';
import { Plugin } from 'obsidian';
import { KhojSetting, KhojSettingTab, DEFAULT_SETTINGS } from 'src/settings'
import { KhojSearchModal } from 'src/search_modal'
import { KhojChatModal } from 'src/chat_modal'
import { updateContentIndex } from './utils';
import { updateContentIndex, canConnectToBackend } from './utils';
export default class Khoj extends Plugin {
@ -70,22 +70,9 @@ export default class Khoj extends Plugin {
// Load khoj obsidian plugin settings
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
// Check if khoj backend is configured, note if cannot connect to backend
let headers = { "Authorization": `Bearer ${this.settings.khojApiKey}` };
if (this.settings.khojApiKey === "" && this.settings.khojUrl === "https://app.khoj.dev") {
new Notice(`Khoj API key is not configured. Please visit https://app.khoj.dev/config#clients to get an API key.`);
return;
}
await request({ url: this.settings.khojUrl ,method: "GET", headers: headers })
.then(response => {
this.settings.connectedToBackend = true;
})
.catch(error => {
this.settings.connectedToBackend = false;
new Notice(`Ensure Khoj backend is running and Khoj URL is pointing to it in the plugin settings.\n\n${error}`);
});
// Check if can connect to khoj server
({ connectedToBackend: this.settings.connectedToBackend } =
await canConnectToBackend(this.settings.khojUrl, this.settings.khojApiKey, true));
}
async saveSettings() {

View file

@ -1,6 +1,6 @@
import { App, Notice, PluginSettingTab, Setting, TFile } from 'obsidian';
import Khoj from 'src/main';
import { updateContentIndex } from './utils';
import { canConnectToBackend, getBackendStatusMessage, updateContentIndex } from './utils';
export interface KhojSetting {
resultsCount: number;
@ -9,6 +9,7 @@ export interface KhojSetting {
connectedToBackend: boolean;
autoConfigure: boolean;
lastSyncedFiles: TFile[];
userEmail: string;
}
export const DEFAULT_SETTINGS: KhojSetting = {
@ -17,7 +18,8 @@ export const DEFAULT_SETTINGS: KhojSetting = {
khojApiKey: '',
connectedToBackend: false,
autoConfigure: true,
lastSyncedFiles: []
lastSyncedFiles: [],
userEmail: '',
}
export class KhojSettingTab extends PluginSettingTab {
@ -33,7 +35,15 @@ export class KhojSettingTab extends PluginSettingTab {
containerEl.empty();
// Add notice whether able to connect to khoj backend or not
containerEl.createEl('small', { text: this.getBackendStatusMessage() });
let backendStatusEl = containerEl.createEl('small', {
text: getBackendStatusMessage(
this.plugin.settings.connectedToBackend,
this.plugin.settings.userEmail,
this.plugin.settings.khojUrl,
this.plugin.settings.khojApiKey
)}
);
let backendStatusMessage: string = '';
// Add khoj settings configurable from the plugin settings tab
new Setting(containerEl)
@ -43,8 +53,14 @@ export class KhojSettingTab extends PluginSettingTab {
.setValue(`${this.plugin.settings.khojUrl}`)
.onChange(async (value) => {
this.plugin.settings.khojUrl = value.trim().replace(/\/$/, '');
({
connectedToBackend: this.plugin.settings.connectedToBackend,
userEmail: this.plugin.settings.userEmail,
statusMessage: backendStatusMessage,
} = await canConnectToBackend(this.plugin.settings.khojUrl, this.plugin.settings.khojApiKey));
await this.plugin.saveSettings();
containerEl.firstElementChild?.setText(this.getBackendStatusMessage());
backendStatusEl.setText(backendStatusMessage);
}));
new Setting(containerEl)
.setName('Khoj API Key')
@ -53,7 +69,13 @@ export class KhojSettingTab extends PluginSettingTab {
.setValue(`${this.plugin.settings.khojApiKey}`)
.onChange(async (value) => {
this.plugin.settings.khojApiKey = value.trim();
({
connectedToBackend: this.plugin.settings.connectedToBackend,
userEmail: this.plugin.settings.userEmail,
statusMessage: backendStatusMessage,
} = await canConnectToBackend(this.plugin.settings.khojUrl, this.plugin.settings.khojApiKey));
await this.plugin.saveSettings();
backendStatusEl.setText(backendStatusMessage);
}));
new Setting(containerEl)
.setName('Results Count')
@ -123,10 +145,4 @@ export class KhojSettingTab extends PluginSettingTab {
})
);
}
getBackendStatusMessage() {
return !this.plugin.settings.connectedToBackend
? '❗Disconnected from Khoj backend. Ensure Khoj backend is running and Khoj URL is correctly set below.'
: '✅ Connected to Khoj backend.';
}
}

View file

@ -1,4 +1,4 @@
import { FileSystemAdapter, Notice, Vault, Modal, TFile } from 'obsidian';
import { FileSystemAdapter, Notice, Vault, Modal, TFile, request } from 'obsidian';
import { KhojSetting } from 'src/settings'
export function getVaultAbsolutePath(vault: Vault): string {
@ -123,3 +123,50 @@ export async function createNoteAndCloseModal(query: string, modal: Modal, opt?:
}
modal.close();
}
export async function canConnectToBackend(
khojUrl: string,
khojApiKey: string,
showNotice: boolean = false
): Promise<{ connectedToBackend: boolean; statusMessage: string, userEmail: string }> {
let connectedToBackend = false;
let userEmail: string = '';
if (!!khojUrl) {
let headers = !!khojApiKey ? { "Authorization": `Bearer ${khojApiKey}` } : undefined;
await request({ url: `${khojUrl}/api/health`, method: "GET", headers: headers })
.then(response => {
connectedToBackend = true;
userEmail = JSON.parse(response)?.email;
})
.catch(error => {
connectedToBackend = false;
console.log(`Khoj connection error:\n\n${error}`);
});
}
let statusMessage: string = getBackendStatusMessage(connectedToBackend, userEmail, khojUrl, khojApiKey);
if (showNotice) new Notice(statusMessage);
return { connectedToBackend, statusMessage, userEmail };
}
export function getBackendStatusMessage(
connectedToServer: boolean,
userEmail: string,
khojUrl: string,
khojApiKey: string
): string {
// Welcome message with default settings. Khoj cloud always expects an API key.
if (!!khojApiKey && khojUrl === 'https://app.khoj.dev')
return `🌈 Welcome to Khoj! Get your API key from ${khojUrl}/config#clients and set it in the Khoj plugin settings on Obsidian`;
if (!connectedToServer)
return `Could not connect to Khoj at ${khojUrl}. Ensure your can access it`;
else if (!userEmail)
return `✅ Connected to Khoj. ❗Get a valid API key from ${khojUrl}/config#clients to log in`;
else if (userEmail === 'default@example.com')
// Logged in as default user in anonymous mode
return `✅ Signed in to Khoj`;
else
return `✅ Signed in to Khoj as ${userEmail}`;
}