devonthesofa_obsidian-note-.../integrations/commands/command-integration.ts
2025-05-24 21:37:06 +02:00

227 lines
6.8 KiB
TypeScript

// integrations/commands/command-integration.ts
import { App, Editor, MarkdownView, Notice, TFile } from 'obsidian';
import { NoteStatusSettings } from '../../models/types';
import { StatusService } from 'services/status-service';
import { StatusDropdown } from 'components/status-dropdown';
import { StatusPaneViewController } from 'views/status-pane-view';
import NoteStatus from 'main';
export class CommandIntegration {
private app: App;
private plugin: NoteStatus;
private settings: NoteStatusSettings;
private statusService: StatusService;
private statusDropdown: StatusDropdown;
constructor(
app: App,
plugin: NoteStatus,
settings: NoteStatusSettings,
statusService: StatusService,
statusDropdown: StatusDropdown
) {
this.app = app;
this.plugin = plugin;
this.settings = settings;
this.statusService = statusService;
this.statusDropdown = statusDropdown;
}
public updateSettings(settings: NoteStatusSettings): void {
this.settings = settings;
}
public registerCommands(): void {
// Open status pane
this.plugin.addCommand({
id: 'open-status-pane',
name: 'Open status pane',
callback: () => StatusPaneViewController.open(this.app)
});
// Change status of current note
this.plugin.addCommand({
id: 'change-status',
name: 'Change status of current note',
checkCallback: (checking: boolean) => {
const file = this.app.workspace.getActiveFile();
if (!file) return false;
if (!checking) {
this.statusDropdown.openStatusDropdown({ files: [file] });
}
return true;
}
});
// Insert status metadata
this.plugin.addCommand({
id: 'insert-status-metadata',
name: 'Insert status metadata',
editorCheckCallback: (checking: boolean, editor: Editor, view: MarkdownView) => {
if (!view.file) return false;
const statuses = this.statusService.getFileStatuses(view.file);
const hasNoStatus = statuses.length === 1 && statuses[0] === 'unknown';
if (!checking && hasNoStatus) {
this.statusService.insertStatusMetadataInEditor(editor);
new Notice('Status metadata inserted');
}
return hasNoStatus;
}
});
// Cycle through statuses
this.plugin.addCommand({
id: 'cycle-status',
name: 'Cycle to next status',
checkCallback: (checking: boolean) => {
const file = this.app.workspace.getActiveFile();
if (!file) return false;
if (!checking) {
this.cycleStatus(file);
}
return true;
}
});
// Quick status commands for common statuses
const quickStatuses = ['active', 'completed', 'onHold', 'dropped'];
quickStatuses.forEach(status => {
this.plugin.addCommand({
id: `set-status-${status}`,
name: `Set status to ${status}`,
checkCallback: (checking: boolean) => {
const file = this.app.workspace.getActiveFile();
if (!file) return false;
if (!checking) {
this.statusService.handleStatusChange({
files: file,
statuses: status,
operation: 'set'
});
new Notice(`Status set to ${status}`);
}
return true;
}
});
});
// Clear status
this.plugin.addCommand({
id: 'clear-status',
name: 'Clear status (set to unknown)',
checkCallback: (checking: boolean) => {
const file = this.app.workspace.getActiveFile();
if (!file) return false;
if (!checking) {
this.statusService.handleStatusChange({
files: file,
statuses: 'unknown',
operation: 'set'
});
new Notice('Status cleared');
}
return true;
}
});
// Copy status from current note
this.plugin.addCommand({
id: 'copy-status',
name: 'Copy status from current note',
checkCallback: (checking: boolean) => {
const file = this.app.workspace.getActiveFile();
if (!file) return false;
if (!checking) {
const statuses = this.statusService.getFileStatuses(file);
(this.app as any).clipboard = statuses;
new Notice(`Copied status: ${statuses.join(', ')}`);
}
return true;
}
});
// Paste status to current note
this.plugin.addCommand({
id: 'paste-status',
name: 'Paste status to current note',
checkCallback: (checking: boolean) => {
const file = this.app.workspace.getActiveFile();
const clipboard = (this.app as any).clipboard;
if (!file || !clipboard || !Array.isArray(clipboard)) return false;
if (!checking) {
this.statusService.handleStatusChange({
files: file,
statuses: clipboard,
operation: 'set'
});
new Notice(`Pasted status: ${clipboard.join(', ')}`);
}
return true;
}
});
// Toggle multiple statuses mode
this.plugin.addCommand({
id: 'toggle-multiple-statuses',
name: 'Toggle multiple statuses mode',
callback: () => {
this.settings.useMultipleStatuses = !this.settings.useMultipleStatuses;
this.plugin.saveSettings();
new Notice(`Multiple statuses mode ${this.settings.useMultipleStatuses ? 'enabled' : 'disabled'}`);
}
});
// Search notes by status
this.plugin.addCommand({
id: 'search-by-status',
name: 'Search notes by current status',
checkCallback: (checking: boolean) => {
const file = this.app.workspace.getActiveFile();
if (!file) return false;
if (!checking) {
const statuses = this.statusService.getFileStatuses(file);
const query = `[${this.settings.tagPrefix}:"${statuses[0]}"]`;
(this.app as any).internalPlugins.getPluginById('global-search').instance.openGlobalSearch(query);
}
return true;
}
});
}
private cycleStatus(file: TFile): void {
const allStatuses = this.statusService.getAllStatuses()
.filter(s => s.name !== 'unknown')
.map(s => s.name);
if (allStatuses.length === 0) {
new Notice('No statuses available');
return;
}
const currentStatuses = this.statusService.getFileStatuses(file);
const currentStatus = currentStatuses[0];
let nextIndex = 0;
if (currentStatus !== 'unknown') {
const currentIndex = allStatuses.indexOf(currentStatus);
nextIndex = (currentIndex + 1) % allStatuses.length;
}
this.statusService.handleStatusChange({
files: file,
statuses: allStatuses[nextIndex],
operation: 'set'
});
new Notice(`Status changed to ${allStatuses[nextIndex]}`);
}
}