Add move to daily note support

This commit is contained in:
2026-03-19 11:33:22 -07:00
parent 17ce7efbd1
commit 33aaec15e2
2 changed files with 107 additions and 26 deletions

View File

@@ -22,6 +22,14 @@ npm run build
npm run lint npm run lint
``` ```
## Development Workflow
After every code change, run **both**:
1. `npm run build` — type-checks and bundles
2. `npm run lint` — ESLint (Obsidian-specific rules + TypeScript strict checks)
Fix all lint errors before considering a change complete.
## Architecture ## Architecture
### Entry Points & Build Process ### Entry Points & Build Process

View File

@@ -1,29 +1,102 @@
import { TodoItem } from 'core/types'; import { App, Modal, Notice, Setting, TFile } from 'obsidian';
import { App, Modal, Setting, TFile } from 'obsidian'; import type { TodoItem } from '../core/types';
import { HeadingSelectModal } from './heading-select-modal';
import {
removeTodoBlock,
insertTodoAtBeginning,
collectTodoBlockLines,
} from '../core/todo-transformer';
export class DailyNoteSelectModal extends Modal { export class DailyNoteSelectModal extends Modal {
constructor(app: App, todo: TodoItem, file: TFile) { private todo: TodoItem;
super(app); private sourceFile: TFile;
this.setTitle('Select a daily note'); private selectedDate = '';
let name = ''; constructor(app: App, todo: TodoItem, sourceFile: TFile) {
new Setting(this.contentEl) super(app);
.setName('Date') this.todo = todo;
.addMomentFormat((component) => { this.sourceFile = sourceFile;
component.onChange((value) => { this.setTitle('Select a daily note');
name = value;
}); new Setting(this.contentEl)
}); .setName('Date')
.addText((text) => {
new Setting(this.contentEl) text.inputEl.type = 'date';
.addButton((btn) => text.onChange((value) => {
btn this.selectedDate = value;
.setButtonText('Submit') });
.setCta() });
.onClick(() => {
this.close(); new Setting(this.contentEl)
// do some stuff .addButton((btn) =>
console.debug(name); btn
})); .setButtonText('Submit')
} .setCta()
.onClick(() => {
this.onSubmit();
})
);
}
private onSubmit(): void {
if (!this.selectedDate) {
new Notice('Please select a date.');
return;
}
const targetFile = this.findDailyNote(this.selectedDate);
if (!targetFile) {
new Notice(`No daily note found for ${this.selectedDate}.`);
return;
}
this.close();
this.openTargetFile(targetFile);
}
private findDailyNote(dateString: string): TFile | null {
interface DailyNotesOptions { format?: string; folder?: string; }
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
const options = ((this.app as any).internalPlugins?.plugins?.['daily-notes']?.instance?.options ?? {}) as DailyNotesOptions;
const format = options.format ?? 'YYYY-MM-DD';
const folder = options.folder ?? '';
const fileName = window.moment(dateString).format(format);
const filePath = folder ? `${folder}/${fileName}.md` : `${fileName}.md`;
const file = this.app.vault.getAbstractFileByPath(filePath);
return file instanceof TFile ? file : null;
}
private openTargetFile(targetFile: TFile): void {
const fileCache = this.app.metadataCache.getFileCache(targetFile);
const headings = fileCache?.headings ?? [];
if (headings.length > 0) {
new HeadingSelectModal(
this.app,
this.todo,
this.sourceFile,
targetFile,
headings
).open();
} else {
void this.moveTodo(targetFile);
}
}
private async moveTodo(targetFile: TFile): Promise<void> {
let blockLines: string[] = [];
await this.app.vault.process(this.sourceFile, (content) => {
const lines = content.split('\n');
const blockLineNumbers = [this.todo.lineNumber, ...collectTodoBlockLines(content, this.todo.lineNumber)];
blockLines = blockLineNumbers.map((ln) => lines[ln]!);
return removeTodoBlock(content, this.todo.lineNumber);
});
await this.app.vault.process(targetFile, (content) => {
return insertTodoAtBeginning(content, blockLines.join('\n'));
});
}
} }