From 197aa2ed51a1d15442ebc4b5d9ee1d3a0648c8fa Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Tue, 27 Aug 2024 03:56:49 +0200 Subject: [PATCH 01/24] Add time formatting for edit duration CAMS; Fix some linted issues --- src/gates.utils.ts | 4 +- src/main.ts | 91 ++++++++++++++++++++++++++++------------------ src/settings.ts | 15 ++++++++ 3 files changed, 73 insertions(+), 37 deletions(-) diff --git a/src/gates.utils.ts b/src/gates.utils.ts index 29b7f14..a8d2f4d 100644 --- a/src/gates.utils.ts +++ b/src/gates.utils.ts @@ -11,7 +11,7 @@ export interface FilterList { export function isFileMatchFilter(file: TFile, filter: FilterList,): boolean { // Check if file matches paths - if (isStringInList(file.parent.path, filter.folders)) { + if (file.parent && isStringInList(file.parent.path, filter.folders)) { return true; } // Check if file matches tags @@ -27,7 +27,7 @@ export function isStringInList(path: string, list: string[]): boolean { export async function isTagPresentInFile(file: TFile, tag: string,) { await this.app.fileManager.processFrontMatter( file as TFile, - (frontmatter) => { + (frontmatter: any) => { const updateKeyValue = BOMS.getValue(frontmatter, "tags"); if (updateKeyValue.includes(tag)) { diff --git a/src/main.ts b/src/main.ts index 7b6d237..a98fef5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -205,14 +205,16 @@ export default class TimeThings extends Plugin { // Our view could not be found in the workspace, create a new leaf // in the right sidebar for it leaf = workspace.getRightLeaf(false); - await leaf.setViewState({ + await leaf?.setViewState({ type: VIEW_TYPE_MOST_EDITED, active: true, }); } // "Reveal" the leaf in case it is in a collapsed sidebar - workspace.revealLeaf(leaf); + if(leaf) { + workspace.revealLeaf(leaf); + } } // A function for reading and editing metadata realtime @@ -242,7 +244,7 @@ export default class TimeThings extends Plugin { useCustomSolution && environment instanceof Editor ) { - // CAMS + // CAMS: Custom Asset Management System this.updateModifiedPropertyEditor(environment); if (this.settings.enableEditDurationKey) { this.updateDurationPropertyEditor(environment); @@ -251,7 +253,7 @@ export default class TimeThings extends Plugin { !useCustomSolution && environment instanceof TFile ) { - // BOMS + // BOMS: Build-in Object Management System this.updateModifiedPropertyFrontmatter(environment); if (this.settings.enableEditDurationKey) { this.updateDurationPropertyFrontmatter(environment); @@ -260,6 +262,9 @@ export default class TimeThings extends Plugin { } } + + + updateModifiedPropertyEditor(editor: Editor) { const dateNow = moment(); const userDateFormat = this.settings.modifiedKeyFormat; @@ -282,6 +287,9 @@ export default class TimeThings extends Plugin { CAMS.setValue(editor, userModifiedKeyName, dateFormatted); } + + + async updateModifiedPropertyFrontmatter(file: TFile) { await this.app.fileManager.processFrontMatter( file as TFile, @@ -313,8 +321,51 @@ export default class TimeThings extends Plugin { }, ); } + + + + + async updateDurationPropertyEditor(editor: Editor) { + // Prepare everything + if (this.allowEditDurationUpdate === false) { + return; + } + this.allowEditDurationUpdate = false; + const fieldLine = CAMS.getLine(editor, this.settings.editDurationPath); + + if (fieldLine === undefined) { + this.allowEditDurationUpdate = true; + return; + } + + // Fetch & check validity + const value = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); + const userDateFormat = this.settings.editDurationFormat; + if(moment(value, userDateFormat, true).isValid() === false) { + this.isDebugBuild && console.log("Wrong format of edit_duration property"); + return; + } + + // Increment & set + const incremented = moment.duration(value).add(1, 'seconds').format(userDateFormat, { trim: false }); // Stick to given format + CAMS.setValue( + editor, + this.settings.editDurationPath, + incremented.toString(), + ); + + // Cool down + await sleep(1000 - this.settings.nonTypingEditingTimePercentage * 10); + this.allowEditDurationUpdate = true; + } + + + async updateDurationPropertyFrontmatter(file: TFile) { + + // TODO: Same for BOMS! + // Prepare everything if (this.allowEditDurationUpdate === false) { return; @@ -322,7 +373,7 @@ export default class TimeThings extends Plugin { this.allowEditDurationUpdate = false; await this.app.fileManager.processFrontMatter( file as TFile, - (frontmatter) => { + (frontmatter: any) => { let value = BOMS.getValue( frontmatter, this.settings.editDurationPath, @@ -332,7 +383,6 @@ export default class TimeThings extends Plugin { } // Increment - const newValue = +value + 10; BOMS.setValue( frontmatter, @@ -343,39 +393,10 @@ export default class TimeThings extends Plugin { ); // Cool down - await sleep(10000 - this.settings.nonTypingEditingTimePercentage * 100); this.allowEditDurationUpdate = true; } - async updateDurationPropertyEditor(editor: Editor) { - // Prepare everything - if (this.allowEditDurationUpdate === false) { - return; - } - this.allowEditDurationUpdate = false; - const fieldLine = CAMS.getLine(editor, this.settings.editDurationPath); - if (fieldLine === undefined) { - this.allowEditDurationUpdate = true; - return; - } - - // Increment - - const value = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); - const newValue = +value + 1; - CAMS.setValue( - editor, - this.settings.editDurationPath, - newValue.toString(), - ); - - // Cool down - - await sleep(1000 - this.settings.nonTypingEditingTimePercentage * 10); - this.allowEditDurationUpdate = true; - } - // Don't worry about it updateClockBar() { const dateNow = moment(); diff --git a/src/settings.ts b/src/settings.ts index fdc232d..ab729c2 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -23,6 +23,7 @@ export interface TimeThingsSettings { //DURATION KEY editDurationPath: string; + editDurationFormat: string; enableEditDurationKey: boolean; nonTypingEditingTimePercentage: number; @@ -49,6 +50,7 @@ export const DEFAULT_SETTINGS: TimeThingsSettings = { enableModifiedKeyUpdate: true, editDurationPath: "edited_seconds", + editDurationFormat: "HH:mm:ss", enableEditDurationKey: true, updateIntervalFrontmatterMinutes: 1, @@ -311,6 +313,19 @@ export class TimeThingsSettingsTab extends PluginSettingTab { }), ); + new Setting(containerEl) + .setName("Edited duration key format") + .setDesc(createLink()) + .addText((text) => + text + .setPlaceholder("HH:mm:ss.SSSZ") + .setValue(this.plugin.settings.editDurationFormat) + .onChange(async (value) => { + this.plugin.settings.editDurationFormat = value; + await this.plugin.saveSettings(); + }), + ); + const descA = document.createDocumentFragment(); descA.append( "The portion of time you are not typing when editing a note. Works best with custom frontmatter handling solution. ", From 1de468a14fd783693f969a95f65880e99dd82973 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Thu, 29 Aug 2024 01:58:38 +0200 Subject: [PATCH 02/24] Formatting for edited_time works; Has unresolved debugging todos --- src/main.ts | 101 ++++++++++++++++++++++++------------------------ src/settings.ts | 18 ++++----- 2 files changed, 58 insertions(+), 61 deletions(-) diff --git a/src/main.ts b/src/main.ts index a98fef5..0da2f0c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,8 +4,9 @@ import { WorkspaceLeaf, Plugin, TFile, + Notice, } from "obsidian"; -import { moment } from "obsidian"; +import { moment, Debouncer } from "obsidian"; import { MostEditedView, VIEW_TYPE_MOST_EDITED as VIEW_TYPE_MOST_EDITED, @@ -20,6 +21,7 @@ import { } from "./settings"; import * as timeUtils from "./time.utils"; import * as gates from "./gates.utils"; +import { allowedNodeEnvironmentFlags } from "process"; export default class TimeThings extends Plugin { settings: TimeThingsSettings; @@ -28,12 +30,10 @@ export default class TimeThings extends Plugin { debugBar: HTMLElement; editDurationBar: HTMLElement; allowEditDurationUpdate: boolean; - isProccessing = false; + isEditing = false; async onload() { - // Add commands - this.addCommand( { id: 'Show most edited notes view', @@ -45,24 +45,21 @@ export default class TimeThings extends Plugin { ); // Add buttons - this.addRibbonIcon("history", "Activate view", () => { this.activateMostEditedNotesView(); }); // Register views - this.registerView( VIEW_TYPE_MOST_EDITED, (leaf) => new MostEditedView(leaf), ); // Load settings - await this.loadSettings(); // Variables initialization - this.isDebugBuild = false; // for debugging purposes + this.isDebugBuild = true; // for debugging purposes TODO: WELL IS IT OR IS IT NOT APPARENTLY ITS NOT IF THIS TEXT IS HERE! this.allowEditDurationUpdate = true; // for cooldown // Set up Status Bar items @@ -81,7 +78,6 @@ export default class TimeThings extends Plugin { registerMouseDownDOMEvent() { this.registerDomEvent(document, "mousedown", (evt: MouseEvent) => { // Prepare everything - const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); if (activeView === null) { @@ -100,7 +96,6 @@ export default class TimeThings extends Plugin { this.registerEvent( this.app.workspace.on("active-leaf-change", (leaf) => { // Prepare everything - const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); if (activeView === null) { @@ -112,7 +107,6 @@ export default class TimeThings extends Plugin { } // Change the duration icon in status bar - this.onUserActivity(true, activeView, { updateMetadata: false, updateStatusBar: true, @@ -146,25 +140,18 @@ export default class TimeThings extends Plugin { if (this.settings.useCustomFrontmatterHandlingSolution === true) { // Make sure the document is ready for edit - - const activeView = - this.app.workspace.getActiveViewOfType(MarkdownView); + const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); if (activeView === null) { - if (this.isDebugBuild) { - console.log("No active view"); - } + this.isDebugBuild && console.log("No active view"); return; } const editor: Editor = activeView.editor; if (editor.hasFocus() === false) { - if (this.isDebugBuild) { - console.log("No focus"); - } + this.isDebugBuild && console.log("No focus"); return; } // Update everything - this.onUserActivity(true, activeView); } }); @@ -174,7 +161,6 @@ export default class TimeThings extends Plugin { this.registerEvent( this.app.vault.on("modify", (file) => { // Make everything ready for edit - const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); if (activeView === null) { @@ -228,7 +214,7 @@ export default class TimeThings extends Plugin { let environment; useCustomSolution ? environment = activeView.editor : environment = activeView.file; - + console.log('User activity! ', environment, updateStatusBar, updateMetadata);) // Check if the file is in the blacklisted folder // Check if the file has a property that puts it into a blacklist // Check if the file itself is in the blacklist @@ -262,9 +248,7 @@ export default class TimeThings extends Plugin { } } - - - + // CAMS updateModifiedPropertyEditor(editor: Editor) { const dateNow = moment(); const userDateFormat = this.settings.modifiedKeyFormat; @@ -285,11 +269,9 @@ export default class TimeThings extends Plugin { } // this.setValue(true, editor, userModifiedKeyName, dateFormatted,); CAMS.setValue(editor, userModifiedKeyName, dateFormatted); - } - - - + } + // BOMS (Default) async updateModifiedPropertyFrontmatter(file: TFile) { await this.app.fileManager.processFrontMatter( file as TFile, @@ -321,17 +303,17 @@ export default class TimeThings extends Plugin { }, ); } - - - - + + // CAMS async updateDurationPropertyEditor(editor: Editor) { + this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); + // Prepare everything if (this.allowEditDurationUpdate === false) { return; } this.allowEditDurationUpdate = false; - const fieldLine = CAMS.getLine(editor, this.settings.editDurationPath); + const fieldLine = CAMS.getLine(editor, this.settings.editDurationKeyName); if (fieldLine === undefined) { this.allowEditDurationUpdate = true; @@ -340,7 +322,7 @@ export default class TimeThings extends Plugin { // Fetch & check validity const value = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); - const userDateFormat = this.settings.editDurationFormat; + const userDateFormat = this.settings.editDurationKeyFormat; if(moment(value, userDateFormat, true).isValid() === false) { this.isDebugBuild && console.log("Wrong format of edit_duration property"); return; @@ -348,23 +330,26 @@ export default class TimeThings extends Plugin { // Increment & set const incremented = moment.duration(value).add(1, 'seconds').format(userDateFormat, { trim: false }); // Stick to given format + this.isDebugBuild && console.log(`Increment CAMS from ${value} to ${incremented}`); CAMS.setValue( editor, - this.settings.editDurationPath, + this.settings.editDurationKeyName, incremented.toString(), ); // Cool down - await sleep(1000 - this.settings.nonTypingEditingTimePercentage * 10); + console.log('cams sleepy start'); + // TODO: Reset to 1 second + + await sleep(4000 - this.settings.nonTypingEditingTimePercentage * 10); this.allowEditDurationUpdate = true; + this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); + console.log('cams sleepy end'); } - - - + // BOMS (Default) async updateDurationPropertyFrontmatter(file: TFile) { - - // TODO: Same for BOMS! + this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); // Prepare everything if (this.allowEditDurationUpdate === false) { @@ -374,20 +359,29 @@ export default class TimeThings extends Plugin { await this.app.fileManager.processFrontMatter( file as TFile, (frontmatter: any) => { + // Fetch let value = BOMS.getValue( frontmatter, - this.settings.editDurationPath, + this.settings.editDurationKeyName, ); if (value === undefined) { value = "0"; } - // Increment - const newValue = +value + 10; + // Check validity + const userDateFormat = this.settings.editDurationKeyFormat; + if(moment(value, userDateFormat, true).isValid() === false) { + this.isDebugBuild && console.log("Wrong format of edit_duration property"); + return; + } + + // Increment + const incremented = moment.duration(value).add(10, 'seconds').format(userDateFormat, {trim: false}); + this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`, 0); BOMS.setValue( frontmatter, - this.settings.editDurationPath, - newValue, + this.settings.editDurationKeyName, + incremented, ); }, ); @@ -395,8 +389,11 @@ export default class TimeThings extends Plugin { // Cool down await sleep(10000 - this.settings.nonTypingEditingTimePercentage * 100); this.allowEditDurationUpdate = true; + this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); + } + // Don't worry about it updateClockBar() { const dateNow = moment(); @@ -406,9 +403,11 @@ export default class TimeThings extends Plugin { const dateFormatted = dateChosen.format(this.settings.clockFormat); const emoji = timeUtils.momentToClockEmoji(dateChosen); - this.settings.showEmojiStatusBar - ? this.clockBar.setText(emoji + " " + dateFormatted) - : this.clockBar.setText(dateFormatted); + // TODO: Remove override + // this.settings.showEmojiStatusBar + // ? this.clockBar.setText(emoji + " " + dateFormatted) + // : this.clockBar.setText(dateFormatted); + } // Gets called on OnLoad diff --git a/src/settings.ts b/src/settings.ts index ab729c2..7164dae 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -22,16 +22,14 @@ export interface TimeThingsSettings { updateIntervalFrontmatterMinutes: number; //DURATION KEY - editDurationPath: string; - editDurationFormat: string; + editDurationKeyName: string; + editDurationKeyFormat: string; enableEditDurationKey: boolean; nonTypingEditingTimePercentage: number; enableSwitch: boolean; switchKey: string; switchKeyValue: string; - - } @@ -49,8 +47,8 @@ export const DEFAULT_SETTINGS: TimeThingsSettings = { modifiedKeyFormat: "YYYY-MM-DD[T]HH:mm:ss.SSSZ", enableModifiedKeyUpdate: true, - editDurationPath: "edited_seconds", - editDurationFormat: "HH:mm:ss", + editDurationKeyName: "edited_seconds", + editDurationKeyFormat: "HH:mm:ss", enableEditDurationKey: true, updateIntervalFrontmatterMinutes: 1, @@ -306,9 +304,9 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .addText((text) => text .setPlaceholder("edited_seconds") - .setValue(this.plugin.settings.editDurationPath) + .setValue(this.plugin.settings.editDurationKeyName) .onChange(async (value) => { - this.plugin.settings.editDurationPath = value; + this.plugin.settings.editDurationKeyName = value; await this.plugin.saveSettings(); }), ); @@ -319,9 +317,9 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .addText((text) => text .setPlaceholder("HH:mm:ss.SSSZ") - .setValue(this.plugin.settings.editDurationFormat) + .setValue(this.plugin.settings.editDurationKeyFormat) .onChange(async (value) => { - this.plugin.settings.editDurationFormat = value; + this.plugin.settings.editDurationKeyFormat = value; await this.plugin.saveSettings(); }), ); From 393d5d6e3da4e6e46c765ea32a086a7606b5a97b Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Thu, 29 Aug 2024 04:01:13 +0200 Subject: [PATCH 03/24] First iteration of debounced time tracking core refactoring. Editing is tracked in the status bar, but neither connected to core tracking nor reflected in the properties. --- src/main.ts | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/main.ts b/src/main.ts index 0da2f0c..dd36f88 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,6 +5,7 @@ import { Plugin, TFile, Notice, + debounce, } from "obsidian"; import { moment, Debouncer } from "obsidian"; import { @@ -203,6 +204,40 @@ export default class TimeThings extends Plugin { } } + + + timeout: number = 4000; + debounceEditingTime = debounce(() => { + // Only when the function finally runs through, calc time diff -> TODO: Make a custom debouncer which contains the calling function too? + if(this.startTime) { + const timeDiff = moment.now() - this.startTime; + // Reset state + this.isEditing = false; + this.startTime = null; + // Write the change! + console.log(`Debounced, add timeDiff of ${(timeDiff-this.timeout)/1000}s (typing time) + ${this.timeout/1000}s (timeout) and reset editing state.`); + this.clockBar.setText(`✋🔴`); + } else { + this.isDebugBuild && console.log('Error calculating typing time, startTime: ', this.startTime); + } + }, this.timeout, true); + + startTime: number | null; + whenToCallThis() { + // Save current time only once, regardless of repeated calls (flag) + if(!this.isEditing) { + this.startTime = moment.now(); + this.isEditing = true; + console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); + this.clockBar.setText(`✏🔵`); + + } + this.debounceEditingTime(); + } + + + + // A function for reading and editing metadata realtime onUserActivity( useCustomSolution: boolean, @@ -214,7 +249,9 @@ export default class TimeThings extends Plugin { let environment; useCustomSolution ? environment = activeView.editor : environment = activeView.file; - console.log('User activity! ', environment, updateStatusBar, updateMetadata);) + console.log('User activity! '); + this.whenToCallThis(); + // Check if the file is in the blacklisted folder // Check if the file has a property that puts it into a blacklist // Check if the file itself is in the blacklist @@ -223,9 +260,10 @@ export default class TimeThings extends Plugin { if (updateStatusBar) { // update status bar } - + // Update metadata using either BOMS or cams if (updateMetadata) { + // console.log('updating metadata'); if ( useCustomSolution && environment instanceof Editor @@ -233,6 +271,7 @@ export default class TimeThings extends Plugin { // CAMS: Custom Asset Management System this.updateModifiedPropertyEditor(environment); if (this.settings.enableEditDurationKey) { + // console.log('calling cams'); this.updateDurationPropertyEditor(environment); } } else if ( @@ -306,8 +345,8 @@ export default class TimeThings extends Plugin { // CAMS async updateDurationPropertyEditor(editor: Editor) { - this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); + // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); // Prepare everything if (this.allowEditDurationUpdate === false) { return; @@ -343,13 +382,13 @@ export default class TimeThings extends Plugin { await sleep(4000 - this.settings.nonTypingEditingTimePercentage * 10); this.allowEditDurationUpdate = true; - this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); + // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); console.log('cams sleepy end'); } // BOMS (Default) async updateDurationPropertyFrontmatter(file: TFile) { - this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); + // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); // Prepare everything if (this.allowEditDurationUpdate === false) { @@ -389,7 +428,7 @@ export default class TimeThings extends Plugin { // Cool down await sleep(10000 - this.settings.nonTypingEditingTimePercentage * 100); this.allowEditDurationUpdate = true; - this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); + // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); } From 203d4c9a8a91a13f0e2c4a013eac9634fb935a5c Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:35:12 +0200 Subject: [PATCH 04/24] backup intermediate state changing edit updates --- src/main.ts | 100 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/src/main.ts b/src/main.ts index dd36f88..bbb626a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -205,85 +205,101 @@ export default class TimeThings extends Plugin { } - - timeout: number = 4000; - debounceEditingTime = debounce(() => { - // Only when the function finally runs through, calc time diff -> TODO: Make a custom debouncer which contains the calling function too? + // built-in debouncer -> TODO: this may handle the icon and time diff calculation while the frontmatter update could happen periodically + timeout: number = 10000; + startTime: number | null; + timeDiff: number | null; + stopEditing = debounce(() => { + // Only when the function finally runs through, calc time diff if(this.startTime) { - const timeDiff = moment.now() - this.startTime; - // Reset state + this.timeDiff = moment.now() - this.startTime; // !!! THis is required, maybe send an event?! + // Reset state this.isEditing = false; this.startTime = null; // Write the change! - console.log(`Debounced, add timeDiff of ${(timeDiff-this.timeout)/1000}s (typing time) + ${this.timeout/1000}s (timeout) and reset editing state.`); + console.log(`Debounced, add timeDiff of ${(this.timeDiff-this.timeout)/1000}s (typing time) + ${this.timeout/1000}s (timeout) and reset editing state.`); this.clockBar.setText(`✋🔴`); + } else { this.isDebugBuild && console.log('Error calculating typing time, startTime: ', this.startTime); } }, this.timeout, true); - startTime: number | null; - whenToCallThis() { + // Save max every 10 seconds during interaction and once after it stops + updateEditedText = debounce(() => { + + console.log("UPDATE EDITING TIME MAX EVERY 10 SECONDS"); + + }, 10000, false); + + startEditing() { // Save current time only once, regardless of repeated calls (flag) if(!this.isEditing) { this.startTime = moment.now(); this.isEditing = true; console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); this.clockBar.setText(`✏🔵`); - } - this.debounceEditingTime(); + // this.updateEditedText(); + this.stopEditing(); } - + debouncedUpdateMetadata = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { + console.log('debounced updating metadata'); + let environment; + useCustomSolution ? environment = activeView.editor : environment = activeView.file; + if ( + useCustomSolution && + environment instanceof Editor + ) { + // CAMS: Custom Asset Management System + this.updateModifiedPropertyEditor(environment); + if (this.settings.enableEditDurationKey) { + // console.log('calling cams'); + // this.updateDurationPropertyEditor(environment); + + + } + } else if ( + !useCustomSolution && + environment instanceof TFile + ) { + // BOMS: Build-in Object Management System + this.updateModifiedPropertyFrontmatter(environment); + if (this.settings.enableEditDurationKey) { + this.updateDurationPropertyFrontmatter(environment); + } + } + } + , 10000, false); // A function for reading and editing metadata realtime + // Gets called when a user changes a leaf, clicks a mouse, types in the editor, or modifies a file onUserActivity( useCustomSolution: boolean, activeView: MarkdownView, options: { updateMetadata: boolean, updateStatusBar: boolean, } = { updateMetadata: true, updateStatusBar: true, }, ) { const { updateMetadata, updateStatusBar } = options; - // Gets called when a user changes a leaf, clicks a mouse, types in the editor, or modifies a file - let environment; - useCustomSolution ? environment = activeView.editor : environment = activeView.file; - console.log('User activity! '); - this.whenToCallThis(); - // Check if the file is in the blacklisted folder // Check if the file has a property that puts it into a blacklist // Check if the file itself is in the blacklist - - // + + + console.log('User activity!'); + this.startEditing(); + if (updateStatusBar) { // update status bar + // console.log('Update status bar called'); } - // Update metadata using either BOMS or cams + // Update metadata using either BOMS or CAMS if (updateMetadata) { - // console.log('updating metadata'); - if ( - useCustomSolution && - environment instanceof Editor - ) { - // CAMS: Custom Asset Management System - this.updateModifiedPropertyEditor(environment); - if (this.settings.enableEditDurationKey) { - // console.log('calling cams'); - this.updateDurationPropertyEditor(environment); - } - } else if ( - !useCustomSolution && - environment instanceof TFile - ) { - // BOMS: Build-in Object Management System - this.updateModifiedPropertyFrontmatter(environment); - if (this.settings.enableEditDurationKey) { - this.updateDurationPropertyFrontmatter(environment); - } - } + // Needs the time passed for updating! + this.debouncedUpdateMetadata(useCustomSolution, activeView); } } From 5844f43344473fd7876caa64359bd8fd7b4227d2 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Fri, 30 Aug 2024 02:41:18 +0200 Subject: [PATCH 05/24] backup state with intermediate saving in development --- src/main.ts | 60 ++++++++++++++++++++++++++++++------------------- src/settings.ts | 2 ++ 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/main.ts b/src/main.ts index bbb626a..e39edc5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -205,42 +205,55 @@ export default class TimeThings extends Plugin { } - // built-in debouncer -> TODO: this may handle the icon and time diff calculation while the frontmatter update could happen periodically - timeout: number = 10000; + timeout: number = 3000; // TODO: Into settings.ts + iconActive : boolean = false; // In a perfect world this matches the editing timer, but it's way simpler to decouple these variables + // Inactive typing + resetIcon = debounce(() => { + this.clockBar.setText(`✋🔴`); //TODO: settings.ts + this.iconActive = false; + this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.iconActive); + }, this.timeout, true); + + // Active typing icon + updateIcon() { + if(!this.iconActive) { + this.clockBar.setText(`✏🔵`); + this.iconActive = true; + this.isDebugBuild && console.log('Activate typing icon, active: ', this.iconActive); + } + this.resetIcon(); + } + + // !!! MAKE ANOTHER ONE FOR THE PROPERTIES THAT INTERRUPTS + // the frontmatter update should happen periodically, but the timeout depends on BOMS/CAMS, + //not just on the setting as BOMS apparently requires a min of 10s startTime: number | null; timeDiff: number | null; stopEditing = debounce(() => { - // Only when the function finally runs through, calc time diff + // Run every x seconds starting from typing begin and update periodically if(this.startTime) { this.timeDiff = moment.now() - this.startTime; // !!! THis is required, maybe send an event?! - // Reset state - this.isEditing = false; - this.startTime = null; // Write the change! + console.log('Pure timediff: ', this.timeDiff); console.log(`Debounced, add timeDiff of ${(this.timeDiff-this.timeout)/1000}s (typing time) + ${this.timeout/1000}s (timeout) and reset editing state.`); - this.clockBar.setText(`✋🔴`); + + // Reset state + this.isEditing = false; // TODO: This is reset every , which in turn resets the isEditing. FIX!!!!!!!!!!!!!!! + this.startTime = null; } else { this.isDebugBuild && console.log('Error calculating typing time, startTime: ', this.startTime); } - }, this.timeout, true); - - // Save max every 10 seconds during interaction and once after it stops - updateEditedText = debounce(() => { - - console.log("UPDATE EDITING TIME MAX EVERY 10 SECONDS"); - - }, 10000, false); + }, this.timeout, false); startEditing() { // Save current time only once, regardless of repeated calls (flag) + // console.log('editing? ', this.isEditing) if(!this.isEditing) { - this.startTime = moment.now(); this.isEditing = true; + this.startTime = moment.now(); console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); - this.clockBar.setText(`✏🔵`); } - // this.updateEditedText(); this.stopEditing(); } @@ -288,18 +301,19 @@ export default class TimeThings extends Plugin { // Check if the file itself is in the blacklist - console.log('User activity!'); - this.startEditing(); + console.log('--- User activity! ---'); if (updateStatusBar) { - // update status bar + this.updateIcon(); // console.log('Update status bar called'); } - + // Update metadata using either BOMS or CAMS if (updateMetadata) { + // console.log('Update Metadata'); + this.startEditing(); // Needs the time passed for updating! - this.debouncedUpdateMetadata(useCustomSolution, activeView); + // this.debouncedUpdateMetadata(useCustomSolution, activeView); } } diff --git a/src/settings.ts b/src/settings.ts index 7164dae..68cc7a4 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -26,6 +26,7 @@ export interface TimeThingsSettings { editDurationKeyFormat: string; enableEditDurationKey: boolean; nonTypingEditingTimePercentage: number; + editTimeoutMilliseconds: number; enableSwitch: boolean; switchKey: string; @@ -50,6 +51,7 @@ export const DEFAULT_SETTINGS: TimeThingsSettings = { editDurationKeyName: "edited_seconds", editDurationKeyFormat: "HH:mm:ss", enableEditDurationKey: true, + editTimeoutMilliseconds: 3000, updateIntervalFrontmatterMinutes: 1, From 329b81664a4de4ddbd1bb6924cd8f858cc6a4201 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 2 Sep 2024 21:59:17 +0200 Subject: [PATCH 06/24] backup intermittent saving before simplifying solution --- src/main.ts | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main.ts b/src/main.ts index e39edc5..9188435 100644 --- a/src/main.ts +++ b/src/main.ts @@ -205,7 +205,7 @@ export default class TimeThings extends Plugin { } - timeout: number = 3000; // TODO: Into settings.ts + timeout: number = 5000; // TODO: Into settings.ts iconActive : boolean = false; // In a perfect world this matches the editing timer, but it's way simpler to decouple these variables // Inactive typing resetIcon = debounce(() => { @@ -226,26 +226,39 @@ export default class TimeThings extends Plugin { // !!! MAKE ANOTHER ONE FOR THE PROPERTIES THAT INTERRUPTS // the frontmatter update should happen periodically, but the timeout depends on BOMS/CAMS, - //not just on the setting as BOMS apparently requires a min of 10s + // not just on the setting as BOMS apparently requires a min of 10s startTime: number | null; - timeDiff: number | null; - stopEditing = debounce(() => { + exactTimeDiff: number | null; + cumulatedTimeDiff: number = 0; + updateEditingTime = debounce(() => { // Run every x seconds starting from typing begin and update periodically if(this.startTime) { - this.timeDiff = moment.now() - this.startTime; // !!! THis is required, maybe send an event?! + this.exactTimeDiff = moment.now() - this.startTime; + // Write the change! - console.log('Pure timediff: ', this.timeDiff); - console.log(`Debounced, add timeDiff of ${(this.timeDiff-this.timeout)/1000}s (typing time) + ${this.timeout/1000}s (timeout) and reset editing state.`); + // console.log('abs timediff: ', this.exactTimeDiff); + // console.log('rel timediff: ', this.relTimeDiff); + + // this.relTimeDiff += (this.absTimeDiff - this.relTimeDiff); + // console.log('time since last: ', this.relTimeDiff); - // Reset state - this.isEditing = false; // TODO: This is reset every , which in turn resets the isEditing. FIX!!!!!!!!!!!!!!! - this.startTime = null; + // TODO: Only save the relative value, not the absolute like it is here + // console.log(`Debounced, exact timeDiff is ${(this.exactTimeDiff-this.timeout)/1000}s (typing time) ${this.timeout/1000}s (timeout).`); + + this.cumulatedTimeDiff += this.timeout; + console.log('Cumulated timediff: ', this.cumulatedTimeDiff); + this.updateMetadata(); - } else { - this.isDebugBuild && console.log('Error calculating typing time, startTime: ', this.startTime); } }, this.timeout, false); + resetEditing = debounce(() => { + // Reset state + this.isDebugBuild && console.log('Editing halted!'); + this.isEditing = false; + this.startTime = null; + }, this.timeout, true); + startEditing() { // Save current time only once, regardless of repeated calls (flag) // console.log('editing? ', this.isEditing) @@ -254,12 +267,12 @@ export default class TimeThings extends Plugin { this.startTime = moment.now(); console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); } - this.stopEditing(); + this.updateEditingTime(); + this.resetEditing(); } - debouncedUpdateMetadata = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { - console.log('debounced updating metadata'); + updateMetadata (useCustomSolution: boolean, activeView: MarkdownView) { let environment; useCustomSolution ? environment = activeView.editor : environment = activeView.file; if ( @@ -270,9 +283,7 @@ export default class TimeThings extends Plugin { this.updateModifiedPropertyEditor(environment); if (this.settings.enableEditDurationKey) { // console.log('calling cams'); - // this.updateDurationPropertyEditor(environment); - - + this.updateDurationPropertyEditor(environment); } } else if ( !useCustomSolution && @@ -285,7 +296,6 @@ export default class TimeThings extends Plugin { } } } - , 10000, false); // A function for reading and editing metadata realtime // Gets called when a user changes a leaf, clicks a mouse, types in the editor, or modifies a file From 5a02473a05cf9f53a8b3aa46539c384dc88fc214 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 2 Sep 2024 23:06:50 +0200 Subject: [PATCH 07/24] proof of concept for updating with cams' --- src/main.ts | 82 ++++++++++++++++++----------------------------------- 1 file changed, 27 insertions(+), 55 deletions(-) diff --git a/src/main.ts b/src/main.ts index 9188435..b4c5736 100644 --- a/src/main.ts +++ b/src/main.ts @@ -74,6 +74,7 @@ export default class TimeThings extends Plugin { // Add a tab for settings this.addSettingTab(new TimeThingsSettingsTab(this.app, this)); + } registerMouseDownDOMEvent() { @@ -205,7 +206,7 @@ export default class TimeThings extends Plugin { } - timeout: number = 5000; // TODO: Into settings.ts + timeout: number = 3000; // TODO: Into settings.ts iconActive : boolean = false; // In a perfect world this matches the editing timer, but it's way simpler to decouple these variables // Inactive typing resetIcon = debounce(() => { @@ -223,34 +224,21 @@ export default class TimeThings extends Plugin { } this.resetIcon(); } + - // !!! MAKE ANOTHER ONE FOR THE PROPERTIES THAT INTERRUPTS - // the frontmatter update should happen periodically, but the timeout depends on BOMS/CAMS, - // not just on the setting as BOMS apparently requires a min of 10s startTime: number | null; exactTimeDiff: number | null; cumulatedTimeDiff: number = 0; - updateEditingTime = debounce(() => { - // Run every x seconds starting from typing begin and update periodically - if(this.startTime) { - this.exactTimeDiff = moment.now() - this.startTime; - - // Write the change! - // console.log('abs timediff: ', this.exactTimeDiff); - // console.log('rel timediff: ', this.relTimeDiff); - - // this.relTimeDiff += (this.absTimeDiff - this.relTimeDiff); - // console.log('time since last: ', this.relTimeDiff); - - // TODO: Only save the relative value, not the absolute like it is here - // console.log(`Debounced, exact timeDiff is ${(this.exactTimeDiff-this.timeout)/1000}s (typing time) ${this.timeout/1000}s (timeout).`); - - this.cumulatedTimeDiff += this.timeout; - console.log('Cumulated timediff: ', this.cumulatedTimeDiff); - this.updateMetadata(); - - } - }, this.timeout, false); + // the frontmatter update should happen periodically, but the timeout depends on BOMS/CAMS, + // not just on the setting as BOMS apparently requires a min of 10s -> TODO: Limit Timeout if BOMS is active! + updateEditedValue = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { + // Run every x seconds starting from typing begin and update periodically + if(this.startTime) { + this.cumulatedTimeDiff += this.timeout; + console.log('Cumulated timediff: ', this.cumulatedTimeDiff); + this.updateMetadata(useCustomSolution, activeView); + } + }, this.timeout, false); resetEditing = debounce(() => { // Reset state @@ -259,15 +247,14 @@ export default class TimeThings extends Plugin { this.startTime = null; }, this.timeout, true); - startEditing() { + updateEditing(useCustomSolution: boolean, activeView: MarkdownView) { // Save current time only once, regardless of repeated calls (flag) - // console.log('editing? ', this.isEditing) if(!this.isEditing) { this.isEditing = true; this.startTime = moment.now(); console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); } - this.updateEditingTime(); + this.updateEditedValue(useCustomSolution, activeView); this.resetEditing(); } @@ -282,8 +269,9 @@ export default class TimeThings extends Plugin { // CAMS: Custom Asset Management System this.updateModifiedPropertyEditor(environment); if (this.settings.enableEditDurationKey) { - // console.log('calling cams'); + console.log('calling cams!'); this.updateDurationPropertyEditor(environment); + } } else if ( !useCustomSolution && @@ -292,6 +280,7 @@ export default class TimeThings extends Plugin { // BOMS: Build-in Object Management System this.updateModifiedPropertyFrontmatter(environment); if (this.settings.enableEditDurationKey) { + console.log('boms update'); this.updateDurationPropertyFrontmatter(environment); } } @@ -305,6 +294,8 @@ export default class TimeThings extends Plugin { options: { updateMetadata: boolean, updateStatusBar: boolean, } = { updateMetadata: true, updateStatusBar: true, }, ) { const { updateMetadata, updateStatusBar } = options; + let environment; + useCustomSolution ? environment = activeView.editor : environment = activeView.file; // Check if the file is in the blacklisted folder // Check if the file has a property that puts it into a blacklist @@ -315,15 +306,11 @@ export default class TimeThings extends Plugin { if (updateStatusBar) { this.updateIcon(); - // console.log('Update status bar called'); } // Update metadata using either BOMS or CAMS if (updateMetadata) { - // console.log('Update Metadata'); - this.startEditing(); - // Needs the time passed for updating! - // this.debouncedUpdateMetadata(useCustomSolution, activeView); + this.updateEditing(useCustomSolution, activeView); } } @@ -386,29 +373,23 @@ export default class TimeThings extends Plugin { // CAMS async updateDurationPropertyEditor(editor: Editor) { - // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); - // Prepare everything - if (this.allowEditDurationUpdate === false) { - return; - } - this.allowEditDurationUpdate = false; + // Fetch value const fieldLine = CAMS.getLine(editor, this.settings.editDurationKeyName); - - if (fieldLine === undefined) { - this.allowEditDurationUpdate = true; + if(fieldLine === undefined) { + console.log("Undefined value for duration property"); return; } - // Fetch & check validity + // Parse & check validity const value = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); const userDateFormat = this.settings.editDurationKeyFormat; if(moment(value, userDateFormat, true).isValid() === false) { - this.isDebugBuild && console.log("Wrong format of edit_duration property"); + this.isDebugBuild && console.log("Wrong format or invalid value with edit_duration property"); return; } // Increment & set - const incremented = moment.duration(value).add(1, 'seconds').format(userDateFormat, { trim: false }); // Stick to given format + const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Stick to given format this.isDebugBuild && console.log(`Increment CAMS from ${value} to ${incremented}`); CAMS.setValue( editor, @@ -416,19 +397,10 @@ export default class TimeThings extends Plugin { incremented.toString(), ); - // Cool down - console.log('cams sleepy start'); - // TODO: Reset to 1 second - - await sleep(4000 - this.settings.nonTypingEditingTimePercentage * 10); - this.allowEditDurationUpdate = true; - // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); - console.log('cams sleepy end'); } // BOMS (Default) async updateDurationPropertyFrontmatter(file: TFile) { - // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); // Prepare everything if (this.allowEditDurationUpdate === false) { From d9e5a5196b8b38059c2276ba394545bee33e2eef Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 2 Sep 2024 23:14:36 +0200 Subject: [PATCH 08/24] clean up poc before adding boms --- src/main.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main.ts b/src/main.ts index b4c5736..a14c4ce 100644 --- a/src/main.ts +++ b/src/main.ts @@ -226,16 +226,13 @@ export default class TimeThings extends Plugin { } + // not just on the setting as BOMS apparently requires a min of 10s + // -> TODO: Limit Timeout if BOMS is active! Provide slider + numberbox > 10 for BOMS, >1 for cams) + + // Run every x seconds starting from typing begin and update periodically startTime: number | null; - exactTimeDiff: number | null; - cumulatedTimeDiff: number = 0; - // the frontmatter update should happen periodically, but the timeout depends on BOMS/CAMS, - // not just on the setting as BOMS apparently requires a min of 10s -> TODO: Limit Timeout if BOMS is active! updateEditedValue = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { - // Run every x seconds starting from typing begin and update periodically if(this.startTime) { - this.cumulatedTimeDiff += this.timeout; - console.log('Cumulated timediff: ', this.cumulatedTimeDiff); this.updateMetadata(useCustomSolution, activeView); } }, this.timeout, false); @@ -258,7 +255,6 @@ export default class TimeThings extends Plugin { this.resetEditing(); } - updateMetadata (useCustomSolution: boolean, activeView: MarkdownView) { let environment; useCustomSolution ? environment = activeView.editor : environment = activeView.file; @@ -301,7 +297,6 @@ export default class TimeThings extends Plugin { // Check if the file has a property that puts it into a blacklist // Check if the file itself is in the blacklist - console.log('--- User activity! ---'); if (updateStatusBar) { @@ -389,7 +384,7 @@ export default class TimeThings extends Plugin { } // Increment & set - const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Stick to given format + const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format this.isDebugBuild && console.log(`Increment CAMS from ${value} to ${incremented}`); CAMS.setValue( editor, From a9667827f419f5408b0f866b431297420a6d32f9 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 2 Sep 2024 23:35:17 +0200 Subject: [PATCH 09/24] add boms to new update mechanism --- src/main.ts | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/main.ts b/src/main.ts index a14c4ce..5ec9bf6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -367,14 +367,12 @@ export default class TimeThings extends Plugin { // CAMS async updateDurationPropertyEditor(editor: Editor) { - // Fetch value - const fieldLine = CAMS.getLine(editor, this.settings.editDurationKeyName); + let fieldLine: number | undefined = CAMS.getLine(editor, this.settings.editDurationKeyName); if(fieldLine === undefined) { console.log("Undefined value for duration property"); - return; + fieldLine = 0; } - // Parse & check validity const value = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); const userDateFormat = this.settings.editDurationKeyFormat; @@ -382,7 +380,6 @@ export default class TimeThings extends Plugin { this.isDebugBuild && console.log("Wrong format or invalid value with edit_duration property"); return; } - // Increment & set const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format this.isDebugBuild && console.log(`Increment CAMS from ${value} to ${incremented}`); @@ -391,38 +388,32 @@ export default class TimeThings extends Plugin { this.settings.editDurationKeyName, incremented.toString(), ); - } // BOMS (Default) async updateDurationPropertyFrontmatter(file: TFile) { - - // Prepare everything - if (this.allowEditDurationUpdate === false) { - return; - } - this.allowEditDurationUpdate = false; + // Slow update await this.app.fileManager.processFrontMatter( file as TFile, (frontmatter: any) => { // Fetch - let value = BOMS.getValue( - frontmatter, - this.settings.editDurationKeyName, - ); + let value = BOMS.getValue(frontmatter, this.settings.editDurationKeyName); if (value === undefined) { - value = "0"; + this.isDebugBuild && console.log('No edit_duration, initialize with 0.'); + value = moment.duration(0); } - // Check validity const userDateFormat = this.settings.editDurationKeyFormat; if(moment(value, userDateFormat, true).isValid() === false) { - this.isDebugBuild && console.log("Wrong format of edit_duration property"); + this.isDebugBuild && console.log("Wrong format for edit_duration property"); return; } - + if(this.timeout < 10000) { + console.log('Invalid timeout for BOMS, reset to 10 seconds.'); + this.timeout = 10000; + } // Increment - const incremented = moment.duration(value).add(10, 'seconds').format(userDateFormat, {trim: false}); + const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, {trim: false}); this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`, 0); BOMS.setValue( frontmatter, @@ -431,12 +422,6 @@ export default class TimeThings extends Plugin { ); }, ); - - // Cool down - await sleep(10000 - this.settings.nonTypingEditingTimePercentage * 100); - this.allowEditDurationUpdate = true; - // this.clockBar.setText(`Paused? ${this.allowEditDurationUpdate.toString()}`); - } From c400f85125b67d0bc432eef60907a71fd37f75b2 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Tue, 3 Sep 2024 00:28:18 +0200 Subject: [PATCH 10/24] Update settings to reflect timeout values in slider+textbox combination --- src/main.ts | 4 ++-- src/settings.ts | 44 +++++++++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/main.ts b/src/main.ts index 5ec9bf6..9e8a129 100644 --- a/src/main.ts +++ b/src/main.ts @@ -30,7 +30,6 @@ export default class TimeThings extends Plugin { clockBar: HTMLElement; // # Required debugBar: HTMLElement; editDurationBar: HTMLElement; - allowEditDurationUpdate: boolean; isEditing = false; async onload() { @@ -61,7 +60,6 @@ export default class TimeThings extends Plugin { // Variables initialization this.isDebugBuild = true; // for debugging purposes TODO: WELL IS IT OR IS IT NOT APPARENTLY ITS NOT IF THIS TEXT IS HERE! - this.allowEditDurationUpdate = true; // for cooldown // Set up Status Bar items this.setUpStatusBarItems(); @@ -408,6 +406,8 @@ export default class TimeThings extends Plugin { this.isDebugBuild && console.log("Wrong format for edit_duration property"); return; } + + // TODO: Do this right in the settings. Maybe the date could also be validated directly in the settings? if(this.timeout < 10000) { console.log('Invalid timeout for BOMS, reset to 10 seconds.'); this.timeout = 10000; diff --git a/src/settings.ts b/src/settings.ts index 68cc7a4..9d9b5e1 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,4 +1,4 @@ -import { App, PluginSettingTab, Setting } from "obsidian"; +import { App, PluginSettingTab, Setting, SliderComponent, TextComponent } from "obsidian"; import TimeThings from "./main"; export interface TimeThingsSettings { @@ -250,28 +250,42 @@ export class TimeThingsSettingsTab extends PluginSettingTab { }), ); - if ( - this.plugin.settings.useCustomFrontmatterHandlingSolution === - false - ) { + + let mySlider : SliderComponent; + let myText: TextComponent; + let minValue = 1 + if (this.plugin.settings.useCustomFrontmatterHandlingSolution === false) { + minValue = 10; + } new Setting(containerEl) - .setName("Interval between updates") - .setDesc("Only for Obsidian frontmatter API.") + // .setName("Interval between updates") + .setName(`Editing Timeout for ${this.plugin.settings.useCustomFrontmatterHandlingSolution === false ? "BOMS" : "CAMS"}`) + .setDesc("Timeout in seconds to stop counting. Also reflected in the status bar. Affects all update frequencies. IF DEFAULT IS ACTIVE THEN > 10, OTHERWISE >1!!! ENFORECE! Also preview on slider wrong.") .addSlider((slider) => - slider - .setLimits(1, 15, 1) + mySlider = slider + .setLimits(1, 90, 1) .setValue( - this.plugin.settings - .updateIntervalFrontmatterMinutes, + this.plugin.settings.editTimeoutMilliseconds, ) .onChange(async (value) => { - this.plugin.settings.updateIntervalFrontmatterMinutes = - value; + this.plugin.settings.editTimeoutMilliseconds = value * 1000; + myText.setValue(value.toString()); await this.plugin.saveSettings(); }) .setDynamicTooltip(), - ); - } + ) + .addText((text) => + myText = text + .setPlaceholder("10020") + .setValue( + this.plugin.settings.editTimeoutMilliseconds.toString(), + ) + .onChange(async (value) => { + const numericValue = parseInt(value, 10); + this.plugin.settings.editTimeoutMilliseconds = numericValue * 1000; + mySlider.setValue(numericValue); + await this.plugin.saveSettings(); + })) } // #endregion From cd20582ee9aca9294ea5bbb016aee4bd3bc4e81f Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Thu, 5 Sep 2024 18:05:33 +0200 Subject: [PATCH 11/24] Overhaul complete settings menu including styling; Add ability to set timeout for CAMS/BOMS; Add customizable edit indicators; MISSING usage of actual settings values --- src/main.ts | 21 ++-- src/settings.ts | 283 +++++++++++++++++++++++++++--------------------- styles.css | 14 +++ 3 files changed, 182 insertions(+), 136 deletions(-) diff --git a/src/main.ts b/src/main.ts index 9e8a129..f8e5493 100644 --- a/src/main.ts +++ b/src/main.ts @@ -28,6 +28,7 @@ export default class TimeThings extends Plugin { settings: TimeThingsSettings; isDebugBuild: boolean; clockBar: HTMLElement; // # Required + editingBar: HTMLElement; debugBar: HTMLElement; editDurationBar: HTMLElement; isEditing = false; @@ -171,6 +172,7 @@ export default class TimeThings extends Plugin { if ( this.settings.useCustomFrontmatterHandlingSolution === false ) { + console.log('this2 '); this.onUserActivity(false, activeView); } }), @@ -208,7 +210,7 @@ export default class TimeThings extends Plugin { iconActive : boolean = false; // In a perfect world this matches the editing timer, but it's way simpler to decouple these variables // Inactive typing resetIcon = debounce(() => { - this.clockBar.setText(`✋🔴`); //TODO: settings.ts + this.editingBar.setText(`✋🔴`); //TODO: settings.ts this.iconActive = false; this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.iconActive); }, this.timeout, true); @@ -216,7 +218,7 @@ export default class TimeThings extends Plugin { // Active typing icon updateIcon() { if(!this.iconActive) { - this.clockBar.setText(`✏🔵`); + this.editingBar.setText(`✏🔵`); this.iconActive = true; this.isDebugBuild && console.log('Activate typing icon, active: ', this.iconActive); } @@ -433,21 +435,14 @@ export default class TimeThings extends Plugin { const dateChosen = this.settings.isUTC ? dateUTC : dateNow; const dateFormatted = dateChosen.format(this.settings.clockFormat); const emoji = timeUtils.momentToClockEmoji(dateChosen); - - // TODO: Remove override - // this.settings.showEmojiStatusBar - // ? this.clockBar.setText(emoji + " " + dateFormatted) - // : this.clockBar.setText(dateFormatted); - } - // Gets called on OnLoad + // Called on OnLoad, adds status bar setUpStatusBarItems() { if (this.settings.enableClock) { // Add clock icon - // Adds a status bar this.clockBar = this.addStatusBarItem(); - this.clockBar.setText(":)"); + this.clockBar.setText(timeUtils.momentToClockEmoji(moment())); // Change status bar text every second this.updateClockBar(); @@ -458,6 +453,10 @@ export default class TimeThings extends Plugin { ), ); } + if (this.settings.enableEditStatus) { + this.editingBar = this.addStatusBarItem(); + this.editingBar.setText(this.settings.editIndicatorActive); + } } diff --git a/src/settings.ts b/src/settings.ts index 9d9b5e1..4b7e4d2 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -5,9 +5,6 @@ export interface TimeThingsSettings { //CAMS useCustomFrontmatterHandlingSolution: boolean; - //EMOJIS - showEmojiStatusBar: boolean; - //CLOCK clockFormat: string; updateIntervalMilliseconds: string; @@ -15,18 +12,21 @@ export interface TimeThingsSettings { isUTC: boolean; //MODIFIED KEY + enableModifiedKey: boolean; modifiedKeyName: string; modifiedKeyFormat: string; - enableModifiedKeyUpdate: boolean; //BOMS updateIntervalFrontmatterMinutes: number; //DURATION KEY + enableEditDurationKey: boolean; editDurationKeyName: string; editDurationKeyFormat: string; - enableEditDurationKey: boolean; nonTypingEditingTimePercentage: number; editTimeoutMilliseconds: number; + enableEditStatus: boolean; + editIndicatorActive: string; + editIndicatorInactive: string; enableSwitch: boolean; switchKey: string; @@ -37,8 +37,6 @@ export interface TimeThingsSettings { export const DEFAULT_SETTINGS: TimeThingsSettings = { useCustomFrontmatterHandlingSolution: false, - showEmojiStatusBar: true, - clockFormat: "hh:mm A", updateIntervalMilliseconds: "1000", enableClock: true, @@ -46,12 +44,15 @@ export const DEFAULT_SETTINGS: TimeThingsSettings = { modifiedKeyName: "updated_at", modifiedKeyFormat: "YYYY-MM-DD[T]HH:mm:ss.SSSZ", - enableModifiedKeyUpdate: true, + enableModifiedKey: true, editDurationKeyName: "edited_seconds", editDurationKeyFormat: "HH:mm:ss", enableEditDurationKey: true, editTimeoutMilliseconds: 3000, + enableEditStatus: true, + editIndicatorActive: "✋🔴", + editIndicatorInactive: "✏🔵", updateIntervalFrontmatterMinutes: 1, @@ -77,7 +78,6 @@ export class TimeThingsSettingsTab extends PluginSettingTab { containerEl.empty(); // #region prerequisites - const createLink = () => { const linkEl = document.createDocumentFragment(); @@ -89,54 +89,85 @@ export class TimeThingsSettingsTab extends PluginSettingTab { ); return linkEl; }; - // #endregion + // #region custom frontmatter solution + let mySlider : SliderComponent; + let myText: TextComponent; + let description = "In seconds. Time to stop tracking after interaction has stopped. Value also used for saving interval. Textbox allows for higher values." + const minTimeoutBoms = 10; + const minTimeoutCams = 1; new Setting(containerEl) .setName("Use custom frontmatter handling solution") - .setDesc( - "Smoother experience. Prone to bugs if you use a nested value.", - ) + .setDesc("Smoother experience. Prone to bugs if you use a nested value.",) .addToggle((toggle) => toggle - .setValue( - this.plugin.settings - .useCustomFrontmatterHandlingSolution, - ) + .setValue(this.plugin.settings.useCustomFrontmatterHandlingSolution,) .onChange(async (newValue) => { - this.plugin.settings.useCustomFrontmatterHandlingSolution = - newValue; + // console.log("Use custom frontmatter handling: ", newValue); + this.plugin.settings.useCustomFrontmatterHandlingSolution = newValue; + // await this.display(); // UI update obsolete + + if (this.plugin.settings.useCustomFrontmatterHandlingSolution) { + // CAMS: Reset lower limit + mySlider.setLimits(minTimeoutCams, 90, 1); + } + else { + // BOMS: Raise lower limit and bump if below + description += " Switch to default frontmatter solution for values <10s."; + console.log(mySlider.getValue()); + mySlider.setLimits(minTimeoutBoms, 90, 1); + if(this.plugin.settings.editTimeoutMilliseconds < minTimeoutBoms * 1000) { + this.plugin.settings.editTimeoutMilliseconds = minTimeoutBoms * 1000; + myText.setValue(minTimeoutBoms.toString()); + console.log("Bump BOMS timeout", this.plugin.settings.editTimeoutMilliseconds); + } + } await this.plugin.saveSettings(); - await this.display(); }), ); + new Setting(containerEl.createDiv({cls: "textbox"})) + // .setName("Interval between updates") + .setName(`Editing Timeout for ${this.plugin.settings.useCustomFrontmatterHandlingSolution === false ? "BOMS" : "CAMS"}`) + .setDesc(description) + .addSlider((slider) => mySlider = slider // implicit return without curlies + .setLimits(minTimeoutCams, 90, 1) + .setValue(this.plugin.settings.editTimeoutMilliseconds / 1000) + .onChange(async (value) => { + this.plugin.settings.editTimeoutMilliseconds = value * 1000; + myText.setValue(value.toString()); + await this.plugin.saveSettings(); + }) + .setDynamicTooltip(), + ) + .addText((text) => { + myText = text + .setPlaceholder("50") + .setValue((this.plugin.settings.editTimeoutMilliseconds/1000).toString(),) + .onChange(async (value) => { + const numericValue = parseInt(value, 10); + this.plugin.settings.editTimeoutMilliseconds = numericValue * 1000; + mySlider.setValue(numericValue); + await this.plugin.saveSettings(); + }) + // myText.inputEl.style.width = "4rem"; // because of the explicit return it's acting on the text element + // myText.inputEl.style.textAlign = "center"; + }); + + // #endregion - // #region status bar + // #region status bar containerEl.createEl("h1", { text: "Status bar" }); - containerEl.createEl("p", { - text: "Displays clock in the status bar", - }); + containerEl.createEl("p", { text: "Display symbols in the status bar" }); containerEl.createEl("h2", { text: "🕰️ Clock" }); - new Setting(containerEl) - .setName("Enable emojis") - .setDesc("Show emojis in the status bar?") - .addToggle((toggle) => - toggle - .setValue(this.plugin.settings.showEmojiStatusBar) - .onChange(async (newValue) => { - this.plugin.settings.showEmojiStatusBar = newValue; - await this.plugin.saveSettings(); - await this.display(); - }), - ); new Setting(containerEl) - .setName("Enable status bar clock") + .setName("Enable clock") .setDesc( "Show clock on the status bar? This setting requires restart of the plugin.", ) @@ -164,23 +195,24 @@ export class TimeThingsSettingsTab extends PluginSettingTab { }), ); - new Setting(containerEl) - .setName("Update interval") - .setDesc( - "In milliseconds. Restart plugin for this setting to take effect.", - ) - .addText((text) => - text - .setPlaceholder("1000") - .setValue( - this.plugin.settings.updateIntervalMilliseconds, - ) - .onChange(async (value) => { - this.plugin.settings.updateIntervalMilliseconds = - value; - await this.plugin.saveSettings(); - }), - ); + // TODO: delete + // new Setting(containerEl) + // .setName("Update interval") + // .setDesc( + // "In milliseconds. Restart plugin for this setting to take effect.", + // ) + // .addText((text) => + // text + // .setPlaceholder("1000") + // .setValue( + // this.plugin.settings.updateIntervalMilliseconds, + // ) + // .onChange(async (value) => { + // this.plugin.settings.updateIntervalMilliseconds = + // value; + // await this.plugin.saveSettings(); + // }), + // ); new Setting(containerEl) .setName("UTC timezone") @@ -195,33 +227,71 @@ export class TimeThingsSettingsTab extends PluginSettingTab { ); } + containerEl.createEl("h2", { text: "✏ Typing indicator" }); + new Setting(containerEl) + .setName("Enable typing indicator") + .setDesc("Show typing indicator in the status bar? This setting requires restart of the plugin.") + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.enableEditStatus) + .onChange(async (newValue) => { + this.plugin.settings.enableEditStatus = newValue; + await this.plugin.saveSettings(); + await this.display(); + }), + ); + + if (this.plugin.settings.enableEditStatus === true) { + new Setting(containerEl.createDiv({cls: "statusBarTypingIndicator"})) + .setName("Icon for tracking active/inactive") + .addText((text) => + text + .setPlaceholder(this.plugin.settings.editIndicatorActive) + .setValue(this.plugin.settings.editIndicatorActive) + .onChange(async (value) => { + this.plugin.settings.editIndicatorActive = value; + await this.plugin.saveSettings(); + }), + ) + .addText((text) => + text + .setPlaceholder("Your moj") + .setValue(this.plugin.settings.editIndicatorInactive) + .onChange(async (value) => { + this.plugin.settings.editIndicatorInactive = value; + await this.plugin.saveSettings(); + }), + ); + } // #endregion - // #region keys + // #region keys containerEl.createEl("h1", { text: "Frontmatter" }); containerEl.createEl("p", { text: "Handles timestamp keys in frontmatter.", }); // #region updated_at key - containerEl.createEl("h2", { text: "🔑 Modified timestamp" }); + containerEl.createEl("p", { + text: "Track the last time a note was edited.", + }); new Setting(containerEl) - .setName("Enable update of the modified key") + .setName("Enable update of the modified key") // TODO: only update after a certain amount has passed? Otherwise pretty useless depending on what triggers the tracking. I think mouse doesn't! .setDesc("") .addToggle((toggle) => toggle - .setValue(this.plugin.settings.enableModifiedKeyUpdate) + .setValue(this.plugin.settings.enableModifiedKey) .onChange(async (newValue) => { - this.plugin.settings.enableModifiedKeyUpdate = newValue; + this.plugin.settings.enableModifiedKey = newValue; await this.plugin.saveSettings(); await this.display(); }), ); - if (this.plugin.settings.enableModifiedKeyUpdate === true) { + if (this.plugin.settings.enableModifiedKey === true) { new Setting(containerEl) .setName("Modified key name") .setDesc( @@ -249,49 +319,11 @@ export class TimeThingsSettingsTab extends PluginSettingTab { await this.plugin.saveSettings(); }), ); - - - let mySlider : SliderComponent; - let myText: TextComponent; - let minValue = 1 - if (this.plugin.settings.useCustomFrontmatterHandlingSolution === false) { - minValue = 10; - } - new Setting(containerEl) - // .setName("Interval between updates") - .setName(`Editing Timeout for ${this.plugin.settings.useCustomFrontmatterHandlingSolution === false ? "BOMS" : "CAMS"}`) - .setDesc("Timeout in seconds to stop counting. Also reflected in the status bar. Affects all update frequencies. IF DEFAULT IS ACTIVE THEN > 10, OTHERWISE >1!!! ENFORECE! Also preview on slider wrong.") - .addSlider((slider) => - mySlider = slider - .setLimits(1, 90, 1) - .setValue( - this.plugin.settings.editTimeoutMilliseconds, - ) - .onChange(async (value) => { - this.plugin.settings.editTimeoutMilliseconds = value * 1000; - myText.setValue(value.toString()); - await this.plugin.saveSettings(); - }) - .setDynamicTooltip(), - ) - .addText((text) => - myText = text - .setPlaceholder("10020") - .setValue( - this.plugin.settings.editTimeoutMilliseconds.toString(), - ) - .onChange(async (value) => { - const numericValue = parseInt(value, 10); - this.plugin.settings.editTimeoutMilliseconds = numericValue * 1000; - mySlider.setValue(numericValue); - await this.plugin.saveSettings(); - })) } - // #endregion - // #region edited_duration key + // #region edited_duration key containerEl.createEl("h2", { text: "🔑 Edited duration" }); containerEl.createEl("p", { text: "Track for how long you have been editing a note.", @@ -340,37 +372,38 @@ export class TimeThingsSettingsTab extends PluginSettingTab { }), ); - const descA = document.createDocumentFragment(); - descA.append( - "The portion of time you are not typing when editing a note. Works best with custom frontmatter handling solution. ", - createEl("a", { - href: "https://github.com/DynamicPlayerSector/timethings/wiki/Calculating-your-non%E2%80%90typing-editing-percentage", - text: "How to calculate yours?", - }), - ); - - new Setting(containerEl) - .setName("Non-typing editing time percentage") - .setDesc(descA) - .addSlider((slider) => - slider - .setLimits(0, 40, 2) - .setValue( - this.plugin.settings.nonTypingEditingTimePercentage, - ) - .onChange(async (value) => { - this.plugin.settings.nonTypingEditingTimePercentage = - value; - await this.plugin.saveSettings(); - }) - .setDynamicTooltip(), - ); + // TODO: DELETE + // const descA = document.createDocumentFragment(); + // descA.append( + // "The portion of time you are not typing when editing a note. Works best with custom frontmatter handling solution. ", + // createEl("a", { + // href: "https://github.com/DynamicPlayerSector/timethings/wiki/Calculating-your-non%E2%80%90typing-editing-percentage", + // text: "How to calculate yours?", + // }), + // ); + + // new Setting(containerEl) + // .setName("Non-typing editing time percentage") + // .setDesc(descA) + // .addSlider((slider) => + // slider + // .setLimits(0, 40, 2) + // .setValue( + // this.plugin.settings.nonTypingEditingTimePercentage, + // ) + // .onChange(async (value) => { + // this.plugin.settings.nonTypingEditingTimePercentage = + // value; + // await this.plugin.saveSettings(); + // }) + // .setDynamicTooltip(), + // ); } - // #endregion // #endregion + // #region danger zone containerEl.createEl("h1", { text: "Danger zone" }); diff --git a/styles.css b/styles.css index de1462c..b3608c8 100644 --- a/styles.css +++ b/styles.css @@ -24,4 +24,18 @@ If your plugin does not need CSS, delete this file. width: 100px; max-height: 1rem; text-align: end; +} + +.statusBarTypingIndicator input[type="text"] +{ + display: flex; + justify-content: flex-end; + text-align: center; + width: 5rem; +} + +.textbox input[type="text"] +{ + text-align: center; + width: 3rem; } \ No newline at end of file From 29ffa673251cb15a35b181fd144c0d1063de99a1 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Thu, 5 Sep 2024 19:15:53 +0200 Subject: [PATCH 12/24] backup, usage of settings in progress, complications because of dynamic values --- src/main.ts | 107 +++++++++++++++++++++++++++--------------------- src/settings.ts | 10 ++--- 2 files changed, 66 insertions(+), 51 deletions(-) diff --git a/src/main.ts b/src/main.ts index f8e5493..4c3c845 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,12 +27,14 @@ import { allowedNodeEnvironmentFlags } from "process"; export default class TimeThings extends Plugin { settings: TimeThingsSettings; isDebugBuild: boolean; + isEditing = false; + timeout = 1000; // Fallback in case settings doesn't immediately initialize + clockBar: HTMLElement; // # Required - editingBar: HTMLElement; + editIndicatorBar: HTMLElement; debugBar: HTMLElement; - editDurationBar: HTMLElement; - isEditing = false; + //#region Load plugin async onload() { // Add commands this.addCommand( @@ -58,6 +60,7 @@ export default class TimeThings extends Plugin { // Load settings await this.loadSettings(); + this.timeout = this.settings.editTimeoutMilliseconds; // Variables initialization this.isDebugBuild = true; // for debugging purposes TODO: WELL IS IT OR IS IT NOT APPARENTLY ITS NOT IF THIS TEXT IS HERE! @@ -73,9 +76,11 @@ export default class TimeThings extends Plugin { // Add a tab for settings this.addSettingTab(new TimeThingsSettingsTab(this.app, this)); - } + //#endregion + + //#region UserActivity events registerMouseDownDOMEvent() { this.registerDomEvent(document, "mousedown", (evt: MouseEvent) => { // Prepare everything @@ -178,6 +183,7 @@ export default class TimeThings extends Plugin { }), ); } + //#endregion async activateMostEditedNotesView() { @@ -205,37 +211,20 @@ export default class TimeThings extends Plugin { } } + // TODO: Use actual settings values and verify those are the used ones + // TODO: Verify CAMS/BOMS configured is correclty used + // TODO: Check how the updateModificationDate is used and maybe change if it's updating too easily. Should only be updated on Keypresses or maybe keypresses with an overall usage > 30 seconds. + // (Hint: use old logic of aggregating change time) - timeout: number = 3000; // TODO: Into settings.ts - iconActive : boolean = false; // In a perfect world this matches the editing timer, but it's way simpler to decouple these variables - // Inactive typing - resetIcon = debounce(() => { - this.editingBar.setText(`✋🔴`); //TODO: settings.ts - this.iconActive = false; - this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.iconActive); - }, this.timeout, true); - - // Active typing icon - updateIcon() { - if(!this.iconActive) { - this.editingBar.setText(`✏🔵`); - this.iconActive = true; - this.isDebugBuild && console.log('Activate typing icon, active: ', this.iconActive); - } - this.resetIcon(); - } - - // not just on the setting as BOMS apparently requires a min of 10s - // -> TODO: Limit Timeout if BOMS is active! Provide slider + numberbox > 10 for BOMS, >1 for cams) - + //region Editing tracking // Run every x seconds starting from typing begin and update periodically startTime: number | null; updateEditedValue = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { if(this.startTime) { this.updateMetadata(useCustomSolution, activeView); } - }, this.timeout, false); + }, this.timeout); resetEditing = debounce(() => { // Reset state @@ -249,7 +238,7 @@ export default class TimeThings extends Plugin { if(!this.isEditing) { this.isEditing = true; this.startTime = moment.now(); - console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); + this.isDebugBuild && console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); } this.updateEditedValue(useCustomSolution, activeView); this.resetEditing(); @@ -257,6 +246,7 @@ export default class TimeThings extends Plugin { updateMetadata (useCustomSolution: boolean, activeView: MarkdownView) { let environment; + useCustomSolution ? environment = activeView.editor : environment = activeView.file; if ( useCustomSolution && @@ -265,7 +255,7 @@ export default class TimeThings extends Plugin { // CAMS: Custom Asset Management System this.updateModifiedPropertyEditor(environment); if (this.settings.enableEditDurationKey) { - console.log('calling cams!'); + this.isDebugBuild && console.log('calling cams!'); this.updateDurationPropertyEditor(environment); } @@ -276,7 +266,7 @@ export default class TimeThings extends Plugin { // BOMS: Build-in Object Management System this.updateModifiedPropertyFrontmatter(environment); if (this.settings.enableEditDurationKey) { - console.log('boms update'); + this.isDebugBuild && console.log('boms update'); this.updateDurationPropertyFrontmatter(environment); } } @@ -297,18 +287,22 @@ export default class TimeThings extends Plugin { // Check if the file has a property that puts it into a blacklist // Check if the file itself is in the blacklist - console.log('--- User activity! ---'); - + this.isDebugBuild && console.log('--- User activity! ---'); + console.log('Timeout: ', this.timeout); if (updateStatusBar) { + console.log("Update status bar, timeout: ", this.timeout); this.updateIcon(); } - - // Update metadata using either BOMS or CAMS if (updateMetadata) { + // Update metadata using either BOMS or CAMS + console.log("Update metadata, timeout: ", this.timeout); this.updateEditing(useCustomSolution, activeView); } } + //#endregion + + //#region Frontmatter update modified // CAMS updateModifiedPropertyEditor(editor: Editor) { const dateNow = moment(); @@ -365,6 +359,7 @@ export default class TimeThings extends Plugin { ); } + //#region Frontmatter update duration // CAMS async updateDurationPropertyEditor(editor: Editor) { // Fetch value @@ -381,7 +376,7 @@ export default class TimeThings extends Plugin { return; } // Increment & set - const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format + const incremented = moment.duration(value).add(this.settings.editTimeoutMilliseconds, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format this.isDebugBuild && console.log(`Increment CAMS from ${value} to ${incremented}`); CAMS.setValue( editor, @@ -408,14 +403,8 @@ export default class TimeThings extends Plugin { this.isDebugBuild && console.log("Wrong format for edit_duration property"); return; } - - // TODO: Do this right in the settings. Maybe the date could also be validated directly in the settings? - if(this.timeout < 10000) { - console.log('Invalid timeout for BOMS, reset to 10 seconds.'); - this.timeout = 10000; - } // Increment - const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, {trim: false}); + const incremented = moment.duration(value).add(this.settings.editTimeoutMilliseconds, 'milliseconds').format(userDateFormat, {trim: false}); this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`, 0); BOMS.setValue( frontmatter, @@ -425,8 +414,10 @@ export default class TimeThings extends Plugin { }, ); } + //#endregion - + + //#region Status bar // Don't worry about it updateClockBar() { const dateNow = moment(); @@ -437,6 +428,29 @@ export default class TimeThings extends Plugin { const emoji = timeUtils.momentToClockEmoji(dateChosen); } + // Typing indicator + iconActive : boolean = false; // Will match the editing timer, but it's better to decouple these variables + // Inactive typing + resetIcon = debounce(() => { + console.log("immedaitely", this.timeout); + this.editIndicatorBar.setText(this.settings.editIndicatorInactive); + this.iconActive = false; + this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.iconActive); + }, this.timeout, true); + + // Active typing icon + updateIcon() { + if(!this.iconActive) { + this.editIndicatorBar.setText(this.settings.editIndicatorActive); + this.iconActive = true; + this.isDebugBuild && console.log('Activate typing icon, active: ', this.iconActive); + } + console.log("Timeout updateIcon(): ", this.timeout); + console.log("Timeout updateIcon()2: ", this.settings.editTimeoutMilliseconds); + + this.resetIcon(); + } + // Called on OnLoad, adds status bar setUpStatusBarItems() { if (this.settings.enableClock) { @@ -454,11 +468,12 @@ export default class TimeThings extends Plugin { ); } if (this.settings.enableEditStatus) { - this.editingBar = this.addStatusBarItem(); - this.editingBar.setText(this.settings.editIndicatorActive); + this.editIndicatorBar = this.addStatusBarItem(); + this.editIndicatorBar.setText(this.settings.editIndicatorActive); } - } + //#endregion + // Don't worry about it onunload() {} diff --git a/src/settings.ts b/src/settings.ts index 4b7e4d2..2820b8c 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -51,8 +51,8 @@ export const DEFAULT_SETTINGS: TimeThingsSettings = { enableEditDurationKey: true, editTimeoutMilliseconds: 3000, enableEditStatus: true, - editIndicatorActive: "✋🔴", - editIndicatorInactive: "✏🔵", + editIndicatorActive: "✏🔵", + editIndicatorInactive: "✋🔴", updateIntervalFrontmatterMinutes: 1, @@ -243,10 +243,10 @@ export class TimeThingsSettingsTab extends PluginSettingTab { if (this.plugin.settings.enableEditStatus === true) { new Setting(containerEl.createDiv({cls: "statusBarTypingIndicator"})) - .setName("Icon for tracking active/inactive") + .setName("Icon for tracking inactive/active") .addText((text) => text - .setPlaceholder(this.plugin.settings.editIndicatorActive) + .setPlaceholder("Inactive") .setValue(this.plugin.settings.editIndicatorActive) .onChange(async (value) => { this.plugin.settings.editIndicatorActive = value; @@ -255,7 +255,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("Your moj") + .setPlaceholder("Active") .setValue(this.plugin.settings.editIndicatorInactive) .onChange(async (value) => { this.plugin.settings.editIndicatorInactive = value; From a5bbdcb0e62561e830b9cccd1ccea5bd0336c94a Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Thu, 5 Sep 2024 21:14:06 +0200 Subject: [PATCH 13/24] backup, timeouts still use stale reference. Most probable fix to put the assignment of debounced functions into loadSettings --- src/main.ts | 35 ++++++++++++++++++++++++----------- src/settings.ts | 1 - 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/main.ts b/src/main.ts index 4c3c845..7cf4013 100644 --- a/src/main.ts +++ b/src/main.ts @@ -28,14 +28,28 @@ export default class TimeThings extends Plugin { settings: TimeThingsSettings; isDebugBuild: boolean; isEditing = false; - timeout = 1000; // Fallback in case settings doesn't immediately initialize clockBar: HTMLElement; // # Required editIndicatorBar: HTMLElement; debugBar: HTMLElement; + //TODO: Still uses 2000 internally somewhere! + // Allows for dynamic retrieval whereas a value stored in a closure would be copied and subsequentially outdated + get timeout() { + let to = this.settings?.editTimeoutMilliseconds; + if(!to || isNaN(to) || to === undefined) { + console.log(`Timeout setting ${to} invalid, fallback!`); + to = 1300; + } + console.log('Timeout fetched: ', to); + return to; + } + //#region Load plugin async onload() { + // Load settings + await this.loadSettings(); + // Add commands this.addCommand( { @@ -58,12 +72,8 @@ export default class TimeThings extends Plugin { (leaf) => new MostEditedView(leaf), ); - // Load settings - await this.loadSettings(); - this.timeout = this.settings.editTimeoutMilliseconds; - // Variables initialization - this.isDebugBuild = true; // for debugging purposes TODO: WELL IS IT OR IS IT NOT APPARENTLY ITS NOT IF THIS TEXT IS HERE! + this.isDebugBuild = true; // for debugging purposes TODO: reset // Set up Status Bar items this.setUpStatusBarItems(); @@ -376,7 +386,7 @@ export default class TimeThings extends Plugin { return; } // Increment & set - const incremented = moment.duration(value).add(this.settings.editTimeoutMilliseconds, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format + const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format this.isDebugBuild && console.log(`Increment CAMS from ${value} to ${incremented}`); CAMS.setValue( editor, @@ -404,7 +414,7 @@ export default class TimeThings extends Plugin { return; } // Increment - const incremented = moment.duration(value).add(this.settings.editTimeoutMilliseconds, 'milliseconds').format(userDateFormat, {trim: false}); + const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, {trim: false}); this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`, 0); BOMS.setValue( frontmatter, @@ -431,8 +441,11 @@ export default class TimeThings extends Plugin { // Typing indicator iconActive : boolean = false; // Will match the editing timer, but it's better to decouple these variables // Inactive typing + // Because the method is stored in a variable, the variable in the closure, + // namely timeout is not stored by reference but internally duplicated. + // Using a getter decouples the method from the settings resetIcon = debounce(() => { - console.log("immedaitely", this.timeout); + console.log("immedaitely getter", this.timeout); this.editIndicatorBar.setText(this.settings.editIndicatorInactive); this.iconActive = false; this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.iconActive); @@ -445,8 +458,8 @@ export default class TimeThings extends Plugin { this.iconActive = true; this.isDebugBuild && console.log('Activate typing icon, active: ', this.iconActive); } - console.log("Timeout updateIcon(): ", this.timeout); - console.log("Timeout updateIcon()2: ", this.settings.editTimeoutMilliseconds); + console.log("Timeout updateIcon()getter: ", this.timeout); + // console.log("Timeout updateIcon()settingsprop: ", this.settings.editTimeoutMilliseconds); this.resetIcon(); } diff --git a/src/settings.ts b/src/settings.ts index 2820b8c..1ec854c 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -130,7 +130,6 @@ export class TimeThingsSettingsTab extends PluginSettingTab { ); new Setting(containerEl.createDiv({cls: "textbox"})) - // .setName("Interval between updates") .setName(`Editing Timeout for ${this.plugin.settings.useCustomFrontmatterHandlingSolution === false ? "BOMS" : "CAMS"}`) .setDesc(description) .addSlider((slider) => mySlider = slider // implicit return without curlies From 790a8dd26a6f561b27e1fee10e1cb3f23abe72e4 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:36:43 +0200 Subject: [PATCH 14/24] Timeout setting works, might be simplified --- src/main.ts | 71 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/main.ts b/src/main.ts index 7cf4013..f8820cc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -32,19 +32,27 @@ export default class TimeThings extends Plugin { clockBar: HTMLElement; // # Required editIndicatorBar: HTMLElement; debugBar: HTMLElement; + + // Debounced functions + updateFrontmatter: (useCustomSolution: boolean, activeView: MarkdownView) => void; + resetEditing: () => void; + resetIcon: () => void; + activityIconActive : boolean = false; // Will match the editing timer of isEditing, but it's better to decouple these variables + // timeout: number; - //TODO: Still uses 2000 internally somewhere! // Allows for dynamic retrieval whereas a value stored in a closure would be copied and subsequentially outdated get timeout() { let to = this.settings?.editTimeoutMilliseconds; if(!to || isNaN(to) || to === undefined) { console.log(`Timeout setting ${to} invalid, fallback!`); - to = 1300; + to = 1000; } console.log('Timeout fetched: ', to); return to; } + + //#region Load plugin async onload() { // Load settings @@ -230,18 +238,6 @@ export default class TimeThings extends Plugin { //region Editing tracking // Run every x seconds starting from typing begin and update periodically startTime: number | null; - updateEditedValue = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { - if(this.startTime) { - this.updateMetadata(useCustomSolution, activeView); - } - }, this.timeout); - - resetEditing = debounce(() => { - // Reset state - this.isDebugBuild && console.log('Editing halted!'); - this.isEditing = false; - this.startTime = null; - }, this.timeout, true); updateEditing(useCustomSolution: boolean, activeView: MarkdownView) { // Save current time only once, regardless of repeated calls (flag) @@ -250,7 +246,7 @@ export default class TimeThings extends Plugin { this.startTime = moment.now(); this.isDebugBuild && console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); } - this.updateEditedValue(useCustomSolution, activeView); + this.updateFrontmatter(useCustomSolution, activeView); this.resetEditing(); } @@ -439,24 +435,13 @@ export default class TimeThings extends Plugin { } // Typing indicator - iconActive : boolean = false; // Will match the editing timer, but it's better to decouple these variables - // Inactive typing - // Because the method is stored in a variable, the variable in the closure, - // namely timeout is not stored by reference but internally duplicated. - // Using a getter decouples the method from the settings - resetIcon = debounce(() => { - console.log("immedaitely getter", this.timeout); - this.editIndicatorBar.setText(this.settings.editIndicatorInactive); - this.iconActive = false; - this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.iconActive); - }, this.timeout, true); // Active typing icon updateIcon() { - if(!this.iconActive) { + if(!this.activityIconActive) { this.editIndicatorBar.setText(this.settings.editIndicatorActive); - this.iconActive = true; - this.isDebugBuild && console.log('Activate typing icon, active: ', this.iconActive); + this.activityIconActive = true; + this.isDebugBuild && console.log('Activate typing icon, active: ', this.activityIconActive); } console.log("Timeout updateIcon()getter: ", this.timeout); // console.log("Timeout updateIcon()settingsprop: ", this.settings.editTimeoutMilliseconds); @@ -491,17 +476,43 @@ export default class TimeThings extends Plugin { // Don't worry about it onunload() {} - // Don't worry about it + async loadSettings() { this.settings = Object.assign( {}, DEFAULT_SETTINGS, await this.loadData(), ); + + this.isDebugBuild && console.log("LOAD settings, timeout: ", this.timeout); + // Because the methods are stored in a variable, the values inside the closure will be stale. + // Reloading here keeps it fresh and decoupled from the settings file. + this.updateFrontmatter = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { + if(this.startTime) { + this.updateMetadata(useCustomSolution, activeView); + } + }, this.timeout); + + this.resetIcon = debounce(() => { + // Inactive typing + console.log("immedaitely getter", this.timeout); + this.editIndicatorBar.setText(this.settings.editIndicatorInactive); + this.activityIconActive = false; + this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.activityIconActive); + }, this.timeout, true); + + this.resetEditing = debounce(() => { + // Reset state + this.isDebugBuild && console.log('Editing halted!'); + this.isEditing = false; + this.startTime = null; + }, this.timeout, true); } // Don't worry about it async saveSettings() { + this.isDebugBuild && console.log("SAVE settings") await this.saveData(this.settings); + await this.loadSettings(); } } From d4b96e380c1c98236e4508c68e185b55a837ea18 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:56:08 +0200 Subject: [PATCH 15/24] Refactor, format, remove unused variables --- src/main.ts | 34 +++++++++++--------------------- src/settings.ts | 52 +++++++++++++++++-------------------------------- 2 files changed, 29 insertions(+), 57 deletions(-) diff --git a/src/main.ts b/src/main.ts index f8820cc..0e4f3f5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -38,19 +38,7 @@ export default class TimeThings extends Plugin { resetEditing: () => void; resetIcon: () => void; activityIconActive : boolean = false; // Will match the editing timer of isEditing, but it's better to decouple these variables - // timeout: number; - - // Allows for dynamic retrieval whereas a value stored in a closure would be copied and subsequentially outdated - get timeout() { - let to = this.settings?.editTimeoutMilliseconds; - if(!to || isNaN(to) || to === undefined) { - console.log(`Timeout setting ${to} invalid, fallback!`); - to = 1000; - } - console.log('Timeout fetched: ', to); - return to; - } - + timeout: number; //#region Load plugin @@ -296,12 +284,12 @@ export default class TimeThings extends Plugin { this.isDebugBuild && console.log('--- User activity! ---'); console.log('Timeout: ', this.timeout); if (updateStatusBar) { - console.log("Update status bar, timeout: ", this.timeout); + this.isDebugBuild && console.log("Update status bar, timeout: ", this.timeout); this.updateIcon(); } if (updateMetadata) { // Update metadata using either BOMS or CAMS - console.log("Update metadata, timeout: ", this.timeout); + this.isDebugBuild && console.log("Update metadata, timeout: ", this.timeout); this.updateEditing(useCustomSolution, activeView); } } @@ -349,7 +337,7 @@ export default class TimeThings extends Plugin { if ( updateKeyValue.add( - this.settings.updateIntervalFrontmatterMinutes, + this.timeout, "minutes", ) > dateNow ) { @@ -435,17 +423,12 @@ export default class TimeThings extends Plugin { } // Typing indicator - - // Active typing icon updateIcon() { if(!this.activityIconActive) { this.editIndicatorBar.setText(this.settings.editIndicatorActive); this.activityIconActive = true; this.isDebugBuild && console.log('Activate typing icon, active: ', this.activityIconActive); } - console.log("Timeout updateIcon()getter: ", this.timeout); - // console.log("Timeout updateIcon()settingsprop: ", this.settings.editTimeoutMilliseconds); - this.resetIcon(); } @@ -461,7 +444,7 @@ export default class TimeThings extends Plugin { this.registerInterval( window.setInterval( this.updateClockBar.bind(this), - +this.settings.updateIntervalMilliseconds, + + this.timeout, ), ); } @@ -484,6 +467,12 @@ export default class TimeThings extends Plugin { await this.loadData(), ); + this.timeout = this.settings?.typingTimeoutMilliseconds; + if(!this.timeout || isNaN(this.timeout) || this.timeout === undefined) { + console.log(`Timeout setting ${this.timeout} invalid, fallback!`); + this.timeout = 3000; + } + this.isDebugBuild && console.log("LOAD settings, timeout: ", this.timeout); // Because the methods are stored in a variable, the values inside the closure will be stale. // Reloading here keeps it fresh and decoupled from the settings file. @@ -495,7 +484,6 @@ export default class TimeThings extends Plugin { this.resetIcon = debounce(() => { // Inactive typing - console.log("immedaitely getter", this.timeout); this.editIndicatorBar.setText(this.settings.editIndicatorInactive); this.activityIconActive = false; this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.activityIconActive); diff --git a/src/settings.ts b/src/settings.ts index 1ec854c..577350a 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -2,67 +2,51 @@ import { App, PluginSettingTab, Setting, SliderComponent, TextComponent } from " import TimeThings from "./main"; export interface TimeThingsSettings { - //CAMS + //CAMS/BOMS useCustomFrontmatterHandlingSolution: boolean; + typingTimeoutMilliseconds: number; //CLOCK clockFormat: string; - updateIntervalMilliseconds: string; enableClock: boolean; isUTC: boolean; - + //MODIFIED KEY enableModifiedKey: boolean; modifiedKeyName: string; modifiedKeyFormat: string; - //BOMS - updateIntervalFrontmatterMinutes: number; - + //DURATION KEY enableEditDurationKey: boolean; editDurationKeyName: string; editDurationKeyFormat: string; - nonTypingEditingTimePercentage: number; - editTimeoutMilliseconds: number; + + // EDIT INDICATOR enableEditStatus: boolean; editIndicatorActive: string; editIndicatorInactive: string; - - enableSwitch: boolean; - switchKey: string; - switchKeyValue: string; - } export const DEFAULT_SETTINGS: TimeThingsSettings = { useCustomFrontmatterHandlingSolution: false, + typingTimeoutMilliseconds: 3000, clockFormat: "hh:mm A", - updateIntervalMilliseconds: "1000", enableClock: true, isUTC: false, - + modifiedKeyName: "updated_at", modifiedKeyFormat: "YYYY-MM-DD[T]HH:mm:ss.SSSZ", enableModifiedKey: true, - + editDurationKeyName: "edited_seconds", editDurationKeyFormat: "HH:mm:ss", enableEditDurationKey: true, - editTimeoutMilliseconds: 3000, + + // EDIT INDICATOR enableEditStatus: true, editIndicatorActive: "✏🔵", editIndicatorInactive: "✋🔴", - - updateIntervalFrontmatterMinutes: 1, - - nonTypingEditingTimePercentage: 22, - - enableSwitch: false, - switchKey: "timethings.switch", - switchKeyValue: "true", - - }; export class TimeThingsSettingsTab extends PluginSettingTab { @@ -119,10 +103,10 @@ export class TimeThingsSettingsTab extends PluginSettingTab { description += " Switch to default frontmatter solution for values <10s."; console.log(mySlider.getValue()); mySlider.setLimits(minTimeoutBoms, 90, 1); - if(this.plugin.settings.editTimeoutMilliseconds < minTimeoutBoms * 1000) { - this.plugin.settings.editTimeoutMilliseconds = minTimeoutBoms * 1000; + if(this.plugin.settings.typingTimeoutMilliseconds < minTimeoutBoms * 1000) { + this.plugin.settings.typingTimeoutMilliseconds = minTimeoutBoms * 1000; myText.setValue(minTimeoutBoms.toString()); - console.log("Bump BOMS timeout", this.plugin.settings.editTimeoutMilliseconds); + console.log("Bump BOMS timeout", this.plugin.settings.typingTimeoutMilliseconds); } } await this.plugin.saveSettings(); @@ -134,9 +118,9 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .setDesc(description) .addSlider((slider) => mySlider = slider // implicit return without curlies .setLimits(minTimeoutCams, 90, 1) - .setValue(this.plugin.settings.editTimeoutMilliseconds / 1000) + .setValue(this.plugin.settings.typingTimeoutMilliseconds / 1000) .onChange(async (value) => { - this.plugin.settings.editTimeoutMilliseconds = value * 1000; + this.plugin.settings.typingTimeoutMilliseconds = value * 1000; myText.setValue(value.toString()); await this.plugin.saveSettings(); }) @@ -145,10 +129,10 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .addText((text) => { myText = text .setPlaceholder("50") - .setValue((this.plugin.settings.editTimeoutMilliseconds/1000).toString(),) + .setValue((this.plugin.settings.typingTimeoutMilliseconds/1000).toString(),) .onChange(async (value) => { const numericValue = parseInt(value, 10); - this.plugin.settings.editTimeoutMilliseconds = numericValue * 1000; + this.plugin.settings.typingTimeoutMilliseconds = numericValue * 1000; mySlider.setValue(numericValue); await this.plugin.saveSettings(); }) From ca0200a0f11152931e8c598709a5b025d015a2b5 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Sun, 8 Sep 2024 21:17:52 +0200 Subject: [PATCH 16/24] Refactor frontmatter updating including realtime date format validation. Current state: CAMS modified, other 3 not updated --- src/main.ts | 100 ++++++++++++++++++++++++++--------------------- src/settings.ts | 101 ++++++++++++++---------------------------------- styles.css | 7 +++- 3 files changed, 93 insertions(+), 115 deletions(-) diff --git a/src/main.ts b/src/main.ts index 0e4f3f5..4ac5aad 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,8 +6,8 @@ import { TFile, Notice, debounce, + moment } from "obsidian"; -import { moment, Debouncer } from "obsidian"; import { MostEditedView, VIEW_TYPE_MOST_EDITED as VIEW_TYPE_MOST_EDITED, @@ -27,8 +27,14 @@ import { allowedNodeEnvironmentFlags } from "process"; export default class TimeThings extends Plugin { settings: TimeThingsSettings; isDebugBuild: boolean; - isEditing = false; + // Edit tracking + isEditing = false; // Not a lock but used for tracking (Status bar) + startTime: number | null; // How long was isEditing active + activityIconActive : boolean = false; // Will match the editing timer of isEditing, but it's better to decouple these variables + timeout: number; // Loaded from settings, timeout for tracking and periodic saving + + // Status bar clockBar: HTMLElement; // # Required editIndicatorBar: HTMLElement; debugBar: HTMLElement; @@ -37,8 +43,7 @@ export default class TimeThings extends Plugin { updateFrontmatter: (useCustomSolution: boolean, activeView: MarkdownView) => void; resetEditing: () => void; resetIcon: () => void; - activityIconActive : boolean = false; // Will match the editing timer of isEditing, but it's better to decouple these variables - timeout: number; + //#region Load plugin @@ -99,7 +104,6 @@ export default class TimeThings extends Plugin { if (editor.hasFocus() === false) { return; } - this.onUserActivity(true, activeView, { updateMetadata: false, updateStatusBar: true }); }); } @@ -183,7 +187,6 @@ export default class TimeThings extends Plugin { if ( this.settings.useCustomFrontmatterHandlingSolution === false ) { - console.log('this2 '); this.onUserActivity(false, activeView); } }), @@ -217,15 +220,12 @@ export default class TimeThings extends Plugin { } } - // TODO: Use actual settings values and verify those are the used ones - // TODO: Verify CAMS/BOMS configured is correclty used - // TODO: Check how the updateModificationDate is used and maybe change if it's updating too easily. Should only be updated on Keypresses or maybe keypresses with an overall usage > 30 seconds. + // TODO: Check how the updateModificationDate is used and maybe change if it's updating too easily. + // Should only be updated on Keypresses or maybe keypresses with an overall usage > 30 seconds. // (Hint: use old logic of aggregating change time) //region Editing tracking - // Run every x seconds starting from typing begin and update periodically - startTime: number | null; updateEditing(useCustomSolution: boolean, activeView: MarkdownView) { // Save current time only once, regardless of repeated calls (flag) @@ -238,29 +238,38 @@ export default class TimeThings extends Plugin { this.resetEditing(); } + validEditDuration() : number | null { + const diffSeconds = (moment.now() - moment.duration(this.startTime).asMilliseconds()) / 1000; + return isNaN(diffSeconds) ? null : diffSeconds; + } + updateMetadata (useCustomSolution: boolean, activeView: MarkdownView) { let environment; useCustomSolution ? environment = activeView.editor : environment = activeView.file; + const editDiff = this.validEditDuration() if ( useCustomSolution && environment instanceof Editor ) { // CAMS: Custom Asset Management System - this.updateModifiedPropertyEditor(environment); + if(editDiff !== null && editDiff >= 4) { // TODO: Add setting + this.isDebugBuild && console.log(`Threshold reached with ${editDiff}, update modified property!`) + this.updateModifiedPropertyEditor(environment); + } if (this.settings.enableEditDurationKey) { - this.isDebugBuild && console.log('calling cams!'); this.updateDurationPropertyEditor(environment); - } } else if ( !useCustomSolution && environment instanceof TFile ) { // BOMS: Build-in Object Management System - this.updateModifiedPropertyFrontmatter(environment); + if(editDiff !== null && editDiff >= 10) { // TODO: Add setting + this.isDebugBuild && console.log(`Threshold reached with ${editDiff}, update modified property!`) + this.updateModifiedPropertyFrontmatter(environment); + } if (this.settings.enableEditDurationKey) { - this.isDebugBuild && console.log('boms update'); this.updateDurationPropertyFrontmatter(environment); } } @@ -281,15 +290,14 @@ export default class TimeThings extends Plugin { // Check if the file has a property that puts it into a blacklist // Check if the file itself is in the blacklist - this.isDebugBuild && console.log('--- User activity! ---'); - console.log('Timeout: ', this.timeout); if (updateStatusBar) { - this.isDebugBuild && console.log("Update status bar, timeout: ", this.timeout); - this.updateIcon(); + // this.isDebugBuild && console.log('--- Update status bar ---'); + // this.isDebugBuild && console.log("Update status bar, timeout: ", this.timeout); } if (updateMetadata) { // Update metadata using either BOMS or CAMS - this.isDebugBuild && console.log("Update metadata, timeout: ", this.timeout); + // this.isDebugBuild && console.log("Update metadata, timeout: ", this.timeout); + this.updateIcon(); this.updateEditing(useCustomSolution, activeView); } } @@ -297,26 +305,12 @@ export default class TimeThings extends Plugin { //#region Frontmatter update modified + // CAMS updateModifiedPropertyEditor(editor: Editor) { - const dateNow = moment(); - const userDateFormat = this.settings.modifiedKeyFormat; - const dateFormatted = dateNow.format(userDateFormat); - + const userDateFormat = this.settings.modifiedKeyFormat; // Target format. Existing format unknown and irrelevant. const userModifiedKeyName = this.settings.modifiedKeyName; - const valueLineNumber = CAMS.getLine(editor, userModifiedKeyName); - - if (typeof valueLineNumber !== "number") { - this.isDebugBuild && console.log("Couldn't get the line number of last_modified property"); - return; - } - const value = editor.getLine(valueLineNumber).split(/:(.*)/s)[1].trim(); - if (moment(value, userDateFormat, true).isValid() === false) { - // Little safecheck in place to reduce chance of bugs - this.isDebugBuild && console.log("Wrong format of last_modified property"); - return; - } - // this.setValue(true, editor, userModifiedKeyName, dateFormatted,); + const dateFormatted = moment().format(userDateFormat); CAMS.setValue(editor, userModifiedKeyName, dateFormatted); } @@ -354,15 +348,31 @@ export default class TimeThings extends Plugin { } //#region Frontmatter update duration + + + /* Date updating is delicate: Moment.js validity check might check an updated setting + against a pre-existing date and would return false. So it would never act on old documents. + Instead: Check existing date for general validity. Add diff. Check if the new format is valid and display as such. + */ // CAMS async updateDurationPropertyEditor(editor: Editor) { + + + + // if(!moment(value).isValid()) { + // this.isDebugBuild && console.log("Wrong format of updated_at property!"); + // return; + // } + + + // Fetch value let fieldLine: number | undefined = CAMS.getLine(editor, this.settings.editDurationKeyName); if(fieldLine === undefined) { console.log("Undefined value for duration property"); fieldLine = 0; } - // Parse & check validity + // Parse & check validity TODO: Doesn't make sense because the format might change and we're checking enw format against existing frontmatter format const value = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); const userDateFormat = this.settings.editDurationKeyFormat; if(moment(value, userDateFormat, true).isValid() === false) { @@ -427,7 +437,7 @@ export default class TimeThings extends Plugin { if(!this.activityIconActive) { this.editIndicatorBar.setText(this.settings.editIndicatorActive); this.activityIconActive = true; - this.isDebugBuild && console.log('Activate typing icon, active: ', this.activityIconActive); + this.isDebugBuild && console.log('Activate typing icon, active: ', this.activityIconActive, this.settings.editIndicatorActive); } this.resetIcon(); } @@ -448,7 +458,7 @@ export default class TimeThings extends Plugin { ), ); } - if (this.settings.enableEditStatus) { + if (this.settings.enableEditIndicator) { this.editIndicatorBar = this.addStatusBarItem(); this.editIndicatorBar.setText(this.settings.editIndicatorActive); } @@ -470,7 +480,7 @@ export default class TimeThings extends Plugin { this.timeout = this.settings?.typingTimeoutMilliseconds; if(!this.timeout || isNaN(this.timeout) || this.timeout === undefined) { console.log(`Timeout setting ${this.timeout} invalid, fallback!`); - this.timeout = 3000; + this.timeout = 10000; } this.isDebugBuild && console.log("LOAD settings, timeout: ", this.timeout); @@ -485,13 +495,17 @@ export default class TimeThings extends Plugin { this.resetIcon = debounce(() => { // Inactive typing this.editIndicatorBar.setText(this.settings.editIndicatorInactive); + console.log('this is inactive: ', this.settings.editIndicatorInactive); + console.log('this is active: ', this.settings.editIndicatorActive); + this.activityIconActive = false; this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.activityIconActive); }, this.timeout, true); this.resetEditing = debounce(() => { // Reset state - this.isDebugBuild && console.log('Editing halted!'); + let diff: number = moment.now() - moment.duration(this.startTime).asMilliseconds(); + this.isDebugBuild && console.log(`Editing halted after ${diff/1000}s.`); this.isEditing = false; this.startTime = null; }, this.timeout, true); diff --git a/src/settings.ts b/src/settings.ts index 577350a..3622577 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,5 +1,6 @@ import { App, PluginSettingTab, Setting, SliderComponent, TextComponent } from "obsidian"; import TimeThings from "./main"; +import moment from "moment"; export interface TimeThingsSettings { //CAMS/BOMS @@ -22,14 +23,14 @@ export interface TimeThingsSettings { editDurationKeyFormat: string; // EDIT INDICATOR - enableEditStatus: boolean; + enableEditIndicator: boolean; editIndicatorActive: string; editIndicatorInactive: string; } export const DEFAULT_SETTINGS: TimeThingsSettings = { useCustomFrontmatterHandlingSolution: false, - typingTimeoutMilliseconds: 3000, + typingTimeoutMilliseconds: 10000, // Default setting is BOMS, which triggers an endless loop due to the file modification event when going <10s clockFormat: "hh:mm A", enableClock: true, @@ -44,7 +45,7 @@ export const DEFAULT_SETTINGS: TimeThingsSettings = { enableEditDurationKey: true, // EDIT INDICATOR - enableEditStatus: true, + enableEditIndicator: true, editIndicatorActive: "✏🔵", editIndicatorInactive: "✋🔴", }; @@ -76,6 +77,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { // #endregion + // #region custom frontmatter solution let mySlider : SliderComponent; let myText: TextComponent; @@ -136,8 +138,6 @@ export class TimeThingsSettingsTab extends PluginSettingTab { mySlider.setValue(numericValue); await this.plugin.saveSettings(); }) - // myText.inputEl.style.width = "4rem"; // because of the explicit return it's acting on the text element - // myText.inputEl.style.textAlign = "center"; }); @@ -178,25 +178,6 @@ export class TimeThingsSettingsTab extends PluginSettingTab { }), ); - // TODO: delete - // new Setting(containerEl) - // .setName("Update interval") - // .setDesc( - // "In milliseconds. Restart plugin for this setting to take effect.", - // ) - // .addText((text) => - // text - // .setPlaceholder("1000") - // .setValue( - // this.plugin.settings.updateIntervalMilliseconds, - // ) - // .onChange(async (value) => { - // this.plugin.settings.updateIntervalMilliseconds = - // value; - // await this.plugin.saveSettings(); - // }), - // ); - new Setting(containerEl) .setName("UTC timezone") .setDesc("Use UTC instead of local time?") @@ -216,31 +197,34 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .setDesc("Show typing indicator in the status bar? This setting requires restart of the plugin.") .addToggle((toggle) => toggle - .setValue(this.plugin.settings.enableEditStatus) + .setValue(this.plugin.settings.enableEditIndicator) .onChange(async (newValue) => { - this.plugin.settings.enableEditStatus = newValue; + this.plugin.settings.enableEditIndicator = newValue; await this.plugin.saveSettings(); await this.display(); }), ); - if (this.plugin.settings.enableEditStatus === true) { + if (this.plugin.settings.enableEditIndicator === true) { new Setting(containerEl.createDiv({cls: "statusBarTypingIndicator"})) - .setName("Icon for tracking inactive/active") + .setName("Icon for tracking active/inactive") .addText((text) => text - .setPlaceholder("Inactive") + .setPlaceholder("Active") .setValue(this.plugin.settings.editIndicatorActive) .onChange(async (value) => { + console.log('update active tracking icon: ', value) this.plugin.settings.editIndicatorActive = value; await this.plugin.saveSettings(); }), ) .addText((text) => text - .setPlaceholder("Active") + .setPlaceholder("Inactive") .setValue(this.plugin.settings.editIndicatorInactive) .onChange(async (value) => { + console.log('update inactive tracking icon: ', value) + this.plugin.settings.editIndicatorInactive = value; await this.plugin.saveSettings(); }), @@ -251,15 +235,12 @@ export class TimeThingsSettingsTab extends PluginSettingTab { // #region keys containerEl.createEl("h1", { text: "Frontmatter" }); - containerEl.createEl("p", { - text: "Handles timestamp keys in frontmatter.", - }); + containerEl.createEl("p", { text: "Handles timestamp keys in frontmatter." }); // #region updated_at key containerEl.createEl("h2", { text: "🔑 Modified timestamp" }); - containerEl.createEl("p", { - text: "Track the last time a note was edited.", - }); + containerEl.createEl("p", { text: "Track the last time a note was edited." }); + new Setting(containerEl) .setName("Enable update of the modified key") // TODO: only update after a certain amount has passed? Otherwise pretty useless depending on what triggers the tracking. I think mouse doesn't! @@ -297,15 +278,22 @@ export class TimeThingsSettingsTab extends PluginSettingTab { text .setPlaceholder("YYYY-MM-DD[T]HH:mm:ss.SSSZ") .setValue(this.plugin.settings.modifiedKeyFormat) - .onChange(async (value) => { - this.plugin.settings.modifiedKeyFormat = value; - await this.plugin.saveSettings(); + .onChange(async (formatter) => { + // Try formatting the current date + const formatTest = moment().format(formatter); + const valid = moment(formatTest, formatter).isValid(); + if(!valid) { + text.inputEl.addClass('invalid-format'); + } else { + text.inputEl.removeClass('invalid-format'); + this.plugin.settings.modifiedKeyFormat = formatter; + await this.plugin.saveSettings(); + } }), - ); + ) } // #endregion - // #region edited_duration key containerEl.createEl("h2", { text: "🔑 Edited duration" }); containerEl.createEl("p", { @@ -354,36 +342,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { await this.plugin.saveSettings(); }), ); - - // TODO: DELETE - // const descA = document.createDocumentFragment(); - // descA.append( - // "The portion of time you are not typing when editing a note. Works best with custom frontmatter handling solution. ", - // createEl("a", { - // href: "https://github.com/DynamicPlayerSector/timethings/wiki/Calculating-your-non%E2%80%90typing-editing-percentage", - // text: "How to calculate yours?", - // }), - // ); - - // new Setting(containerEl) - // .setName("Non-typing editing time percentage") - // .setDesc(descA) - // .addSlider((slider) => - // slider - // .setLimits(0, 40, 2) - // .setValue( - // this.plugin.settings.nonTypingEditingTimePercentage, - // ) - // .onChange(async (value) => { - // this.plugin.settings.nonTypingEditingTimePercentage = - // value; - // await this.plugin.saveSettings(); - // }) - // .setDynamicTooltip(), - // ); - } - // #endregion - + } // #endregion diff --git a/styles.css b/styles.css index b3608c8..f4e753a 100644 --- a/styles.css +++ b/styles.css @@ -38,4 +38,9 @@ If your plugin does not need CSS, delete this file. { text-align: center; width: 3rem; -} \ No newline at end of file +} + +.setting-item .setting-item-control .invalid-format { + border-color: orangered; +} + From 73b049665c37fe7d302e9a2f0ba3c7cdf17e3ef2 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:17:10 +0200 Subject: [PATCH 17/24] Refactor frontmatter update in progress --- src/main.ts | 63 +++++++++++++++++++++++++++---------------------- src/settings.ts | 32 ++++++++++++++++++------- 2 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/main.ts b/src/main.ts index 4ac5aad..41385f6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -316,6 +316,7 @@ export default class TimeThings extends Plugin { // BOMS (Default) async updateModifiedPropertyFrontmatter(file: TFile) { + // TODO update await this.app.fileManager.processFrontMatter( file as TFile, (frontmatter) => { @@ -352,45 +353,54 @@ export default class TimeThings extends Plugin { /* Date updating is delicate: Moment.js validity check might check an updated setting against a pre-existing date and would return false. So it would never act on old documents. - Instead: Check existing date for general validity. Add diff. Check if the new format is valid and display as such. + Instead: Check existing duration for general validity. Add diff. Check if the new format is valid and display as such. */ // CAMS async updateDurationPropertyEditor(editor: Editor) { - - - // if(!moment(value).isValid()) { - // this.isDebugBuild && console.log("Wrong format of updated_at property!"); - // return; - // } + //TODO update + + // Fetch edit duration + const fieldLine: number | undefined = CAMS.getLine(editor, this.settings.editDurationKeyName); + const userDateFormat = this.settings.editDurationKeyFormat; + let newValue : any; + console.log("---------------------------") + console.log('frontmatter', CAMS.getLine(editor, this.settings.editDurationKeyName)); + console.log('frontmatter2', CAMS.getLine(editor, this.settings.editDurationKeyName)) + - // Fetch value - let fieldLine: number | undefined = CAMS.getLine(editor, this.settings.editDurationKeyName); + console.log('key name: ', this.settings.editDurationKeyName); + console.log('cams prop', CAMS.getLine(editor, this.settings.editDurationKeyName)); + console.log('editor fieldline', (CAMS.getLine(editor, this.settings.editDurationKeyName))); + if(fieldLine === undefined) { - console.log("Undefined value for duration property"); - fieldLine = 0; - } - // Parse & check validity TODO: Doesn't make sense because the format might change and we're checking enw format against existing frontmatter format - const value = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); - const userDateFormat = this.settings.editDurationKeyFormat; - if(moment(value, userDateFormat, true).isValid() === false) { - this.isDebugBuild && console.log("Wrong format or invalid value with edit_duration property"); - return; + console.log(`Undefined value for ${this.settings.editDurationKeyName}`); + newValue = moment.duration(0, "minutes").format(userDateFormat, { trim: false }) + console.log('set value here'); + + CAMS.setValue(editor, "welltest", newValue); + + } else { + newValue = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); + const test = moment(newValue, userDateFormat, true).isValid() + console.log("test vlaid? ", test) } + + this.isDebugBuild && console.log(`Current edit duration ${newValue} and current/new formatter ${userDateFormat}`); + // Increment & set - const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format - this.isDebugBuild && console.log(`Increment CAMS from ${value} to ${incremented}`); - CAMS.setValue( - editor, - this.settings.editDurationKeyName, - incremented.toString(), - ); + const incremented = moment.duration(newValue).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format + this.isDebugBuild && console.log(`Increment CAMS from ${newValue} to ${incremented}`); + CAMS.setValue(editor, this.settings.editDurationKeyName, incremented.toString()); } // BOMS (Default) async updateDurationPropertyFrontmatter(file: TFile) { + + // TODO update + // Slow update await this.app.fileManager.processFrontMatter( file as TFile, @@ -495,9 +505,6 @@ export default class TimeThings extends Plugin { this.resetIcon = debounce(() => { // Inactive typing this.editIndicatorBar.setText(this.settings.editIndicatorInactive); - console.log('this is inactive: ', this.settings.editIndicatorInactive); - console.log('this is active: ', this.settings.editIndicatorActive); - this.activityIconActive = false; this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.activityIconActive); }, this.timeout, true); diff --git a/src/settings.ts b/src/settings.ts index 3622577..2194af4 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -116,7 +116,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { ); new Setting(containerEl.createDiv({cls: "textbox"})) - .setName(`Editing Timeout for ${this.plugin.settings.useCustomFrontmatterHandlingSolution === false ? "BOMS" : "CAMS"}`) + .setName("Editing Timeout") .setDesc(description) .addSlider((slider) => mySlider = slider // implicit return without curlies .setLimits(minTimeoutCams, 90, 1) @@ -172,9 +172,17 @@ export class TimeThingsSettingsTab extends PluginSettingTab { text .setPlaceholder("hh:mm A") .setValue(this.plugin.settings.clockFormat) - .onChange(async (value) => { - this.plugin.settings.clockFormat = value; - await this.plugin.saveSettings(); + .onChange(async (formatter) => { + // Validate formatter by using it + const formatTest = moment().format(formatter); + const valid = moment(formatTest, formatter).isValid(); + if(!valid) { + text.inputEl.addClass('invalid-format'); + } else { + text.inputEl.removeClass('invalid-format'); + this.plugin.settings.clockFormat = formatter; + await this.plugin.saveSettings(); + } }), ); @@ -279,7 +287,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .setPlaceholder("YYYY-MM-DD[T]HH:mm:ss.SSSZ") .setValue(this.plugin.settings.modifiedKeyFormat) .onChange(async (formatter) => { - // Try formatting the current date + // Validate formatter by using it const formatTest = moment().format(formatter); const valid = moment(formatTest, formatter).isValid(); if(!valid) { @@ -337,9 +345,17 @@ export class TimeThingsSettingsTab extends PluginSettingTab { text .setPlaceholder("HH:mm:ss.SSSZ") .setValue(this.plugin.settings.editDurationKeyFormat) - .onChange(async (value) => { - this.plugin.settings.editDurationKeyFormat = value; - await this.plugin.saveSettings(); + .onChange(async (formatter) => { + // Validate formatter by using it + const formatTest = moment().format(formatter); + const valid = moment(formatTest, formatter).isValid(); + if(!valid) { + text.inputEl.addClass('invalid-format'); + } else { + text.inputEl.removeClass('invalid-format'); + this.plugin.settings.editDurationKeyFormat = formatter; + await this.plugin.saveSettings(); + } }), ); } From cb89b1a48833c6a8e67dbffe5acaa0a239daf91e Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:01:49 +0200 Subject: [PATCH 18/24] BOMS modified date works, rest in progress --- src/main.ts | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/src/main.ts b/src/main.ts index 41385f6..7c58a61 100644 --- a/src/main.ts +++ b/src/main.ts @@ -308,6 +308,9 @@ export default class TimeThings extends Plugin { // CAMS updateModifiedPropertyEditor(editor: Editor) { + this.isDebugBuild && console.log('CAMS: Update modified property!'); + // With the old solution updating frontmatter keys only worked on BOMS! + // todo: allow key changes const userDateFormat = this.settings.modifiedKeyFormat; // Target format. Existing format unknown and irrelevant. const userModifiedKeyName = this.settings.modifiedKeyName; const dateFormatted = moment().format(userDateFormat); @@ -316,34 +319,13 @@ export default class TimeThings extends Plugin { // BOMS (Default) async updateModifiedPropertyFrontmatter(file: TFile) { - // TODO update + this.isDebugBuild && console.log('--- BOMS: Update modified property! ---'); await this.app.fileManager.processFrontMatter( file as TFile, (frontmatter) => { - const dateNow = moment(); - const dateFormatted = dateNow.format( - this.settings.modifiedKeyFormat, - ); - - const updateKeyValue = moment( - BOMS.getValue(frontmatter, this.settings.modifiedKeyName), - this.settings.modifiedKeyFormat, - ); - - if ( - updateKeyValue.add( - this.timeout, - "minutes", - ) > dateNow - ) { - return; - } - - BOMS.setValue( - frontmatter, - this.settings.modifiedKeyName, - dateFormatted, - ); + const dateFormatted = moment().format(this.settings.modifiedKeyFormat); + // BOMS creates key if it doesn't exist + BOMS.setValue(frontmatter,this.settings.modifiedKeyName, dateFormatted); }, ); } @@ -357,6 +339,8 @@ export default class TimeThings extends Plugin { */ // CAMS async updateDurationPropertyEditor(editor: Editor) { + this.isDebugBuild && console.log('CAMS: Update duration property!'); + // With the old solution updating frontmatter keys only worked on BOMS! //TODO update @@ -398,6 +382,7 @@ export default class TimeThings extends Plugin { // BOMS (Default) async updateDurationPropertyFrontmatter(file: TFile) { + this.isDebugBuild && console.log('--- BOMS: Update duration property! ---'); // TODO update From 5ae09e7fb7ec6ec8d334fd4af75a2bef0fcf12da Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:46:41 +0200 Subject: [PATCH 19/24] backup before going even deeper into cams/boms refactoring --- src/main.ts | 142 ++++++++++++++++++++++++++---------------------- src/settings.ts | 5 +- 2 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/main.ts b/src/main.ts index 7c58a61..68e2adf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -80,7 +80,7 @@ export default class TimeThings extends Plugin { this.setUpStatusBarItems(); // Events initialization - this.registerFileModificationEvent(); + // this.registerFileModificationEvent(); this.registerKeyDownDOMEvent(); this.registerLeafChangeEvent(); this.registerMouseDownDOMEvent(); @@ -92,22 +92,7 @@ export default class TimeThings extends Plugin { //#region UserActivity events - registerMouseDownDOMEvent() { - this.registerDomEvent(document, "mousedown", (evt: MouseEvent) => { - // Prepare everything - const activeView = - this.app.workspace.getActiveViewOfType(MarkdownView); - if (activeView === null) { - return; - } - const editor: Editor = activeView.editor; - if (editor.hasFocus() === false) { - return; - } - this.onUserActivity(true, activeView, { updateMetadata: false, updateStatusBar: true }); - }); - } - + // CAMS registerLeafChangeEvent() { this.registerEvent( this.app.workspace.on("active-leaf-change", (leaf) => { @@ -121,19 +106,14 @@ export default class TimeThings extends Plugin { if (editor.hasFocus() === false) { return; } - - // Change the duration icon in status bar - this.onUserActivity(true, activeView, { - updateMetadata: false, - updateStatusBar: true, - }); + this.onUserActivity(true, activeView); }), ); } + // CAMS registerKeyDownDOMEvent() { this.registerDomEvent(document, "keyup", (evt: KeyboardEvent) => { - // If CAMS enabled const ignoreKeys = [ "ArrowDown", "ArrowUp", @@ -154,6 +134,7 @@ export default class TimeThings extends Plugin { return; } + this.isDebugBuild && console.log(`Key down: ${this.settings.useCustomFrontmatterHandlingSolution ? "CAMS" : "BOMS"}`); if (this.settings.useCustomFrontmatterHandlingSolution === true) { // Make sure the document is ready for edit const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); @@ -169,11 +150,15 @@ export default class TimeThings extends Plugin { // Update everything this.onUserActivity(true, activeView); + } else { + console.log('well, just use boms?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); } }); } + // BOMS registerFileModificationEvent() { + // ! If BOMS is updated it triggers a new file modification event this.registerEvent( this.app.vault.on("modify", (file) => { // Make everything ready for edit @@ -182,17 +167,33 @@ export default class TimeThings extends Plugin { if (activeView === null) { return; } + console.log('filemod'); - // Main - if ( - this.settings.useCustomFrontmatterHandlingSolution === false - ) { + if (this.settings.useCustomFrontmatterHandlingSolution === false) { this.onUserActivity(false, activeView); } }), ); } - //#endregion + + // NONE + registerMouseDownDOMEvent() { + this.registerDomEvent(document, "mousedown", (evt: MouseEvent) => { + // Prepare everything + const activeView = + this.app.workspace.getActiveViewOfType(MarkdownView); + if (activeView === null) { + return; + } + const editor: Editor = activeView.editor; + if (editor.hasFocus() === false) { + return; + } + + this.onUserActivity(true, activeView, { updateMetadata: false, updateTypingIndicator: false }); + }); + } + // #endregion async activateMostEditedNotesView() { @@ -232,8 +233,9 @@ export default class TimeThings extends Plugin { if(!this.isEditing) { this.isEditing = true; this.startTime = moment.now(); - this.isDebugBuild && console.log(`Editing ${this.isEditing} with startTime ${this.startTime}`); + this.isDebugBuild && console.log(`Editing ${this.isEditing} with startTime `, moment(this.startTime).format(this.settings.modifiedKeyFormat)); } + this.isDebugBuild && console.log(`updateEditing: ${useCustomSolution ? "CAMS" : "BOMS"}`); this.updateFrontmatter(useCustomSolution, activeView); this.resetEditing(); } @@ -247,30 +249,34 @@ export default class TimeThings extends Plugin { let environment; useCustomSolution ? environment = activeView.editor : environment = activeView.file; + console.log('updateMetadata custom setting: ', this.settings.useCustomFrontmatterHandlingSolution); + console.log('updateMetadata CUSTOM parameter from event: ' , useCustomSolution); const editDiff = this.validEditDuration() if ( useCustomSolution && environment instanceof Editor ) { // CAMS: Custom Asset Management System + console.log("Calling CAMS handler"); if(editDiff !== null && editDiff >= 4) { // TODO: Add setting this.isDebugBuild && console.log(`Threshold reached with ${editDiff}, update modified property!`) - this.updateModifiedPropertyEditor(environment); + this.updateModifiedPropertyCAMS(environment); } if (this.settings.enableEditDurationKey) { - this.updateDurationPropertyEditor(environment); + this.updateDurationPropertyCAMS(environment); } } else if ( !useCustomSolution && environment instanceof TFile - ) { + ) { // BOMS: Build-in Object Management System + console.log("Calling BOMS handler"); if(editDiff !== null && editDiff >= 10) { // TODO: Add setting this.isDebugBuild && console.log(`Threshold reached with ${editDiff}, update modified property!`) - this.updateModifiedPropertyFrontmatter(environment); + this.updateModifiedPropertyBOMS(environment); } if (this.settings.enableEditDurationKey) { - this.updateDurationPropertyFrontmatter(environment); + this.updateDurationPropertyBOMS(environment); } } } @@ -280,24 +286,22 @@ export default class TimeThings extends Plugin { onUserActivity( useCustomSolution: boolean, activeView: MarkdownView, - options: { updateMetadata: boolean, updateStatusBar: boolean, } = { updateMetadata: true, updateStatusBar: true, }, + options: { updateMetadata: boolean, updateTypingIndicator: boolean, } = { updateMetadata: true, updateTypingIndicator: true, }, ) { - const { updateMetadata, updateStatusBar } = options; + const { updateMetadata, updateTypingIndicator } = options; let environment; useCustomSolution ? environment = activeView.editor : environment = activeView.file; - + // Check if the file is in the blacklisted folder // Check if the file has a property that puts it into a blacklist // Check if the file itself is in the blacklist - if (updateStatusBar) { - // this.isDebugBuild && console.log('--- Update status bar ---'); - // this.isDebugBuild && console.log("Update status bar, timeout: ", this.timeout); - } if (updateMetadata) { // Update metadata using either BOMS or CAMS - // this.isDebugBuild && console.log("Update metadata, timeout: ", this.timeout); - this.updateIcon(); + this.isDebugBuild && console.log(`UserActivity: ${useCustomSolution ? "CAMS" : "BOMS"}, with timeout ${this.timeout}`); + if(updateTypingIndicator) { + this.updateIcon(); + } this.updateEditing(useCustomSolution, activeView); } } @@ -307,8 +311,8 @@ export default class TimeThings extends Plugin { //#region Frontmatter update modified // CAMS - updateModifiedPropertyEditor(editor: Editor) { - this.isDebugBuild && console.log('CAMS: Update modified property!'); + updateModifiedPropertyCAMS(editor: Editor) { + this.isDebugBuild && console.log('--- CAMS: Update modified property! ---'); // With the old solution updating frontmatter keys only worked on BOMS! // todo: allow key changes const userDateFormat = this.settings.modifiedKeyFormat; // Target format. Existing format unknown and irrelevant. @@ -318,7 +322,7 @@ export default class TimeThings extends Plugin { } // BOMS (Default) - async updateModifiedPropertyFrontmatter(file: TFile) { + async updateModifiedPropertyBOMS(file: TFile) { this.isDebugBuild && console.log('--- BOMS: Update modified property! ---'); await this.app.fileManager.processFrontMatter( file as TFile, @@ -333,13 +337,9 @@ export default class TimeThings extends Plugin { //#region Frontmatter update duration - /* Date updating is delicate: Moment.js validity check might check an updated setting - against a pre-existing date and would return false. So it would never act on old documents. - Instead: Check existing duration for general validity. Add diff. Check if the new format is valid and display as such. - */ // CAMS - async updateDurationPropertyEditor(editor: Editor) { - this.isDebugBuild && console.log('CAMS: Update duration property!'); + async updateDurationPropertyCAMS(editor: Editor) { + this.isDebugBuild && console.log('--- CAMS: Update duration property! ---'); // With the old solution updating frontmatter keys only worked on BOMS! //TODO update @@ -381,28 +381,31 @@ export default class TimeThings extends Plugin { } // BOMS (Default) - async updateDurationPropertyFrontmatter(file: TFile) { + /* Date updating is delicate: Moment.js validity check might check an updated setting + against a pre-existing date and would return false. So it would never act on format changes. + Instead: Check existing duration for general validity. Increment. Display. (Format is validated in settings) + */ + async updateDurationPropertyBOMS(file: TFile) { + this.isDebugBuild && console.log('--- BOMS: Update duration property! ---'); - - // TODO update - // Slow update await this.app.fileManager.processFrontMatter( file as TFile, (frontmatter: any) => { // Fetch let value = BOMS.getValue(frontmatter, this.settings.editDurationKeyName); + // Zero if non-existent if (value === undefined) { - this.isDebugBuild && console.log('No edit_duration, initialize with 0.'); + this.isDebugBuild && console.log('No edit duration, initialize with 0.'); value = moment.duration(0); } - // Check validity - const userDateFormat = this.settings.editDurationKeyFormat; - if(moment(value, userDateFormat, true).isValid() === false) { - this.isDebugBuild && console.log("Wrong format for edit_duration property"); + // Check for general validity + if(!moment.duration(value).isValid()) { + console.log(`Unable to update ${this.settings.editDurationKeyName} due to invalid value of ${value}.`); return; } // Increment + const userDateFormat = this.settings.editDurationKeyFormat; const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, {trim: false}); this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`, 0); BOMS.setValue( @@ -425,6 +428,11 @@ export default class TimeThings extends Plugin { const dateChosen = this.settings.isUTC ? dateUTC : dateNow; const dateFormatted = dateChosen.format(this.settings.clockFormat); const emoji = timeUtils.momentToClockEmoji(dateChosen); + + this.clockBar.setText(emoji + " " + dateFormatted) + // this.settings.enableClock + // ? this.clockBar.setText(emoji + " " + dateFormatted) + // : this.clockBar.setText(dateFormatted); } // Typing indicator @@ -439,8 +447,8 @@ export default class TimeThings extends Plugin { // Called on OnLoad, adds status bar setUpStatusBarItems() { + // Clock if (this.settings.enableClock) { - // Add clock icon this.clockBar = this.addStatusBarItem(); this.clockBar.setText(timeUtils.momentToClockEmoji(moment())); @@ -453,9 +461,10 @@ export default class TimeThings extends Plugin { ), ); } + // Typing indicator if (this.settings.enableEditIndicator) { this.editIndicatorBar = this.addStatusBarItem(); - this.editIndicatorBar.setText(this.settings.editIndicatorActive); + this.editIndicatorBar.setText(this.settings.editIndicatorInactive); } } //#endregion @@ -478,11 +487,12 @@ export default class TimeThings extends Plugin { this.timeout = 10000; } - this.isDebugBuild && console.log("LOAD settings, timeout: ", this.timeout); + this.isDebugBuild && console.log("LOAD settings: ", this.timeout); // Because the methods are stored in a variable, the values inside the closure will be stale. // Reloading here keeps it fresh and decoupled from the settings file. this.updateFrontmatter = debounce((useCustomSolution: boolean, activeView: MarkdownView) => { if(this.startTime) { + this.isDebugBuild && console.log(`Update frontmatter using ${useCustomSolution ? "CAMS" : "BOMS"}`); this.updateMetadata(useCustomSolution, activeView); } }, this.timeout); @@ -491,7 +501,7 @@ export default class TimeThings extends Plugin { // Inactive typing this.editIndicatorBar.setText(this.settings.editIndicatorInactive); this.activityIconActive = false; - this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.activityIconActive); + this.isDebugBuild && console.log('Deactivate typing icon, active: ', this.activityIconActive, this.settings.editIndicatorInactive); }, this.timeout, true); this.resetEditing = debounce(() => { diff --git a/src/settings.ts b/src/settings.ts index 2194af4..8cd8c05 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -103,7 +103,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { else { // BOMS: Raise lower limit and bump if below description += " Switch to default frontmatter solution for values <10s."; - console.log(mySlider.getValue()); + // console.log("Slider lower limit: ", mySlider.getValue()); mySlider.setLimits(minTimeoutBoms, 90, 1); if(this.plugin.settings.typingTimeoutMilliseconds < minTimeoutBoms * 1000) { this.plugin.settings.typingTimeoutMilliseconds = minTimeoutBoms * 1000; @@ -119,7 +119,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .setName("Editing Timeout") .setDesc(description) .addSlider((slider) => mySlider = slider // implicit return without curlies - .setLimits(minTimeoutCams, 90, 1) + .setLimits(minTimeoutBoms, 90, 1) .setValue(this.plugin.settings.typingTimeoutMilliseconds / 1000) .onChange(async (value) => { this.plugin.settings.typingTimeoutMilliseconds = value * 1000; @@ -160,6 +160,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .onChange(async (newValue) => { this.plugin.settings.enableClock = newValue; await this.plugin.saveSettings(); + await this.plugin.loadSettings(); await this.display(); }), ); From b5ae28b71d2673cb2edb0f1abd68dfa95106477d Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:52:27 +0200 Subject: [PATCH 20/24] BOMS working, CAMS in progress --- src/main.ts | 132 +++++++++++++++++++++--------------------------- src/settings.ts | 62 ++++++++++++++++++----- 2 files changed, 106 insertions(+), 88 deletions(-) diff --git a/src/main.ts b/src/main.ts index 68e2adf..1a38591 100644 --- a/src/main.ts +++ b/src/main.ts @@ -97,16 +97,21 @@ export default class TimeThings extends Plugin { this.registerEvent( this.app.workspace.on("active-leaf-change", (leaf) => { // Prepare everything - const activeView = - this.app.workspace.getActiveViewOfType(MarkdownView); + const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); + const useCustom : boolean = this.settings.useCustomFrontmatterHandlingSolution; + this.isDebugBuild && console.log(`Key down, use: ${useCustom ? "CAMS" : "BOMS"}`); + if (activeView === null) { return; } - const editor = activeView.editor; - if (editor.hasFocus() === false) { - return; + + if(useCustom) { + const editor = activeView.editor; + if (editor.hasFocus() === false) { + return; + } } - this.onUserActivity(true, activeView); + this.onUserActivity(useCustom, activeView); }), ); } @@ -134,47 +139,46 @@ export default class TimeThings extends Plugin { return; } - this.isDebugBuild && console.log(`Key down: ${this.settings.useCustomFrontmatterHandlingSolution ? "CAMS" : "BOMS"}`); - if (this.settings.useCustomFrontmatterHandlingSolution === true) { - // Make sure the document is ready for edit - const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); - if (activeView === null) { - this.isDebugBuild && console.log("No active view"); - return; - } + // Make sure the document is ready for edit + const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); + const useCustom : boolean = this.settings.useCustomFrontmatterHandlingSolution; + // this.isDebugBuild && console.log(`Key down, use: ${useCustom ? "CAMS" : "BOMS"}`); + + if (activeView === null) { + this.isDebugBuild && console.log("No active view"); + return; + } + + if (useCustom) { const editor: Editor = activeView.editor; if (editor.hasFocus() === false) { this.isDebugBuild && console.log("No focus"); return; - } - - // Update everything - this.onUserActivity(true, activeView); - } else { - console.log('well, just use boms?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); + } } + this.onUserActivity(useCustom, activeView); }); } // BOMS - registerFileModificationEvent() { - // ! If BOMS is updated it triggers a new file modification event - this.registerEvent( - this.app.vault.on("modify", (file) => { - // Make everything ready for edit - const activeView = - this.app.workspace.getActiveViewOfType(MarkdownView); - if (activeView === null) { - return; - } - console.log('filemod'); - - if (this.settings.useCustomFrontmatterHandlingSolution === false) { - this.onUserActivity(false, activeView); - } - }), - ); - } + // registerFileModificationEvent() { + // // ! If BOMS is updated it triggers a new file modification event + // this.registerEvent( + // this.app.vault.on("modify", (file) => { + // // Make everything ready for edit + // const activeView = + // this.app.workspace.getActiveViewOfType(MarkdownView); + // if (activeView === null) { + // return; + // } + // console.log('filemod'); + + // if (this.settings.useCustomFrontmatterHandlingSolution === false) { + // this.onUserActivity(false, activeView); + // } + // }), + // ); + // } // NONE registerMouseDownDOMEvent() { @@ -221,10 +225,6 @@ export default class TimeThings extends Plugin { } } - // TODO: Check how the updateModificationDate is used and maybe change if it's updating too easily. - // Should only be updated on Keypresses or maybe keypresses with an overall usage > 30 seconds. - // (Hint: use old logic of aggregating change time) - //region Editing tracking @@ -235,7 +235,6 @@ export default class TimeThings extends Plugin { this.startTime = moment.now(); this.isDebugBuild && console.log(`Editing ${this.isEditing} with startTime `, moment(this.startTime).format(this.settings.modifiedKeyFormat)); } - this.isDebugBuild && console.log(`updateEditing: ${useCustomSolution ? "CAMS" : "BOMS"}`); this.updateFrontmatter(useCustomSolution, activeView); this.resetEditing(); } @@ -247,19 +246,18 @@ export default class TimeThings extends Plugin { updateMetadata (useCustomSolution: boolean, activeView: MarkdownView) { let environment; - useCustomSolution ? environment = activeView.editor : environment = activeView.file; - console.log('updateMetadata custom setting: ', this.settings.useCustomFrontmatterHandlingSolution); - console.log('updateMetadata CUSTOM parameter from event: ' , useCustomSolution); const editDiff = this.validEditDuration() + const modificationThreshold = this.settings.modifiedThreshold/1000; + if ( useCustomSolution && environment instanceof Editor ) { // CAMS: Custom Asset Management System console.log("Calling CAMS handler"); - if(editDiff !== null && editDiff >= 4) { // TODO: Add setting - this.isDebugBuild && console.log(`Threshold reached with ${editDiff}, update modified property!`) + if(editDiff !== null && editDiff >= modificationThreshold) { + this.isDebugBuild && console.log(`Modified property threshold reached with ${editDiff}s, update property!`) this.updateModifiedPropertyCAMS(environment); } if (this.settings.enableEditDurationKey) { @@ -271,8 +269,8 @@ export default class TimeThings extends Plugin { ) { // BOMS: Build-in Object Management System console.log("Calling BOMS handler"); - if(editDiff !== null && editDiff >= 10) { // TODO: Add setting - this.isDebugBuild && console.log(`Threshold reached with ${editDiff}, update modified property!`) + if(editDiff !== null && editDiff >= modificationThreshold) { + this.isDebugBuild && console.log(`Modified property threshold reached with ${editDiff}s, update property!`) this.updateModifiedPropertyBOMS(environment); } if (this.settings.enableEditDurationKey) { @@ -281,8 +279,7 @@ export default class TimeThings extends Plugin { } } - // A function for reading and editing metadata realtime - // Gets called when a user changes a leaf, clicks a mouse, types in the editor, or modifies a file + // Called on typing onUserActivity( useCustomSolution: boolean, activeView: MarkdownView, @@ -298,7 +295,7 @@ export default class TimeThings extends Plugin { if (updateMetadata) { // Update metadata using either BOMS or CAMS - this.isDebugBuild && console.log(`UserActivity: ${useCustomSolution ? "CAMS" : "BOMS"}, with timeout ${this.timeout}`); + // this.isDebugBuild && console.log(`UserActivity: ${useCustomSolution ? "CAMS" : "BOMS"}, with timeout ${this.timeout}`); if(updateTypingIndicator) { this.updateIcon(); } @@ -312,7 +309,7 @@ export default class TimeThings extends Plugin { // CAMS updateModifiedPropertyCAMS(editor: Editor) { - this.isDebugBuild && console.log('--- CAMS: Update modified property! ---'); + this.isDebugBuild && console.log('*** CAMS: Update modified property! ***'); // With the old solution updating frontmatter keys only worked on BOMS! // todo: allow key changes const userDateFormat = this.settings.modifiedKeyFormat; // Target format. Existing format unknown and irrelevant. @@ -323,7 +320,7 @@ export default class TimeThings extends Plugin { // BOMS (Default) async updateModifiedPropertyBOMS(file: TFile) { - this.isDebugBuild && console.log('--- BOMS: Update modified property! ---'); + this.isDebugBuild && console.log('*** BOMS: Update modified property! ***'); await this.app.fileManager.processFrontMatter( file as TFile, (frontmatter) => { @@ -339,7 +336,7 @@ export default class TimeThings extends Plugin { // CAMS async updateDurationPropertyCAMS(editor: Editor) { - this.isDebugBuild && console.log('--- CAMS: Update duration property! ---'); + this.isDebugBuild && console.log('*** CAMS: Update duration property! ***'); // With the old solution updating frontmatter keys only worked on BOMS! //TODO update @@ -349,34 +346,19 @@ export default class TimeThings extends Plugin { const fieldLine: number | undefined = CAMS.getLine(editor, this.settings.editDurationKeyName); const userDateFormat = this.settings.editDurationKeyFormat; let newValue : any; - - console.log("---------------------------") - console.log('frontmatter', CAMS.getLine(editor, this.settings.editDurationKeyName)); - console.log('frontmatter2', CAMS.getLine(editor, this.settings.editDurationKeyName)) - - - console.log('key name: ', this.settings.editDurationKeyName); - console.log('cams prop', CAMS.getLine(editor, this.settings.editDurationKeyName)); - console.log('editor fieldline', (CAMS.getLine(editor, this.settings.editDurationKeyName))); if(fieldLine === undefined) { console.log(`Undefined value for ${this.settings.editDurationKeyName}`); newValue = moment.duration(0, "minutes").format(userDateFormat, { trim: false }) - console.log('set value here'); - - CAMS.setValue(editor, "welltest", newValue); - } else { newValue = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); - const test = moment(newValue, userDateFormat, true).isValid() - console.log("test vlaid? ", test) + // const test = moment(newValue, userDateFormat, true).isValid() } - this.isDebugBuild && console.log(`Current edit duration ${newValue} and current/new formatter ${userDateFormat}`); // Increment & set const incremented = moment.duration(newValue).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format - this.isDebugBuild && console.log(`Increment CAMS from ${newValue} to ${incremented}`); + this.isDebugBuild && console.log(`Increment CAMS edit duration from ${newValue} to ${incremented}`); CAMS.setValue(editor, this.settings.editDurationKeyName, incremented.toString()); } @@ -387,7 +369,7 @@ export default class TimeThings extends Plugin { */ async updateDurationPropertyBOMS(file: TFile) { - this.isDebugBuild && console.log('--- BOMS: Update duration property! ---'); + this.isDebugBuild && console.log('*** BOMS: Update duration property! ***'); // Slow update await this.app.fileManager.processFrontMatter( file as TFile, @@ -407,7 +389,7 @@ export default class TimeThings extends Plugin { // Increment const userDateFormat = this.settings.editDurationKeyFormat; const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, {trim: false}); - this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`, 0); + this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`); BOMS.setValue( frontmatter, this.settings.editDurationKeyName, diff --git a/src/settings.ts b/src/settings.ts index 8cd8c05..55c12ed 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -16,6 +16,7 @@ export interface TimeThingsSettings { enableModifiedKey: boolean; modifiedKeyName: string; modifiedKeyFormat: string; + modifiedThreshold: number; // todo: add settings field //DURATION KEY enableEditDurationKey: boolean; @@ -39,6 +40,7 @@ export const DEFAULT_SETTINGS: TimeThingsSettings = { modifiedKeyName: "updated_at", modifiedKeyFormat: "YYYY-MM-DD[T]HH:mm:ss.SSSZ", enableModifiedKey: true, + modifiedThreshold: 30000, editDurationKeyName: "edited_seconds", editDurationKeyFormat: "HH:mm:ss", @@ -81,8 +83,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { // #region custom frontmatter solution let mySlider : SliderComponent; let myText: TextComponent; - let description = "In seconds. Time to stop tracking after interaction has stopped. Value also used for saving interval. Textbox allows for higher values." - const minTimeoutBoms = 10; + const minTimeoutBoms = 10; // Not sure const minTimeoutCams = 1; new Setting(containerEl) @@ -102,7 +103,6 @@ export class TimeThingsSettingsTab extends PluginSettingTab { } else { // BOMS: Raise lower limit and bump if below - description += " Switch to default frontmatter solution for values <10s."; // console.log("Slider lower limit: ", mySlider.getValue()); mySlider.setLimits(minTimeoutBoms, 90, 1); if(this.plugin.settings.typingTimeoutMilliseconds < minTimeoutBoms * 1000) { @@ -116,15 +116,25 @@ export class TimeThingsSettingsTab extends PluginSettingTab { ); new Setting(containerEl.createDiv({cls: "textbox"})) - .setName("Editing Timeout") - .setDesc(description) - .addSlider((slider) => mySlider = slider // implicit return without curlies - .setLimits(minTimeoutBoms, 90, 1) - .setValue(this.plugin.settings.typingTimeoutMilliseconds / 1000) - .onChange(async (value) => { - this.plugin.settings.typingTimeoutMilliseconds = value * 1000; - myText.setValue(value.toString()); - await this.plugin.saveSettings(); + .setName("Editing Timeout") + .setDesc("In seconds. Time to stop tracking after interaction has stopped. Value also used for saving interval. Textbox allows for higher values.") + .addSlider((slider) => mySlider = slider // implicit return without curlies + .setLimits(minTimeoutBoms, 90, 1) + .setValue(this.plugin.settings.typingTimeoutMilliseconds / 1000) + .onChange(async (value) => { + myText.setValue(value.toString()); + // Validity check including BOMS limit + const useCustom = this.plugin.settings.useCustomFrontmatterHandlingSolution; + if( + value < (useCustom? minTimeoutCams : minTimeoutBoms) + || isNaN(value) + ) { + myText.inputEl.addClass('invalid-format'); + } else { + myText.inputEl.removeClass('invalid-format'); + this.plugin.settings.typingTimeoutMilliseconds = value * 1000; + await this.plugin.saveSettings(); + } }) .setDynamicTooltip(), ) @@ -246,7 +256,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { containerEl.createEl("h1", { text: "Frontmatter" }); containerEl.createEl("p", { text: "Handles timestamp keys in frontmatter." }); - // #region updated_at key + // #region frontmatter modification timestamp containerEl.createEl("h2", { text: "🔑 Modified timestamp" }); containerEl.createEl("p", { text: "Track the last time a note was edited." }); @@ -300,6 +310,32 @@ export class TimeThingsSettingsTab extends PluginSettingTab { } }), ) + + let thresholdText: TextComponent; + new Setting(containerEl.createDiv({cls: "textbox"})) + .setName("Date refresh threshold") + .setDesc("Active typing duration that must be exceeded in one continuous period for the modification date to be updated. Will always be updated if lower than the editing timeout.") + .addSlider((slider) => slider // implicit return without curlies + .setLimits(0, 60, 1) + .setValue(this.plugin.settings.modifiedThreshold / 1000) + .onChange(async (value) => { + this.plugin.settings.modifiedThreshold = value * 1000; + thresholdText.setValue(value.toString()); + await this.plugin.saveSettings(); + }) + .setDynamicTooltip(), + ) + .addText((text) => { + thresholdText = text + .setPlaceholder("30") + .setValue((this.plugin.settings.modifiedThreshold/1000).toString(),) + .onChange(async (value) => { + const numericValue = parseInt(value, 10); + this.plugin.settings.modifiedThreshold = numericValue * 1000; + mySlider.setValue(numericValue); + await this.plugin.saveSettings(); + }) + }); } // #endregion From b964cbd6e7f65191f1d4b1a2a8625a97ad4a97bd Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:25:23 +0200 Subject: [PATCH 21/24] CAMS doesnt handle frontmatter creation and only works on modified. Backup before adding this --- src/CAMS.ts | 2 ++ src/main.ts | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/CAMS.ts b/src/CAMS.ts index fbb07f6..7008e5c 100644 --- a/src/CAMS.ts +++ b/src/CAMS.ts @@ -91,9 +91,11 @@ export function setValue(editor: Editor, fieldPath: string, fieldValue: string,) // The thing with this function is that it uses the format from settings to check against. I can make it as an argument that can be passed, or better yet, eradicate the check from the function to make it more atomic and place it somewhere else in the main code. const fieldLine = getLine(editor, fieldPath); if (fieldLine === undefined) { + console.log("!!!fieldline undefined"); // TODO: delete return; } const initialLine = editor.getLine(fieldLine).split(":", 1); const newLine = initialLine[0] + ": " + fieldValue; + console.log('!!!fieldline/newline', fieldLine, newLine); editor.setLine(fieldLine, newLine); } diff --git a/src/main.ts b/src/main.ts index 1a38591..18c180d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -250,10 +250,7 @@ export default class TimeThings extends Plugin { const editDiff = this.validEditDuration() const modificationThreshold = this.settings.modifiedThreshold/1000; - if ( - useCustomSolution && - environment instanceof Editor - ) { + if (useCustomSolution && environment instanceof Editor) { // CAMS: Custom Asset Management System console.log("Calling CAMS handler"); if(editDiff !== null && editDiff >= modificationThreshold) { @@ -263,10 +260,7 @@ export default class TimeThings extends Plugin { if (this.settings.enableEditDurationKey) { this.updateDurationPropertyCAMS(environment); } - } else if ( - !useCustomSolution && - environment instanceof TFile - ) { + } else if (!useCustomSolution && environment instanceof TFile) { // BOMS: Build-in Object Management System console.log("Calling BOMS handler"); if(editDiff !== null && editDiff >= modificationThreshold) { @@ -315,6 +309,13 @@ export default class TimeThings extends Plugin { const userDateFormat = this.settings.modifiedKeyFormat; // Target format. Existing format unknown and irrelevant. const userModifiedKeyName = this.settings.modifiedKeyName; const dateFormatted = moment().format(userDateFormat); + + const fetched = CAMS.getLine(editor, this.settings.modifiedKeyName) + if(fetched === undefined) { + // TODO: Initialize somehow, cause it's not crfeated by using CAMS! + console.log("!!!Attempt to init frontmatter"); + BOMS.setValue(editor, userModifiedKeyName, dateFormatted); + } CAMS.setValue(editor, userModifiedKeyName, dateFormatted); } @@ -326,7 +327,7 @@ export default class TimeThings extends Plugin { (frontmatter) => { const dateFormatted = moment().format(this.settings.modifiedKeyFormat); // BOMS creates key if it doesn't exist - BOMS.setValue(frontmatter,this.settings.modifiedKeyName, dateFormatted); + BOMS.setValue(frontmatter, this.settings.modifiedKeyName, dateFormatted); }, ); } @@ -368,7 +369,6 @@ export default class TimeThings extends Plugin { Instead: Check existing duration for general validity. Increment. Display. (Format is validated in settings) */ async updateDurationPropertyBOMS(file: TFile) { - this.isDebugBuild && console.log('*** BOMS: Update duration property! ***'); // Slow update await this.app.fileManager.processFrontMatter( From 25b224c952f43362f1731445e9fa6f82a4281d2b Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:02:02 +0200 Subject: [PATCH 22/24] CAMS standalone frontmatter handling --- src/CAMS.ts | 75 +++++++++++++++++++++++++++++++++++++---------------- src/main.ts | 4 +-- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/CAMS.ts b/src/CAMS.ts index 7008e5c..d40b6d5 100644 --- a/src/CAMS.ts +++ b/src/CAMS.ts @@ -1,9 +1,5 @@ import { Editor } from "obsidian"; -export function isLineIndented(line: string): boolean { - return /^[\s\t]/.test(line); -} - export function getLine(editor: Editor, fieldPath: string): number | undefined { const frontmatterLine = frontmatterEndLine(editor); const keys = fieldPath.split("."); @@ -25,13 +21,10 @@ export function getLine(editor: Editor, fieldPath: string): number | undefined { if (currentFieldName === key) { emergingPath.push(currentFieldName); const targetPath = fieldPath.split("."); - const targetPathShrink = targetPath.slice( - 0, - emergingPath.length, - ); + const targetPathShrink = targetPath.slice(0, emergingPath.length); if ( - (targetPathShrink.join(".") === emergingPath.join(".")) === - false + (targetPathShrink.join(".") === emergingPath.join(".")) + === false ) { emergingPath.pop(); startLine = i + 1; @@ -63,10 +56,31 @@ export function getLine(editor: Editor, fieldPath: string): number | undefined { return undefined; } -export function isFrontmatterPresent(editor: Editor): boolean { +export function setLine(editor: Editor, fieldPath: string, fieldValue: string,) { + // Check for frontmatter + if(!isFrontmatterPresent(editor)) { + // Create empty frontmatter + editor.setLine(0, "---\n---\n"); + } + // Check for path + if(!fieldPathPresent(editor, fieldPath)) { + appendNewLine(editor, fieldPath, fieldValue); + } else { + overrideCurrentLine(editor, fieldPath, fieldValue); + } +} + +//#region private +function isLineIndented(line: string): boolean { + return /^[\s\t]/.test(line); +} + + +function isFrontmatterPresent(editor: Editor): boolean { if (editor.getLine(0) !== "---") { return false; } + for (let i = 1; i <= editor.lastLine(); i++) { if (editor.getLine(i) === "---") { return true; @@ -75,7 +89,7 @@ export function isFrontmatterPresent(editor: Editor): boolean { return false; } -export function frontmatterEndLine(editor: Editor): number | undefined { +function frontmatterEndLine(editor: Editor): number | undefined { if (isFrontmatterPresent(editor)) { for (let i = 1; i <= editor.lastLine(); i++) { if (editor.getLine(i) === "---") { @@ -86,16 +100,31 @@ export function frontmatterEndLine(editor: Editor): number | undefined { return undefined; // # End line not found } +function fieldPathPresent(editor: Editor, fieldPath: string): boolean { + const pathValue = getLine(editor, fieldPath) + if(pathValue) { + return true; + } + return false; +} -export function setValue(editor: Editor, fieldPath: string, fieldValue: string,) { - // The thing with this function is that it uses the format from settings to check against. I can make it as an argument that can be passed, or better yet, eradicate the check from the function to make it more atomic and place it somewhere else in the main code. - const fieldLine = getLine(editor, fieldPath); - if (fieldLine === undefined) { - console.log("!!!fieldline undefined"); // TODO: delete - return; - } - const initialLine = editor.getLine(fieldLine).split(":", 1); - const newLine = initialLine[0] + ": " + fieldValue; - console.log('!!!fieldline/newline', fieldLine, newLine); - editor.setLine(fieldLine, newLine); +function appendNewLine(editor: Editor, fieldPath: string, fieldValue: string) { + const endLine = frontmatterEndLine(editor); + if(!endLine) { + console.log("No frontmatter endline found!"); + return; + } + editor.setLine(endLine, fieldPath + ": " + fieldValue + "\n---"); +} + +function overrideCurrentLine(editor: Editor, fieldPath: string, fieldValue: string) { + const currentValue = getLine(editor, fieldPath); + if (currentValue === undefined) { + console.log("Value not found!"); + return; + } + const initialLine = editor.getLine(currentValue).split(":", 1); + const newLine = initialLine[0] + ": " + fieldValue; + editor.setLine(currentValue, newLine); } +//#endregion \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 18c180d..0ec683a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -316,7 +316,7 @@ export default class TimeThings extends Plugin { console.log("!!!Attempt to init frontmatter"); BOMS.setValue(editor, userModifiedKeyName, dateFormatted); } - CAMS.setValue(editor, userModifiedKeyName, dateFormatted); + CAMS.setLine(editor, userModifiedKeyName, dateFormatted); } // BOMS (Default) @@ -360,7 +360,7 @@ export default class TimeThings extends Plugin { // Increment & set const incremented = moment.duration(newValue).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format this.isDebugBuild && console.log(`Increment CAMS edit duration from ${newValue} to ${incremented}`); - CAMS.setValue(editor, this.settings.editDurationKeyName, incremented.toString()); + CAMS.setLine(editor, this.settings.editDurationKeyName, incremented.toString()); } // BOMS (Default) From d07dbae2ff6cff0508d05cb2a4f552a0277bd340 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Tue, 10 Sep 2024 18:49:07 +0200 Subject: [PATCH 23/24] Formatting, commenting --- src/main.ts | 55 ++++++++++++++++++------------------------------- src/settings.ts | 31 ++++++++++++---------------- 2 files changed, 33 insertions(+), 53 deletions(-) diff --git a/src/main.ts b/src/main.ts index 0ec683a..8769280 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,6 @@ import { WorkspaceLeaf, Plugin, TFile, - Notice, debounce, moment } from "obsidian"; @@ -43,7 +42,6 @@ export default class TimeThings extends Plugin { updateFrontmatter: (useCustomSolution: boolean, activeView: MarkdownView) => void; resetEditing: () => void; resetIcon: () => void; - //#region Load plugin @@ -74,7 +72,7 @@ export default class TimeThings extends Plugin { ); // Variables initialization - this.isDebugBuild = true; // for debugging purposes TODO: reset + this.isDebugBuild = false; // for debugging purposes TODO: reset // Set up Status Bar items this.setUpStatusBarItems(); @@ -160,6 +158,7 @@ export default class TimeThings extends Plugin { }); } + // UNUSED // BOMS // registerFileModificationEvent() { // // ! If BOMS is updated it triggers a new file modification event @@ -180,7 +179,7 @@ export default class TimeThings extends Plugin { // ); // } - // NONE + // UNUSED registerMouseDownDOMEvent() { this.registerDomEvent(document, "mousedown", (evt: MouseEvent) => { // Prepare everything @@ -227,7 +226,6 @@ export default class TimeThings extends Plugin { //region Editing tracking - updateEditing(useCustomSolution: boolean, activeView: MarkdownView) { // Save current time only once, regardless of repeated calls (flag) if(!this.isEditing) { @@ -252,7 +250,7 @@ export default class TimeThings extends Plugin { if (useCustomSolution && environment instanceof Editor) { // CAMS: Custom Asset Management System - console.log("Calling CAMS handler"); + this.isDebugBuild && console.log("Calling CAMS handler"); if(editDiff !== null && editDiff >= modificationThreshold) { this.isDebugBuild && console.log(`Modified property threshold reached with ${editDiff}s, update property!`) this.updateModifiedPropertyCAMS(environment); @@ -262,7 +260,7 @@ export default class TimeThings extends Plugin { } } else if (!useCustomSolution && environment instanceof TFile) { // BOMS: Build-in Object Management System - console.log("Calling BOMS handler"); + this.isDebugBuild && console.log("Calling BOMS handler"); if(editDiff !== null && editDiff >= modificationThreshold) { this.isDebugBuild && console.log(`Modified property threshold reached with ${editDiff}s, update property!`) this.updateModifiedPropertyBOMS(environment); @@ -300,22 +298,13 @@ export default class TimeThings extends Plugin { //#region Frontmatter update modified - // CAMS updateModifiedPropertyCAMS(editor: Editor) { this.isDebugBuild && console.log('*** CAMS: Update modified property! ***'); // With the old solution updating frontmatter keys only worked on BOMS! - // todo: allow key changes const userDateFormat = this.settings.modifiedKeyFormat; // Target format. Existing format unknown and irrelevant. const userModifiedKeyName = this.settings.modifiedKeyName; const dateFormatted = moment().format(userDateFormat); - - const fetched = CAMS.getLine(editor, this.settings.modifiedKeyName) - if(fetched === undefined) { - // TODO: Initialize somehow, cause it's not crfeated by using CAMS! - console.log("!!!Attempt to init frontmatter"); - BOMS.setValue(editor, userModifiedKeyName, dateFormatted); - } CAMS.setLine(editor, userModifiedKeyName, dateFormatted); } @@ -331,42 +320,35 @@ export default class TimeThings extends Plugin { }, ); } - //#region Frontmatter update duration // CAMS async updateDurationPropertyCAMS(editor: Editor) { this.isDebugBuild && console.log('*** CAMS: Update duration property! ***'); - // With the old solution updating frontmatter keys only worked on BOMS! - - //TODO update - - - // Fetch edit duration + // With the old solution updating frontmatter keys only worked on BOMS! + // Fetch duration const fieldLine: number | undefined = CAMS.getLine(editor, this.settings.editDurationKeyName); const userDateFormat = this.settings.editDurationKeyFormat; let newValue : any; - + // Check for existing if(fieldLine === undefined) { - console.log(`Undefined value for ${this.settings.editDurationKeyName}`); newValue = moment.duration(0, "minutes").format(userDateFormat, { trim: false }) } else { newValue = editor.getLine(fieldLine).split(/:(.*)/s)[1].trim(); - // const test = moment(newValue, userDateFormat, true).isValid() } - this.isDebugBuild && console.log(`Current edit duration ${newValue} and current/new formatter ${userDateFormat}`); - // Increment & set - const incremented = moment.duration(newValue).add(this.timeout, 'milliseconds').format(userDateFormat, { trim: false }); // Always stick to given format - this.isDebugBuild && console.log(`Increment CAMS edit duration from ${newValue} to ${incremented}`); + const incremented = moment.duration(newValue) + .add(this.timeout, 'milliseconds') + .format(userDateFormat, { trim: false }); // Force formatting + this.isDebugBuild && console.log(`Increment CAMS edit duration from ${newValue} to ${incremented} with formatter ${userDateFormat}`); CAMS.setLine(editor, this.settings.editDurationKeyName, incremented.toString()); } // BOMS (Default) - /* Date updating is delicate: Moment.js validity check might check an updated setting - against a pre-existing date and would return false. So it would never act on format changes. - Instead: Check existing duration for general validity. Increment. Display. (Format is validated in settings) + /* Date updating is delicate: Moment.js validity check might check an updated formatter + against a pre-existing date and would return false. So it would never act after format changes. + Instead: Check existing duration for general validity. Increment. Display in the given, pre-validated format. */ async updateDurationPropertyBOMS(file: TFile) { this.isDebugBuild && console.log('*** BOMS: Update duration property! ***'); @@ -388,7 +370,10 @@ export default class TimeThings extends Plugin { } // Increment const userDateFormat = this.settings.editDurationKeyFormat; - const incremented = moment.duration(value).add(this.timeout, 'milliseconds').format(userDateFormat, {trim: false}); + const incremented = moment + .duration(value) + .add(this.timeout, 'milliseconds') + .format(userDateFormat, {trim: false}); this.isDebugBuild && console.log(`Increment BOMS from ${value} to ${incremented}`); BOMS.setValue( frontmatter, @@ -465,7 +450,7 @@ export default class TimeThings extends Plugin { this.timeout = this.settings?.typingTimeoutMilliseconds; if(!this.timeout || isNaN(this.timeout) || this.timeout === undefined) { - console.log(`Timeout setting ${this.timeout} invalid, fallback!`); + this.isDebugBuild && console.log(`Timeout setting ${this.timeout} invalid, fallback!`); this.timeout = 10000; } diff --git a/src/settings.ts b/src/settings.ts index 55c12ed..c2c5b6f 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -16,7 +16,7 @@ export interface TimeThingsSettings { enableModifiedKey: boolean; modifiedKeyName: string; modifiedKeyFormat: string; - modifiedThreshold: number; // todo: add settings field + modifiedThreshold: number; //DURATION KEY enableEditDurationKey: boolean; @@ -64,7 +64,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { const { containerEl } = this; containerEl.empty(); - // #region prerequisites + // #region Prerequisites const createLink = () => { const linkEl = document.createDocumentFragment(); @@ -80,7 +80,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { - // #region custom frontmatter solution + // #region General let mySlider : SliderComponent; let myText: TextComponent; const minTimeoutBoms = 10; // Not sure @@ -108,7 +108,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { if(this.plugin.settings.typingTimeoutMilliseconds < minTimeoutBoms * 1000) { this.plugin.settings.typingTimeoutMilliseconds = minTimeoutBoms * 1000; myText.setValue(minTimeoutBoms.toString()); - console.log("Bump BOMS timeout", this.plugin.settings.typingTimeoutMilliseconds); + // console.log("Bump BOMS timeout", this.plugin.settings.typingTimeoutMilliseconds); } } await this.plugin.saveSettings(); @@ -149,12 +149,10 @@ export class TimeThingsSettingsTab extends PluginSettingTab { await this.plugin.saveSettings(); }) }); - - // #endregion - // #region status bar + // #region Status bar containerEl.createEl("h1", { text: "Status bar" }); containerEl.createEl("p", { text: "Display symbols in the status bar" }); containerEl.createEl("h2", { text: "🕰️ Clock" }); @@ -232,7 +230,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .setPlaceholder("Active") .setValue(this.plugin.settings.editIndicatorActive) .onChange(async (value) => { - console.log('update active tracking icon: ', value) + // console.log('update active tracking icon: ', value) this.plugin.settings.editIndicatorActive = value; await this.plugin.saveSettings(); }), @@ -242,8 +240,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { .setPlaceholder("Inactive") .setValue(this.plugin.settings.editIndicatorInactive) .onChange(async (value) => { - console.log('update inactive tracking icon: ', value) - + // console.log('update inactive tracking icon: ', value) this.plugin.settings.editIndicatorInactive = value; await this.plugin.saveSettings(); }), @@ -252,17 +249,16 @@ export class TimeThingsSettingsTab extends PluginSettingTab { // #endregion - // #region keys + // #region Frontmatter containerEl.createEl("h1", { text: "Frontmatter" }); containerEl.createEl("p", { text: "Handles timestamp keys in frontmatter." }); - // #region frontmatter modification timestamp + // Modified timestamp containerEl.createEl("h2", { text: "🔑 Modified timestamp" }); containerEl.createEl("p", { text: "Track the last time a note was edited." }); - new Setting(containerEl) - .setName("Enable update of the modified key") // TODO: only update after a certain amount has passed? Otherwise pretty useless depending on what triggers the tracking. I think mouse doesn't! + .setName("Enable update of the modified key") .setDesc("") .addToggle((toggle) => toggle @@ -314,7 +310,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { let thresholdText: TextComponent; new Setting(containerEl.createDiv({cls: "textbox"})) .setName("Date refresh threshold") - .setDesc("Active typing duration that must be exceeded in one continuous period for the modification date to be updated. Will always be updated if lower than the editing timeout.") + .setDesc("Active typing duration that must be exceeded in one continuous period for the modification date to be updated.") .addSlider((slider) => slider // implicit return without curlies .setLimits(0, 60, 1) .setValue(this.plugin.settings.modifiedThreshold / 1000) @@ -339,7 +335,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { } // #endregion - // #region edited_duration key + // Edit duration containerEl.createEl("h2", { text: "🔑 Edited duration" }); containerEl.createEl("p", { text: "Track for how long you have been editing a note.", @@ -399,8 +395,7 @@ export class TimeThingsSettingsTab extends PluginSettingTab { // #endregion - // #region danger zone - + // #region Danger zone containerEl.createEl("h1", { text: "Danger zone" }); containerEl.createEl("p", { text: "You've been warned!" }); From 29b048dc74a8ab67f71842f2935869cd56bde749 Mon Sep 17 00:00:00 2001 From: rupel <23055682+rupel190@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:35:24 +0200 Subject: [PATCH 24/24] Update manifest (authors, ...) --- manifest.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/manifest.json b/manifest.json index 46e819f..c99acdd 100644 --- a/manifest.json +++ b/manifest.json @@ -1,11 +1,11 @@ { "id": "timethings", "name": "Time Things", - "version": "1.3.0", + "version": "2.0.0", "minAppVersion": "0.15.0", - "description": "Show clock in the corner. Track total editing time of a note and the last time it was modified.", - "author": "Nick Winters", - "authorUrl": "https://github.com/plasmabit", - "fundingUrl": "https://www.patreon.com/nickwinters", + "description": "Track total editing time of a note and the last time it was modified. Show clock and/or editing indicator in the corner", + "author": "Nick Winters, Rupel Rupelsson", + "authorUrl": "https://github.com/plasmabit, https://github.com/rupel190", + "fundingUrl": "https://www.patreon.com/nickwinters, https://ko-fi.com/rupel190", "isDesktopOnly": true }