From 3be8d8de02df63872b06b7a69058fb09697013e8 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 11 Aug 2023 19:32:43 +0200 Subject: [PATCH] ignore vault files --- .editorconfig | 18 +- .gitignore | 46 +- .../plugins/simple-time-tracker/.gitignore | 3 + .../plugins/simple-time-tracker/main | 404 ------------------ .../plugins/simple-time-tracker/main.js | 404 ------------------ .../plugins/simple-time-tracker/manifest | 10 - .../plugins/simple-time-tracker/manifest.json | 10 - .../plugins/simple-time-tracker/styles | 64 --- .../plugins/simple-time-tracker/styles.css | 64 --- 9 files changed, 35 insertions(+), 988 deletions(-) create mode 100644 test-vault/.obsidian/plugins/simple-time-tracker/.gitignore delete mode 100644 test-vault/.obsidian/plugins/simple-time-tracker/main delete mode 100644 test-vault/.obsidian/plugins/simple-time-tracker/main.js delete mode 100644 test-vault/.obsidian/plugins/simple-time-tracker/manifest delete mode 100644 test-vault/.obsidian/plugins/simple-time-tracker/manifest.json delete mode 100644 test-vault/.obsidian/plugins/simple-time-tracker/styles delete mode 100644 test-vault/.obsidian/plugins/simple-time-tracker/styles.css diff --git a/.editorconfig b/.editorconfig index e49a856..02905fd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,9 @@ -# top-most EditorConfig file -root = true - -[*] -charset = utf-8 -insert_final_newline = true -indent_style = space -indent_size = 4 -tab_width = 4 +# top-most EditorConfig file +root = true + +[*] +charset = utf-8 +insert_final_newline = true +indent_style = space +indent_size = 4 +tab_width = 4 diff --git a/.gitignore b/.gitignore index 4059302..7a8a715 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,23 @@ -# vscode -.vscode - -# Intellij -*.iml -.idea - -# npm -node_modules - -# Don't include the compiled main.js file in the repo. -# They should be uploaded to GitHub releases instead. -/main.js - -# Exclude sourcemaps -*.map - -# obsidian -workspace -workspace.json - -# Exclude macOS Finder (System Explorer) View States -.DS_Store +# vscode +.vscode + +# Intellij +*.iml +.idea + +# npm +node_modules + +# Don't include the compiled main.js file in the repo. +# They should be uploaded to GitHub releases instead. +/main.js + +# Exclude sourcemaps +*.map + +# obsidian +workspace +workspace.json + +# Exclude macOS Finder (System Explorer) View States +.DS_Store diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/.gitignore b/test-vault/.obsidian/plugins/simple-time-tracker/.gitignore new file mode 100644 index 0000000..d334fd2 --- /dev/null +++ b/test-vault/.obsidian/plugins/simple-time-tracker/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!data.json diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/main b/test-vault/.obsidian/plugins/simple-time-tracker/main deleted file mode 100644 index f152d05..0000000 --- a/test-vault/.obsidian/plugins/simple-time-tracker/main +++ /dev/null @@ -1,404 +0,0 @@ -/* -THIS IS A GENERATED/BUNDLED FILE BY ESBUILD -if you want to view the source, please visit the github repository of this plugin -*/ -var __create = Object.create; -var __defProp = Object.defineProperty; -var __defProps = Object.defineProperties; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropDescs = Object.getOwnPropertyDescriptors; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getOwnPropSymbols = Object.getOwnPropertySymbols; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __propIsEnum = Object.prototype.propertyIsEnumerable; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; -var __spreadValues = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp.call(b, prop)) - __defNormalProp(a, prop, b[prop]); - if (__getOwnPropSymbols) - for (var prop of __getOwnPropSymbols(b)) { - if (__propIsEnum.call(b, prop)) - __defNormalProp(a, prop, b[prop]); - } - return a; -}; -var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); -var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); -var __export = (target, all) => { - __markAsModule(target); - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __reExport = (target, module2, desc) => { - if (module2 && typeof module2 === "object" || typeof module2 === "function") { - for (let key of __getOwnPropNames(module2)) - if (!__hasOwnProp.call(target, key) && key !== "default") - __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); - } - return target; -}; -var __toModule = (module2) => { - return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); -}; -var __async = (__this, __arguments, generator) => { - return new Promise((resolve, reject) => { - var fulfilled = (value) => { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - }; - var rejected = (value) => { - try { - step(generator.throw(value)); - } catch (e) { - reject(e); - } - }; - var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); - step((generator = generator.apply(__this, __arguments)).next()); - }); -}; - -// src/main.ts -__export(exports, { - default: () => SimpleTimeTrackerPlugin -}); -var import_obsidian3 = __toModule(require("obsidian")); - -// src/settings.ts -var defaultSettings = { - timestampFormat: "YY-MM-DD hh:mm:ss", - csvDelimiter: ",", - fineGrainedDurations: true -}; - -// src/settings-tab.ts -var import_obsidian = __toModule(require("obsidian")); -var SimpleTimeTrackerSettingsTab = class extends import_obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); - this.plugin = plugin; - } - display() { - this.containerEl.empty(); - this.containerEl.createEl("h2", { text: "Super Simple Time Tracker Settings" }); - new import_obsidian.Setting(this.containerEl).setName("Timestamp Display Format").setDesc(createFragment((f) => { - f.createSpan({ text: "The way that timestamps in time tracker tables should be displayed. Uses " }); - f.createEl("a", { text: "moment.js", href: "https://momentjs.com/docs/#/parsing/string-format/" }); - f.createSpan({ text: " syntax." }); - })).addText((t) => { - t.setValue(String(this.plugin.settings.timestampFormat)); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.timestampFormat = v.length ? v : defaultSettings.timestampFormat; - yield this.plugin.saveSettings(); - })); - }); - new import_obsidian.Setting(this.containerEl).setName("CSV Delimiter").setDesc("The delimiter character that should be used when copying a tracker table as CSV. For example, some languages use a semicolon instead of a comma.").addText((t) => { - t.setValue(String(this.plugin.settings.csvDelimiter)); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.csvDelimiter = v.length ? v : defaultSettings.csvDelimiter; - yield this.plugin.saveSettings(); - })); - }); - new import_obsidian.Setting(this.containerEl).setName("Fine-Grained Durations").setDesc("Whether durations should include days, months and years. If this is disabled, additional time units will be displayed as part of the hours.").addToggle((t) => { - t.setValue(this.plugin.settings.fineGrainedDurations); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.fineGrainedDurations = v; - yield this.plugin.saveSettings(); - })); - }); - this.containerEl.createEl("hr"); - this.containerEl.createEl("p", { text: "If you like this plugin and want to support its development, you can do so through my website by clicking this fancy image!" }); - this.containerEl.createEl("a", { href: "https://ellpeck.de/support" }).createEl("img", { - attr: { src: "https://ellpeck.de/res/generalsupport.png" }, - cls: "simple-time-tracker-support" - }); - } -}; - -// src/tracker.ts -var import_obsidian2 = __toModule(require("obsidian")); -function saveTracker(tracker, app, fileName, section) { - return __async(this, null, function* () { - let file = app.vault.getAbstractFileByPath(fileName); - if (!file) - return; - let content = yield app.vault.read(file); - 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"); - content = `${prev} -${JSON.stringify(tracker)} -${next}`; - yield app.vault.modify(file, content); - }); -} -function loadTracker(json) { - if (json) { - try { - return JSON.parse(json); - } catch (e) { - console.log(`Failed to parse Tracker from ${json}`); - } - } - return { entries: [] }; -} -function displayTracker(tracker, element, file, getSectionInfo, settings) { - let running = isRunning(tracker); - let btn = new import_obsidian2.ButtonComponent(element).setClass("clickable-icon").setIcon(`lucide-${running ? "stop" : "play"}-circle`).setTooltip(running ? "End" : "Start").onClick(() => __async(this, null, function* () { - if (running) { - endRunningEntry(tracker); - } else { - startNewEntry(tracker, newSegmentNameBox.getValue()); - } - yield saveTracker(tracker, this.app, file, getSectionInfo()); - })); - btn.buttonEl.addClass("simple-time-tracker-btn"); - let newSegmentNameBox = new import_obsidian2.TextComponent(element).setPlaceholder("Segment name").setDisabled(running); - newSegmentNameBox.inputEl.addClass("simple-time-tracker-txt"); - let timer = element.createDiv({ cls: "simple-time-tracker-timers" }); - let currentDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); - let current = currentDiv.createEl("span", { cls: "simple-time-tracker-timer-time" }); - currentDiv.createEl("span", { text: "Current" }); - let totalDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); - let total = totalDiv.createEl("span", { cls: "simple-time-tracker-timer-time", text: "0s" }); - totalDiv.createEl("span", { text: "Total" }); - if (tracker.entries.length > 0) { - let table = element.createEl("table", { cls: "simple-time-tracker-table" }); - table.createEl("tr").append(createEl("th", { text: "Segment" }), createEl("th", { text: "Start time" }), createEl("th", { text: "End time" }), createEl("th", { text: "Duration" }), createEl("th")); - for (let entry of tracker.entries) - addEditableTableRow(tracker, entry, table, newSegmentNameBox, running, file, getSectionInfo, settings, 0); - let buttons = element.createEl("div", { cls: "simple-time-tracker-bottom" }); - new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as table").onClick(() => navigator.clipboard.writeText(createMarkdownTable(tracker, settings))); - new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as CSV").onClick(() => navigator.clipboard.writeText(createCsv(tracker, settings))); - } - setCountdownValues(tracker, current, total, currentDiv, settings); - let intervalId = window.setInterval(() => { - if (!element.isConnected) { - window.clearInterval(intervalId); - return; - } - setCountdownValues(tracker, current, total, currentDiv, settings); - }, 1e3); -} -function startSubEntry(entry, name) { - if (!entry.subEntries) { - entry.subEntries = [__spreadProps(__spreadValues({}, entry), { name: `Part 1` })]; - entry.startTime = null; - entry.endTime = null; - } - if (!name) - name = `Part ${entry.subEntries.length + 1}`; - entry.subEntries.push({ name, startTime: (0, import_obsidian2.moment)().unix(), endTime: null, subEntries: null }); -} -function startNewEntry(tracker, name) { - if (!name) - name = `Segment ${tracker.entries.length + 1}`; - let entry = { name, startTime: (0, import_obsidian2.moment)().unix(), endTime: null, subEntries: null }; - tracker.entries.push(entry); -} -function endRunningEntry(tracker) { - let entry = getRunningEntry(tracker.entries); - entry.endTime = (0, import_obsidian2.moment)().unix(); -} -function removeEntry(entries, toRemove) { - if (entries.contains(toRemove)) { - entries.remove(toRemove); - return true; - } else { - for (let entry of entries) { - if (entry.subEntries && removeEntry(entry.subEntries, toRemove)) { - if (entry.subEntries.length == 1) { - let single = entry.subEntries[0]; - entry.startTime = single.startTime; - entry.endTime = single.endTime; - entry.subEntries = null; - } - return true; - } - } - } - return false; -} -function isRunning(tracker) { - return !!getRunningEntry(tracker.entries); -} -function getRunningEntry(entries) { - for (let entry of entries) { - if (entry.subEntries) { - let running = getRunningEntry(entry.subEntries); - if (running) - return running; - } else { - if (!entry.endTime) - return entry; - } - } - return null; -} -function getDuration(entry) { - if (entry.subEntries) { - return getTotalDuration(entry.subEntries); - } else { - let endTime = entry.endTime ? import_obsidian2.moment.unix(entry.endTime) : (0, import_obsidian2.moment)(); - return endTime.diff(import_obsidian2.moment.unix(entry.startTime)); - } -} -function getTotalDuration(entries) { - let ret = 0; - for (let entry of entries) - ret += getDuration(entry); - return ret; -} -function setCountdownValues(tracker, current, total, currentDiv, settings) { - let running = getRunningEntry(tracker.entries); - if (running && !running.endTime) { - current.setText(formatDuration(getDuration(running), settings)); - currentDiv.hidden = false; - } else { - currentDiv.hidden = true; - } - total.setText(formatDuration(getTotalDuration(tracker.entries), settings)); -} -function formatTimestamp(timestamp, settings) { - return import_obsidian2.moment.unix(timestamp).format(settings.timestampFormat); -} -function formatDuration(totalTime, settings) { - let ret = ""; - let duration = import_obsidian2.moment.duration(totalTime); - let hours; - if (settings.fineGrainedDurations) { - if (duration.years() > 0) - ret += duration.years() + "y "; - if (duration.months() > 0) - ret += duration.months() + "M "; - if (duration.days() > 0) - ret += duration.days() + "d "; - hours = duration.hours(); - } else { - hours = Math.floor(duration.asHours()); - } - if (hours > 0) - ret += hours + "h "; - if (duration.minutes() > 0) - ret += duration.minutes() + "m "; - ret += duration.seconds() + "s"; - return ret; -} -function createMarkdownTable(tracker, settings) { - let table = [["Segment", "Start time", "End time", "Duration"]]; - for (let entry of tracker.entries) - table.push(...createTableSection(entry, settings)); - table.push(["**Total**", "", "", `**${formatDuration(getTotalDuration(tracker.entries), settings)}**`]); - let ret = ""; - let widths = Array.from(Array(4).keys()).map((i) => Math.max(...table.map((a) => a[i].length))); - for (let r = 0; r < table.length; r++) { - if (r == 1) - ret += "| " + Array.from(Array(4).keys()).map((i) => "-".repeat(widths[i])).join(" | ") + " |\n"; - let row = []; - for (let i = 0; i < 4; i++) - row.push(table[r][i].padEnd(widths[i], " ")); - ret += "| " + row.join(" | ") + " |\n"; - } - return ret; -} -function createCsv(tracker, settings) { - let ret = ""; - for (let entry of tracker.entries) { - for (let row of createTableSection(entry, settings)) - ret += row.join(settings.csvDelimiter) + "\n"; - } - return ret; -} -function createTableSection(entry, settings) { - let ret = [[ - entry.name, - entry.startTime ? formatTimestamp(entry.startTime, settings) : "", - entry.endTime ? formatTimestamp(entry.endTime, settings) : "", - entry.endTime || entry.subEntries ? formatDuration(getDuration(entry), settings) : "" - ]]; - if (entry.subEntries) { - for (let sub of entry.subEntries) - ret.push(...createTableSection(sub, settings)); - } - return ret; -} -function addEditableTableRow(tracker, entry, table, newSegmentNameBox, running, file, getSectionInfo, settings, indent) { - let row = table.createEl("tr"); - let name = row.createEl("td"); - let namePar = name.createEl("span", { text: entry.name }); - namePar.style.marginLeft = `${indent}em`; - let nameBox = new import_obsidian2.TextComponent(name).setValue(entry.name); - nameBox.inputEl.hidden = true; - row.createEl("td", { text: entry.startTime ? formatTimestamp(entry.startTime, settings) : "" }); - row.createEl("td", { text: entry.endTime ? formatTimestamp(entry.endTime, settings) : "" }); - row.createEl("td", { text: entry.endTime || entry.subEntries ? formatDuration(getDuration(entry), settings) : "" }); - let entryButtons = row.createEl("td"); - if (!running) { - new import_obsidian2.ButtonComponent(entryButtons).setClass("clickable-icon").setIcon(`lucide-play`).setTooltip("Continue").onClick(() => __async(this, null, function* () { - startSubEntry(entry, newSegmentNameBox.getValue()); - yield saveTracker(tracker, this.app, file, getSectionInfo()); - })); - } - let editButton = new import_obsidian2.ButtonComponent(entryButtons).setClass("clickable-icon").setTooltip("Edit").setIcon("lucide-pencil").onClick(() => __async(this, null, function* () { - if (namePar.hidden) { - namePar.hidden = false; - nameBox.inputEl.hidden = true; - editButton.setIcon("lucide-pencil"); - if (nameBox.getValue()) { - entry.name = nameBox.getValue(); - namePar.setText(entry.name); - yield saveTracker(tracker, this.app, file, getSectionInfo()); - } - } else { - namePar.hidden = true; - nameBox.inputEl.hidden = false; - nameBox.setValue(entry.name); - editButton.setIcon("lucide-check"); - } - })); - new import_obsidian2.ButtonComponent(entryButtons).setClass("clickable-icon").setTooltip("Remove").setIcon("lucide-trash").onClick(() => __async(this, null, function* () { - removeEntry(tracker.entries, entry); - yield saveTracker(tracker, this.app, file, getSectionInfo()); - })); - if (entry.subEntries) { - for (let sub of entry.subEntries) - addEditableTableRow(tracker, sub, table, newSegmentNameBox, running, file, getSectionInfo, settings, indent + 1); - } -} - -// src/main.ts -var SimpleTimeTrackerPlugin = class extends import_obsidian3.Plugin { - onload() { - return __async(this, null, function* () { - yield this.loadSettings(); - this.addSettingTab(new SimpleTimeTrackerSettingsTab(this.app, this)); - this.registerMarkdownCodeBlockProcessor("simple-time-tracker", (s, e, i) => { - let tracker = loadTracker(s); - e.empty(); - displayTracker(tracker, e, i.sourcePath, () => i.getSectionInfo(e), this.settings); - }); - this.addCommand({ - id: `insert`, - name: `Insert Time Tracker`, - editorCallback: (e, _) => { - e.replaceSelection("```simple-time-tracker\n```\n"); - } - }); - }); - } - loadSettings() { - return __async(this, null, function* () { - this.settings = Object.assign({}, defaultSettings, yield this.loadData()); - }); - } - saveSettings() { - return __async(this, null, function* () { - yield this.saveData(this.settings); - }); - } -}; diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/main.js b/test-vault/.obsidian/plugins/simple-time-tracker/main.js deleted file mode 100644 index f152d05..0000000 --- a/test-vault/.obsidian/plugins/simple-time-tracker/main.js +++ /dev/null @@ -1,404 +0,0 @@ -/* -THIS IS A GENERATED/BUNDLED FILE BY ESBUILD -if you want to view the source, please visit the github repository of this plugin -*/ -var __create = Object.create; -var __defProp = Object.defineProperty; -var __defProps = Object.defineProperties; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropDescs = Object.getOwnPropertyDescriptors; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getOwnPropSymbols = Object.getOwnPropertySymbols; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __propIsEnum = Object.prototype.propertyIsEnumerable; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; -var __spreadValues = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp.call(b, prop)) - __defNormalProp(a, prop, b[prop]); - if (__getOwnPropSymbols) - for (var prop of __getOwnPropSymbols(b)) { - if (__propIsEnum.call(b, prop)) - __defNormalProp(a, prop, b[prop]); - } - return a; -}; -var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); -var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); -var __export = (target, all) => { - __markAsModule(target); - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __reExport = (target, module2, desc) => { - if (module2 && typeof module2 === "object" || typeof module2 === "function") { - for (let key of __getOwnPropNames(module2)) - if (!__hasOwnProp.call(target, key) && key !== "default") - __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); - } - return target; -}; -var __toModule = (module2) => { - return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); -}; -var __async = (__this, __arguments, generator) => { - return new Promise((resolve, reject) => { - var fulfilled = (value) => { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - }; - var rejected = (value) => { - try { - step(generator.throw(value)); - } catch (e) { - reject(e); - } - }; - var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); - step((generator = generator.apply(__this, __arguments)).next()); - }); -}; - -// src/main.ts -__export(exports, { - default: () => SimpleTimeTrackerPlugin -}); -var import_obsidian3 = __toModule(require("obsidian")); - -// src/settings.ts -var defaultSettings = { - timestampFormat: "YY-MM-DD hh:mm:ss", - csvDelimiter: ",", - fineGrainedDurations: true -}; - -// src/settings-tab.ts -var import_obsidian = __toModule(require("obsidian")); -var SimpleTimeTrackerSettingsTab = class extends import_obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); - this.plugin = plugin; - } - display() { - this.containerEl.empty(); - this.containerEl.createEl("h2", { text: "Super Simple Time Tracker Settings" }); - new import_obsidian.Setting(this.containerEl).setName("Timestamp Display Format").setDesc(createFragment((f) => { - f.createSpan({ text: "The way that timestamps in time tracker tables should be displayed. Uses " }); - f.createEl("a", { text: "moment.js", href: "https://momentjs.com/docs/#/parsing/string-format/" }); - f.createSpan({ text: " syntax." }); - })).addText((t) => { - t.setValue(String(this.plugin.settings.timestampFormat)); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.timestampFormat = v.length ? v : defaultSettings.timestampFormat; - yield this.plugin.saveSettings(); - })); - }); - new import_obsidian.Setting(this.containerEl).setName("CSV Delimiter").setDesc("The delimiter character that should be used when copying a tracker table as CSV. For example, some languages use a semicolon instead of a comma.").addText((t) => { - t.setValue(String(this.plugin.settings.csvDelimiter)); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.csvDelimiter = v.length ? v : defaultSettings.csvDelimiter; - yield this.plugin.saveSettings(); - })); - }); - new import_obsidian.Setting(this.containerEl).setName("Fine-Grained Durations").setDesc("Whether durations should include days, months and years. If this is disabled, additional time units will be displayed as part of the hours.").addToggle((t) => { - t.setValue(this.plugin.settings.fineGrainedDurations); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.fineGrainedDurations = v; - yield this.plugin.saveSettings(); - })); - }); - this.containerEl.createEl("hr"); - this.containerEl.createEl("p", { text: "If you like this plugin and want to support its development, you can do so through my website by clicking this fancy image!" }); - this.containerEl.createEl("a", { href: "https://ellpeck.de/support" }).createEl("img", { - attr: { src: "https://ellpeck.de/res/generalsupport.png" }, - cls: "simple-time-tracker-support" - }); - } -}; - -// src/tracker.ts -var import_obsidian2 = __toModule(require("obsidian")); -function saveTracker(tracker, app, fileName, section) { - return __async(this, null, function* () { - let file = app.vault.getAbstractFileByPath(fileName); - if (!file) - return; - let content = yield app.vault.read(file); - 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"); - content = `${prev} -${JSON.stringify(tracker)} -${next}`; - yield app.vault.modify(file, content); - }); -} -function loadTracker(json) { - if (json) { - try { - return JSON.parse(json); - } catch (e) { - console.log(`Failed to parse Tracker from ${json}`); - } - } - return { entries: [] }; -} -function displayTracker(tracker, element, file, getSectionInfo, settings) { - let running = isRunning(tracker); - let btn = new import_obsidian2.ButtonComponent(element).setClass("clickable-icon").setIcon(`lucide-${running ? "stop" : "play"}-circle`).setTooltip(running ? "End" : "Start").onClick(() => __async(this, null, function* () { - if (running) { - endRunningEntry(tracker); - } else { - startNewEntry(tracker, newSegmentNameBox.getValue()); - } - yield saveTracker(tracker, this.app, file, getSectionInfo()); - })); - btn.buttonEl.addClass("simple-time-tracker-btn"); - let newSegmentNameBox = new import_obsidian2.TextComponent(element).setPlaceholder("Segment name").setDisabled(running); - newSegmentNameBox.inputEl.addClass("simple-time-tracker-txt"); - let timer = element.createDiv({ cls: "simple-time-tracker-timers" }); - let currentDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); - let current = currentDiv.createEl("span", { cls: "simple-time-tracker-timer-time" }); - currentDiv.createEl("span", { text: "Current" }); - let totalDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); - let total = totalDiv.createEl("span", { cls: "simple-time-tracker-timer-time", text: "0s" }); - totalDiv.createEl("span", { text: "Total" }); - if (tracker.entries.length > 0) { - let table = element.createEl("table", { cls: "simple-time-tracker-table" }); - table.createEl("tr").append(createEl("th", { text: "Segment" }), createEl("th", { text: "Start time" }), createEl("th", { text: "End time" }), createEl("th", { text: "Duration" }), createEl("th")); - for (let entry of tracker.entries) - addEditableTableRow(tracker, entry, table, newSegmentNameBox, running, file, getSectionInfo, settings, 0); - let buttons = element.createEl("div", { cls: "simple-time-tracker-bottom" }); - new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as table").onClick(() => navigator.clipboard.writeText(createMarkdownTable(tracker, settings))); - new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as CSV").onClick(() => navigator.clipboard.writeText(createCsv(tracker, settings))); - } - setCountdownValues(tracker, current, total, currentDiv, settings); - let intervalId = window.setInterval(() => { - if (!element.isConnected) { - window.clearInterval(intervalId); - return; - } - setCountdownValues(tracker, current, total, currentDiv, settings); - }, 1e3); -} -function startSubEntry(entry, name) { - if (!entry.subEntries) { - entry.subEntries = [__spreadProps(__spreadValues({}, entry), { name: `Part 1` })]; - entry.startTime = null; - entry.endTime = null; - } - if (!name) - name = `Part ${entry.subEntries.length + 1}`; - entry.subEntries.push({ name, startTime: (0, import_obsidian2.moment)().unix(), endTime: null, subEntries: null }); -} -function startNewEntry(tracker, name) { - if (!name) - name = `Segment ${tracker.entries.length + 1}`; - let entry = { name, startTime: (0, import_obsidian2.moment)().unix(), endTime: null, subEntries: null }; - tracker.entries.push(entry); -} -function endRunningEntry(tracker) { - let entry = getRunningEntry(tracker.entries); - entry.endTime = (0, import_obsidian2.moment)().unix(); -} -function removeEntry(entries, toRemove) { - if (entries.contains(toRemove)) { - entries.remove(toRemove); - return true; - } else { - for (let entry of entries) { - if (entry.subEntries && removeEntry(entry.subEntries, toRemove)) { - if (entry.subEntries.length == 1) { - let single = entry.subEntries[0]; - entry.startTime = single.startTime; - entry.endTime = single.endTime; - entry.subEntries = null; - } - return true; - } - } - } - return false; -} -function isRunning(tracker) { - return !!getRunningEntry(tracker.entries); -} -function getRunningEntry(entries) { - for (let entry of entries) { - if (entry.subEntries) { - let running = getRunningEntry(entry.subEntries); - if (running) - return running; - } else { - if (!entry.endTime) - return entry; - } - } - return null; -} -function getDuration(entry) { - if (entry.subEntries) { - return getTotalDuration(entry.subEntries); - } else { - let endTime = entry.endTime ? import_obsidian2.moment.unix(entry.endTime) : (0, import_obsidian2.moment)(); - return endTime.diff(import_obsidian2.moment.unix(entry.startTime)); - } -} -function getTotalDuration(entries) { - let ret = 0; - for (let entry of entries) - ret += getDuration(entry); - return ret; -} -function setCountdownValues(tracker, current, total, currentDiv, settings) { - let running = getRunningEntry(tracker.entries); - if (running && !running.endTime) { - current.setText(formatDuration(getDuration(running), settings)); - currentDiv.hidden = false; - } else { - currentDiv.hidden = true; - } - total.setText(formatDuration(getTotalDuration(tracker.entries), settings)); -} -function formatTimestamp(timestamp, settings) { - return import_obsidian2.moment.unix(timestamp).format(settings.timestampFormat); -} -function formatDuration(totalTime, settings) { - let ret = ""; - let duration = import_obsidian2.moment.duration(totalTime); - let hours; - if (settings.fineGrainedDurations) { - if (duration.years() > 0) - ret += duration.years() + "y "; - if (duration.months() > 0) - ret += duration.months() + "M "; - if (duration.days() > 0) - ret += duration.days() + "d "; - hours = duration.hours(); - } else { - hours = Math.floor(duration.asHours()); - } - if (hours > 0) - ret += hours + "h "; - if (duration.minutes() > 0) - ret += duration.minutes() + "m "; - ret += duration.seconds() + "s"; - return ret; -} -function createMarkdownTable(tracker, settings) { - let table = [["Segment", "Start time", "End time", "Duration"]]; - for (let entry of tracker.entries) - table.push(...createTableSection(entry, settings)); - table.push(["**Total**", "", "", `**${formatDuration(getTotalDuration(tracker.entries), settings)}**`]); - let ret = ""; - let widths = Array.from(Array(4).keys()).map((i) => Math.max(...table.map((a) => a[i].length))); - for (let r = 0; r < table.length; r++) { - if (r == 1) - ret += "| " + Array.from(Array(4).keys()).map((i) => "-".repeat(widths[i])).join(" | ") + " |\n"; - let row = []; - for (let i = 0; i < 4; i++) - row.push(table[r][i].padEnd(widths[i], " ")); - ret += "| " + row.join(" | ") + " |\n"; - } - return ret; -} -function createCsv(tracker, settings) { - let ret = ""; - for (let entry of tracker.entries) { - for (let row of createTableSection(entry, settings)) - ret += row.join(settings.csvDelimiter) + "\n"; - } - return ret; -} -function createTableSection(entry, settings) { - let ret = [[ - entry.name, - entry.startTime ? formatTimestamp(entry.startTime, settings) : "", - entry.endTime ? formatTimestamp(entry.endTime, settings) : "", - entry.endTime || entry.subEntries ? formatDuration(getDuration(entry), settings) : "" - ]]; - if (entry.subEntries) { - for (let sub of entry.subEntries) - ret.push(...createTableSection(sub, settings)); - } - return ret; -} -function addEditableTableRow(tracker, entry, table, newSegmentNameBox, running, file, getSectionInfo, settings, indent) { - let row = table.createEl("tr"); - let name = row.createEl("td"); - let namePar = name.createEl("span", { text: entry.name }); - namePar.style.marginLeft = `${indent}em`; - let nameBox = new import_obsidian2.TextComponent(name).setValue(entry.name); - nameBox.inputEl.hidden = true; - row.createEl("td", { text: entry.startTime ? formatTimestamp(entry.startTime, settings) : "" }); - row.createEl("td", { text: entry.endTime ? formatTimestamp(entry.endTime, settings) : "" }); - row.createEl("td", { text: entry.endTime || entry.subEntries ? formatDuration(getDuration(entry), settings) : "" }); - let entryButtons = row.createEl("td"); - if (!running) { - new import_obsidian2.ButtonComponent(entryButtons).setClass("clickable-icon").setIcon(`lucide-play`).setTooltip("Continue").onClick(() => __async(this, null, function* () { - startSubEntry(entry, newSegmentNameBox.getValue()); - yield saveTracker(tracker, this.app, file, getSectionInfo()); - })); - } - let editButton = new import_obsidian2.ButtonComponent(entryButtons).setClass("clickable-icon").setTooltip("Edit").setIcon("lucide-pencil").onClick(() => __async(this, null, function* () { - if (namePar.hidden) { - namePar.hidden = false; - nameBox.inputEl.hidden = true; - editButton.setIcon("lucide-pencil"); - if (nameBox.getValue()) { - entry.name = nameBox.getValue(); - namePar.setText(entry.name); - yield saveTracker(tracker, this.app, file, getSectionInfo()); - } - } else { - namePar.hidden = true; - nameBox.inputEl.hidden = false; - nameBox.setValue(entry.name); - editButton.setIcon("lucide-check"); - } - })); - new import_obsidian2.ButtonComponent(entryButtons).setClass("clickable-icon").setTooltip("Remove").setIcon("lucide-trash").onClick(() => __async(this, null, function* () { - removeEntry(tracker.entries, entry); - yield saveTracker(tracker, this.app, file, getSectionInfo()); - })); - if (entry.subEntries) { - for (let sub of entry.subEntries) - addEditableTableRow(tracker, sub, table, newSegmentNameBox, running, file, getSectionInfo, settings, indent + 1); - } -} - -// src/main.ts -var SimpleTimeTrackerPlugin = class extends import_obsidian3.Plugin { - onload() { - return __async(this, null, function* () { - yield this.loadSettings(); - this.addSettingTab(new SimpleTimeTrackerSettingsTab(this.app, this)); - this.registerMarkdownCodeBlockProcessor("simple-time-tracker", (s, e, i) => { - let tracker = loadTracker(s); - e.empty(); - displayTracker(tracker, e, i.sourcePath, () => i.getSectionInfo(e), this.settings); - }); - this.addCommand({ - id: `insert`, - name: `Insert Time Tracker`, - editorCallback: (e, _) => { - e.replaceSelection("```simple-time-tracker\n```\n"); - } - }); - }); - } - loadSettings() { - return __async(this, null, function* () { - this.settings = Object.assign({}, defaultSettings, yield this.loadData()); - }); - } - saveSettings() { - return __async(this, null, function* () { - yield this.saveData(this.settings); - }); - } -}; diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/manifest b/test-vault/.obsidian/plugins/simple-time-tracker/manifest deleted file mode 100644 index ae0dedb..0000000 --- a/test-vault/.obsidian/plugins/simple-time-tracker/manifest +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "simple-time-tracker", - "name": "Super Simple Time Tracker", - "version": "0.1.7", - "minAppVersion": "1.2.8", - "description": "Multi-purpose time trackers for your notes!", - "author": "Ellpeck", - "authorUrl": "https://ellpeck.de", - "isDesktopOnly": false -} diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/manifest.json b/test-vault/.obsidian/plugins/simple-time-tracker/manifest.json deleted file mode 100644 index ae0dedb..0000000 --- a/test-vault/.obsidian/plugins/simple-time-tracker/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "simple-time-tracker", - "name": "Super Simple Time Tracker", - "version": "0.1.7", - "minAppVersion": "1.2.8", - "description": "Multi-purpose time trackers for your notes!", - "author": "Ellpeck", - "authorUrl": "https://ellpeck.de", - "isDesktopOnly": false -} diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/styles b/test-vault/.obsidian/plugins/simple-time-tracker/styles deleted file mode 100644 index 61cf378..0000000 --- a/test-vault/.obsidian/plugins/simple-time-tracker/styles +++ /dev/null @@ -1,64 +0,0 @@ -.simple-time-tracker-support { - max-width: 50%; - width: 400px; - height: auto; -} - -.simple-time-tracker-btn, -.simple-time-tracker-txt { - display: block; - margin-left: auto; - margin-right: auto; -} - -.simple-time-tracker-txt { - text-align: center; -} - -.simple-time-tracker-btn { - margin-top: 10px; - margin-bottom: 10px; -} - -.simple-time-tracker-btn svg { - width: 32px; - height: 32px; -} - -.simple-time-tracker-bottom button { - margin: 10px 5px 10px 5px; -} - -.simple-time-tracker-timers, -.simple-time-tracker-bottom { - display: flex; - justify-content: center; - text-align: center; -} - -.simple-time-tracker-timers span { - display: block; -} - -.simple-time-tracker-timer { - margin: 20px; -} - -.simple-time-tracker-timer-time { - font-size: xx-large; - font-weight: bolder; -} - -.simple-time-tracker-table { - width: 100%; - margin-top: 20px; -} - -.simple-time-tracker-table td, -.simple-time-tracker-table th { - border: none; -} - -.simple-time-tracker-table .clickable-icon { - display: inline; -} diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/styles.css b/test-vault/.obsidian/plugins/simple-time-tracker/styles.css deleted file mode 100644 index 61cf378..0000000 --- a/test-vault/.obsidian/plugins/simple-time-tracker/styles.css +++ /dev/null @@ -1,64 +0,0 @@ -.simple-time-tracker-support { - max-width: 50%; - width: 400px; - height: auto; -} - -.simple-time-tracker-btn, -.simple-time-tracker-txt { - display: block; - margin-left: auto; - margin-right: auto; -} - -.simple-time-tracker-txt { - text-align: center; -} - -.simple-time-tracker-btn { - margin-top: 10px; - margin-bottom: 10px; -} - -.simple-time-tracker-btn svg { - width: 32px; - height: 32px; -} - -.simple-time-tracker-bottom button { - margin: 10px 5px 10px 5px; -} - -.simple-time-tracker-timers, -.simple-time-tracker-bottom { - display: flex; - justify-content: center; - text-align: center; -} - -.simple-time-tracker-timers span { - display: block; -} - -.simple-time-tracker-timer { - margin: 20px; -} - -.simple-time-tracker-timer-time { - font-size: xx-large; - font-weight: bolder; -} - -.simple-time-tracker-table { - width: 100%; - margin-top: 20px; -} - -.simple-time-tracker-table td, -.simple-time-tracker-table th { - border: none; -} - -.simple-time-tracker-table .clickable-icon { - display: inline; -}