diff --git a/src/main.ts b/src/main.ts index cbb5025..23b1a92 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import {MarkdownRenderChild, Plugin} from "obsidian"; +import {MarkdownRenderChild, Plugin, TFile} from "obsidian"; import { defaultSettings, SimpleTimeTrackerSettings } from "./settings"; import { SimpleTimeTrackerSettingsTab } from "./settings-tab"; import { displayTracker, loadTracker } from "./tracker"; @@ -16,7 +16,24 @@ export default class SimpleTimeTrackerPlugin extends Plugin { e.empty(); let component = new MarkdownRenderChild(e) let tracker = loadTracker(s); - displayTracker(tracker, e, i.sourcePath, () => i.getSectionInfo(e), this.settings, component); + + // Initial file name + let filePath = i.sourcePath; + + // Getter passed to displayTracker since the file name can change + const getFile = () => filePath; + + // Hook rename events to update the file path + const renameEventRef = this.app.vault.on("rename", (file, oldPath) => { + if (file instanceof TFile && oldPath === filePath) { + filePath = file.path; + } + }) + + // Register the event to remove on unload + component.registerEvent(renameEventRef); + + displayTracker(tracker, e, getFile, () => i.getSectionInfo(e), this.settings, component); i.addChild(component) }); diff --git a/src/tracker.ts b/src/tracker.ts index a4a029e..6596a27 100644 --- a/src/tracker.ts +++ b/src/tracker.ts @@ -41,7 +41,10 @@ export function loadTracker(json: string): Tracker { return {entries: []}; } -export function displayTracker(tracker: Tracker, element: HTMLElement, file: string, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, component: MarkdownRenderChild): void { +type GetFile = () => string; + +export function displayTracker(tracker: Tracker, element: HTMLElement, getFile: GetFile, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, component: MarkdownRenderChild): void { + element.addClass("simple-time-tracker-container"); // add start/stop controls let running = isRunning(tracker); @@ -55,7 +58,7 @@ export function displayTracker(tracker: Tracker, element: HTMLElement, file: str } else { startNewEntry(tracker, newSegmentNameBox.getValue()); } - await saveTracker(tracker, this.app, file, getSectionInfo()); + await saveTracker(tracker, this.app, getFile(), getSectionInfo()); }); btn.buttonEl.addClass("simple-time-tracker-btn"); let newSegmentNameBox = new TextComponent(element) @@ -83,7 +86,7 @@ export function displayTracker(tracker: Tracker, element: HTMLElement, file: str createEl("th")); for (let entry of orderedEntries(tracker.entries, settings)) - addEditableTableRow(tracker, entry, table, newSegmentNameBox, running, file, getSectionInfo, settings, 0, component); + addEditableTableRow(tracker, entry, table, newSegmentNameBox, running, getFile, getSectionInfo, settings, 0, component); // add copy buttons let buttons = element.createEl("div", {cls: "simple-time-tracker-bottom"}); @@ -303,7 +306,7 @@ function orderedEntries(entries: Entry[], settings: SimpleTimeTrackerSettings): return settings.reverseSegmentOrder ? entries.slice().reverse() : entries; } -function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableElement, newSegmentNameBox: TextComponent, trackerRunning: boolean, file: string, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, indent: number, component: MarkdownRenderChild): void { +function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableElement, newSegmentNameBox: TextComponent, trackerRunning: boolean, getFile: GetFile, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, indent: number, component: MarkdownRenderChild): void { let entryRunning = getRunningEntry(tracker.entries) == entry; let row = table.createEl("tr"); @@ -313,7 +316,7 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle row.createEl("td", {text: entry.endTime || entry.subEntries ? formatDuration(getDuration(entry), settings) : ""}); - renderNameAsMarkdown(nameField.label, file, component); + renderNameAsMarkdown(nameField.label, getFile, component); let entryButtons = row.createEl("td"); entryButtons.addClass("simple-time-tracker-table-buttons"); @@ -324,7 +327,7 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle .setDisabled(trackerRunning) .onClick(async () => { startSubEntry(entry, newSegmentNameBox.getValue()); - await saveTracker(tracker, this.app, file, getSectionInfo()); + await saveTracker(tracker, this.app, getFile(), getSectionInfo()); }); let editButton = new ButtonComponent(entryButtons) .setClass("clickable-icon") @@ -339,10 +342,10 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle endField.endEdit(); entry.endTime = endField.getTimestamp(); } - await saveTracker(tracker, this.app, file, getSectionInfo()); + await saveTracker(tracker, this.app, getFile(), getSectionInfo()); editButton.setIcon("lucide-pencil"); - renderNameAsMarkdown(nameField.label, file, component); + renderNameAsMarkdown(nameField.label, getFile, component); } else { nameField.beginEdit(entry.name); // only allow editing start and end times if we don't have sub entries @@ -361,17 +364,17 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle .setDisabled(entryRunning) .onClick(async () => { removeEntry(tracker.entries, entry); - await saveTracker(tracker, this.app, file, getSectionInfo()); + await saveTracker(tracker, this.app, getFile(), getSectionInfo()); }); if (entry.subEntries) { for (let sub of orderedEntries(entry.subEntries, settings)) - addEditableTableRow(tracker, sub, table, newSegmentNameBox, trackerRunning, file, getSectionInfo, settings, indent + 1, component); + addEditableTableRow(tracker, sub, table, newSegmentNameBox, trackerRunning, getFile, getSectionInfo, settings, indent + 1, component); } } -function renderNameAsMarkdown(label: HTMLSpanElement, path: string, component: Component): void { - void MarkdownRenderer.renderMarkdown(label.innerHTML, label, path, component); +function renderNameAsMarkdown(label: HTMLSpanElement, getFile: GetFile, component: Component): void { + void MarkdownRenderer.renderMarkdown(label.innerHTML, label, getFile(), component); // rendering wraps it in a paragraph label.innerHTML = label.querySelector("p").innerHTML; }