137 lines
3.8 KiB
TypeScript
137 lines
3.8 KiB
TypeScript
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<void> {
|
|
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<void> {
|
|
const saved = (await this.loadData()) as Record<string, unknown> | null;
|
|
this.settings = deepMerge(
|
|
DEFAULT_SETTINGS as unknown as Record<string, unknown>,
|
|
saved ?? {},
|
|
) as unknown as FormfireSettings;
|
|
}
|
|
|
|
async saveSettings(): Promise<void> {
|
|
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<void> {
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|