diff --git a/src/editor/EditorPlugin.ts b/src/editor/EditorPlugin.ts index 29336ef..28c429f 100644 --- a/src/editor/EditorPlugin.ts +++ b/src/editor/EditorPlugin.ts @@ -33,7 +33,7 @@ class EditorPlugin implements PluginValue { while (!textIter.done) { text = text + textIter.next().value; } - this.plugin.statusBar.updateStatusBar(text); + this.plugin.statusBar.debounceStatusBarUpdate(text); } else if ( tr.isUserEvent("input") || tr.isUserEvent("delete") || @@ -48,9 +48,9 @@ class EditorPlugin implements PluginValue { text = text + textIter.next().value; } if (tr.docChanged && this.plugin.statsManager) { - this.plugin.statsManager.change(text); + this.plugin.statsManager.debounceChange(text); } - this.plugin.statusBar.updateStatusBar(text); + this.plugin.statusBar.debounceStatusBarUpdate(text); } } diff --git a/src/main.ts b/src/main.ts index 01c8288..2a04b80 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { Plugin } from "obsidian"; +import { Plugin, TFile, WorkspaceLeaf } from "obsidian"; import BetterWordCountSettingsTab from "./settings/SettingsTab"; import StatsManager from "./stats/StatsManager"; import StatusBar from "./status/StatusBar"; @@ -14,11 +14,10 @@ export default class BetterWordCount extends Plugin { public statusBar: StatusBar; public statsManager: StatsManager; - // onunload(): void { - // this.app.workspace - // .getLeavesOfType(VIEW_TYPE_STATS) - // .forEach((leaf) => leaf.detach()); - // } + async onunload(): Promise { + this.statsManager = null; + this.statusBar = null; + } async onload() { // Handle Settings @@ -38,12 +37,37 @@ export default class BetterWordCount extends Plugin { this.registerEditorExtension(editorPlugin); this.app.workspace.onLayoutReady(() => { - //@ts-expect-error, not typed - const editorView = this.app.workspace.getMostRecentLeaf().view.editor - .cm as EditorView; + this.giveEditorPlugin(this.app.workspace.getMostRecentLeaf()); + }); + + this.registerEvent( + this.app.workspace.on( + "active-leaf-change", + async (leaf: WorkspaceLeaf) => { + await this.statsManager.recalcTotals(); + this.giveEditorPlugin(leaf); + } + ) + ); + + this.registerEvent( + this.app.vault.on("delete", async () => { + await this.statsManager.recalcTotals(); + }) + ); + } + + giveEditorPlugin(leaf: WorkspaceLeaf): void { + //@ts-expect-error, not typed + const editor = leaf.view.editor; + if (editor) { + const editorView = editor.cm as EditorView; const editorPlug = editorView.plugin(editorPlugin); editorPlug.addPlugin(this); - }); + //@ts-expect-error, not typed + const data: string = leaf.view.data; + this.statusBar.updateStatusBar(data); + } } async saveSettings(): Promise { diff --git a/src/stats/StatsManager.ts b/src/stats/StatsManager.ts index 3c7197b..0075901 100644 --- a/src/stats/StatsManager.ts +++ b/src/stats/StatsManager.ts @@ -1,4 +1,4 @@ -import type { Vault, TFile, Workspace } from "obsidian"; +import { debounce, Debouncer, TFile, Vault, Workspace } from "obsidian"; import { STATS_FILE } from "../constants"; import type { Day, @@ -16,11 +16,12 @@ export default class StatsManager { private workspace: Workspace; private vaultStats: VaultStatistics; private today: string; - // public debounceChange: Debouncer<[file: TFile, data: string]>; + public debounceChange; constructor(vault: Vault, workspace: Workspace) { this.vault = vault; this.workspace = workspace; + this.debounceChange = debounce((text:string) => this.change(text), 50, false) this.vault.adapter.exists(STATS_FILE).then(async (exists) => { if (!exists) { @@ -52,7 +53,6 @@ export default class StatsManager { const totalWords = await this.calcTotalWords(); const totalCharacters = await this.calcTotalCharacters(); const totalSentences = await this.calcTotalSentences(); - const totalFiles = this.getTotalFiles(); const newDay: Day = { words: 0, @@ -133,6 +133,22 @@ export default class StatsManager { } } + public async recalcTotals() { + if (!this.vaultStats) return; + if ( + this.vaultStats.history.hasOwnProperty(this.today) && + this.today === moment().format("YYYY-MM-DD") + ) { + const todayHist: Day = this.vaultStats.history[this.today]; + todayHist.totalWords = await this.calcTotalWords(); + todayHist.totalCharacters = await this.calcTotalCharacters() + todayHist.totalSentences = await this.calcTotalSentences() + this.update(); + } else { + this.updateToday(); + } + } + private async calcTotalWords(): Promise { let words = 0; @@ -176,15 +192,18 @@ export default class StatsManager { return this.vault.getMarkdownFiles().length; } - public getTotalWords(): number { + public async getTotalWords(): Promise { + if (!this.vaultStats) return await this.calcTotalWords(); return this.vaultStats.history[this.today].totalWords; } - public getTotalCharacters(): number { + public async getTotalCharacters(): Promise { + if (!this.vaultStats) return await this.calcTotalCharacters(); return this.vaultStats.history[this.today].totalCharacters; } - public getTotalSentences(): number { + public async getTotalSentences(): Promise { + if (!this.vaultStats) return await this.calcTotalSentences(); return this.vaultStats.history[this.today].totalSentences; } } diff --git a/src/status/StatusBar.ts b/src/status/StatusBar.ts index 624d36a..c87c2db 100644 --- a/src/status/StatusBar.ts +++ b/src/status/StatusBar.ts @@ -5,14 +5,21 @@ import { getCharacterCount, getSentenceCount, } from "src/utils/StatUtils"; +import { debounce } from "obsidian"; export default class StatusBar { private statusBarEl: HTMLElement; private plugin: BetterWordCount; + public debounceStatusBarUpdate; constructor(statusBarEl: HTMLElement, plugin: BetterWordCount) { this.statusBarEl = statusBarEl; this.plugin = plugin; + this.debounceStatusBarUpdate = debounce( + (text: string) => this.updateStatusBar(text), + 20, + false + ); this.statusBarEl.classList.add("mod-clickable"); this.statusBarEl.setAttribute("aria-label", "Open Stats View"); @@ -30,7 +37,7 @@ export default class StatusBar { this.statusBarEl.setText(text); } - updateStatusBar(text: string) { + async updateStatusBar(text: string) { const sb = this.plugin.settings.statusBar; let display = ""; @@ -49,13 +56,15 @@ export default class StatusBar { display = display + getSentenceCount(text); break; case Counter.totalWords: - display = display + this.plugin.statsManager.getTotalWords(); + display = display + (await this.plugin.statsManager.getTotalWords()); break; case Counter.totalChars: - display = display + this.plugin.statsManager.getTotalCharacters(); + display = + display + (await this.plugin.statsManager.getTotalCharacters()); break; case Counter.totalSentences: - display = display + this.plugin.statsManager.getTotalSentences(); + display = + display + (await this.plugin.statsManager.getTotalSentences()); break; case Counter.totalNotes: display = display + this.plugin.statsManager.getTotalFiles();