import { Plugin } from "obsidian"; import { TaskWeaverView, VIEW_TYPE_TASKWEAVER } from "./view"; import { TaskWeaverSettingTab } from "./settings"; import { TaskWeaverSettings, DEFAULT_SETTINGS, Task, Category } from "./types"; import { generateUniqueId, logTaskToDailyNote } from "./utils"; export default class TaskWeaverPlugin extends Plugin { settings: TaskWeaverSettings; async onload(): Promise { await this.loadSettings(); this.registerView( VIEW_TYPE_TASKWEAVER, (leaf) => new TaskWeaverView(leaf, this) ); this.addRibbonIcon("clock", "Open TaskWeaver", () => { this.activateView(); }); this.addCommand({ id: "open-taskweaver", name: "Open TaskWeaver", callback: () => { this.activateView(); } }); this.addSettingTab(new TaskWeaverSettingTab(this.app, this)); this.app.workspace.onLayoutReady(() => { this.activateView(); }); } async onunload(): Promise { this.app.workspace.detachLeavesOfType(VIEW_TYPE_TASKWEAVER); } async activateView(): Promise { const { workspace } = this.app; let leaf = workspace.getLeavesOfType(VIEW_TYPE_TASKWEAVER)[0]; if (!leaf) { const rightLeaf = workspace.getRightLeaf(false); if (rightLeaf) { await rightLeaf.setViewState({ type: VIEW_TYPE_TASKWEAVER, active: true, }); leaf = rightLeaf; } } if (leaf) { workspace.revealLeaf(leaf); } } async loadSettings(): Promise { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings(): Promise { await this.saveData(this.settings); this.refreshView(); } refreshView(): void { const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_TASKWEAVER); leaves.forEach(leaf => { if (leaf.view instanceof TaskWeaverView) { leaf.view.render(); } }); } async addCategory(name: string, color: string, emoji?: string): Promise { const category: Category = { id: generateUniqueId(), name, color, emoji }; this.settings.categories.push(category); await this.saveSettings(); } async deleteCategory(categoryId: string): Promise { const hasTasks = this.settings.tasks.some(t => t.categoryId === categoryId); if (hasTasks) { return; } this.settings.categories = this.settings.categories.filter(c => c.id !== categoryId); await this.saveSettings(); } async addTask(title: string, categoryId: string): Promise { const task: Task = { id: generateUniqueId(), title, categoryId, startTime: null, totalElapsed: 0, completed: false }; this.settings.tasks.push(task); await this.saveSettings(); } async deleteTask(taskId: string): Promise { this.settings.tasks = this.settings.tasks.filter(t => t.id !== taskId); await this.saveSettings(); } async toggleTaskTimer(taskId: string): Promise { const task = this.settings.tasks.find(t => t.id === taskId); if (!task) return; if (task.startTime) { const elapsed = Date.now() - task.startTime; task.totalElapsed += elapsed; task.startTime = null; } else { task.startTime = Date.now(); } await this.saveSettings(); } async toggleTaskComplete(taskId: string): Promise { const task = this.settings.tasks.find(t => t.id === taskId); if (!task) return; if (!task.completed) { if (task.startTime) { const elapsed = Date.now() - task.startTime; task.totalElapsed += elapsed; task.startTime = null; } task.completed = true; task.completedAt = Date.now(); if (this.settings.enableDailyNoteLogging) { const category = this.settings.categories.find(c => c.id === task.categoryId); await logTaskToDailyNote( this.app, task, category, this.settings.dailyNoteFormat ); } } else { task.completed = false; delete task.completedAt; } await this.saveSettings(); } getTaskElapsed(task: Task): number { let elapsed = task.totalElapsed; if (task.startTime) { elapsed += Date.now() - task.startTime; } return elapsed; } }