2022-09-27 21:23:36 +02:00
|
|
|
import { moment, App, MarkdownSectionInformation } from "obsidian";
|
2022-09-27 16:06:40 +02:00
|
|
|
|
|
|
|
export class Tracker {
|
2022-09-27 17:03:44 +02:00
|
|
|
entries: Entry[];
|
|
|
|
}
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
export interface Entry {
|
|
|
|
name: string;
|
|
|
|
startTime: number;
|
|
|
|
endTime: number;
|
|
|
|
}
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
export function startEntry(tracker: Tracker, name: string): void {
|
2022-09-27 21:23:36 +02:00
|
|
|
if (!name)
|
|
|
|
name = `Segment ${tracker.entries.length + 1}`;
|
|
|
|
let entry: Entry = { name: name, startTime: moment().unix(), endTime: null };
|
2022-09-27 17:03:44 +02:00
|
|
|
tracker.entries.push(entry);
|
|
|
|
};
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
export function endEntry(tracker: Tracker): void {
|
|
|
|
let last = tracker.entries.last();
|
2022-09-27 21:23:36 +02:00
|
|
|
last.endTime = moment().unix();
|
2022-09-27 17:03:44 +02:00
|
|
|
}
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
export function isRunning(tracker: Tracker): boolean {
|
|
|
|
let last = tracker.entries.last();
|
|
|
|
return last != null && !last.endTime;
|
|
|
|
}
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
export async function saveTracker(tracker: Tracker, app: App, section: MarkdownSectionInformation): Promise<void> {
|
|
|
|
let file = app.workspace.getActiveFile();
|
|
|
|
let content = await app.vault.cachedRead(file);
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
// figure out what part of the content we have to edit
|
|
|
|
let lines = content.split("\n");
|
|
|
|
let prev = lines.filter((_, i) => i <= section.lineStart).join("\n");
|
|
|
|
let next = lines.filter((_, i) => i >= section.lineEnd).join("\n");
|
|
|
|
// edit only the code block content, leave the rest untouched
|
|
|
|
content = `${prev}\n${JSON.stringify(tracker)}\n${next}`;
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
await app.vault.modify(file, content);
|
|
|
|
}
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
export function loadTracker(json: string): Tracker {
|
|
|
|
if (json) {
|
|
|
|
try {
|
|
|
|
return JSON.parse(json);
|
|
|
|
} catch (e) {
|
|
|
|
console.log(`Failed to parse Tracker from ${json}`);
|
2022-09-27 16:06:40 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-27 17:03:44 +02:00
|
|
|
return { entries: [] };
|
2022-09-27 16:06:40 +02:00
|
|
|
}
|
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
export function displayTracker(tracker: Tracker, element: HTMLElement): void {
|
2022-09-27 21:23:36 +02:00
|
|
|
// add timers
|
2022-09-27 19:33:34 +02:00
|
|
|
let timer = element.createDiv({ cls: "simple-time-tracker-timers" });
|
2022-09-27 21:23:36 +02:00
|
|
|
let currentDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" });
|
2022-09-27 21:35:26 +02:00
|
|
|
let current = currentDiv.createEl("span", { cls: "simple-time-tracker-timer-time" });
|
2022-09-27 21:23:36 +02:00
|
|
|
currentDiv.createEl("span", { text: "CURRENT" });
|
|
|
|
let totalDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" });
|
2022-09-27 21:35:26 +02:00
|
|
|
let total = totalDiv.createEl("span", { cls: "simple-time-tracker-timer-time" });
|
2022-09-27 21:23:36 +02:00
|
|
|
totalDiv.createEl("span", { text: "TOTAL" });
|
|
|
|
|
|
|
|
// add list
|
|
|
|
let table = element.createEl("table", { cls: "simple-time-tracker-table" });
|
2022-09-27 21:29:50 +02:00
|
|
|
table.createEl("tr").append(
|
|
|
|
createEl("th", { text: "Segment" }),
|
|
|
|
createEl("th", { text: "Start Time" }),
|
|
|
|
createEl("th", { text: "End Time" }),
|
|
|
|
createEl("th", { text: "Total" }));
|
|
|
|
|
2022-09-27 21:23:36 +02:00
|
|
|
for (let entry of tracker.entries) {
|
|
|
|
let row = table.createEl("tr");
|
|
|
|
row.createEl("td", { text: entry.name });
|
|
|
|
row.createEl("td", { text: moment.unix(entry.startTime).format("YY-MM-DD hh:mm:ss") });
|
|
|
|
if (entry.endTime) {
|
|
|
|
row.createEl("td", { text: moment.unix(entry.endTime).format("YY-MM-DD hh:mm:ss") });
|
|
|
|
let duration = moment.unix(entry.endTime).diff(moment.unix(entry.startTime));
|
|
|
|
row.createEl("td", { text: getCountdownDisplay(moment.duration(duration)) });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setCountdownValues(tracker, current, total, currentDiv);
|
|
|
|
let intervalId = window.setInterval(() => {
|
|
|
|
// we delete the interval timer when the element is removed
|
|
|
|
if (!element.isConnected) {
|
|
|
|
window.clearInterval(intervalId);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setCountdownValues(tracker, current, total, currentDiv);
|
|
|
|
}, 1000);
|
|
|
|
|
2022-09-27 17:03:44 +02:00
|
|
|
};
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 21:23:36 +02:00
|
|
|
function getCountdownDisplay(duration: moment.Duration): string {
|
2022-09-27 17:03:44 +02:00
|
|
|
let ret = "";
|
2022-09-27 21:23:36 +02:00
|
|
|
if (duration.hours() > 0)
|
2022-09-27 21:35:26 +02:00
|
|
|
ret += duration.hours() + "h ";
|
|
|
|
if (duration.minutes() > 0)
|
|
|
|
ret += duration.minutes() + "m ";
|
|
|
|
ret += duration.seconds() + "s";
|
2022-09-27 21:23:36 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 21:23:36 +02:00
|
|
|
function setCountdownValues(tracker: Tracker, current: HTMLElement, total: HTMLElement, currentDiv: HTMLDivElement) {
|
|
|
|
let currEntry = tracker.entries.last();
|
|
|
|
if (currEntry) {
|
|
|
|
let currDuration = moment().diff(moment.unix(currEntry.startTime));
|
|
|
|
if (!currEntry.endTime)
|
|
|
|
current.setText(getCountdownDisplay(moment.duration(currDuration)));
|
2022-09-27 16:06:40 +02:00
|
|
|
|
2022-09-27 21:23:36 +02:00
|
|
|
let totalDuration = 0;
|
|
|
|
for (let entry of tracker.entries) {
|
|
|
|
if (entry == currEntry && !currEntry.endTime) {
|
|
|
|
totalDuration += currDuration;
|
|
|
|
} else {
|
|
|
|
totalDuration += moment.unix(entry.endTime).diff(moment.unix(entry.startTime));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
total.setText(getCountdownDisplay(moment.duration(totalDuration)));
|
2022-09-27 16:06:40 +02:00
|
|
|
}
|
2022-09-27 21:35:26 +02:00
|
|
|
currentDiv.hidden = !currEntry || !!currEntry.endTime;
|
2022-09-27 16:06:40 +02:00
|
|
|
}
|