diff --git a/src/main.ts b/src/main.ts index 22f0212..c10d284 100644 --- a/src/main.ts +++ b/src/main.ts @@ -22,11 +22,11 @@ export default class BetterWordCount extends Plugin { async onload() { // Settings Store - this.register( - settingsStore.subscribe((value) => { - this.settings = value; - }) - ); + // this.register( + // settingsStore.subscribe((value) => { + // this.settings = value; + // }) + // ); // Handle Settings this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData()); this.addSettingTab(new BetterWordCountSettingsTab(this.app, this)); @@ -51,14 +51,20 @@ export default class BetterWordCount extends Plugin { this.app.workspace.on( "active-leaf-change", async (leaf: WorkspaceLeaf) => { - await this.statsManager.recalcTotals(); this.giveEditorPlugin(leaf); + if (leaf.view.getViewType() !== "markdown") { + this.statusBar.updateAltBar(); + } + + if (!this.settings.collectStats) return; + await this.statsManager.recalcTotals(); } ) ); this.registerEvent( this.app.vault.on("delete", async () => { + if (!this.settings.collectStats) return; await this.statsManager.recalcTotals(); }) ); diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index daf2a81..c0f6d10 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -1,44 +1,74 @@ -export enum Counter { - fileWords, - fileChars, - fileSentences, - totalWords, - totalChars, - totalSentences, - totalNotes, +export enum MetricCounter { + words, + characters, + sentences, + files, +} + +export enum MetricType { + file, + daily, + total, + folder, +} + +export interface Metric { + type: MetricType; + counter: MetricCounter; + folder?: string; } export interface StatusBarItem { prefix: string; suffix: string; - count: Counter; + metric: Metric; } export const BLANK_SB_ITEM: StatusBarItem = { prefix: "", suffix: "", - count: null, + metric: { + type: null, + counter: null, + }, }; export interface BetterWordCountSettings { statusBar: StatusBarItem[]; + altBar: StatusBarItem[]; countComments: boolean; collectStats: boolean; } -export const DEFAULT_SETTINGS: BetterWordCountSettings = Object.freeze({ +export const DEFAULT_SETTINGS: BetterWordCountSettings = { statusBar: [ { prefix: "", suffix: " words", - count: Counter.fileWords, + metric: { + type: MetricType.file, + counter: MetricCounter.words, + }, }, { prefix: " ", suffix: " characters", - count: Counter.fileChars, + metric: { + type: MetricType.file, + counter: MetricCounter.characters, + }, + }, + ], + altBar: [ + { + prefix: "", + suffix: "files", + metric: { + type: MetricType.total, + counter: MetricCounter.files, + }, }, ], countComments: false, collectStats: false, -}); +}; diff --git a/src/settings/SettingsTab.ts b/src/settings/SettingsTab.ts index 98a2e68..0e55833 100644 --- a/src/settings/SettingsTab.ts +++ b/src/settings/SettingsTab.ts @@ -18,7 +18,7 @@ export default class BetterWordCountSettingsTab extends PluginSettingTab { new Setting(containerEl) .setName("Collect Statistics") .setDesc( - "Reload Required for change to take effect. Turn on to start collecting daily statistics of your writing. Stored in the .vault-stats file in the root of your vault. This is required for counts of the day." + "Reload Required for change to take effect. Turn on to start collecting daily statistics of your writing. Stored in the vault-stats.json file in the .obsidian of your vault. This is required for counts of the day as well as total counts." ) .addToggle((cb: ToggleComponent) => { cb.setValue(this.plugin.settings.collectStats); @@ -39,13 +39,6 @@ export default class BetterWordCountSettingsTab extends PluginSettingTab { }); // Status Bar Settings - containerEl - .createEl("h4", { text: "Status Bar Settings" }) - .addClass("bwc-status-bar-settings-title"); - containerEl.createEl("p", { - text: "Here you can customize what statistics are displayed on the status bar.", - }); - addStatusBarSettings(this.plugin, containerEl); } } diff --git a/src/settings/StatusBarSettings.svelte b/src/settings/StatusBarSettings.svelte index 9ca823b..9e2843a 100644 --- a/src/settings/StatusBarSettings.svelte +++ b/src/settings/StatusBarSettings.svelte @@ -1,38 +1,50 @@
+

Markdown Status Bar

+

Here you can customize what statistics are displayed on the status bar when editing a markdown note.

+ +
+ {#each altSItems as item, i} +
+ + + {metricToString(item.metric)} + + + {#if i !== 0} + + {/if} + {#if i !== altSItems.length - 1} + + {/if} + + + +
+
+
Metric Counter
+
+ Select the counter to display, e.g. words, characters. +
+
+
+ +
+
+
+
+
Metric Type
+
+ Select the type of metric that you want displayed. +
+
+
+ +
+
+
+
+
Prefix Text
+
+ This is the text that is placed before the count. +
+
+
+ { + const { value } = e.target; + item.prefix = value; + await updateAlt(altSItems); + await plugin.saveSettings(); + }} + /> +
+
+
+
+
Suffix Text
+
+ This is the text that is placed after the count. +
+
+
+ { + const { value } = e.target; + item.suffix = value; + await updateAlt(altSItems); + await plugin.saveSettings(); + }} + /> +
+
+
+ {/each}
diff --git a/src/stats/StatsManager.ts b/src/stats/StatsManager.ts index 0075901..2934c25 100644 --- a/src/stats/StatsManager.ts +++ b/src/stats/StatsManager.ts @@ -1,9 +1,6 @@ import { debounce, Debouncer, TFile, Vault, Workspace } from "obsidian"; import { STATS_FILE } from "../constants"; -import type { - Day, - VaultStatistics, -} from "./Stats"; +import type { Day, VaultStatistics } from "./Stats"; import moment from "moment"; import { getCharacterCount, @@ -21,7 +18,11 @@ export default class StatsManager { constructor(vault: Vault, workspace: Workspace) { this.vault = vault; this.workspace = workspace; - this.debounceChange = debounce((text:string) => this.change(text), 50, false) + this.debounceChange = debounce( + (text: string) => this.change(text), + 50, + false + ); this.vault.adapter.exists(STATS_FILE).then(async (exists) => { if (!exists) { @@ -33,6 +34,14 @@ export default class StatsManager { this.vaultStats = JSON.parse(await this.vault.adapter.read(STATS_FILE)); } else { this.vaultStats = JSON.parse(await this.vault.adapter.read(STATS_FILE)); + if (!this.vaultStats.hasOwnProperty("history")) { + const vaultSt: VaultStatistics = { + history: {}, + modifiedFiles: {}, + }; + await this.vault.adapter.write(STATS_FILE, JSON.stringify(vaultSt)); + } + this.vaultStats = JSON.parse(await this.vault.adapter.read(STATS_FILE)); } await this.updateToday(); @@ -81,14 +90,15 @@ export default class StatsManager { let modFiles = this.vaultStats.modifiedFiles; if (modFiles.hasOwnProperty(fileName)) { - this.vaultStats.history[this.today].totalWords += currentWords - modFiles[fileName].words.current; - this.vaultStats.history[this.today].totalCharacters += currentCharacters - modFiles[fileName].characters.current; - this.vaultStats.history[this.today].totalSentences += currentSentences - modFiles[fileName].sentences.current; + this.vaultStats.history[this.today].totalWords += + currentWords - modFiles[fileName].words.current; + this.vaultStats.history[this.today].totalCharacters += + currentCharacters - modFiles[fileName].characters.current; + this.vaultStats.history[this.today].totalSentences += + currentSentences - modFiles[fileName].sentences.current; modFiles[fileName].words.current = currentWords; modFiles[fileName].characters.current = currentCharacters; modFiles[fileName].sentences.current = currentSentences; - - } else { modFiles[fileName] = { words: { @@ -102,7 +112,7 @@ export default class StatsManager { sentences: { initial: currentSentences, current: currentSentences, - } + }, }; } @@ -141,8 +151,8 @@ export default class StatsManager { ) { const todayHist: Day = this.vaultStats.history[this.today]; todayHist.totalWords = await this.calcTotalWords(); - todayHist.totalCharacters = await this.calcTotalCharacters() - todayHist.totalSentences = await this.calcTotalSentences() + todayHist.totalCharacters = await this.calcTotalCharacters(); + todayHist.totalSentences = await this.calcTotalSentences(); this.update(); } else { this.updateToday(); @@ -188,6 +198,18 @@ export default class StatsManager { return sentence; } + public getDailyWords(): number { + return this.vaultStats.history[this.today].words; + } + + public getDailyCharacters(): number { + return this.vaultStats.history[this.today].characters; + } + + public getDailySentences(): number { + return this.vaultStats.history[this.today].sentences; + } + public getTotalFiles(): number { return this.vault.getMarkdownFiles().length; } diff --git a/src/status/StatusBar.ts b/src/status/StatusBar.ts index 1872edc..7d40bfc 100644 --- a/src/status/StatusBar.ts +++ b/src/status/StatusBar.ts @@ -1,4 +1,4 @@ -import { Counter } from "src/settings/Settings"; +import { MetricCounter, MetricType } from "src/settings/Settings"; import type BetterWordCount from "../main"; import { getWordCount, @@ -45,33 +45,194 @@ export default class StatusBar { const sbItem = sb[i]; display = display + sbItem.prefix; - switch (sbItem.count) { - case Counter.fileWords: - display = display + getWordCount(text); - break; - case Counter.fileChars: - display = display + getCharacterCount(text); - break; - case Counter.fileSentences: - display = display + getSentenceCount(text); - break; - case Counter.totalWords: - display = display + (await this.plugin.statsManager.getTotalWords()); - break; - case Counter.totalChars: - display = - display + (await this.plugin.statsManager.getTotalCharacters()); - break; - case Counter.totalSentences: - display = - display + (await this.plugin.statsManager.getTotalSentences()); - break; - case Counter.totalNotes: - display = display + this.plugin.statsManager.getTotalFiles(); - break; + const metric = sbItem.metric; - default: - break; + if (metric.counter === MetricCounter.words) { + switch (metric.type) { + case MetricType.file: + display = display + getWordCount(text); + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getDailyWords() + : 0); + break; + case MetricType.total: + display = + display + + (await (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalWords() + : 0)); + break; + } + } else if (metric.counter === MetricCounter.characters) { + switch (metric.type) { + case MetricType.file: + display = display + getCharacterCount(text); + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getDailyCharacters() + : 0); + break; + case MetricType.total: + display = + display + + (await (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalCharacters() + : 0)); + break; + } + } else if (metric.counter === MetricCounter.sentences) { + switch (metric.type) { + case MetricType.file: + display = display + getSentenceCount(text); + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getDailySentences() + : 0); + break; + case MetricType.total: + display = + display + + (await (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalSentences() + : 0)); + break; + } + } else if (metric.counter === MetricCounter.files) { + switch (metric.type) { + case MetricType.file: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalFiles() + : 0); + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalFiles() + : 0); + break; + case MetricType.total: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalFiles() + : 0); + break; + } + } + + display = display + sbItem.suffix; + } + + this.displayText(display); + } + + async updateAltBar() { + const ab = this.plugin.settings.altBar; + let display = ""; + + for (let i = 0; i < ab.length; i++) { + const sbItem = ab[i]; + + display = display + sbItem.prefix; + const metric = sbItem.metric; + + if (metric.counter === MetricCounter.words) { + switch (metric.type) { + case MetricType.file: + display = display + 0; + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getDailyWords() + : 0); + break; + case MetricType.total: + display = + display + + (await (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalWords() + : 0)); + break; + } + } else if (metric.counter === MetricCounter.characters) { + switch (metric.type) { + case MetricType.file: + display = display + 0; + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getDailyCharacters() + : 0); + break; + case MetricType.total: + display = + display + + (await (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalCharacters() + : 0)); + break; + } + } else if (metric.counter === MetricCounter.sentences) { + switch (metric.type) { + case MetricType.file: + display = display + 0; + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getDailySentences() + : 0); + break; + case MetricType.total: + display = + display + + (await (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalSentences() + : 0)); + break; + } + } else if (metric.counter === MetricCounter.files) { + switch (metric.type) { + case MetricType.file: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalFiles() + : 0); + break; + case MetricType.daily: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalFiles() + : 0); + break; + case MetricType.total: + display = + display + + (this.plugin.settings.collectStats + ? this.plugin.statsManager.getTotalFiles() + : 0); + break; + } } display = display + sbItem.suffix;