Files
Taskweaver/main.ts

174 lines
4.1 KiB
TypeScript

import { Plugin, Notice } 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<void> {
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<void> {
this.app.workspace.detachLeavesOfType(VIEW_TYPE_TASKWEAVER);
}
async activateView(): Promise<void> {
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<void> {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings(): Promise<void> {
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<void> {
const category: Category = {
id: generateUniqueId(),
name,
color,
emoji
};
this.settings.categories.push(category);
await this.saveSettings();
}
async deleteCategory(categoryId: string): Promise<void> {
const hasTasks = this.settings.tasks.some(t => t.categoryId === categoryId);
if (hasTasks) {
new Notice("Cannot delete category: it still contains tasks. Please delete or move all tasks first.");
return;
}
this.settings.categories = this.settings.categories.filter(c => c.id !== categoryId);
await this.saveSettings();
}
async addTask(title: string, categoryId: string): Promise<void> {
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<void> {
this.settings.tasks = this.settings.tasks.filter(t => t.id !== taskId);
await this.saveSettings();
}
async toggleTaskTimer(taskId: string): Promise<void> {
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<void> {
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;
}
}