Add Alt Status Bar
This commit is contained in:
parent
67221411f8
commit
5c7ca2abc5
6 changed files with 554 additions and 130 deletions
18
src/main.ts
18
src/main.ts
|
@ -22,11 +22,11 @@ export default class BetterWordCount extends Plugin {
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
// Settings Store
|
// Settings Store
|
||||||
this.register(
|
// this.register(
|
||||||
settingsStore.subscribe((value) => {
|
// settingsStore.subscribe((value) => {
|
||||||
this.settings = value;
|
// this.settings = value;
|
||||||
})
|
// })
|
||||||
);
|
// );
|
||||||
// Handle Settings
|
// Handle Settings
|
||||||
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData());
|
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData());
|
||||||
this.addSettingTab(new BetterWordCountSettingsTab(this.app, this));
|
this.addSettingTab(new BetterWordCountSettingsTab(this.app, this));
|
||||||
|
@ -51,14 +51,20 @@ export default class BetterWordCount extends Plugin {
|
||||||
this.app.workspace.on(
|
this.app.workspace.on(
|
||||||
"active-leaf-change",
|
"active-leaf-change",
|
||||||
async (leaf: WorkspaceLeaf) => {
|
async (leaf: WorkspaceLeaf) => {
|
||||||
await this.statsManager.recalcTotals();
|
|
||||||
this.giveEditorPlugin(leaf);
|
this.giveEditorPlugin(leaf);
|
||||||
|
if (leaf.view.getViewType() !== "markdown") {
|
||||||
|
this.statusBar.updateAltBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.settings.collectStats) return;
|
||||||
|
await this.statsManager.recalcTotals();
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.registerEvent(
|
this.registerEvent(
|
||||||
this.app.vault.on("delete", async () => {
|
this.app.vault.on("delete", async () => {
|
||||||
|
if (!this.settings.collectStats) return;
|
||||||
await this.statsManager.recalcTotals();
|
await this.statsManager.recalcTotals();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,44 +1,74 @@
|
||||||
export enum Counter {
|
export enum MetricCounter {
|
||||||
fileWords,
|
words,
|
||||||
fileChars,
|
characters,
|
||||||
fileSentences,
|
sentences,
|
||||||
totalWords,
|
files,
|
||||||
totalChars,
|
}
|
||||||
totalSentences,
|
|
||||||
totalNotes,
|
export enum MetricType {
|
||||||
|
file,
|
||||||
|
daily,
|
||||||
|
total,
|
||||||
|
folder,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Metric {
|
||||||
|
type: MetricType;
|
||||||
|
counter: MetricCounter;
|
||||||
|
folder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StatusBarItem {
|
export interface StatusBarItem {
|
||||||
prefix: string;
|
prefix: string;
|
||||||
suffix: string;
|
suffix: string;
|
||||||
count: Counter;
|
metric: Metric;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BLANK_SB_ITEM: StatusBarItem = {
|
export const BLANK_SB_ITEM: StatusBarItem = {
|
||||||
prefix: "",
|
prefix: "",
|
||||||
suffix: "",
|
suffix: "",
|
||||||
count: null,
|
metric: {
|
||||||
|
type: null,
|
||||||
|
counter: null,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface BetterWordCountSettings {
|
export interface BetterWordCountSettings {
|
||||||
statusBar: StatusBarItem[];
|
statusBar: StatusBarItem[];
|
||||||
|
altBar: StatusBarItem[];
|
||||||
countComments: boolean;
|
countComments: boolean;
|
||||||
collectStats: boolean;
|
collectStats: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_SETTINGS: BetterWordCountSettings = Object.freeze({
|
export const DEFAULT_SETTINGS: BetterWordCountSettings = {
|
||||||
statusBar: [
|
statusBar: [
|
||||||
{
|
{
|
||||||
prefix: "",
|
prefix: "",
|
||||||
suffix: " words",
|
suffix: " words",
|
||||||
count: Counter.fileWords,
|
metric: {
|
||||||
|
type: MetricType.file,
|
||||||
|
counter: MetricCounter.words,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prefix: " ",
|
prefix: " ",
|
||||||
suffix: " characters",
|
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,
|
countComments: false,
|
||||||
collectStats: false,
|
collectStats: false,
|
||||||
});
|
};
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default class BetterWordCountSettingsTab extends PluginSettingTab {
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName("Collect Statistics")
|
.setName("Collect Statistics")
|
||||||
.setDesc(
|
.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) => {
|
.addToggle((cb: ToggleComponent) => {
|
||||||
cb.setValue(this.plugin.settings.collectStats);
|
cb.setValue(this.plugin.settings.collectStats);
|
||||||
|
@ -39,13 +39,6 @@ export default class BetterWordCountSettingsTab extends PluginSettingTab {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Status Bar Settings
|
// 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);
|
addStatusBarSettings(this.plugin, containerEl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,50 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { StatusBarItem } from "./Settings";
|
import type { StatusBarItem } from "./Settings";
|
||||||
import { Counter, BLANK_SB_ITEM } from "./Settings";
|
import { MetricType, MetricCounter, BLANK_SB_ITEM, DEFAULT_SETTINGS } from "./Settings";
|
||||||
import type BetterWordCount from "src/main";
|
import type BetterWordCount from "src/main";
|
||||||
|
|
||||||
export let plugin: BetterWordCount;
|
export let plugin: BetterWordCount;
|
||||||
const { settings } = plugin;
|
const { settings } = plugin;
|
||||||
|
|
||||||
let statusItems: StatusBarItem[] = [...plugin.settings.statusBar];
|
let statusItems: StatusBarItem[] = [...plugin.settings.statusBar];
|
||||||
|
let altSItems: StatusBarItem[] = [...plugin.settings.altBar];
|
||||||
|
|
||||||
function counterToString(count: Counter): string {
|
function metricToString(metric: Metric): string {
|
||||||
switch (count) {
|
if (metric.type === MetricType.file) {
|
||||||
case Counter.fileWords:
|
switch (metric.counter) {
|
||||||
return "File Words";
|
case MetricCounter.words:
|
||||||
|
return "Words in Note"
|
||||||
case Counter.fileChars:
|
case MetricCounter.characters:
|
||||||
return "File Chars";
|
return "Chars in Note"
|
||||||
|
case MetricCounter.sentences:
|
||||||
case Counter.fileSentences:
|
return "Sentences in Note"
|
||||||
return "File Sentences";
|
case MetricCounter.files:
|
||||||
|
return "Total Notes"
|
||||||
case Counter.totalWords:
|
}
|
||||||
return "Total Words";
|
} else if (metric.type === MetricType.daily) {
|
||||||
|
switch (metric.counter) {
|
||||||
case Counter.totalChars:
|
case MetricCounter.words:
|
||||||
return "Total Chars";
|
return "Daily Words"
|
||||||
|
case MetricCounter.characters:
|
||||||
case Counter.totalSentences:
|
return "Daily Chars"
|
||||||
return "Total Sentences"
|
case MetricCounter.sentences:
|
||||||
|
return "Daily Sentences"
|
||||||
case Counter.totalNotes:
|
case MetricCounter.files:
|
||||||
return "Total Notes";
|
return "Total Notes"
|
||||||
|
}
|
||||||
default:
|
} else if (metric.type === MetricType.total) {
|
||||||
return "Select Options"
|
switch (metric.counter) {
|
||||||
|
case MetricCounter.words:
|
||||||
|
return "Total Words"
|
||||||
|
case MetricCounter.characters:
|
||||||
|
return "Total Chars"
|
||||||
|
case MetricCounter.sentences:
|
||||||
|
return "Total Sentences"
|
||||||
|
case MetricCounter.files:
|
||||||
|
return "Total Notes"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "Select Options"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,19 +59,32 @@
|
||||||
|
|
||||||
async function update(statusItems: StatusBarItem[]) {
|
async function update(statusItems: StatusBarItem[]) {
|
||||||
plugin.settings.statusBar = statusItems.filter((item) => {
|
plugin.settings.statusBar = statusItems.filter((item) => {
|
||||||
if (counterToString(item.count) !== "Select Options") {
|
if (metricToString(item.metric) !== "Select Options") {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await plugin.saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateAlt(altSItems: StatusBarItem[]) {
|
||||||
|
plugin.settings.altBar = altSItems.filter((item) => {
|
||||||
|
if (metricToString(item.metric) !== "Select Options") {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
await plugin.saveSettings();
|
await plugin.saveSettings();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
<h4>Markdown Status Bar</h4>
|
||||||
|
<p>Here you can customize what statistics are displayed on the status bar when editing a markdown note.</p>
|
||||||
<div class="bwc-sb-buttons">
|
<div class="bwc-sb-buttons">
|
||||||
<button
|
<button
|
||||||
aria-label="Add New Status Bar Item"
|
aria-label="Add New Status Bar Item"
|
||||||
on:click={async () => (statusItems = [...statusItems, Object.create(BLANK_SB_ITEM)])}
|
on:click={async () => (statusItems = [...statusItems, JSON.parse(JSON.stringify(BLANK_SB_ITEM))])}
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
Add Item
|
Add Item
|
||||||
|
@ -68,19 +93,26 @@
|
||||||
<button
|
<button
|
||||||
aria-label="Reset Status Bar to Default"
|
aria-label="Reset Status Bar to Default"
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
statusItems = [{
|
statusItems = [
|
||||||
prefix: "",
|
{
|
||||||
suffix: " words",
|
prefix: "",
|
||||||
count: Counter.fileWords,
|
suffix: " words",
|
||||||
},
|
metric: {
|
||||||
{
|
type: MetricType.file,
|
||||||
prefix: " ",
|
counter: MetricCounter.words,
|
||||||
suffix: " characters",
|
},
|
||||||
count: Counter.fileChars,
|
},
|
||||||
},
|
{
|
||||||
];
|
prefix: " ",
|
||||||
await update(statusItems);
|
suffix: " characters",
|
||||||
}}
|
metric: {
|
||||||
|
type: MetricType.file,
|
||||||
|
counter: MetricCounter.characters,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
await update(statusItems);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
Reset
|
Reset
|
||||||
|
@ -91,7 +123,7 @@
|
||||||
<details class="bwc-sb-item-setting">
|
<details class="bwc-sb-item-setting">
|
||||||
<summary>
|
<summary>
|
||||||
<span class="bwc-sb-item-text">
|
<span class="bwc-sb-item-text">
|
||||||
{counterToString(item.count)}
|
{metricToString(item.metric)}
|
||||||
</span>
|
</span>
|
||||||
<span class="bwc-sb-buttons">
|
<span class="bwc-sb-buttons">
|
||||||
{#if i !== 0}
|
{#if i !== 0}
|
||||||
|
@ -129,39 +161,52 @@
|
||||||
</summary>
|
</summary>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<div class="setting-item-info">
|
<div class="setting-item-info">
|
||||||
<div class="setting-item-name">Count Type</div>
|
<div class="setting-item-name">Metric Counter</div>
|
||||||
<div class="setting-item-description">
|
<div class="setting-item-description">
|
||||||
This is the type of counter that will be displayed.
|
Select the counter to display, e.g. words, characters.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item-control">
|
<div class="setting-item-control">
|
||||||
<select
|
<select
|
||||||
class="dropdown"
|
class="dropdown"
|
||||||
value={item.count}
|
value={item.metric.counter}
|
||||||
on:change={async (e) => {
|
on:change={async (e) => {
|
||||||
const {value} = e.target;
|
const {value} = e.target;
|
||||||
item.count = Counter[Counter[value]];
|
item.metric.counter = MetricCounter[MetricCounter[value]];
|
||||||
await update(statusItems);
|
await update(statusItems);
|
||||||
await plugin.saveSettings();
|
await plugin.saveSettings();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value>Select Option</option>
|
<option value>Select Option</option>
|
||||||
<optgroup label="Words">
|
<option value={MetricCounter.words}>Words</option>
|
||||||
<option value={Counter.fileWords}>{counterToString(Counter.fileWords)}</option>
|
<option value={MetricCounter.characters}>Characters</option>
|
||||||
<option value={Counter.totalWords}>{counterToString(Counter.totalWords)}</option>
|
<option value={MetricCounter.sentences}>Sentences</option>
|
||||||
</optgroup>
|
<option value={MetricCounter.files}>Files</option>
|
||||||
<optgroup label="Characters">
|
</select>
|
||||||
<option value={Counter.fileChars}>{counterToString(Counter.fileChars)}</option>
|
</div>
|
||||||
<option value={Counter.totalChars}>{counterToString(Counter.totalChars)}</option>
|
</div>
|
||||||
</optgroup>
|
<div class="setting-item">
|
||||||
<optgroup label="Sentences">
|
<div class="setting-item-info">
|
||||||
<option value={Counter.fileSentences}>{counterToString(Counter.fileSentences)}</option>
|
<div class="setting-item-name">Metric Type</div>
|
||||||
<option value={Counter.totalSentences}>{counterToString(Counter.totalSentences)}</option>
|
<div class="setting-item-description">
|
||||||
</optgroup>
|
Select the type of metric that you want displayed.
|
||||||
<optgroup label="Notes">
|
</div>
|
||||||
<option value={Counter.totalNotes}>{counterToString(Counter.totalNotes)}</option>
|
</div>
|
||||||
</optgroup>
|
<div class="setting-item-control">
|
||||||
|
<select
|
||||||
|
class="dropdown"
|
||||||
|
value={item.metric.type}
|
||||||
|
on:change={async (e) => {
|
||||||
|
const {value} = e.target;
|
||||||
|
item.metric.type = MetricType[MetricType[value]];
|
||||||
|
await update(statusItems);
|
||||||
|
await plugin.saveSettings();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value>Select Option</option>
|
||||||
|
<option value={MetricType.file}>Current Note</option>
|
||||||
|
<option value={MetricType.daily}>Daily Metric</option>
|
||||||
|
<option value={MetricType.total}>Total in Vault</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -209,4 +254,171 @@
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
{/each}
|
{/each}
|
||||||
|
<h4>Alternative Status Bar</h4>
|
||||||
|
<p>Here you can customize what statistics are displayed on the status bar when not editing a markdown file.</p>
|
||||||
|
<div class="bwc-sb-buttons">
|
||||||
|
<button
|
||||||
|
aria-label="Add New Status Bar Item"
|
||||||
|
on:click={async () => (altSItems = [...altSItems, JSON.parse(JSON.stringify(BLANK_SB_ITEM))])}
|
||||||
|
>
|
||||||
|
<div class="icon">
|
||||||
|
Add Item
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Reset Status Bar to Default"
|
||||||
|
on:click={async () => {
|
||||||
|
altSItems = [
|
||||||
|
{
|
||||||
|
prefix: "",
|
||||||
|
suffix: " files",
|
||||||
|
metric: {
|
||||||
|
type: MetricType.total,
|
||||||
|
counter: MetricCounter.files,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
await update(statusItems);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="icon">
|
||||||
|
Reset
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{#each altSItems as item, i}
|
||||||
|
<details class="bwc-sb-item-setting">
|
||||||
|
<summary>
|
||||||
|
<span class="bwc-sb-item-text">
|
||||||
|
{metricToString(item.metric)}
|
||||||
|
</span>
|
||||||
|
<span class="bwc-sb-buttons">
|
||||||
|
{#if i !== 0}
|
||||||
|
<button
|
||||||
|
aria-label="Move Status Bar Item Up"
|
||||||
|
on:click={async () => {
|
||||||
|
altSItems = swapStatusBarItems(i, i-1, altSItems);
|
||||||
|
await updateAlt(altSItems);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
↑
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
{#if i !== altSItems.length - 1}
|
||||||
|
<button
|
||||||
|
aria-label="Move Status Bar Item Down"
|
||||||
|
on:click={async () => {
|
||||||
|
altSItems = swapStatusBarItems(i, i+1, altSItems);
|
||||||
|
await updateAlt(altSItems);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
↓
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
<button
|
||||||
|
aria-label="Remove Status Bar Item"
|
||||||
|
on:click={async () => {
|
||||||
|
altSItems = altSItems.filter((item, j) => i !== j);
|
||||||
|
await updateAlt(altSItems);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</summary>
|
||||||
|
<div class="setting-item">
|
||||||
|
<div class="setting-item-info">
|
||||||
|
<div class="setting-item-name">Metric Counter</div>
|
||||||
|
<div class="setting-item-description">
|
||||||
|
Select the counter to display, e.g. words, characters.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-item-control">
|
||||||
|
<select
|
||||||
|
class="dropdown"
|
||||||
|
value={item.metric.counter}
|
||||||
|
on:change={async (e) => {
|
||||||
|
const {value} = e.target;
|
||||||
|
item.metric.counter = MetricCounter[MetricCounter[value]];
|
||||||
|
await updateAlt(altSItems);
|
||||||
|
await plugin.saveSettings();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value>Select Option</option>
|
||||||
|
<option value={MetricCounter.words}>Words</option>
|
||||||
|
<option value={MetricCounter.characters}>Characters</option>
|
||||||
|
<option value={MetricCounter.sentences}>Sentences</option>
|
||||||
|
<option value={MetricCounter.files}>Files</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-item">
|
||||||
|
<div class="setting-item-info">
|
||||||
|
<div class="setting-item-name">Metric Type</div>
|
||||||
|
<div class="setting-item-description">
|
||||||
|
Select the type of metric that you want displayed.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-item-control">
|
||||||
|
<select
|
||||||
|
class="dropdown"
|
||||||
|
value={item.metric.type}
|
||||||
|
on:change={async (e) => {
|
||||||
|
const {value} = e.target;
|
||||||
|
item.metric.type = MetricType[MetricType[value]];
|
||||||
|
await updateAlt(altSItems);
|
||||||
|
await plugin.saveSettings();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value>Select Option</option>
|
||||||
|
<option value={MetricType.file}>Current Note</option>
|
||||||
|
<option value={MetricType.daily}>Daily Metric</option>
|
||||||
|
<option value={MetricType.total}>Total in Vault</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-item">
|
||||||
|
<div class="setting-item-info">
|
||||||
|
<div class="setting-item-name">Prefix Text</div>
|
||||||
|
<div class="setting-item-description">
|
||||||
|
This is the text that is placed before the count.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-item-control">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="prefix"
|
||||||
|
value={item.prefix}
|
||||||
|
on:change={async (e) => {
|
||||||
|
const { value } = e.target;
|
||||||
|
item.prefix = value;
|
||||||
|
await updateAlt(altSItems);
|
||||||
|
await plugin.saveSettings();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-item">
|
||||||
|
<div class="setting-item-info">
|
||||||
|
<div class="setting-item-name">Suffix Text</div>
|
||||||
|
<div class="setting-item-description">
|
||||||
|
This is the text that is placed after the count.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-item-control">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="suffix"
|
||||||
|
value={item.suffix}
|
||||||
|
on:change={async (e) => {
|
||||||
|
const { value } = e.target;
|
||||||
|
item.suffix = value;
|
||||||
|
await updateAlt(altSItems);
|
||||||
|
await plugin.saveSettings();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import { debounce, Debouncer, TFile, Vault, Workspace } from "obsidian";
|
import { debounce, Debouncer, TFile, Vault, Workspace } from "obsidian";
|
||||||
import { STATS_FILE } from "../constants";
|
import { STATS_FILE } from "../constants";
|
||||||
import type {
|
import type { Day, VaultStatistics } from "./Stats";
|
||||||
Day,
|
|
||||||
VaultStatistics,
|
|
||||||
} from "./Stats";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {
|
import {
|
||||||
getCharacterCount,
|
getCharacterCount,
|
||||||
|
@ -21,7 +18,11 @@ export default class StatsManager {
|
||||||
constructor(vault: Vault, workspace: Workspace) {
|
constructor(vault: Vault, workspace: Workspace) {
|
||||||
this.vault = vault;
|
this.vault = vault;
|
||||||
this.workspace = workspace;
|
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) => {
|
this.vault.adapter.exists(STATS_FILE).then(async (exists) => {
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
|
@ -33,6 +34,14 @@ export default class StatsManager {
|
||||||
this.vaultStats = JSON.parse(await this.vault.adapter.read(STATS_FILE));
|
this.vaultStats = JSON.parse(await this.vault.adapter.read(STATS_FILE));
|
||||||
} else {
|
} else {
|
||||||
this.vaultStats = JSON.parse(await this.vault.adapter.read(STATS_FILE));
|
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();
|
await this.updateToday();
|
||||||
|
@ -81,14 +90,15 @@ export default class StatsManager {
|
||||||
let modFiles = this.vaultStats.modifiedFiles;
|
let modFiles = this.vaultStats.modifiedFiles;
|
||||||
|
|
||||||
if (modFiles.hasOwnProperty(fileName)) {
|
if (modFiles.hasOwnProperty(fileName)) {
|
||||||
this.vaultStats.history[this.today].totalWords += currentWords - modFiles[fileName].words.current;
|
this.vaultStats.history[this.today].totalWords +=
|
||||||
this.vaultStats.history[this.today].totalCharacters += currentCharacters - modFiles[fileName].characters.current;
|
currentWords - modFiles[fileName].words.current;
|
||||||
this.vaultStats.history[this.today].totalSentences += currentSentences - modFiles[fileName].sentences.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].words.current = currentWords;
|
||||||
modFiles[fileName].characters.current = currentCharacters;
|
modFiles[fileName].characters.current = currentCharacters;
|
||||||
modFiles[fileName].sentences.current = currentSentences;
|
modFiles[fileName].sentences.current = currentSentences;
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
modFiles[fileName] = {
|
modFiles[fileName] = {
|
||||||
words: {
|
words: {
|
||||||
|
@ -102,7 +112,7 @@ export default class StatsManager {
|
||||||
sentences: {
|
sentences: {
|
||||||
initial: currentSentences,
|
initial: currentSentences,
|
||||||
current: currentSentences,
|
current: currentSentences,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,8 +151,8 @@ export default class StatsManager {
|
||||||
) {
|
) {
|
||||||
const todayHist: Day = this.vaultStats.history[this.today];
|
const todayHist: Day = this.vaultStats.history[this.today];
|
||||||
todayHist.totalWords = await this.calcTotalWords();
|
todayHist.totalWords = await this.calcTotalWords();
|
||||||
todayHist.totalCharacters = await this.calcTotalCharacters()
|
todayHist.totalCharacters = await this.calcTotalCharacters();
|
||||||
todayHist.totalSentences = await this.calcTotalSentences()
|
todayHist.totalSentences = await this.calcTotalSentences();
|
||||||
this.update();
|
this.update();
|
||||||
} else {
|
} else {
|
||||||
this.updateToday();
|
this.updateToday();
|
||||||
|
@ -188,6 +198,18 @@ export default class StatsManager {
|
||||||
return sentence;
|
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 {
|
public getTotalFiles(): number {
|
||||||
return this.vault.getMarkdownFiles().length;
|
return this.vault.getMarkdownFiles().length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Counter } from "src/settings/Settings";
|
import { MetricCounter, MetricType } from "src/settings/Settings";
|
||||||
import type BetterWordCount from "../main";
|
import type BetterWordCount from "../main";
|
||||||
import {
|
import {
|
||||||
getWordCount,
|
getWordCount,
|
||||||
|
@ -45,33 +45,194 @@ export default class StatusBar {
|
||||||
const sbItem = sb[i];
|
const sbItem = sb[i];
|
||||||
|
|
||||||
display = display + sbItem.prefix;
|
display = display + sbItem.prefix;
|
||||||
switch (sbItem.count) {
|
const metric = sbItem.metric;
|
||||||
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;
|
|
||||||
|
|
||||||
default:
|
if (metric.counter === MetricCounter.words) {
|
||||||
break;
|
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;
|
display = display + sbItem.suffix;
|
||||||
|
|
Loading…
Reference in a new issue