From 0897e08647ac6158c31d99383dd65e21381c5f1e Mon Sep 17 00:00:00 2001 From: Jeremy Valentine <38669521+valentine195@users.noreply.github.com> Date: Thu, 26 Jan 2023 20:14:00 -0500 Subject: [PATCH] feat: adds admonition exporting --- src/modal/export.ts | 66 +++++++++++++++++++++++++++++++++++++++++++++ src/settings.ts | 54 +++++++++++++++++++++++++++++++++++-- 2 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/modal/export.ts diff --git a/src/modal/export.ts b/src/modal/export.ts new file mode 100644 index 0000000..f4709e8 --- /dev/null +++ b/src/modal/export.ts @@ -0,0 +1,66 @@ +import { Modal, Setting } from "obsidian"; +import ObsidianAdmonition from "src/main"; + +export default class Export extends Modal { + constructor(public plugin: ObsidianAdmonition) { + super(app); + } + admonitionDefinitions = Object.values(this.plugin.data.userAdmonitions); + + admonitionNames = Object.keys(this.plugin.data.userAdmonitions); + + selectedAdmonitions = [...this.admonitionNames]; + + export = false; + + onOpen() { + this.titleEl.setText("Export Admonitions"); + this.containerEl.addClasses([ + "admonition-settings", + "admonition-modal", + "admonition-export-modal" + ]); + new Setting(this.contentEl).addButton((b) => + b.setButtonText("Export Selected").onClick(() => { + this.export = true; + this.close(); + }) + ); + let toggleEl: HTMLDivElement; + new Setting(this.contentEl) + .addButton((b) => + b + .setButtonText("Select All") + .setCta() + .onClick(() => { + this.selectedAdmonitions = [...this.admonitionNames]; + this.generateToggles(toggleEl); + }) + ) + .addButton((b) => + b.setButtonText("Deselect All").onClick(() => { + this.selectedAdmonitions = []; + this.generateToggles(toggleEl); + }) + ); + toggleEl = this.contentEl.createDiv("additional"); + this.generateToggles(toggleEl); + } + + generateToggles(toggleEl: HTMLDivElement) { + toggleEl.empty(); + for (const name of this.admonitionNames) { + new Setting(toggleEl).setName(name).addToggle((t) => { + t.setValue(this.selectedAdmonitions.includes(name)).onChange( + (v) => { + if (v) { + this.selectedAdmonitions.push(name); + } else { + this.selectedAdmonitions.remove(name); + } + } + ); + }); + } + } +} diff --git a/src/settings.ts b/src/settings.ts index f3e7690..abb1b1d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -35,6 +35,7 @@ import ObsidianAdmonition from "./main"; import { confirmWithModal } from "./modal/confirm"; import { DownloadableIconPack, DownloadableIcons } from "./icons/packs"; import { AdmonitionValidator } from "./util/validator"; +import Export from "./modal/export"; /** Taken from https://stackoverflow.com/questions/34849001/check-if-css-selector-is-valid/42149818 */ const isSelectorValid = ((dummyElement) => (selector: string) => { @@ -93,6 +94,40 @@ export default class AdmonitionSetting extends PluginSettingTab { ); } + new Setting(admonitionEl) + .setName("Export Custom Types as JSON") + .setDesc( + "Choose custom types to export as a JSON file that you can then share with other users." + ) + .addButton((b) => + b + .setButtonText("Download All") + .setCta() + .onClick(() => { + const admonitions = Object.values( + this.plugin.data.userAdmonitions + ); + this.download(admonitions); + }) + ) + .addButton((b) => + b.setButtonText("Select & Download").onClick(() => { + const modal = new Export(this.plugin); + modal.onClose = () => { + if (!modal.export) return; + const admonitions = Object.values( + this.plugin.data.userAdmonitions + ); + this.download( + admonitions.filter((a) => + modal.selectedAdmonitions.includes(a.type) + ) + ); + }; + modal.open(); + }) + ); + new Setting(admonitionEl) .setName("Use CSS Snippet for Custom Callouts") .setDesc( @@ -307,7 +342,21 @@ export default class AdmonitionSetting extends PluginSettingTab { } }); } - + download(admonitions: Admonition[]) { + if (!admonitions.length) { + new Notice("At least one admonition must be chosen to export."); + return; + } + const link = createEl("a"); + const file = new Blob([JSON.stringify(admonitions)], { + type: "json" + }); + const url = URL.createObjectURL(file); + link.href = url; + link.download = `admonitions.json`; + link.click(); + URL.revokeObjectURL(url); + } buildAdmonitions(containerEl: HTMLDetailsElement) { containerEl.empty(); containerEl.ontoggle = () => { @@ -462,7 +511,8 @@ export default class AdmonitionSetting extends PluginSettingTab { let selected: DownloadableIconPack; const possibilities = Object.entries(DownloadableIcons).filter( - ([icon]) => !this.plugin.data.icons.includes(icon) + ([icon]) => + !this.plugin.data.icons.includes(icon as DownloadableIconPack) ); new Setting(containerEl) .setName("Load Additional Icons")