import { Plugin, Notice } from 'obsidian'; import { FormfireSettings, DEFAULT_SETTINGS, deepMerge } from './types'; import { FormStore } from './core/form-store'; import { FormModal } from './ui/form-modal'; import { FormPickerModal } from './ui/form-picker-modal'; import { FormfireSettingTab } from './ui/settings-tab'; import { FormfireSidebarView, VIEW_TYPE_FORMFIRE_SIDEBAR } from './ui/form-sidebar'; export default class FormfirePlugin extends Plugin { settings!: FormfireSettings; store!: FormStore; async onload(): Promise { console.log('[Formfire] Loading plugin...'); await this.loadSettings(); this.store = new FormStore(this.settings); // Settings tab this.addSettingTab(new FormfireSettingTab(this.app, this)); // Sidebar view this.registerView( VIEW_TYPE_FORMFIRE_SIDEBAR, (leaf) => new FormfireSidebarView(leaf, this), ); // Ribbon icon this.addRibbonIcon('file-input', 'Formfire: Open form', () => { this.openFormPicker(); }); // Static commands this.addCommand({ id: 'open-form', name: 'Open form', callback: () => this.openFormPicker(), }); this.addCommand({ id: 'open-sidebar', name: 'Open sidebar', callback: () => this.activateSidebar(), }); this.addCommand({ id: 'open-settings', name: 'Open settings', callback: () => { (this.app as any).setting.open(); (this.app as any).setting.openTabById('formfire'); }, }); // Dynamic per-form commands this.registerDynamicCommands(); } onunload(): void { console.log('[Formfire] Unloading plugin.'); } async loadSettings(): Promise { const saved = (await this.loadData()) as Record | null; this.settings = deepMerge( DEFAULT_SETTINGS as unknown as Record, saved ?? {}, ) as unknown as FormfireSettings; } async saveSettings(): Promise { await this.saveData(this.settings); this.refreshSidebar(); } /** Open the form picker, then the chosen form. */ openFormPicker(): void { const forms = this.store.getAll(); if (forms.length === 0) { new Notice('No forms defined. Open Formfire settings to create one.'); return; } if (forms.length === 1) { this.openForm(forms[0].id); return; } new FormPickerModal(this.app, forms, (form) => { this.openForm(form.id); }).open(); } /** Open a specific form by ID. */ openForm(formId: string): void { const form = this.store.getById(formId); if (!form) { new Notice('Form not found.'); return; } new FormModal(this.app, form).open(); } /** Register a command for each form for direct access. */ private registerDynamicCommands(): void { for (const form of this.store.getAll()) { this.addCommand({ id: `open-form-${form.id}`, name: `Open form: ${form.name}`, callback: () => this.openForm(form.id), }); } } /** Activate or reveal the sidebar view. */ async activateSidebar(): Promise { const existing = this.app.workspace.getLeavesOfType(VIEW_TYPE_FORMFIRE_SIDEBAR); if (existing.length > 0) { this.app.workspace.revealLeaf(existing[0]); return; } const leaf = this.app.workspace.getRightLeaf(false); if (leaf) { await leaf.setViewState({ type: VIEW_TYPE_FORMFIRE_SIDEBAR, active: true }); this.app.workspace.revealLeaf(leaf); } } /** Re-render sidebar if it's open. */ refreshSidebar(): void { const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_FORMFIRE_SIDEBAR); for (const leaf of leaves) { const view = leaf.view; if (view instanceof FormfireSidebarView) { view.render(); } } } }