mirror of
https://github.com/tekknoman/obsidian-prio-plugin.git
synced 2026-07-22 07:30:23 +00:00
feat(setting-tab): general settings now working
This commit is contained in:
parent
0c68306169
commit
10f3f10080
3 changed files with 225 additions and 22 deletions
9
main.ts
9
main.ts
|
|
@ -109,15 +109,6 @@ export default class PrioPlugin extends Plugin {
|
|||
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new SettingTab(this.app, this));
|
||||
|
||||
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
|
||||
// Using this function will automatically remove the event listener when this plugin is disabled.
|
||||
// this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
|
||||
// console.log('click', evt);
|
||||
// });
|
||||
|
||||
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
|
|
|||
57
styles.css
57
styles.css
|
|
@ -1,11 +1,4 @@
|
|||
/*
|
||||
|
||||
This CSS file will be included with your plugin, and
|
||||
available in the app when your plugin is enabled.
|
||||
|
||||
If your plugin does not need CSS, delete this file.
|
||||
|
||||
*/
|
||||
/*Preset list setting*/
|
||||
.preset-list {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
|
@ -30,10 +23,27 @@ If your plugin does not need CSS, delete this file.
|
|||
background-color: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.mod-danger {
|
||||
background-color: var(--background-modifier-error);
|
||||
color: var(--text-error);
|
||||
}
|
||||
|
||||
.mod-danger:hover {
|
||||
background-color: var(--background-modifier-error-hover);
|
||||
color: var(--text-faint);
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
background-color: var(--color-base-10) !important;
|
||||
color: var(--color-base-60) !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--interactive-accent);
|
||||
}
|
||||
|
|
@ -42,7 +52,38 @@ If your plugin does not need CSS, delete this file.
|
|||
background-color: var(--interactive-accent-hover);
|
||||
}
|
||||
|
||||
/*---------------------*/
|
||||
|
||||
/*Level Slider setting*/
|
||||
.level-text {
|
||||
max-width: 50px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
/*---------------------*/
|
||||
|
||||
/*Level aliases list setting*/
|
||||
.level-aliases-list {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.level-aliases-list-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
border-top: 1px solid var(--background-modifier-border);
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
|
||||
.level-aliases-list-item-input {
|
||||
margin-left: 5px;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
/*---------------------*/
|
||||
|
|
|
|||
|
|
@ -1,22 +1,43 @@
|
|||
import {App, PluginSettingTab, Setting, SliderComponent} from "obsidian";
|
||||
import {App, Modal, Notice, PluginSettingTab, Setting, SliderComponent} from "obsidian";
|
||||
import PrioPlugin from "../main";
|
||||
import {Preset} from "./Presets";
|
||||
import {PrioPluginSettings} from "./Settings";
|
||||
|
||||
export class SettingTab extends PluginSettingTab {
|
||||
plugin: PrioPlugin;
|
||||
saveConfirm: SaveConfirm;
|
||||
|
||||
previousSettings: PrioPluginSettings;
|
||||
|
||||
modified = false;
|
||||
|
||||
constructor(app: App, plugin: PrioPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
this.saveConfirm = new SaveConfirm(this);
|
||||
}
|
||||
|
||||
hide(): any {
|
||||
if (this.modified) {
|
||||
this.saveConfirm.open();
|
||||
return;
|
||||
}
|
||||
return super.hide();
|
||||
}
|
||||
|
||||
display(): void {
|
||||
this.previousSettings = Object.assign({}, this.plugin.settings);
|
||||
const {containerEl} = this;
|
||||
this.plugin.registerDomEvent(document, 'change', () => {
|
||||
this.modified = true;
|
||||
});
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
let presets: Preset[] = this.plugin.settings.presets ?? [];
|
||||
|
||||
const saveButton = createEl('button', {text: 'Save', cls: ['mod-cta', 'mod-primary', 'btn']});
|
||||
|
||||
|
||||
containerEl.createEl('h2', {text: 'General Settings'});
|
||||
|
||||
|
|
@ -68,6 +89,8 @@ export class SettingTab extends PluginSettingTab {
|
|||
value = 10;
|
||||
}
|
||||
levelSlider.setValue(value);
|
||||
this.plugin.settings.levels = value;
|
||||
this.generateLevelAliasList(this.plugin.settings, levelAliasesList, [saveButton]);
|
||||
});
|
||||
|
||||
this.generatePresetList(presets, presetList);
|
||||
|
|
@ -83,10 +106,70 @@ export class SettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.levels = value;
|
||||
levelText.value = value.toString();
|
||||
this.generateLevelAliasList(this.plugin.settings, levelAliasesList, [saveButton]);
|
||||
})
|
||||
.setDynamicTooltip()
|
||||
})
|
||||
});
|
||||
|
||||
new Setting(containerEl).setName('Level Aliases').setDesc('Set the aliases for each level.');
|
||||
|
||||
const levelAliasesContainer = containerEl.createEl('div');
|
||||
|
||||
const levelAliasesList = createEl('ol', {
|
||||
cls: 'level-aliases-list',
|
||||
parent: levelAliasesContainer
|
||||
});
|
||||
|
||||
this.generateLevelAliasList(this.plugin.settings, levelAliasesList, [saveButton]);
|
||||
|
||||
containerEl.append(saveButton);
|
||||
saveButton.addEventListener('click', () => {
|
||||
if (!this.isValid(levelAliasesList, [saveButton])) {
|
||||
return;
|
||||
}
|
||||
this.setAliases(this.plugin.settings, levelAliasesList);
|
||||
this.plugin.saveSettings().then(() => {
|
||||
this.plugin.loadSettings().then(() => {
|
||||
new Notice('Settings saved successfully!');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setAliases = (settings: PrioPluginSettings, levelAliasesList: HTMLOListElement) => {
|
||||
const inputs = levelAliasesList.querySelectorAll('input');
|
||||
const aliases: string[] = [];
|
||||
inputs.forEach(input => {
|
||||
aliases.push((input as HTMLInputElement).value);
|
||||
});
|
||||
aliases.map((alias, index) => {
|
||||
this.plugin.settings.levelAliases[index] = alias;
|
||||
});
|
||||
}
|
||||
|
||||
generateLevelAliasList = (settings: PrioPluginSettings, levelAliasesList: HTMLOListElement, buttons: HTMLButtonElement[]) => {
|
||||
levelAliasesList.empty();
|
||||
const els: HTMLElement[] = [];
|
||||
while (settings.levels > levelAliasesList.children.length) {
|
||||
const el = createEl('li', {
|
||||
text: `${levelAliasesList.children.length + 1}`,
|
||||
cls: 'level-aliases-list-item',
|
||||
parent: levelAliasesList
|
||||
});
|
||||
const input = el.createEl('input', {
|
||||
cls: 'level-aliases-list-item-input',
|
||||
value: settings.levelAliases[levelAliasesList.children.length - 1] ?? '',
|
||||
})
|
||||
input.addEventListener('blur', (event) => {
|
||||
const valid = this.validateLevelAlias((event.target as HTMLInputElement).value, parseInt((event.target as HTMLInputElement).parentElement?.textContent ?? '') - 1, settings.levelAliases.slice(0, settings.levels));
|
||||
for (const button of buttons) {
|
||||
button.disabled = !valid;
|
||||
}
|
||||
});
|
||||
els.push(el);
|
||||
}
|
||||
|
||||
return els;
|
||||
}
|
||||
|
||||
generatePresetList = (presets: Preset[], presetList: HTMLOListElement) => (presets || []).map(preset => {
|
||||
|
|
@ -100,14 +183,14 @@ export class SettingTab extends PluginSettingTab {
|
|||
});
|
||||
|
||||
btnGroup.createEl('button', {
|
||||
text: 'Select',
|
||||
cls: ['preset-list-item-select', 'btn', 'btn-primary'],
|
||||
text: 'Apply',
|
||||
cls: ['preset-list-item-apply', 'btn', 'btn-primary'],
|
||||
attr: {
|
||||
'onclick': 'alert("Preset Selected")'
|
||||
}
|
||||
})
|
||||
btnGroup.createEl('button', {
|
||||
text: 'Save',
|
||||
text: 'Overwrite',
|
||||
cls: ['preset-list-item-save', 'btn', 'btn-primary'],
|
||||
attr: {
|
||||
'onclick': 'alert("Save Preset")'
|
||||
|
|
@ -115,4 +198,92 @@ export class SettingTab extends PluginSettingTab {
|
|||
})
|
||||
return el;
|
||||
});
|
||||
|
||||
isValid = (levelAliasesList: HTMLOListElement, buttons: HTMLButtonElement[]) => {
|
||||
const inputs = levelAliasesList.querySelectorAll('input');
|
||||
const aliases: string[] = [];
|
||||
inputs.forEach(input => {
|
||||
aliases.push((input as HTMLInputElement).value);
|
||||
});
|
||||
if (aliases.length !== new Set(aliases).size) {
|
||||
new Notice('Level aliases must be unique.');
|
||||
return false;
|
||||
}
|
||||
if (aliases.some(alias => alias.length === 0)) {
|
||||
new Notice('Level aliases must not be empty.');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
validateLevelAlias = (alias: string, index: number, aliases: string[]) => {
|
||||
if (aliases.indexOf(alias) != index && aliases.includes(alias)) {
|
||||
new Notice('Alias already exists!');
|
||||
return false;
|
||||
}
|
||||
if (alias.length < 1) {
|
||||
new Notice('Alias must be at least 1 character long!');
|
||||
return false;
|
||||
}
|
||||
if (alias.match(/[^a-zA-Z0-9]/)) {
|
||||
new Notice('Alias must only contain alphanumeric characters!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class SaveConfirm extends Modal {
|
||||
private settingsTab: SettingTab;
|
||||
|
||||
constructor(settingsTab: SettingTab) {
|
||||
super(settingsTab.app);
|
||||
this.settingsTab = settingsTab;
|
||||
}
|
||||
|
||||
open() {
|
||||
super.open();
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
const {contentEl} = this;
|
||||
contentEl.setText('You have unsaved changes. Would you like to save them?');
|
||||
|
||||
const btnGroup = contentEl.createEl('div', {
|
||||
cls: 'save-btn-group'
|
||||
});
|
||||
|
||||
const saveButton = createEl('button', {
|
||||
text: 'Save',
|
||||
cls: ['btn', 'mod-cta'],
|
||||
});
|
||||
const discardButton = createEl('button', {
|
||||
text: 'Discard',
|
||||
cls: ['btn', 'mod-danger'],
|
||||
});
|
||||
|
||||
saveButton.addEventListener('click', () => {
|
||||
this.settingsTab.plugin.saveSettings().then(() => {
|
||||
this.settingsTab.plugin.loadSettings().then(() => {
|
||||
new Notice('Settings saved successfully!');
|
||||
});
|
||||
});
|
||||
this.close();
|
||||
});
|
||||
|
||||
discardButton.addEventListener('click', () => {
|
||||
this.settingsTab.plugin.loadSettings().then(() => {
|
||||
new Notice('Settings discarded successfully!');
|
||||
});
|
||||
this.close();
|
||||
});
|
||||
|
||||
btnGroup.append(saveButton);
|
||||
btnGroup.append(discardButton);
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const {contentEl} = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue