Finish Settings
This commit is contained in:
parent
3192b681b8
commit
1ae2418394
10 changed files with 341 additions and 159 deletions
|
@ -41,6 +41,7 @@
|
|||
"typescript": "^4.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"svelte": "^3.38.3"
|
||||
"svelte": "^3.38.3",
|
||||
"svelte-icons": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import typescript from '@rollup/plugin-typescript';
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import copy from 'rollup-plugin-copy';
|
||||
import typescript from "@rollup/plugin-typescript";
|
||||
import { nodeResolve } from "@rollup/plugin-node-resolve";
|
||||
import commonjs from "@rollup/plugin-commonjs";
|
||||
import copy from "rollup-plugin-copy";
|
||||
import svelte from "rollup-plugin-svelte";
|
||||
import autoPreprocess from "svelte-preprocess";
|
||||
const TEST_VAULT = 'test-vault/.obsidian/plugins/better-word-count';
|
||||
import sveltePreprocess from "svelte-preprocess";
|
||||
const TEST_VAULT = "test-vault/.obsidian/plugins/better-word-count";
|
||||
|
||||
export default {
|
||||
input: 'src/main.ts',
|
||||
input: "src/main.ts",
|
||||
output: {
|
||||
dir: 'dist/',
|
||||
sourcemap: 'inline',
|
||||
format: 'cjs',
|
||||
exports: 'default'
|
||||
dir: "dist/",
|
||||
sourcemap: "inline",
|
||||
format: "cjs",
|
||||
exports: "default",
|
||||
},
|
||||
external: [
|
||||
"obsidian",
|
||||
|
@ -47,13 +47,17 @@ export default {
|
|||
nodeResolve({ browser: true }),
|
||||
commonjs(),
|
||||
svelte({
|
||||
preprocess: autoPreprocess(),
|
||||
include: "src/**/*.svelte",
|
||||
compilerOptions: { css: true },
|
||||
preprocess: sveltePreprocess(),
|
||||
}),
|
||||
copy({
|
||||
targets: [
|
||||
{ src: 'dist/main.js', dest: TEST_VAULT },
|
||||
{ src: ['manifest.json'], dest: TEST_VAULT }
|
||||
], flatten: true
|
||||
})
|
||||
]
|
||||
};
|
||||
{ src: "src/styles.css", dest: TEST_VAULT },
|
||||
{ src: "dist/main.js", dest: TEST_VAULT },
|
||||
{ src: ["manifest.json"], dest: TEST_VAULT },
|
||||
],
|
||||
flatten: true,
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
|
24
src/main.ts
24
src/main.ts
|
@ -10,10 +10,14 @@ import {
|
|||
editorEditorField,
|
||||
Notice,
|
||||
} from "obsidian";
|
||||
// import { BetterWordCountSettingsTab } from "./settings/settings-tab";
|
||||
// import { BetterWordCountSettings, DEFAULT_SETTINGS } from "./settings/settings";
|
||||
// import { StatusBar } from "./status/bar";
|
||||
// import { STATS_ICON, STATS_ICON_NAME, VIEW_TYPE_STATS } from "./constants";
|
||||
import {
|
||||
BetterWordCountSettings,
|
||||
DEFAULT_SETTINGS,
|
||||
} from "src/settings/Settings";
|
||||
import { BetterWordCountSettingsTab } from "./settings/SettingsTab";
|
||||
|
||||
// import { StatusBar } from "./status/bar";
|
||||
// import StatsView from "./view/view";
|
||||
// import { DataManager } from "./data/manager";
|
||||
// import { BarManager } from "./status/manager";
|
||||
|
@ -28,7 +32,7 @@ import { StatusBar } from "./status/bar";
|
|||
export default class BetterWordCount extends Plugin {
|
||||
public static statusBar: StatusBar;
|
||||
// public currentFile: TFile;
|
||||
// public settings: BetterWordCountSettings;
|
||||
public settings: BetterWordCountSettings;
|
||||
// public view: StatsView;
|
||||
// public dataManager: DataManager;
|
||||
// public barManager: BarManager;
|
||||
|
@ -39,13 +43,13 @@ export default class BetterWordCount extends Plugin {
|
|||
// .forEach((leaf) => leaf.detach());
|
||||
// }
|
||||
|
||||
onload() {
|
||||
async onload() {
|
||||
let statusBarEl = this.addStatusBarItem();
|
||||
BetterWordCount.statusBar = new StatusBar(statusBarEl);
|
||||
this.createCMExtension();
|
||||
|
||||
// this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData());
|
||||
// this.addSettingTab(new BetterWordCountSettingsTab(this.app, this));
|
||||
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData());
|
||||
this.addSettingTab(new BetterWordCountSettingsTab(this.app, this));
|
||||
|
||||
// let statusBarElTest = this.addStatusBarItem();
|
||||
// statusBarElTest.setText("§l§aTest§r");
|
||||
|
@ -123,9 +127,9 @@ export default class BetterWordCount extends Plugin {
|
|||
// }
|
||||
// }
|
||||
|
||||
// async saveSettings(): Promise<void> {
|
||||
// await this.saveData(this.settings);
|
||||
// }
|
||||
async saveSettings(): Promise<void> {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
|
||||
// initLeaf(): void {
|
||||
// if (this.app.workspace.getLeavesOfType(VIEW_TYPE_STATS).length) {
|
||||
|
|
|
@ -4,12 +4,19 @@ export enum Counter {
|
|||
totalWords,
|
||||
totalChars,
|
||||
}
|
||||
|
||||
export interface StatusBarItem {
|
||||
start: string;
|
||||
end: string;
|
||||
count: Counter;
|
||||
}
|
||||
|
||||
export const BLANK_SB_ITEM: StatusBarItem = {
|
||||
start: "",
|
||||
end: "",
|
||||
count: null,
|
||||
};
|
||||
|
||||
export interface BetterWordCountSettings {
|
||||
statusBar: StatusBarItem[];
|
||||
countComments: boolean;
|
62
src/settings/SettingsTab.ts
Normal file
62
src/settings/SettingsTab.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import {
|
||||
App,
|
||||
DropdownComponent,
|
||||
PluginSettingTab,
|
||||
Setting,
|
||||
TextAreaComponent,
|
||||
ToggleComponent,
|
||||
} from "obsidian";
|
||||
import type BetterWordCount from "src/main";
|
||||
import type { StatusBarItem } from "./Settings";
|
||||
import { addStatusBarSettings } from "./StatusBarSettings";
|
||||
|
||||
export const details = (text: string, parent: HTMLElement) =>
|
||||
parent.createEl("details", {}, (d) => d.createEl("summary", { text }));
|
||||
|
||||
export class BetterWordCountSettingsTab extends PluginSettingTab {
|
||||
constructor(app: App, private plugin: BetterWordCount) {
|
||||
super(app, plugin);
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let { containerEl } = this;
|
||||
|
||||
containerEl.empty();
|
||||
containerEl.createEl("h3", { text: "Better Word Count Settings" });
|
||||
|
||||
// General Settings
|
||||
containerEl.createEl("h4", { text: "General Settings" });
|
||||
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."
|
||||
)
|
||||
.addToggle((cb: ToggleComponent) => {
|
||||
cb.setValue(this.plugin.settings.collectStats);
|
||||
cb.onChange(async (value: boolean) => {
|
||||
this.plugin.settings.collectStats = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName("Don't Count Comments")
|
||||
.setDesc("Turn on if you don't want markdown comments to be counted.")
|
||||
.addToggle((cb: ToggleComponent) => {
|
||||
cb.setValue(this.plugin.settings.countComments);
|
||||
cb.onChange(async (value: boolean) => {
|
||||
this.plugin.settings.countComments = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
191
src/settings/StatusBarSettings.svelte
Normal file
191
src/settings/StatusBarSettings.svelte
Normal file
|
@ -0,0 +1,191 @@
|
|||
<script lang="ts">
|
||||
import type { StatusBarItem } from "./Settings";
|
||||
import { Counter, BLANK_SB_ITEM } from "./Settings";
|
||||
import type BetterWordCount from "src/main";
|
||||
|
||||
export let plugin: BetterWordCount;
|
||||
const { settings } = plugin;
|
||||
|
||||
let statusItems: StatusBarItem[] = [...plugin.settings.statusBar];
|
||||
|
||||
function counterToString(count: Counter): string {
|
||||
switch (count) {
|
||||
case Counter.fileWords:
|
||||
return "File Words";
|
||||
|
||||
case Counter.fileChars:
|
||||
return "File Chars";
|
||||
|
||||
case Counter.totalWords:
|
||||
return "Total Words";
|
||||
|
||||
case Counter.totalChars:
|
||||
return "Total Chars";
|
||||
|
||||
default:
|
||||
return "Select Options"
|
||||
}
|
||||
}
|
||||
|
||||
function swapStatusBarItems(i: number, j: number, arr: StatusBarItem[]) {
|
||||
const max = arr.length - 1;
|
||||
if (i < 0 || i > max || j < 0 || j > max) return arr;
|
||||
const tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
return arr;
|
||||
}
|
||||
|
||||
async function update(statusItems: StatusBarItem[]) {
|
||||
plugin.settings.statusBar = statusItems.filter((item) => {
|
||||
if (counterToString(item.count) !== "Select Options") {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
await plugin.saveSettings();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="bwc-sb-buttons">
|
||||
<button
|
||||
aria-label="Add New Status Bar Item"
|
||||
on:click={async () => (statusItems = [...statusItems, Object.create(BLANK_SB_ITEM)])}
|
||||
>
|
||||
<div class="icon">
|
||||
Add Item
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Reset Status Bar to Default"
|
||||
on:click={async () => {
|
||||
statusItems = [{
|
||||
prefix: "",
|
||||
suffix: " words",
|
||||
count: Counter.fileWords,
|
||||
},
|
||||
{
|
||||
prefix: " ",
|
||||
suffix: " characters",
|
||||
count: Counter.fileChars,
|
||||
},
|
||||
];
|
||||
await update(statusItems);
|
||||
}}
|
||||
>
|
||||
<div class="icon">
|
||||
Reset
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
{#each statusItems as item, i}
|
||||
<details class="bwc-sb-item-setting">
|
||||
<summary>
|
||||
<span class="bwc-sb-item-text">
|
||||
{counterToString(item.count)}
|
||||
</span>
|
||||
<span class="bwc-sb-buttons">
|
||||
{#if i !== 0}
|
||||
<button
|
||||
aria-label="Move Status Bar Item Up"
|
||||
on:click={async () => {
|
||||
statusItems = swapStatusBarItems(i, i-1, statusItems);
|
||||
await update(statusItems);
|
||||
}}
|
||||
>
|
||||
↑
|
||||
</button>
|
||||
{/if}
|
||||
{#if i !== statusItems.length - 1}
|
||||
<button
|
||||
aria-label="Move Status Bar Item Down"
|
||||
on:click={async () => {
|
||||
statusItems = swapStatusBarItems(i, i+1, statusItems);
|
||||
await update(statusItems);
|
||||
}}
|
||||
>
|
||||
↓
|
||||
</button>
|
||||
{/if}
|
||||
<button
|
||||
aria-label="Remove Status Bar Item"
|
||||
on:click={async () => {
|
||||
statusItems = statusItems.filter((item, j) => i !== j);
|
||||
await update(statusItems);
|
||||
}}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</span>
|
||||
</summary>
|
||||
<div class="setting-item">
|
||||
<div class="setting-item-info">
|
||||
<div class="setting-item-name">Count Type</div>
|
||||
<div class="setting-item-description">
|
||||
This is the type of counter that will be displayed.
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item-control">
|
||||
<select
|
||||
class="dropdown"
|
||||
value={item.count}
|
||||
on:change={async (e) => {
|
||||
const {value} = e.target;
|
||||
item.count = Counter[Counter[value]];
|
||||
await update(statusItems);
|
||||
await plugin.saveSettings();
|
||||
}}
|
||||
>
|
||||
<option value>Select Option</option>
|
||||
<option value={Counter.fileWords}>{counterToString(Counter.fileWords)}</option>
|
||||
<option value={Counter.totalWords}>{counterToString(Counter.totalWords)}</option>
|
||||
<option value={Counter.fileChars}>{counterToString(Counter.fileChars)}</option>
|
||||
<option value={Counter.totalChars}>{counterToString(Counter.totalChars)}</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 update(statusItems);
|
||||
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 update(statusItems);
|
||||
await plugin.saveSettings();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
{/each}
|
||||
</div>
|
14
src/settings/StatusBarSettings.ts
Normal file
14
src/settings/StatusBarSettings.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import StatusBarSettings from "./StatusBarSettings.svelte";
|
||||
import type BetterWordCount from "../main";
|
||||
|
||||
export function addStatusBarSettings(
|
||||
plugin: BetterWordCount,
|
||||
containerEl: HTMLElement
|
||||
) {
|
||||
const statusItemsEl = containerEl.createEl("div");
|
||||
|
||||
new StatusBarSettings({
|
||||
target: statusItemsEl,
|
||||
props: { plugin },
|
||||
});
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
import {
|
||||
App,
|
||||
DropdownComponent,
|
||||
PluginSettingTab,
|
||||
Setting,
|
||||
TextAreaComponent,
|
||||
ToggleComponent,
|
||||
} from "obsidian";
|
||||
import type BetterWordCount from "../main";
|
||||
import { BetterWordCountSettings, DEFAULT_SETTINGS } from "./settings";
|
||||
|
||||
export class BetterWordCountSettingsTab extends PluginSettingTab {
|
||||
constructor(app: App, private plugin: BetterWordCount) {
|
||||
super(app, plugin);
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let { containerEl } = this;
|
||||
|
||||
containerEl.empty();
|
||||
containerEl.createEl("h2", { text: "Better Word Count Settings" });
|
||||
|
||||
// General Settings
|
||||
containerEl.createEl("h3", { text: "General Settings" });
|
||||
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."
|
||||
)
|
||||
.addToggle((cb: ToggleComponent) => {
|
||||
cb.setValue(this.plugin.settings.collectStats);
|
||||
cb.onChange(async (value: boolean) => {
|
||||
this.plugin.settings.collectStats = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName("Don't Count Comments")
|
||||
.setDesc("Turn on if you don't want markdown comments to be counted.")
|
||||
.addToggle((cb: ToggleComponent) => {
|
||||
cb.setValue(this.plugin.settings.countComments);
|
||||
cb.onChange(async (value: boolean) => {
|
||||
this.plugin.settings.countComments = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
// Status Bar Settings
|
||||
containerEl.createEl("h3", { text: "Status Bar Settings" });
|
||||
new Setting(containerEl)
|
||||
.setName("Select a Preset")
|
||||
.setDesc(
|
||||
"Presets are premade status bar expressions. Overides status bar settings."
|
||||
)
|
||||
.addDropdown((cb: DropdownComponent) => {
|
||||
PRESETS.forEach((preset: PresetOption) => {
|
||||
cb.addOption(preset.name, preset.name);
|
||||
});
|
||||
cb.setValue(this.plugin.settings.preset.name);
|
||||
|
||||
cb.onChange(async (value: string) => {
|
||||
let newPreset = PRESETS.find((preset) => preset.name === value);
|
||||
this.plugin.settings.preset = newPreset;
|
||||
this.plugin.settings.statusBarQuery = newPreset.statusBarQuery;
|
||||
this.plugin.settings.statusBarAltQuery = newPreset.statusBarAltQuery;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName("Status Bar Text")
|
||||
.setDesc("Customize the Status Bar text with this.")
|
||||
.addTextArea((cb: TextAreaComponent) => {
|
||||
cb.setPlaceholder("Enter an expression...");
|
||||
cb.setValue(this.plugin.settings.statusBarQuery);
|
||||
cb.onChange((value: string) => {
|
||||
let newPreset = PRESETS.find((preset) => preset.name === "custom");
|
||||
this.plugin.settings.preset = newPreset;
|
||||
this.plugin.settings.statusBarQuery = value;
|
||||
this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName("Alternative Status Bar Text")
|
||||
.setDesc("Customize the Alternative Status Bar text with this.")
|
||||
.addTextArea((cb: TextAreaComponent) => {
|
||||
cb.setPlaceholder("Enter an expression...");
|
||||
cb.setValue(this.plugin.settings.statusBarAltQuery);
|
||||
cb.onChange((value: string) => {
|
||||
let newPreset = PRESETS.find((preset) => preset.name === "custom");
|
||||
this.plugin.settings.preset = newPreset;
|
||||
this.plugin.settings.statusBarAltQuery = value;
|
||||
this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
this.containerEl.createEl("h3", {
|
||||
text: "Syntax for the status bars works like this: ",
|
||||
});
|
||||
|
||||
this.containerEl.createEl("li", {
|
||||
text: "To get a stat input the name of the stat in between `{}` eg. `{word_count}`.",
|
||||
});
|
||||
|
||||
this.containerEl.createEl("li", {
|
||||
text: "All other words remain.",
|
||||
});
|
||||
|
||||
this.containerEl.createEl("br");
|
||||
|
||||
this.containerEl.createEl("h4", {
|
||||
text: "Available Stats:",
|
||||
});
|
||||
|
||||
this.containerEl.createEl("p", {
|
||||
text:
|
||||
"word_count, " +
|
||||
"character_count, " +
|
||||
"sentence_count, " +
|
||||
"total_word_count, " +
|
||||
"total_character_count, " +
|
||||
"total_sentence_count, " +
|
||||
"file_count, " +
|
||||
"words_today, " +
|
||||
"characters_today, " +
|
||||
"sentences_today, ",
|
||||
});
|
||||
}
|
||||
}
|
21
src/styles.css
Normal file
21
src/styles.css
Normal file
|
@ -0,0 +1,21 @@
|
|||
details.bwc-sb-item-setting {
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 10px;
|
||||
padding: 10px 5px 20px 10px;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.bwc-sb-item-setting summary::marker {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
/* .bwc-sb-item-setting summary { */
|
||||
/* margin-bottom: 5px; */
|
||||
/* } */
|
||||
.bwc-sb-item-setting summary span.bwc-sb-buttons {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.bwc-status-bar-settings-title {
|
||||
margin-bottom: 0px;
|
||||
}
|
|
@ -12,7 +12,13 @@
|
|||
"importHelpers": true
|
||||
// "lib": ["dom", "es5", "scripthost", "es2015"]
|
||||
},
|
||||
// "include": ["**/*.ts"],
|
||||
"include": ["**/main.ts", "**/bar.ts"],
|
||||
"include": [
|
||||
"**/main.ts",
|
||||
"**/bar.ts",
|
||||
"**/Settings.ts",
|
||||
"**/SettingsTab.ts",
|
||||
"**/StatusBarSettings.ts",
|
||||
"**/StatusBarSettings.svelte"
|
||||
],
|
||||
"exclude": ["node_modules/*"]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue