Finish Settings

This commit is contained in:
Luke Leppan 2022-11-08 06:45:18 +02:00
parent 3192b681b8
commit 1ae2418394
No known key found for this signature in database
GPG key ID: AE403C75AFBBC102
10 changed files with 341 additions and 159 deletions

View file

@ -41,6 +41,7 @@
"typescript": "^4.0.3"
},
"dependencies": {
"svelte": "^3.38.3"
"svelte": "^3.38.3",
"svelte-icons": "^2.1.0"
}
}

View file

@ -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,
}),
],
};

View file

@ -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) {

View file

@ -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;

View 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);
}
}

View 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>

View 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 },
});
}

View file

@ -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
View 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;
}

View file

@ -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/*"]
}