style(ui): refactor CSS imports and modernize task item styling

- Centralize CSS imports in content.ts component
- Add modern.css with updated task item design
- Remove task item borders for cleaner appearance
- Clean up code formatting (trailing commas)
- Update README description text
This commit is contained in:
Quorafind 2025-11-09 22:21:48 +08:00
parent 2408e8f4b0
commit 54e55f4ba1
8 changed files with 717 additions and 658 deletions

View file

@ -11,7 +11,7 @@
## Overview
Task Genius transforms Obsidian into a powerful task management system with advanced features, beautiful visualizations, and seamless in-editor task management workflow - all while preserving Obsidian's philosophy of plain-text, future-proof note-taking.
Task Genius plugin transforms Obsidian into a powerful task management system with advanced features, beautiful visualizations, and seamless in-editor task management workflow - all while preserving Obsidian's philosophy of plain-text, future-proof note-taking.
---

View file

@ -8,6 +8,10 @@ import { t } from "@/translations/helper";
import TaskProgressBarPlugin from "@/index";
import { getInitialViewMode, saveViewMode } from "@/utils/ui/view-mode-utils";
import "@/styles/task-list.css";
import "@/styles/tree-view.css";
import "@/styles/modern.css";
// @ts-ignore
import { filterTasks } from "@/utils/task/task-filter-utils";
import { sortTasks } from "@/commands/sortTaskCommands"; // 导入 sortTasks 函数
@ -61,7 +65,7 @@ export class ContentComponent extends Component {
private parentEl: HTMLElement,
private app: App,
private plugin: TaskProgressBarPlugin,
private params: ContentComponentParams = {},
private params: ContentComponentParams = {}
) {
super();
}
@ -147,7 +151,7 @@ export class ContentComponent extends Component {
{
root: this.taskListEl, // Observe within the task list container
threshold: 0.1, // Trigger when 10% of the marker is visible
},
}
);
}
@ -158,11 +162,11 @@ export class ContentComponent extends Component {
this.isTreeView = getInitialViewMode(
this.app,
this.plugin,
this.currentViewId,
this.currentViewId
);
// Update the toggle button icon to match the initial state
const viewToggleBtn = this.headerEl?.querySelector(
".view-toggle-btn",
".view-toggle-btn"
) as HTMLElement;
if (viewToggleBtn) {
setIcon(viewToggleBtn, this.isTreeView ? "git-branch" : "list");
@ -172,7 +176,7 @@ export class ContentComponent extends Component {
private toggleViewMode() {
this.isTreeView = !this.isTreeView;
const viewToggleBtn = this.headerEl.querySelector(
".view-toggle-btn",
".view-toggle-btn"
) as HTMLElement;
if (viewToggleBtn) {
setIcon(viewToggleBtn, this.isTreeView ? "git-branch" : "list");
@ -188,7 +192,7 @@ export class ContentComponent extends Component {
if (this.isTreeView !== isTree) {
this.isTreeView = isTree;
const viewToggleBtn = this.headerEl?.querySelector(
".view-toggle-btn",
".view-toggle-btn"
) as HTMLElement;
if (viewToggleBtn) {
setIcon(viewToggleBtn, this.isTreeView ? "git-branch" : "list");
@ -200,7 +204,7 @@ export class ContentComponent extends Component {
public setTasks(
tasks: Task[],
notFilteredTasks: Task[],
forceRefresh: boolean = false,
forceRefresh: boolean = false
) {
const updateSignatures = () => {
this.lastAllTasksSignature = this.computeTaskSignature(tasks);
@ -225,7 +229,7 @@ export class ContentComponent extends Component {
// If a force refresh is pending, skip non-forced updates
if (this.pendingForceRefresh) {
console.log(
"ContentComponent: Skipping non-forced update, force refresh is pending",
"ContentComponent: Skipping non-forced update, force refresh is pending"
);
return;
}
@ -238,7 +242,7 @@ export class ContentComponent extends Component {
nextNotFilteredSignature === this.lastNotFilteredTasksSignature
) {
console.log(
"ContentComponent: Task signatures unchanged, skipping refresh",
"ContentComponent: Task signatures unchanged, skipping refresh"
);
return;
}
@ -275,17 +279,17 @@ export class ContentComponent extends Component {
this.allTasks,
this.currentViewId,
this.plugin,
{ textQuery: this.filterInput?.value }, // Pass text query from input
{ textQuery: this.filterInput?.value } // Pass text query from input
);
const sortCriteria = this.plugin.settings.viewConfiguration.find(
(view) => view.id === this.currentViewId,
(view) => view.id === this.currentViewId
)?.sortCriteria;
if (sortCriteria && sortCriteria.length > 0) {
this.filteredTasks = sortTasks(
this.filteredTasks,
sortCriteria,
this.plugin.settings,
this.plugin.settings
);
} else {
// Default sorting: completed tasks last, then by priority, due date, content,
@ -313,7 +317,7 @@ export class ContentComponent extends Component {
});
const contentCmp = collator.compare(
a.content ?? "",
b.content ?? "",
b.content ?? ""
);
if (contentCmp !== 0) return contentCmp;
// Lowest-priority tie-breakers to ensure stability across files
@ -342,7 +346,7 @@ export class ContentComponent extends Component {
task.originalMarkdown ?? "",
task.content ?? "",
task.metadata ? JSON.stringify(task.metadata) : "",
].join("|"),
].join("|")
)
.join(";");
}
@ -409,7 +413,7 @@ export class ContentComponent extends Component {
// If a render is already in progress, queue a refresh instead of skipping
if (this.isRendering) {
console.log(
"ContentComponent: Already rendering, queueing a refresh",
"ContentComponent: Already rendering, queueing a refresh"
);
this.pendingForceRefresh = true;
return;
@ -448,19 +452,19 @@ export class ContentComponent extends Component {
const taskMap = new Map<string, Task>();
// Add all non-filtered tasks to the taskMap
this.notFilteredTasks.forEach((task) =>
taskMap.set(task.id, task),
taskMap.set(task.id, task)
);
this.rootTasks = tasksToTree(this.filteredTasks); // Calculate root tasks
// Sort roots according to view's sort criteria (fallback to sensible defaults)
const viewSortCriteria =
this.plugin.settings.viewConfiguration.find(
(view) => view.id === this.currentViewId,
(view) => view.id === this.currentViewId
)?.sortCriteria;
if (viewSortCriteria && viewSortCriteria.length > 0) {
this.rootTasks = sortTasks(
this.rootTasks,
viewSortCriteria,
this.plugin.settings,
this.plugin.settings
);
} else {
// Default sorting: completed tasks last, then by priority, due date, content,
@ -489,12 +493,12 @@ export class ContentComponent extends Component {
});
const contentCmp = collator.compare(
a.content ?? "",
b.content ?? "",
b.content ?? ""
);
if (contentCmp !== 0) return contentCmp;
// Lowest-priority tie-breakers to ensure stability across files
const fp = (a.filePath || "").localeCompare(
b.filePath || "",
b.filePath || ""
);
if (fp !== 0) return fp;
return (a.line ?? 0) - (b.line ?? 0);
@ -541,7 +545,7 @@ export class ContentComponent extends Component {
const containerRect = container.getBoundingClientRect();
// Find first visible task item
const items = Array.from(
container.querySelectorAll<HTMLElement>(".task-item"),
container.querySelectorAll<HTMLElement>(".task-item")
);
for (const el of items) {
const rect = el.getBoundingClientRect();
@ -566,7 +570,7 @@ export class ContentComponent extends Component {
// Try anchor-based restoration first
if (state.anchorId) {
const anchorEl = container.querySelector<HTMLElement>(
`[data-task-id="${state.anchorId}"]`,
`[data-task-id="${state.anchorId}"]`
);
if (anchorEl) {
const desiredOffset = state.anchorOffset;
@ -583,7 +587,7 @@ export class ContentComponent extends Component {
}
private loadTaskBatch(
target: DocumentFragment | HTMLElement = this.taskListEl,
target: DocumentFragment | HTMLElement = this.taskListEl
): number {
const fragment = document.createDocumentFragment();
const countToLoad = this.taskPageSize;
@ -599,7 +603,7 @@ export class ContentComponent extends Component {
this.currentViewId, // Pass currentViewId
this.app,
this.plugin,
this.params.selectionManager, // Pass selection manager
this.params.selectionManager // Pass selection manager
);
// Attach event handlers
@ -630,7 +634,7 @@ export class ContentComponent extends Component {
private loadRootTaskBatch(
taskMap: Map<string, Task>,
target: DocumentFragment | HTMLElement = this.taskListEl,
target: DocumentFragment | HTMLElement = this.taskListEl
): number {
const fragment = document.createDocumentFragment();
const countToLoad = this.taskPageSize;
@ -647,7 +651,7 @@ export class ContentComponent extends Component {
for (let i = start; i < end; i++) {
const rootTask = this.rootTasks[i];
const childTasks = this.notFilteredTasks.filter(
(task) => task.metadata.parent === rootTask.id,
(task) => task.metadata.parent === rootTask.id
);
const treeComponent = new TaskTreeItemComponent(
@ -658,7 +662,7 @@ export class ContentComponent extends Component {
childTasks,
taskMap,
this.plugin,
this.params.selectionManager, // Pass selection manager
this.params.selectionManager // Pass selection manager
);
// Attach event handlers
@ -732,7 +736,7 @@ export class ContentComponent extends Component {
// );
const taskMap = new Map<string, Task>();
this.filteredTasks.forEach((task) =>
taskMap.set(task.id, task),
taskMap.set(task.id, task)
);
this.loadRootTaskBatch(taskMap);
} else {
@ -793,12 +797,12 @@ export class ContentComponent extends Component {
public updateTask(updatedTask: Task) {
// 1) Update sources
const taskIndexAll = this.allTasks.findIndex(
(t) => t.id === updatedTask.id,
(t) => t.id === updatedTask.id
);
if (taskIndexAll !== -1)
this.allTasks[taskIndexAll] = { ...updatedTask };
const taskIndexNotFiltered = this.notFilteredTasks.findIndex(
(t) => t.id === updatedTask.id,
(t) => t.id === updatedTask.id
);
if (taskIndexNotFiltered !== -1)
this.notFilteredTasks[taskIndexNotFiltered] = { ...updatedTask };
@ -809,17 +813,17 @@ export class ContentComponent extends Component {
const prevLen = this.filteredTasks.length;
this.applyFilters();
const taskFromFiltered = this.filteredTasks.find(
(t) => t.id === updatedTask.id,
(t) => t.id === updatedTask.id
);
const taskStillVisible = !!taskFromFiltered;
// Helper: insert list item at correct position (list view)
const insertListItem = (taskToInsert: Task) => {
const compIds = new Set(
this.taskComponents.map((c) => c.getTask().id),
this.taskComponents.map((c) => c.getTask().id)
);
const sortedIndex = this.filteredTasks.findIndex(
(t) => t.id === taskToInsert.id,
(t) => t.id === taskToInsert.id
);
// Find the next rendered neighbor after sortedIndex
let nextComp: any = null;
@ -827,7 +831,7 @@ export class ContentComponent extends Component {
const id = this.filteredTasks[i].id;
if (compIds.has(id)) {
nextComp = this.taskComponents.find(
(c) => c.getTask().id === id,
(c) => c.getTask().id === id
);
break;
}
@ -838,7 +842,7 @@ export class ContentComponent extends Component {
this.currentViewId,
this.app,
this.plugin,
this.params.selectionManager, // Pass selection manager
this.params.selectionManager // Pass selection manager
);
// Attach events
taskComponent.onTaskSelected = this.selectTask.bind(this);
@ -859,7 +863,7 @@ export class ContentComponent extends Component {
if (nextComp) {
this.taskListEl.insertBefore(
taskComponent.element,
nextComp.element,
nextComp.element
);
const idx = this.taskComponents.indexOf(nextComp);
this.taskComponents.splice(idx, 0, taskComponent);
@ -872,7 +876,7 @@ export class ContentComponent extends Component {
// Helper: remove list item
const removeListItem = (taskId: string) => {
const idx = this.taskComponents.findIndex(
(c) => c.getTask().id === taskId,
(c) => c.getTask().id === taskId
);
if (idx >= 0) {
const comp = this.taskComponents[idx];
@ -893,7 +897,7 @@ export class ContentComponent extends Component {
if (!this.isTreeView) {
// List view: update in place or insert if new to view
const comp = this.taskComponents.find(
(c) => c.getTask().id === updatedTask.id,
(c) => c.getTask().id === updatedTask.id
);
if (comp) {
comp.updateTask(taskFromFiltered!);
@ -903,7 +907,7 @@ export class ContentComponent extends Component {
} else {
// Tree view: update existing subtree or insert to parent/root
const comp = this.treeComponents.find(
(c) => c.getTask().id === updatedTask.id,
(c) => c.getTask().id === updatedTask.id
);
if (comp) {
comp.updateTask(taskFromFiltered!);
@ -928,7 +932,7 @@ export class ContentComponent extends Component {
const newChildren =
this.notFilteredTasks.filter(
(t) =>
t.metadata.parent === parentId,
t.metadata.parent === parentId
);
parentComp.updateChildTasks(newChildren);
updated = true;
@ -939,11 +943,11 @@ export class ContentComponent extends Component {
// Root insertion
const taskMap = new Map<string, Task>();
this.notFilteredTasks.forEach((t) =>
taskMap.set(t.id, t),
taskMap.set(t.id, t)
);
const childTasks = this.notFilteredTasks.filter(
(t) =>
t.metadata.parent === taskFromFiltered!.id,
t.metadata.parent === taskFromFiltered!.id
);
const newRoot = new TaskTreeItemComponent(
taskFromFiltered!,
@ -953,7 +957,7 @@ export class ContentComponent extends Component {
childTasks,
taskMap,
this.plugin,
this.params.selectionManager, // Pass selection manager
this.params.selectionManager // Pass selection manager
);
newRoot.onTaskSelected = this.selectTask.bind(this);
newRoot.onTaskCompleted = (t) => {
@ -978,7 +982,7 @@ export class ContentComponent extends Component {
if (
rootComparator(
taskFromFiltered!,
this.treeComponents[i].getTask(),
this.treeComponents[i].getTask()
) < 0
) {
insertAt = i;
@ -988,12 +992,12 @@ export class ContentComponent extends Component {
if (insertAt < this.treeComponents.length) {
this.taskListEl.insertBefore(
newRoot.element,
this.treeComponents[insertAt].element,
this.treeComponents[insertAt].element
);
this.treeComponents.splice(
insertAt,
0,
newRoot,
newRoot
);
} else {
this.taskListEl.appendChild(newRoot.element);
@ -1015,7 +1019,7 @@ export class ContentComponent extends Component {
// Tree view removal
// If root component exists, remove it
const idx = this.treeComponents.findIndex(
(c) => c.getTask().id === updatedTask.id,
(c) => c.getTask().id === updatedTask.id
);
if (idx >= 0) {
const comp = this.treeComponents[idx];

View file

@ -9,7 +9,7 @@ import {
} from "obsidian";
import { Task } from "@/types/task";
import { MarkdownRendererComponent } from "@/components/ui/renderers/MarkdownRenderer";
import "@/styles/task-list.css";
import "@/styles/task-status-indicator.css";
import { createTaskCheckbox } from "./details";
import { getRelativeTimeString } from "@/utils/date/date-formatter";

View file

@ -8,8 +8,7 @@ import {
Workspace,
} from "obsidian";
import { Task } from "@/types/task";
import "@/styles/tree-view.css";
import "@/styles/task-status-indicator.css";
import { MarkdownRendererComponent } from "@/components/ui/renderers/MarkdownRenderer";
import { createTaskCheckbox } from "./details";
import { getViewSettingOrDefault, ViewMode } from "@/common/setting-definition";

View file

@ -81,6 +81,7 @@ import "./styles/onboarding.css";
import "./styles/universal-suggest.css";
import "./styles/noise.css";
import "./styles/changelog.css";
import {
TASK_SPECIFIC_VIEW_TYPE,
TaskSpecificView,
@ -225,7 +226,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.changelogManager = new ChangelogManager(this);
this.registerView(
CHANGELOG_VIEW_TYPE,
(leaf) => new ChangelogView(leaf, this),
(leaf) => new ChangelogView(leaf, this)
);
// Initialize onboarding config manager
@ -268,18 +269,18 @@ export default class TaskProgressBarPlugin extends Plugin {
item.setTitle(
`${t("Set priority")}: ${
priority.text
}`,
}`
);
item.setIcon("arrow-big-up-dash");
item.onClick(() => {
setPriorityAtCursor(
editor,
priority.emoji,
priority.emoji
);
});
});
}
},
}
);
submenu.addSeparator();
@ -289,17 +290,17 @@ export default class TaskProgressBarPlugin extends Plugin {
([key, priority]) => {
submenu.addItem((item) => {
item.setTitle(
`${t("Set priority")}: ${key}`,
`${t("Set priority")}: ${key}`
);
item.setIcon("a-arrow-up");
item.onClick(() => {
setPriorityAtCursor(
editor,
`[#${key}]`,
`[#${key}]`
);
});
});
},
}
);
// Remove priority command
@ -319,7 +320,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (this.settings.workflow.enableWorkflow) {
updateWorkflowContextMenu(menu, editor, this);
}
}),
})
);
this.app.workspace.onLayoutReady(async () => {
@ -331,7 +332,7 @@ export default class TaskProgressBarPlugin extends Plugin {
const deferWorkspaceLeaves =
this.app.workspace.getLeavesOfType(TASK_VIEW_TYPE);
const deferSpecificLeaves = this.app.workspace.getLeavesOfType(
TASK_SPECIFIC_VIEW_TYPE,
TASK_SPECIFIC_VIEW_TYPE
);
const deferTaskGeniusLeaves =
this.app.workspace.getLeavesOfType(FLUENT_TASK_VIEW);
@ -359,8 +360,8 @@ export default class TaskProgressBarPlugin extends Plugin {
this.registerEvent(
this.app.workspace.on(
Events.TASK_CACHE_UPDATED as any,
() => this.notificationManager?.onTaskCacheUpdated(),
),
() => this.notificationManager?.onTaskCacheUpdated()
)
);
}
@ -415,7 +416,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.icsManager = new IcsManager(
this.settings.icsIntegration,
this.settings,
this,
this
);
this.addChild(this.icsManager);
@ -435,7 +436,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.activateTimelineSidebarView().catch((error) => {
console.error(
"Failed to auto-open timeline sidebar:",
error,
error
);
});
}, 1000);
@ -484,7 +485,7 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (error) {
console.error(
"[Plugin] Dataflow version check failed during startup:",
error,
error
);
}
@ -522,12 +523,12 @@ export default class TaskProgressBarPlugin extends Plugin {
this.registerView(
TASK_SPECIFIC_VIEW_TYPE,
(leaf) => new TaskSpecificView(leaf, this),
(leaf) => new TaskSpecificView(leaf, this)
);
this.registerView(
TIMELINE_SIDEBAR_VIEW_TYPE,
(leaf) => new TimelineSidebarView(leaf, this),
(leaf) => new TimelineSidebarView(leaf, this)
);
try {
@ -549,7 +550,7 @@ export default class TaskProgressBarPlugin extends Plugin {
new OnboardingView(leaf, this, () => {
console.log("Onboarding completed successfully");
leaf.detach();
}),
})
);
}
@ -624,7 +625,7 @@ export default class TaskProgressBarPlugin extends Plugin {
t("Open Task Genius view"),
() => {
this.activateTaskView();
},
}
);
};
@ -682,16 +683,16 @@ export default class TaskProgressBarPlugin extends Plugin {
detectionMethods:
this.settings.projectConfig?.metadataConfig
?.detectionMethods || [],
},
}
);
return true;
} catch (error) {
console.error(
"[Plugin] Failed to initialize dataflow orchestrator:",
error,
error
);
new Notice(
t("Failed to initialize task system. Please restart Obsidian."),
t("Failed to initialize task system. Please restart Obsidian.")
);
this.dataflowOrchestrator = undefined;
return false;
@ -721,7 +722,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.app.vault,
this.app.metadataCache,
this,
getTaskById,
getTaskById
);
}
@ -759,7 +760,7 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (error) {
console.error(
"[Plugin] Failed registering deferred commands:",
error,
error
);
}
}, 100);
@ -816,7 +817,7 @@ export default class TaskProgressBarPlugin extends Plugin {
}
view.dispatch({
effects: toggleTaskFilter.of(
!view.state.field(taskFilterState),
!view.state.field(taskFilterState)
),
});
},
@ -836,7 +837,7 @@ export default class TaskProgressBarPlugin extends Plugin {
preset.options = migrateOldFilterOptions(preset.options);
}
return preset;
},
}
);
await this.saveSettings();
console.timeEnd("[Task Genius] migratePresetTaskFilters");
@ -854,14 +855,14 @@ export default class TaskProgressBarPlugin extends Plugin {
const changes = sortTasksInDocument(
editorView,
this,
false,
false
);
if (changes) {
new Notice(
t(
"Tasks sorted (using settings). Change application needs refinement.",
),
"Tasks sorted (using settings). Change application needs refinement."
)
);
} else {
// Notice is already handled within sortTasksInDocument if no changes or sorting disabled
@ -885,11 +886,11 @@ export default class TaskProgressBarPlugin extends Plugin {
return changes;
});
new Notice(
t("Entire document sorted (using settings)."),
t("Entire document sorted (using settings).")
);
} else {
new Notice(
t("Tasks already sorted or no tasks found."),
t("Tasks already sorted or no tasks found.")
);
}
},
@ -990,12 +991,10 @@ export default class TaskProgressBarPlugin extends Plugin {
) {
// Use dataflow orchestrator for force reindex
console.log(
"[Command] Force reindexing via dataflow",
"[Command] Force reindexing via dataflow"
);
new Notice(
t(
"Clearing task cache and rebuilding index...",
),
t("Clearing task cache and rebuilding index...")
);
// Clear all caches and rebuild from scratch
@ -1095,7 +1094,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allCompleted",
"allCompleted"
);
},
});
@ -1110,7 +1109,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directChildren",
"directChildren"
);
},
});
@ -1125,7 +1124,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"all",
"all"
);
},
});
@ -1141,7 +1140,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allCompleted",
"allCompleted"
);
},
});
@ -1149,7 +1148,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.addCommand({
id: "auto-move-direct-completed-subtasks",
name: t(
"Auto-move direct completed subtasks to default file",
"Auto-move direct completed subtasks to default file"
),
editorCheckCallback: (checking, editor, ctx) => {
return autoMoveCompletedTasksCommand(
@ -1157,7 +1156,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directChildren",
"directChildren"
);
},
});
@ -1171,7 +1170,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"all",
"all"
);
},
});
@ -1190,7 +1189,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allIncompleted",
"allIncompleted"
);
},
});
@ -1205,7 +1204,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directIncompletedChildren",
"directIncompletedChildren"
);
},
});
@ -1221,7 +1220,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allIncompleted",
"allIncompleted"
);
},
});
@ -1229,7 +1228,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.addCommand({
id: "auto-move-direct-incomplete-subtasks",
name: t(
"Auto-move direct incomplete subtasks to default file",
"Auto-move direct incomplete subtasks to default file"
),
editorCheckCallback: (checking, editor, ctx) => {
return autoMoveCompletedTasksCommand(
@ -1237,7 +1236,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directIncompletedChildren",
"directIncompletedChildren"
);
},
});
@ -1303,8 +1302,8 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (e) {
new Notice(
t(
"Could not open quick capture panel in the current editor",
),
"Could not open quick capture panel in the current editor"
)
);
}
}, 100);
@ -1323,7 +1322,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this,
this
);
},
});
@ -1336,7 +1335,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this,
this
);
},
});
@ -1349,7 +1348,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this,
this
);
},
});
@ -1362,7 +1361,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this,
this
);
},
});
@ -1375,7 +1374,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this,
this
);
},
});
@ -1388,7 +1387,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this,
this
);
},
});
@ -1426,7 +1425,7 @@ export default class TaskProgressBarPlugin extends Plugin {
URL.revokeObjectURL(url);
new Notice(
`Exported ${stats.activeTimers} timer records`,
`Exported ${stats.activeTimers} timer records`
);
} catch (error) {
console.error("Error exporting timer data:", error);
@ -1457,17 +1456,17 @@ export default class TaskProgressBarPlugin extends Plugin {
if (success) {
new Notice(
"Timer data imported successfully",
"Timer data imported successfully"
);
} else {
new Notice(
"Failed to import timer data - invalid format",
"Failed to import timer data - invalid format"
);
}
} catch (error) {
console.error(
"Error importing timer data:",
error,
error
);
new Notice("Failed to import timer data");
}
@ -1511,12 +1510,12 @@ export default class TaskProgressBarPlugin extends Plugin {
URL.revokeObjectURL(url);
new Notice(
`Exported ${stats.activeTimers} timer records to YAML`,
`Exported ${stats.activeTimers} timer records to YAML`
);
} catch (error) {
console.error(
"Error exporting timer data to YAML:",
error,
error
);
new Notice("Failed to export timer data to YAML");
}
@ -1564,7 +1563,7 @@ export default class TaskProgressBarPlugin extends Plugin {
let message = `Task Timer Statistics:\n`;
message += `Active timers: ${stats.activeTimers}\n`;
message += `Total duration: ${Math.round(
stats.totalDuration / 60000,
stats.totalDuration / 60000
)} minutes\n`;
if (stats.oldestTimer) {
@ -1594,12 +1593,12 @@ export default class TaskProgressBarPlugin extends Plugin {
// Initialize task timer manager and exporter
if (!this.taskTimerManager) {
this.taskTimerManager = new TaskTimerManager(
this.settings.taskTimer,
this.settings.taskTimer
);
}
if (!this.taskTimerExporter) {
this.taskTimerExporter = new TaskTimerExporter(
this.taskTimerManager,
this.taskTimerManager
);
}
@ -1648,7 +1647,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (this.settings.quickCapture.enableMinimalMode) {
this.minimalQuickCaptureSuggest = new MinimalQuickCaptureSuggest(
this.app,
this,
this
);
this.registerEditorSuggest(this.minimalQuickCaptureSuggest);
}
@ -1682,7 +1681,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.dataflowOrchestrator.cleanup().catch((error) => {
console.error(
"Error cleaning up dataflow orchestrator:",
error,
error
);
});
// Set to undefined to prevent any further access
@ -1751,11 +1750,11 @@ export default class TaskProgressBarPlugin extends Plugin {
const v2Leaves = workspace.getLeavesOfType(FLUENT_TASK_VIEW);
v2Leaves.forEach((leaf) => leaf.detach());
const specificLeaves = workspace.getLeavesOfType(
TASK_SPECIFIC_VIEW_TYPE,
TASK_SPECIFIC_VIEW_TYPE
);
specificLeaves.forEach((leaf) => leaf.detach());
const timelineLeaves = workspace.getLeavesOfType(
TIMELINE_SIDEBAR_VIEW_TYPE,
TIMELINE_SIDEBAR_VIEW_TYPE
);
timelineLeaves.forEach((leaf) => leaf.detach());
const changelogLeaves = workspace.getLeavesOfType(CHANGELOG_VIEW_TYPE);
@ -1814,7 +1813,7 @@ export default class TaskProgressBarPlugin extends Plugin {
lastVersion !== "9.9.0"
) {
console.log(
`[Task Genius] Migration detected: ${previousVersion} -> ${currentVersion}, opening onboarding`,
`[Task Genius] Migration detected: ${previousVersion} -> ${currentVersion}, opening onboarding`
);
// Directly open onboarding view (same pattern as maybeShowChangelog)
@ -1827,7 +1826,7 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (error) {
console.error(
"[Task Genius] Failed to check migration onboarding:",
error,
error
);
}
}
@ -1868,16 +1867,16 @@ export default class TaskProgressBarPlugin extends Plugin {
enabled: true,
lastVersion: "",
},
this.settings.changelog ?? {},
this.settings.changelog ?? {}
);
try {
console.debug(
"[Plugin][loadSettings] fileMetadataInheritance (raw):",
savedData?.fileMetadataInheritance,
savedData?.fileMetadataInheritance
);
console.debug(
"[Plugin][loadSettings] fileMetadataInheritance (effective):",
this.settings.fileMetadataInheritance,
this.settings.fileMetadataInheritance
);
} catch {}
@ -1919,7 +1918,7 @@ export default class TaskProgressBarPlugin extends Plugin {
try {
console.debug(
"[Plugin][saveSettings] fileMetadataInheritance:",
this.settings?.fileMetadataInheritance,
this.settings?.fileMetadataInheritance
);
} catch {}
await this.saveData(this.settings);
@ -1936,7 +1935,7 @@ export default class TaskProgressBarPlugin extends Plugin {
// Add any missing default views to user settings
defaultViews.forEach((defaultView) => {
const existingView = this.settings.viewConfiguration.find(
(v) => v.id === defaultView.id,
(v) => v.id === defaultView.id
);
if (!existingView) {
this.settings.viewConfiguration.push({ ...defaultView });
@ -2000,7 +1999,7 @@ export default class TaskProgressBarPlugin extends Plugin {
// Check if view is already open
const existingLeaves = workspace.getLeavesOfType(
TIMELINE_SIDEBAR_VIEW_TYPE,
TIMELINE_SIDEBAR_VIEW_TYPE
);
if (existingLeaves.length > 0) {
@ -2046,7 +2045,7 @@ export default class TaskProgressBarPlugin extends Plugin {
// Update Timeline Sidebar Views
const timelineViewLeaves = this.app.workspace.getLeavesOfType(
TIMELINE_SIDEBAR_VIEW_TYPE,
TIMELINE_SIDEBAR_VIEW_TYPE
);
if (timelineViewLeaves.length > 0) {
for (const leaf of timelineViewLeaves) {
@ -2080,7 +2079,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (!diagnosticInfo.canWrite) {
throw new Error(
"Cannot write to version storage - storage may be corrupted",
"Cannot write to version storage - storage may be corrupted"
);
}
@ -2089,7 +2088,7 @@ export default class TaskProgressBarPlugin extends Plugin {
diagnosticInfo.previousVersion
) {
console.warn(
"Invalid version data detected, attempting recovery",
"Invalid version data detected, attempting recovery"
);
await this.versionManager.recoverFromCorruptedVersion();
}
@ -2100,7 +2099,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (versionResult.requiresRebuild) {
console.log(
`Task Genius (Dataflow): ${versionResult.rebuildReason}`,
`Task Genius (Dataflow): ${versionResult.rebuildReason}`
);
// Get all supported files for progress tracking
@ -2109,13 +2108,13 @@ export default class TaskProgressBarPlugin extends Plugin {
.filter(
(file) =>
file.extension === "md" ||
file.extension === "canvas",
file.extension === "canvas"
);
// Start rebuild progress tracking
this.rebuildProgressManager.startRebuild(
allFiles.length,
versionResult.rebuildReason,
versionResult.rebuildReason
);
// After dataflow rebuild, refresh habits to keep in sync
@ -2141,20 +2140,20 @@ export default class TaskProgressBarPlugin extends Plugin {
} else {
// No rebuild needed, dataflow already initialized during creation
console.log(
"Task Genius (Dataflow): No rebuild needed, using existing cache",
"Task Genius (Dataflow): No rebuild needed, using existing cache"
);
}
} catch (error) {
console.error(
"Error during dataflow initialization with version check:",
error,
error
);
// Trigger emergency rebuild for dataflow
try {
const emergencyResult =
await this.versionManager.handleEmergencyRebuild(
`Dataflow initialization failed: ${error.message}`,
`Dataflow initialization failed: ${error.message}`
);
// Get all supported files for progress tracking
@ -2163,13 +2162,13 @@ export default class TaskProgressBarPlugin extends Plugin {
.filter(
(file) =>
file.extension === "md" ||
file.extension === "canvas",
file.extension === "canvas"
);
// Start emergency rebuild
this.rebuildProgressManager.startRebuild(
allFiles.length,
emergencyResult.rebuildReason,
emergencyResult.rebuildReason
);
// Force rebuild dataflow
@ -2187,12 +2186,12 @@ export default class TaskProgressBarPlugin extends Plugin {
await this.versionManager.markVersionProcessed();
console.log(
"Emergency dataflow rebuild completed successfully",
"Emergency dataflow rebuild completed successfully"
);
} catch (emergencyError) {
console.error(
"Emergency dataflow rebuild failed:",
emergencyError,
emergencyError
);
throw emergencyError;
}
@ -2207,7 +2206,7 @@ export default class TaskProgressBarPlugin extends Plugin {
private async initializeTaskManagerWithVersionCheck(): Promise<void> {
// This method is deprecated and should not be called
console.warn(
"initializeTaskManagerWithVersionCheck is deprecated and should not be used",
"initializeTaskManagerWithVersionCheck is deprecated and should not be used"
);
return Promise.resolve();
}

30
src/styles/modern.css Normal file
View file

@ -0,0 +1,30 @@
.task-item {
display: flex;
align-items: flex-start;
padding: 8px 16px;
border-bottom: 1px solid var(--color-base-10);
cursor: pointer;
gap: var(--size-2-3);
min-height: 40px;
gap: 0;
border-radius: var(--radius-m);
}
.task-list > .task-item {
margin-bottom: var(--size-4-2);
}
.fluent-search-container input[type="search"] {
width: 100%;
background-color: var(--background-primary-alt);
height: var(--size-4-8);
border: unset;
}
.search-input-container {
width: 100%;
}
.task-list {
padding: var(--size-4-2);
}

View file

@ -9,7 +9,7 @@
display: flex;
align-items: flex-start;
padding: 8px 16px;
border-bottom: 1px solid var(--background-modifier-border);
/* border-bottom: 1px solid var(--background-modifier-border); */
cursor: pointer;
gap: var(--size-2-3);

1061
styles.css

File diff suppressed because one or more lines are too long