mirror of
https://github.com/Ellpeck/ObsidianSimpleTimeTracker.git
synced 2024-11-26 19:18:34 +01:00
Compare commits
2 commits
05a4710b8a
...
7aa91901c6
Author | SHA1 | Date | |
---|---|---|---|
7aa91901c6 | |||
70ade8ada0 |
11 changed files with 184 additions and 181 deletions
|
@ -4,6 +4,6 @@ root = true
|
|||
[*]
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
|
|
|
@ -11,50 +11,50 @@ if you want to view the source, please visit the github repository of this plugi
|
|||
const prod = (process.argv[2] === 'production');
|
||||
|
||||
esbuild.build({
|
||||
banner: {
|
||||
js: banner,
|
||||
},
|
||||
entryPoints: ['src/main.ts'],
|
||||
bundle: true,
|
||||
external: [
|
||||
'obsidian',
|
||||
'electron',
|
||||
'@codemirror/autocomplete',
|
||||
'@codemirror/closebrackets',
|
||||
'@codemirror/collab',
|
||||
'@codemirror/commands',
|
||||
'@codemirror/comment',
|
||||
'@codemirror/fold',
|
||||
'@codemirror/gutter',
|
||||
'@codemirror/highlight',
|
||||
'@codemirror/history',
|
||||
'@codemirror/language',
|
||||
'@codemirror/lint',
|
||||
'@codemirror/matchbrackets',
|
||||
'@codemirror/panel',
|
||||
'@codemirror/rangeset',
|
||||
'@codemirror/rectangular-selection',
|
||||
'@codemirror/search',
|
||||
'@codemirror/state',
|
||||
'@codemirror/stream-parser',
|
||||
'@codemirror/text',
|
||||
'@codemirror/tooltip',
|
||||
'@codemirror/view',
|
||||
...builtins
|
||||
],
|
||||
plugins: [
|
||||
copy({
|
||||
assets: [{
|
||||
from: ["./manifest.json", "./main.js", "./styles.css"],
|
||||
to: ["./test-vault/.obsidian/plugins/simple-time-tracker/."]
|
||||
}]
|
||||
}),
|
||||
],
|
||||
format: 'cjs',
|
||||
watch: !prod,
|
||||
target: 'es2016',
|
||||
logLevel: "info",
|
||||
sourcemap: prod ? false : 'inline',
|
||||
treeShaking: true,
|
||||
outfile: 'main.js',
|
||||
banner: {
|
||||
js: banner,
|
||||
},
|
||||
entryPoints: ['src/main.ts'],
|
||||
bundle: true,
|
||||
external: [
|
||||
'obsidian',
|
||||
'electron',
|
||||
'@codemirror/autocomplete',
|
||||
'@codemirror/closebrackets',
|
||||
'@codemirror/collab',
|
||||
'@codemirror/commands',
|
||||
'@codemirror/comment',
|
||||
'@codemirror/fold',
|
||||
'@codemirror/gutter',
|
||||
'@codemirror/highlight',
|
||||
'@codemirror/history',
|
||||
'@codemirror/language',
|
||||
'@codemirror/lint',
|
||||
'@codemirror/matchbrackets',
|
||||
'@codemirror/panel',
|
||||
'@codemirror/rangeset',
|
||||
'@codemirror/rectangular-selection',
|
||||
'@codemirror/search',
|
||||
'@codemirror/state',
|
||||
'@codemirror/stream-parser',
|
||||
'@codemirror/text',
|
||||
'@codemirror/tooltip',
|
||||
'@codemirror/view',
|
||||
...builtins
|
||||
],
|
||||
plugins: [
|
||||
copy({
|
||||
assets: [{
|
||||
from: ["./manifest.json", "./main.js", "./styles.css"],
|
||||
to: ["./test-vault/.obsidian/plugins/simple-time-tracker/."]
|
||||
}]
|
||||
}),
|
||||
],
|
||||
format: 'cjs',
|
||||
watch: !prod,
|
||||
target: 'es2016',
|
||||
logLevel: "info",
|
||||
sourcemap: prod ? false : 'inline',
|
||||
treeShaking: true,
|
||||
outfile: 'main.js',
|
||||
}).catch(() => process.exit(1));
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"id": "simple-time-tracker",
|
||||
"name": "Super Simple Time Tracker",
|
||||
"version": "0.1.6",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Multi-purpose time trackers for your notes!",
|
||||
"author": "Ellpeck",
|
||||
"authorUrl": "https://ellpeck.de",
|
||||
"isDesktopOnly": false
|
||||
"id": "simple-time-tracker",
|
||||
"name": "Super Simple Time Tracker",
|
||||
"version": "0.1.6",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Multi-purpose time trackers for your notes!",
|
||||
"author": "Ellpeck",
|
||||
"authorUrl": "https://ellpeck.de",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
|
|
44
package.json
44
package.json
|
@ -1,24 +1,24 @@
|
|||
{
|
||||
"name": "simple-time-tracker",
|
||||
"version": "0.1.6",
|
||||
"description": "Multi-purpose time trackers for your notes!",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Ellpeck",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
"builtin-modules": "^3.2.0",
|
||||
"electron": "^13.6.2",
|
||||
"esbuild": "0.14.0",
|
||||
"esbuild-plugin-copy": "^1.3.0",
|
||||
"obsidian": "latest",
|
||||
"tslib": "2.3.1",
|
||||
"typescript": "4.4.4"
|
||||
}
|
||||
"name": "simple-time-tracker",
|
||||
"version": "0.1.6",
|
||||
"description": "Multi-purpose time trackers for your notes!",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Ellpeck",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
"builtin-modules": "^3.2.0",
|
||||
"electron": "^13.6.2",
|
||||
"esbuild": "0.14.0",
|
||||
"esbuild-plugin-copy": "^1.3.0",
|
||||
"obsidian": "latest",
|
||||
"tslib": "2.3.1",
|
||||
"typescript": "4.4.4"
|
||||
}
|
||||
}
|
||||
|
|
48
src/main.ts
48
src/main.ts
|
@ -1,37 +1,37 @@
|
|||
import { Plugin } from "obsidian";
|
||||
import { defaultSettings, SimpleTimeTrackerSettings } from "./settings";
|
||||
import { SimpleTimeTrackerSettingsTab } from "./settings-tab";
|
||||
import { displayTracker, loadTracker } from "./tracker";
|
||||
import { displayTracker, loadTracker, Tracker } from "./tracker";
|
||||
|
||||
export default class SimpleTimeTrackerPlugin extends Plugin {
|
||||
|
||||
settings: SimpleTimeTrackerSettings;
|
||||
settings: SimpleTimeTrackerSettings;
|
||||
|
||||
async onload(): Promise<void> {
|
||||
await this.loadSettings();
|
||||
async onload(): Promise<void> {
|
||||
await this.loadSettings();
|
||||
|
||||
this.addSettingTab(new SimpleTimeTrackerSettingsTab(this.app, this));
|
||||
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.getSectionInfo(e), this.settings);
|
||||
});
|
||||
this.registerMarkdownCodeBlockProcessor("simple-time-tracker", (s, e, i) => {
|
||||
let tracker: Tracker = loadTracker(s);
|
||||
e.empty();
|
||||
displayTracker(tracker, e, () => i.getSectionInfo(e), this.settings);
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: `insert`,
|
||||
name: `Insert Time Tracker`,
|
||||
editorCallback: (e, _) => {
|
||||
e.replaceSelection("```simple-time-tracker\n```\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
this.addCommand({
|
||||
id: `insert`,
|
||||
name: `Insert Time Tracker`,
|
||||
editorCallback: (e, _) => {
|
||||
e.replaceSelection("```simple-time-tracker\n```\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, defaultSettings, await this.loadData());
|
||||
}
|
||||
async loadSettings(): Promise<void> {
|
||||
this.settings = Object.assign({}, defaultSettings, await this.loadData());
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
async saveSettings(): Promise<void> {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@ export class SimpleTimeTrackerSettingsTab extends PluginSettingTab {
|
|||
|
||||
display(): void {
|
||||
this.containerEl.empty();
|
||||
this.containerEl.createEl("h2", { text: "Super Simple Time Tracker Settings" });
|
||||
this.containerEl.createEl("h2", {text: "Super Simple Time Tracker Settings"});
|
||||
|
||||
new 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." });
|
||||
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));
|
||||
|
@ -42,8 +42,11 @@ export class SimpleTimeTrackerSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
|
||||
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" });
|
||||
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"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ export function loadTracker(json: string): Tracker {
|
|||
console.log(`Failed to parse Tracker from ${json}`);
|
||||
}
|
||||
}
|
||||
return { entries: [] };
|
||||
return {entries: []};
|
||||
}
|
||||
|
||||
export function displayTracker(tracker: Tracker, element: HTMLElement, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings): void {
|
||||
|
@ -61,29 +61,29 @@ export function displayTracker(tracker: Tracker, element: HTMLElement, getSectio
|
|||
newSegmentNameBox.inputEl.addClass("simple-time-tracker-txt");
|
||||
|
||||
// add timers
|
||||
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" });
|
||||
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) {
|
||||
// add table
|
||||
let table = element.createEl("table", { cls: "simple-time-tracker-table" });
|
||||
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", {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, getSectionInfo, settings, 0);
|
||||
|
||||
// add copy buttons
|
||||
let buttons = element.createEl("div", { cls: "simple-time-tracker-bottom" });
|
||||
let buttons = element.createEl("div", {cls: "simple-time-tracker-bottom"});
|
||||
new ButtonComponent(buttons)
|
||||
.setButtonText("Copy as table")
|
||||
.onClick(() => navigator.clipboard.writeText(createMarkdownTable(tracker, settings)));
|
||||
|
@ -107,22 +107,22 @@ export function displayTracker(tracker: Tracker, element: HTMLElement, getSectio
|
|||
function startSubEntry(entry: Entry, name: string) {
|
||||
// if this entry is not split yet, we add its time as a sub-entry instead
|
||||
if (!entry.subEntries) {
|
||||
entry.subEntries = [{ ...entry, name: `Part 1` }];
|
||||
entry.subEntries = [{...entry, name: `Part 1`}];
|
||||
entry.startTime = null;
|
||||
entry.endTime = null;
|
||||
}
|
||||
|
||||
if (!name)
|
||||
name = `Part ${entry.subEntries.length + 1}`;
|
||||
entry.subEntries.push({ name: name, startTime: moment().unix(), endTime: null, subEntries: null });
|
||||
entry.subEntries.push({name: name, startTime: moment().unix(), endTime: null, subEntries: null});
|
||||
}
|
||||
|
||||
function startNewEntry(tracker: Tracker, name: string): void {
|
||||
if (!name)
|
||||
name = `Segment ${tracker.entries.length + 1}`;
|
||||
let entry: Entry = { name: name, startTime: moment().unix(), endTime: null, subEntries: null };
|
||||
let entry: Entry = {name: name, startTime: moment().unix(), endTime: null, subEntries: null};
|
||||
tracker.entries.push(entry);
|
||||
};
|
||||
}
|
||||
|
||||
function endRunningEntry(tracker: Tracker): void {
|
||||
let entry = getRunningEntry(tracker.entries);
|
||||
|
@ -266,14 +266,14 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle
|
|||
let row = table.createEl("tr");
|
||||
|
||||
let name = row.createEl("td");
|
||||
let namePar = name.createEl("span", { text: entry.name });
|
||||
let namePar = name.createEl("span", {text: entry.name});
|
||||
namePar.style.marginLeft = `${indent}em`;
|
||||
let nameBox = new 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)) : "" });
|
||||
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)) : ""});
|
||||
|
||||
let entryButtons = row.createEl("td");
|
||||
if (!running) {
|
||||
|
|
46
styles.css
46
styles.css
|
@ -1,64 +1,64 @@
|
|||
.simple-time-tracker-support {
|
||||
max-width: 50%;
|
||||
width: 400px;
|
||||
height: auto;
|
||||
max-width: 50%;
|
||||
width: 400px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.simple-time-tracker-btn,
|
||||
.simple-time-tracker-txt {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.simple-time-tracker-txt {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.simple-time-tracker-btn {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.simple-time-tracker-btn svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.simple-time-tracker-bottom button {
|
||||
margin: 10px 5px 10px 5px;
|
||||
margin: 10px 5px 10px 5px;
|
||||
}
|
||||
|
||||
.simple-time-tracker-timers,
|
||||
.simple-time-tracker-bottom {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.simple-time-tracker-timers span {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.simple-time-tracker-timer {
|
||||
margin: 20px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.simple-time-tracker-timer-time {
|
||||
font-size: xx-large;
|
||||
font-weight: bolder;
|
||||
font-size: xx-large;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.simple-time-tracker-table {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.simple-time-tracker-table td,
|
||||
.simple-time-tracker-table th {
|
||||
border: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.simple-time-tracker-table .clickable-icon {
|
||||
display: inline;
|
||||
display: inline;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
"target": "ES6",
|
||||
"allowJs": true,
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES5",
|
||||
"ES6",
|
||||
"ES7"
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
"target": "ES6",
|
||||
"allowJs": true,
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES5",
|
||||
"ES6",
|
||||
"ES7"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"0.0.1": "0.15.0",
|
||||
"0.1.0": "0.15.0",
|
||||
"0.1.1": "0.15.0",
|
||||
"0.1.2": "0.15.0",
|
||||
"0.1.3": "0.15.0",
|
||||
"0.1.4": "0.15.0",
|
||||
"0.1.5": "0.15.0",
|
||||
"0.0.1": "0.15.0",
|
||||
"0.1.0": "0.15.0",
|
||||
"0.1.1": "0.15.0",
|
||||
"0.1.2": "0.15.0",
|
||||
"0.1.3": "0.15.0",
|
||||
"0.1.4": "0.15.0",
|
||||
"0.1.5": "0.15.0",
|
||||
"0.1.6": "0.15.0"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue