diff --git a/src/main.ts b/src/main.ts index 30e135d..acfa564 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,128 @@ -import { Plugin } from 'obsidian'; +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(), + }); + + // 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(); + } + } + } }