Initial commit

This commit is contained in:
2025-11-22 13:34:07 +01:00
commit a652a6ac04
14 changed files with 2595 additions and 0 deletions

204
src/modals.ts Normal file
View File

@@ -0,0 +1,204 @@
import {
App,
Modal,
Notice,
Setting,
} from 'obsidian';
import { FocusTask } from './types';
import FocusTaskPlugin from './main';
// ============ Quick Add Task Modal ============
export class QuickAddTaskModal extends Modal {
plugin: FocusTaskPlugin;
taskText: string = '';
estimatedMinutes: number;
selectedList: string = 'work';
constructor(app: App, plugin: FocusTaskPlugin) {
super(app);
this.plugin = plugin;
this.estimatedMinutes = plugin.settings.defaultEstimateMinutes;
if (plugin.settings.lists.length > 0) {
this.selectedList = plugin.settings.lists[0].id;
}
}
onOpen() {
const { contentEl } = this;
contentEl.addClass('focus-task-modal');
contentEl.createEl('h2', { text: '⚡ Add New Task' });
// Task text input
new Setting(contentEl)
.setName('Task')
.addText(text => {
text.setPlaceholder('What do you need to do?')
.onChange(value => this.taskText = value);
text.inputEl.focus();
text.inputEl.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && this.taskText.trim()) {
this.submitTask();
}
});
});
// Time estimate
new Setting(contentEl)
.setName('Estimated Time')
.setDesc('How long do you think this will take?')
.addDropdown(dropdown => {
const options: Record<string, string> = {
'5': '5 min',
'10': '10 min',
'15': '15 min',
'20': '20 min',
'25': '25 min (1 pomodoro)',
'30': '30 min',
'45': '45 min',
'50': '50 min (2 pomodoros)',
'60': '1 hour',
'90': '1.5 hours',
'120': '2 hours',
'180': '3 hours',
};
Object.entries(options).forEach(([value, label]) => {
dropdown.addOption(value, label);
});
dropdown.setValue(this.estimatedMinutes.toString());
dropdown.onChange(value => this.estimatedMinutes = parseInt(value));
});
// List selection
new Setting(contentEl)
.setName('List')
.addDropdown(dropdown => {
this.plugin.settings.lists.forEach(list => {
dropdown.addOption(list.id, `${list.icon} ${list.name}`);
});
dropdown.setValue(this.selectedList);
dropdown.onChange(value => this.selectedList = value);
});
// Buttons
const buttonContainer = contentEl.createEl('div', { cls: 'focus-task-modal-buttons' });
const cancelBtn = buttonContainer.createEl('button', { text: 'Cancel', cls: 'focus-task-btn' });
cancelBtn.addEventListener('click', () => this.close());
const addBtn = buttonContainer.createEl('button', { text: 'Add Task', cls: 'focus-task-btn focus-task-btn-primary' });
addBtn.addEventListener('click', () => this.submitTask());
}
submitTask() {
if (this.taskText.trim()) {
const task = this.plugin.createTask(this.taskText, this.estimatedMinutes, this.selectedList);
this.plugin.addTask(task);
new Notice('✅ Task added!');
this.close();
} else {
new Notice('Please enter a task description');
}
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
}
// ============ Edit Task Modal ============
export class EditTaskModal extends Modal {
plugin: FocusTaskPlugin;
task: FocusTask;
constructor(app: App, plugin: FocusTaskPlugin, task: FocusTask) {
super(app);
this.plugin = plugin;
this.task = { ...task };
}
onOpen() {
const { contentEl } = this;
contentEl.addClass('focus-task-modal');
contentEl.createEl('h2', { text: '✏️ Edit Task' });
new Setting(contentEl)
.setName('Task')
.addText(text => text
.setValue(this.task.text)
.onChange(value => this.task.text = value));
new Setting(contentEl)
.setName('Estimated Time')
.addDropdown(dropdown => {
const options: Record<string, string> = {
'5': '5 min',
'10': '10 min',
'15': '15 min',
'20': '20 min',
'25': '25 min',
'30': '30 min',
'45': '45 min',
'50': '50 min',
'60': '1 hour',
'90': '1.5 hours',
'120': '2 hours',
'180': '3 hours',
};
Object.entries(options).forEach(([value, label]) => {
dropdown.addOption(value, label);
});
dropdown.setValue(this.task.estimatedMinutes.toString());
dropdown.onChange(value => this.task.estimatedMinutes = parseInt(value));
});
new Setting(contentEl)
.setName('List')
.addDropdown(dropdown => {
this.plugin.settings.lists.forEach(list => {
dropdown.addOption(list.id, `${list.icon} ${list.name}`);
});
dropdown.setValue(this.task.list);
dropdown.onChange(value => this.task.list = value);
});
new Setting(contentEl)
.setName('Notes')
.setDesc('Add any additional details or links')
.addTextArea(textarea => {
textarea
.setValue(this.task.notes)
.onChange(value => this.task.notes = value);
textarea.inputEl.rows = 4;
});
// Show actual time if task has been worked on
if (this.task.actualMinutes > 0) {
new Setting(contentEl)
.setName('Time Tracked')
.setDesc(`You've worked on this task for ${this.plugin.formatTimeHuman(this.task.actualMinutes)}`);
}
const buttonContainer = contentEl.createEl('div', { cls: 'focus-task-modal-buttons' });
const cancelBtn = buttonContainer.createEl('button', { text: 'Cancel', cls: 'focus-task-btn' });
cancelBtn.addEventListener('click', () => this.close());
const saveBtn = buttonContainer.createEl('button', { text: 'Save', cls: 'focus-task-btn focus-task-btn-primary' });
saveBtn.addEventListener('click', () => {
this.plugin.updateTask(this.task.id, this.task);
new Notice('✅ Task updated!');
this.close();
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
}