mirror of
https://github.com/ebullient/obsidian-deck-notes.git
synced 2026-07-22 06:40:43 +00:00
🎨 Use 1.13.0 Settings API
This commit is contained in:
parent
990113e1e6
commit
f279ae3297
6 changed files with 189 additions and 154 deletions
|
|
@ -2,7 +2,7 @@
|
|||
"id": "deck-notes",
|
||||
"name": "Deck Notes",
|
||||
"version": "0.7.6",
|
||||
"minAppVersion": "1.12.0",
|
||||
"minAppVersion": "1.13.0",
|
||||
"description": "Define card decks for activities, strategies, or any content you want to rotate through. Embed cards in your notes or browse them in a modal. Filter by tag hierarchies to narrow your selection.",
|
||||
"author": "ebullient",
|
||||
"authorUrl": "https://github.com/ebullient",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "deck-notes",
|
||||
"name": "Deck Notes",
|
||||
"version": "0.7.6",
|
||||
"minAppVersion": "1.12.0",
|
||||
"minAppVersion": "1.13.0",
|
||||
"description": "Define card decks for activities, strategies, or any content you want to rotate through. Embed cards in your notes or browse them in a modal. Filter by tag hierarchies to narrow your selection.",
|
||||
"author": "ebullient",
|
||||
"authorUrl": "https://github.com/ebullient",
|
||||
|
|
|
|||
23
package-lock.json
generated
23
package-lock.json
generated
|
|
@ -15,7 +15,7 @@
|
|||
"auto-changelog": "^2.5.0",
|
||||
"esbuild": "^0.28.0",
|
||||
"eslint-plugin-obsidianmd": "^0.3.0",
|
||||
"obsidian": "^1.12.3",
|
||||
"obsidian": "^1.13.0",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "6.0.2"
|
||||
}
|
||||
|
|
@ -2432,6 +2432,21 @@
|
|||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-obsidianmd/node_modules/obsidian": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.12.3.tgz",
|
||||
"integrity": "sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/codemirror": "5.60.8",
|
||||
"moment": "2.29.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/state": "6.5.0",
|
||||
"@codemirror/view": "6.38.6"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-obsidianmd/node_modules/typescript": {
|
||||
"version": "5.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||
|
|
@ -3992,9 +4007,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/obsidian": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.12.3.tgz",
|
||||
"integrity": "sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw==",
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.13.0.tgz",
|
||||
"integrity": "sha512-PHw5+SAPlJ0S3leFvJ0wgFg63Z3DavxL6+d1ll+8toXR2ZlYKc1rMWqdUv9LgUbTwPQUyY6yfhOMMivampRRiQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
"auto-changelog": "^2.5.0",
|
||||
"esbuild": "^0.28.0",
|
||||
"eslint-plugin-obsidianmd": "^0.3.0",
|
||||
"obsidian": "^1.12.3",
|
||||
"obsidian": "^1.13.0",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "6.0.2"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import { type App, PluginSettingTab, Setting } from "obsidian";
|
||||
import type { DeckNotesSettings } from "./@types/settings";
|
||||
import {
|
||||
type App,
|
||||
Modal,
|
||||
PluginSettingTab,
|
||||
Setting,
|
||||
type SettingDefinitionItem,
|
||||
type Setting as SettingType,
|
||||
} from "obsidian";
|
||||
import type DeckNotesPlugin from "./dn-Plugin";
|
||||
|
||||
export class DeckNotesSettingsTab extends PluginSettingTab {
|
||||
plugin: DeckNotesPlugin;
|
||||
newSettings!: DeckNotesSettings;
|
||||
|
||||
constructor(app: App, plugin: DeckNotesPlugin) {
|
||||
super(app, plugin);
|
||||
|
|
@ -12,155 +17,171 @@ export class DeckNotesSettingsTab extends PluginSettingTab {
|
|||
this.icon = "gallery-thumbnails";
|
||||
}
|
||||
|
||||
async save() {
|
||||
this.plugin.settings = this.newSettings;
|
||||
async setControlValue(key: string, value: unknown): Promise<void> {
|
||||
(this.plugin.settings as unknown as Record<string, unknown>)[key] =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
}
|
||||
|
||||
private cloneSettings(): DeckNotesSettings {
|
||||
return JSON.parse(
|
||||
JSON.stringify(this.plugin.settings),
|
||||
) as DeckNotesSettings;
|
||||
}
|
||||
getSettingDefinitions(): SettingDefinitionItem[] {
|
||||
return [
|
||||
{
|
||||
name: "Usage",
|
||||
render: (setting: SettingType) => {
|
||||
setting.descEl.appendChild(
|
||||
createFragment((f) => {
|
||||
const p = f.createEl("p");
|
||||
p.appendText(
|
||||
"Cards are created from markdown files with ",
|
||||
);
|
||||
p.createEl("code", { text: "##" });
|
||||
p.appendText(" headings.");
|
||||
|
||||
reset() {
|
||||
this.newSettings = this.cloneSettings();
|
||||
this.display();
|
||||
}
|
||||
const ul = f.createEl("ul");
|
||||
|
||||
display(): void {
|
||||
if (!this.newSettings) {
|
||||
this.newSettings = this.cloneSettings();
|
||||
}
|
||||
const li1 = ul.createEl("li");
|
||||
li1.appendText("Use ");
|
||||
li1.createEl("code", { text: "---" });
|
||||
li1.appendText(
|
||||
" (horizontal rule) to mark the end of card content.",
|
||||
);
|
||||
|
||||
const { containerEl } = this;
|
||||
containerEl.empty();
|
||||
|
||||
new Setting(this.containerEl)
|
||||
.setName("Save settings")
|
||||
.setClass("decknotes-save-reset")
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setIcon("reset")
|
||||
.setTooltip("Reset to previously saved values.")
|
||||
.onClick(() => {
|
||||
this.reset();
|
||||
}),
|
||||
)
|
||||
.addButton((button) => {
|
||||
button
|
||||
.setIcon("save")
|
||||
.setCta()
|
||||
.setTooltip("Save all changes")
|
||||
.onClick(async () => {
|
||||
await this.save();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Card paths")
|
||||
.setDesc(
|
||||
"Paths to folders containing card decks; " +
|
||||
"one path relative to vault root per line.",
|
||||
)
|
||||
.addTextArea((text) =>
|
||||
text
|
||||
.setPlaceholder("journal/coping\nactivities/morning")
|
||||
.setValue(this.newSettings.cardPaths.join("\n"))
|
||||
.onChange((value) => {
|
||||
this.newSettings.cardPaths = value
|
||||
.split("\n")
|
||||
.map((p) => p.trim())
|
||||
.filter((p) => p.length > 0);
|
||||
}),
|
||||
)
|
||||
.then((setting) => {
|
||||
setting.controlEl
|
||||
.querySelector("textarea")
|
||||
?.setAttribute("rows", "4");
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Default deck tag")
|
||||
.setDesc(
|
||||
"Optional tag to narrow the selection of cards " +
|
||||
"available for 'Show Card' command; for example, " +
|
||||
"'activities' or 'activities/morning'.",
|
||||
)
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("Activities")
|
||||
.setValue(this.newSettings.defaultDeckTag)
|
||||
.onChange((value) => {
|
||||
this.newSettings.defaultDeckTag = value.trim();
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Selection mode")
|
||||
.setDesc(
|
||||
"Cards can be selected at random or based on " +
|
||||
"when they were last viewed.",
|
||||
)
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption("random", "Random")
|
||||
.addOption("least-recent", "Least recently viewed")
|
||||
.setValue(this.newSettings.selectionMode)
|
||||
.onChange((value) => {
|
||||
this.newSettings.selectionMode = value as
|
||||
| "random"
|
||||
| "least-recent";
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Callout type")
|
||||
.setDesc(
|
||||
"Callout type for embedded cards; " +
|
||||
"for example, note, tip, or warning.",
|
||||
)
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("example")
|
||||
.setValue(this.newSettings.calloutType)
|
||||
.onChange((value) => {
|
||||
this.newSettings.calloutType = value.trim();
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(containerEl).setHeading().setName("Usage");
|
||||
|
||||
containerEl.createEl("p", {
|
||||
text:
|
||||
"Cards are created from markdown files with " +
|
||||
"H2 headings (##). Each heading becomes one card.",
|
||||
});
|
||||
containerEl.createEl("p", {
|
||||
text:
|
||||
"Use --- (horizontal rule) to mark the end of " +
|
||||
"card content. Anything after --- will be ignored.",
|
||||
});
|
||||
containerEl.createEl("p", {
|
||||
text:
|
||||
"Tag cards with #flashcards/deck-name; for example, " +
|
||||
"#flashcards/activities/morning. Tags can be in " +
|
||||
"frontmatter or inline before each H2. Lines starting " +
|
||||
"with #flashcards are stripped from display.",
|
||||
});
|
||||
|
||||
const div = this.containerEl.createDiv("deck-cards-coffee");
|
||||
div.createEl("a", {
|
||||
href: "https://www.buymeacoffee.com/ebullient",
|
||||
}).createEl("img", {
|
||||
attr: {
|
||||
src: "https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=☕&slug=ebullient&button_colour=8e6787&font_colour=ebebeb&font_family=Inter&outline_colour=392a37&coffee_colour=ecc986",
|
||||
const li2 = ul.createEl("li");
|
||||
li2.appendText("Use ");
|
||||
li2.createEl("code", {
|
||||
text: "#flashcards",
|
||||
});
|
||||
li2.appendText(
|
||||
" tags to identify decks. For example, ",
|
||||
);
|
||||
li2.createEl("code", {
|
||||
text: "#flashcards/activities",
|
||||
});
|
||||
li2.appendText(" or ");
|
||||
li2.createEl("code", {
|
||||
text: "#flashcards/meditation",
|
||||
});
|
||||
li2.appendText(
|
||||
". Tags can be added to the whole file (in frontmatter properties), or defined inline before each ",
|
||||
);
|
||||
li2.createEl("code", { text: "##" });
|
||||
li2.appendText(". See the ");
|
||||
li2.createEl("a", {
|
||||
text: "README",
|
||||
href: "https://github.com/ebullient/obsidian-deck-notes#card-format",
|
||||
attr: { target: "_blank" },
|
||||
});
|
||||
li2.appendText(" for examples.");
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** Save on exit */
|
||||
hide(): void {
|
||||
void this.save();
|
||||
{
|
||||
name: "Default deck tag",
|
||||
desc:
|
||||
"Optional tag to narrow the selection of cards available " +
|
||||
"for 'Show Card' command; for example, 'activities' or " +
|
||||
"'activities/morning'.",
|
||||
control: {
|
||||
type: "text",
|
||||
key: "defaultDeckTag",
|
||||
placeholder: "activities",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Selection mode",
|
||||
desc: "Cards can be selected at random or based on when they were last viewed.",
|
||||
control: {
|
||||
type: "dropdown",
|
||||
key: "selectionMode",
|
||||
options: {
|
||||
random: "Random",
|
||||
"least-recent": "Least recently viewed",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Callout type",
|
||||
desc: "Callout type for embedded cards; for example, note, tip, or warning.",
|
||||
control: {
|
||||
type: "text",
|
||||
key: "calloutType",
|
||||
placeholder: "example",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
heading: "Card paths",
|
||||
desc: "Paths to folders containing card decks, relative to vault root.",
|
||||
emptyState: "No card paths configured.",
|
||||
addItem: {
|
||||
name: "Add path",
|
||||
action: () =>
|
||||
new AddCardPathModal(this.app, (path) => {
|
||||
this.plugin.settings.cardPaths.push(path);
|
||||
void this.plugin.saveSettings();
|
||||
this.update();
|
||||
}).open(),
|
||||
},
|
||||
onDelete: async (idx: number) => {
|
||||
this.plugin.settings.cardPaths.splice(idx, 1);
|
||||
await this.plugin.saveSettings();
|
||||
this.update();
|
||||
},
|
||||
items: this.plugin.settings.cardPaths.map((path) => ({
|
||||
name: path,
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
render: (setting: SettingType) => {
|
||||
setting.descEl.addClass("deck-cards-coffee");
|
||||
setting.descEl
|
||||
.createEl("a", {
|
||||
href: "https://www.buymeacoffee.com/ebullient",
|
||||
})
|
||||
.createEl("img", {
|
||||
attr: {
|
||||
src: "https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=☕&slug=ebullient&button_colour=8e6787&font_colour=ebebeb&font_family=Inter&outline_colour=392a37&coffee_colour=ecc986",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class AddCardPathModal extends Modal {
|
||||
private onSubmit: (path: string) => void;
|
||||
|
||||
constructor(app: App, onSubmit: (path: string) => void) {
|
||||
super(app);
|
||||
this.onSubmit = onSubmit;
|
||||
}
|
||||
|
||||
onOpen(): void {
|
||||
const { contentEl } = this;
|
||||
contentEl.createEl("h2", { text: "Add card path" });
|
||||
let input = "";
|
||||
new Setting(contentEl).setName("Path").addText((t) =>
|
||||
t.setPlaceholder("journal/coping").onChange((v) => {
|
||||
input = v.trim();
|
||||
}),
|
||||
);
|
||||
new Setting(contentEl).addButton((b) =>
|
||||
b
|
||||
.setButtonText("Add")
|
||||
.setCta()
|
||||
.onClick(() => {
|
||||
if (input) {
|
||||
this.onSubmit(input);
|
||||
this.close();
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
onClose(): void {
|
||||
this.contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
.deck-cards-coffee {
|
||||
text-align: center;
|
||||
img {
|
||||
margin: auto;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue