import { Plugin, WorkspaceLeaf, App, Setting, Notice, PluginSettingTab } from 'obsidian'; import { ChatView } from './src/chat-view'; import { PluginSettings } from './src/types'; import { isValidHttpUrl, validatePluginSettings, validateOllamaUrl, validateModelName, Logger, } from './src/utils'; export default class OllamaPlugin extends Plugin { settings: PluginSettings = { ollamaUrl: 'http://localhost:11434', model: 'llama3', lastIndexTime: 0, }; async onload() { // Initialize logging Logger.info('Ollama Plugin loading...', 'plugin'); await this.loadSettings(); Logger.info('Plugin loaded successfully', 'plugin'); this.registerView( 'ollama-chat-view', (leaf: WorkspaceLeaf) => new ChatView(leaf, this.settings) ); this.addRibbonIcon('message-square', 'Ollama Chat', async () => { const leaf = this.app.workspace.getLeaf(); await leaf.setViewState({ type: 'ollama-chat-view', active: true, }); this.app.workspace.revealLeaf(leaf); }); this.addSettingTab(new OllamaSettingTab(this.app, this)); } async loadSettings() { try { const data = await this.loadData(); if (data) { Logger.debug('Loading saved settings', 'settings'); this.settings = Object.assign({}, this.settings, data); } } catch (error) { // Use centralized error handling const { ErrorHandler } = await import('./src/error-handler'); ErrorHandler.handleError(error, 'settings load'); } } async saveSettings() { try { // Validate settings before saving const validationErrors = validatePluginSettings(this.settings); if (validationErrors.length > 0) { Logger.error( 'Validation errors prevented saving settings: ' + validationErrors.join('; '), 'settings' ); new Notice(`Cannot save settings: ${validationErrors[0]}`); return false; } Logger.debug('Saving settings: ' + JSON.stringify(this.settings), 'settings'); await this.saveData(this.settings); Logger.info('Settings saved successfully', 'settings'); return true; } catch (error) { // Use centralized error handling const { ErrorHandler } = await import('./src/error-handler'); ErrorHandler.handleError(error, 'settings save'); return false; } } } class OllamaSettingTab extends PluginSettingTab { private plugin: OllamaPlugin; constructor(app: App, plugin: OllamaPlugin) { super(app, plugin); this.plugin = plugin; } display(): void { const container = this.containerEl.createDiv() as HTMLElement; container.empty(); new Setting(container) .setName('Ollama URL') .setDesc('URL of your Ollama instance') .addText((text) => text.setValue(this.plugin.settings.ollamaUrl).onChange(async (value) => { const urlValidation = validateOllamaUrl(value); if (urlValidation.valid) { Logger.debug('URL changed to: ' + value, 'settings'); this.plugin.settings.ollamaUrl = value; await this.plugin.saveSettings(); } else { Logger.warn('Invalid URL format: ' + urlValidation.error, 'settings'); new Notice(urlValidation.error || 'Invalid Ollama URL format.'); } }) ); new Setting(container) .setName('Model') .setDesc('Model to use for chat') .addText((text) => text.setValue(this.plugin.settings.model).onChange(async (value) => { const modelValidation = validateModelName(value); if (modelValidation.valid) { Logger.debug('Model changed to: ' + value, 'settings'); this.plugin.settings.model = value; await this.plugin.saveSettings(); } else { Logger.warn('Invalid model name format: ' + modelValidation.error, 'settings'); new Notice(modelValidation.error || 'Invalid model name format.'); } }) ); } hide(): void { this.containerEl.empty(); } }