obsidian#setIcon TypeScript Examples

The following examples show how to use obsidian#setIcon. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 6 votes vote down vote up
displayPlayers(containerEl: HTMLDivElement) {
        containerEl.empty();
        if (this.party.players.length) {
            for (const player of this.party.players) {
                new Setting(containerEl).setName(player).addExtraButton((b) => {
                    b.setIcon("trash").onClick(() => {
                        this.party.players.splice(
                            this.party.players.indexOf(player),
                            1
                        );
                        this.displayPlayers(containerEl);
                    });
                });
            }
        } else {
            containerEl
                .createDiv({
                    attr: {
                        style: "display: flex; justify-content: center; padding-bottom: 18px;"
                    }
                })
                .createSpan({
                    text: "Add a player to the party to see it here."
                });
        }
    }
Example #2
Source File: PumlView.ts    From obsidian-plantuml with MIT License 6 votes vote down vote up
setState(state: any, result: ViewStateResult): Promise<void> {
        // switch to preview mode
        if (state.mode === 'preview') {
            this.currentView = 'preview';
            setIcon(this.changeModeButton, 'pencil');
            this.changeModeButton.setAttribute('aria-label', 'Edit (Ctrl+Click to edit in new pane)');

            this.previewEl.style.setProperty('display', 'block');
            this.sourceEl.style.setProperty('display', 'none');
            this.renderPreview();
        }
        // switch to source mode
        else {
            this.currentView = 'source';
            setIcon(this.changeModeButton, 'lines-of-text');
            this.changeModeButton.setAttribute('aria-label', 'Preview (Ctrl+Click to open in new pane)');

            this.previewEl.style.setProperty('display', 'none');
            this.sourceEl.style.setProperty('display', 'block');
            //this.editor.refresh();
        }

        return super.setState(state, result);
    }
Example #3
Source File: main.ts    From obsidian-customizable-sidebar with MIT License 6 votes vote down vote up
setAttributes(pin: HTMLElement, sidebar: HTMLElement, value: boolean) {
		if ( value ) {
			setIcon(pin, "filled-pin");

			pin.addClass("is-pinned");
			sidebar.addClass("is-pinned");

			pin.removeClass("is-floating");
			sidebar.removeClass("is-floating");
		} else {
			setIcon(pin, "pin");

			pin.removeClass("is-pinned");
			sidebar.removeClass("is-pinned");

			pin.addClass("is-floating");
			sidebar.addClass("is-floating");
		}
	}
Example #4
Source File: manager.ts    From obsidian-admonition with MIT License 6 votes vote down vote up
getIconNode(icon: AdmonitionIconDefinition): Element {
        if (icon.type === "image") {
            const img = new Image();
            img.src = icon.name;
            return img;
        }
        if (icon.type == "obsidian") {
            const el = createDiv();
            setIcon(el, icon.name);
            return el;
        }
        if (this.DOWNLOADED[icon.type as DownloadableIconPack]?.[icon.name]) {
            const el = createDiv();
            el.innerHTML =
                this.DOWNLOADED[icon.type as DownloadableIconPack]?.[icon.name];
            return el.children[0];
        }
        for (const prefix of ["fas", "far", "fab"] as IconPrefix[]) {
            const definition = findIconDefinition({
                iconName: icon.name as IconName,
                prefix
            });
            if (definition) return getFAIcon(definition).node[0];
        }
    }
Example #5
Source File: main.ts    From obsidian-admonition with MIT License 6 votes vote down vote up
getAdmonitionContentElement(
        type: string,
        admonitionElement: HTMLElement,
        content: string
    ) {
        const contentEl = admonitionElement.createDiv(
            "callout-content admonition-content"
        );
        if (this.admonitions[type].copy ?? this.data.copyButton) {
            let copy = contentEl.createDiv("admonition-content-copy");
            setIcon(copy, "copy");
            copy.addEventListener("click", () => {
                navigator.clipboard.writeText(content.trim()).then(async () => {
                    new Notice("Admonition content copied to clipboard.");
                });
            });
        }
        return contentEl;
    }
Example #6
Source File: utils.ts    From obsidian-fantasy-calendar with MIT License 6 votes vote down vote up
export function warning(node: HTMLElement) {
    setIcon(node, "fantasy-calendar-warning");
}
Example #7
Source File: settings.ts    From obsidian-fantasy-calendar with MIT License 5 votes vote down vote up
showCalendars() {
        this.existingEl.empty();
        if (!this.data.calendars.length) {
            this.existingEl.createSpan({
                text: "No calendars created! Create a calendar to see it here."
            });
            return;
        }
        for (let calendar of this.data.calendars) {
            new Setting(this.existingEl)
                .setName(calendar.name)
                .setDesc(calendar.description ?? "")
                .addExtraButton((b) => {
                    b.setIcon("pencil").onClick(async () => {
                        const edited = await this.launchCalendarCreator(
                            calendar
                        );
                        if (edited) {
                            this.plugin.addNewCalendar(edited, calendar);
                            await this.plugin.saveCalendar();
                            this.display();
                        }
                    });
                })
                .addExtraButton((b) => {
                    b.setIcon("trash").onClick(async () => {
                        if (
                            !this.plugin.data.exit.calendar &&
                            !(await confirmDeleteCalendar(this.plugin))
                        )
                            return;

                        this.plugin.data.calendars =
                            this.plugin.data.calendars.filter(
                                (c) => c.id != calendar.id
                            );
                        if (calendar.id == this.data.defaultCalendar) {
                            this.plugin.data.defaultCalendar =
                                this.plugin.data.calendars[0]?.id;
                            this.plugin.watcher.start();
                        }
                        await this.plugin.saveCalendar();

                        this.display();
                    });
                });
        }
    }
Example #8
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 5 votes vote down vote up
onOpen() {
        this.titleEl.setText(this.editing ? "Edit Status" : "New Status");

        const name = new Setting(this.contentEl)
            .setName("Name")
            .addText((t) => {
                t.setValue(this.status.name).onChange((v) => {
                    this.status.name = v;
                    if (
                        this.plugin.data.statuses.find(
                            (s) => s.name == this.status.name
                        ) &&
                        !this.warned &&
                        this.original != this.status.name
                    ) {
                        this.warned = true;
                        name.setDesc(
                            createFragment((e) => {
                                const container = e.createDiv(
                                    "initiative-tracker-warning"
                                );
                                setIcon(
                                    container,
                                    "initiative-tracker-warning"
                                );
                                container.createSpan({
                                    text: "A status by this name already exists and will be overwritten."
                                });
                            })
                        );
                    } else if (this.warned) {
                        this.warned = false;
                        name.setDesc("");
                    }
                });
            });
        new Setting(this.contentEl).setName("Description").addTextArea((t) => {
            t.setValue(this.status.description).onChange(
                (v) => (this.status.description = v)
            );
        });

        new ButtonComponent(
            this.contentEl.createDiv("initiative-tracker-cancel")
        )
            .setButtonText("Cancel")
            .onClick(() => {
                this.canceled = true;
                this.close();
            });
    }
Example #9
Source File: iconPicker.ts    From obsidian-customizable-sidebar with MIT License 5 votes vote down vote up
renderSuggestion(item: FuzzyMatch<string>, el: HTMLElement): void {
		el.addClass("CS-icon-container");
		const div = createDiv({ cls: "CS-icon" });
		el.appendChild(div);
		setIcon(div, item.item);
		super.renderSuggestion(item, el);
	}
Example #10
Source File: manager.ts    From obsidian-admonition with MIT License 5 votes vote down vote up
calloutProcessor(el: HTMLElement, ctx: MarkdownPostProcessorContext) {
        const callout = el?.querySelector<HTMLDivElement>(".callout");
        if (!callout) return;
        //apply metadata

        const type = callout.dataset.callout;
        const admonition = this.plugin.admonitions[type];
        if (!admonition) return;

        const titleEl = callout.querySelector<HTMLDivElement>(".callout-title");
        const content =
            callout.querySelector<HTMLDivElement>(".callout-content");

        const section = ctx.getSectionInfo(el);
        if (section) {
            const { text, lineStart, lineEnd } = section;
            const definition = text.split("\n")[lineStart];

            const [, metadata] = definition.match(/> \[!.+\|(.*)]/) ?? [];
            if (metadata) {
                callout.dataset.calloutMetadata = metadata;
            }

            if (
                this.plugin.admonitions[type].copy ??
                this.plugin.data.copyButton
            ) {
                let copy = content.createDiv("admonition-content-copy");
                setIcon(copy, "copy");
                copy.addEventListener("click", () => {
                    navigator.clipboard
                        .writeText(
                            text
                                .split("\n")
                                .slice(lineStart + 1, lineEnd + 1)
                                .join("\n")
                                .replace(/^> /gm, "")
                        )
                        .then(async () => {
                            new Notice("Callout content copied to clipboard.");
                        });
                });
            }
        }

        if (admonition.noTitle && !callout.dataset.calloutFold) {
            titleEl.addClass("no-title");
        }
        if (
            !admonition.noTitle &&
            this.plugin.data.autoCollapse &&
            !callout.dataset.calloutFold
        ) {
            this.setCollapsible(callout);
        }

        if (
            admonition.title &&
            titleEl.textContent ==
                type[0].toUpperCase() + type.slice(1).toLowerCase()
        ) {
            const titleContentEl = titleEl.querySelector<HTMLDivElement>(
                ".callout-title-inner"
            );
            if (titleContentEl) {
                titleContentEl.setText(admonition.title);
            }
        }
        if (this.plugin.data.dropShadow) {
            callout.addClass("drop-shadow");
        }
    }
Example #11
Source File: manager.ts    From obsidian-admonition with MIT License 5 votes vote down vote up
setCollapsible(callout: HTMLElement) {
        const titleEl = callout.querySelector<HTMLDivElement>(".callout-title");
        const content =
            callout.querySelector<HTMLDivElement>(".callout-content");

        if (!content) return;
        callout.addClass("is-collapsible");
        if (this.plugin.data.defaultCollapseType == "closed") {
            callout.dataset.calloutFold = "-";
            callout.addClass("is-collapsed");
        } else {
            callout.dataset.calloutFold = "+";
        }

        const iconEl = titleEl.createDiv("callout-fold");

        setIcon(iconEl, "chevron-down");

        let collapsed = callout.hasClass("is-collapsed");

        this.getComputedHeights(content);

        if (collapsed) {
            for (const prop of this.heights) {
                content.style.setProperty(prop, "0px");
            }
        }
        titleEl.onclick = (event: MouseEvent) => {
            event.preventDefault();

            function transitionEnd(evt: TransitionEvent) {
                content.removeEventListener("transitionend", transitionEnd);
                content.style.removeProperty("transition");
            }
            content.addEventListener("transitionend", transitionEnd);
            content.style.setProperty(
                "transition",
                "all 100ms cubic-bezier(.02, .01, .47, 1)"
            );
            collapsed = callout.hasClass("is-collapsed");
            if (event.button == 0) {
                for (const prop of this.heights) {
                    const heights = this.getComputedHeights(content);
                    content.style.setProperty(
                        prop,
                        collapsed ? heights[prop] : "0px"
                    );
                }

                callout.toggleClass("is-collapsed", !collapsed);
            }
        };
    }
Example #12
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
private _displayPlayers(additionalContainer: HTMLDetailsElement) {
        additionalContainer.empty();
        additionalContainer.ontoggle = () => {
            this.plugin.data.openState.player = additionalContainer.open;
        };
        const summary = additionalContainer.createEl("summary");
        new Setting(summary).setHeading().setName("Players");
        summary.createDiv("collapser").createDiv("handle");
        new Setting(additionalContainer)
            .setName("Add New Player")
            .setDesc(
                "Players added here will be available to add to a party. If you do not have a party created, all players will be added to a new encounter."
            )
            .addButton((button: ButtonComponent): ButtonComponent => {
                let b = button
                    .setTooltip("Add Player")
                    .setButtonText("+")
                    .onClick(async () => {
                        const modal = new NewPlayerModal(this.plugin);
                        modal.open();
                        modal.onClose = async () => {
                            if (!modal.saved) return;

                            await this.plugin.savePlayer({
                                ...modal.player,
                                player: true
                            });

                            this._displayPlayers(additionalContainer);
                        };
                    });

                return b;
            });
        const additional = additionalContainer.createDiv("additional");
        const playerView = additional.createDiv("initiative-tracker-players");
        if (!this.plugin.data.players.length) {
            additional
                .createDiv({
                    attr: {
                        style: "display: flex; justify-content: center; padding-bottom: 18px;"
                    }
                })
                .createSpan({
                    text: "No saved players! Create one to see it here."
                });
        } else {
            const headers = playerView.createDiv(
                "initiative-tracker-player headers"
            );

            headers.createDiv({ text: "Name" });
            new ExtraButtonComponent(headers.createDiv())
                .setIcon(HP)
                .setTooltip("Max HP");
            new ExtraButtonComponent(headers.createDiv())
                .setIcon(AC)
                .setTooltip("Armor Class");
            new ExtraButtonComponent(headers.createDiv())
                .setIcon(INITIATIVE)
                .setTooltip("Initiative Modifier");

            headers.createDiv();

            for (let player of this.plugin.data.players) {
                const playerDiv = playerView.createDiv(
                    "initiative-tracker-player"
                );
                playerDiv.createDiv({ text: player.name });
                playerDiv.createDiv({
                    text: `${player.hp ?? DEFAULT_UNDEFINED}`
                });
                playerDiv.createDiv({
                    text: `${player.ac ?? DEFAULT_UNDEFINED}`
                });
                playerDiv.createDiv({
                    text: `${player.modifier ?? DEFAULT_UNDEFINED}`
                });
                const icons = playerDiv.createDiv(
                    "initiative-tracker-player-icon"
                );
                new ExtraButtonComponent(icons.createDiv())
                    .setIcon("pencil")
                    .setTooltip("Edit")
                    .onClick(() => {
                        const modal = new NewPlayerModal(this.plugin, player);
                        modal.open();
                        modal.onClose = async () => {
                            if (!modal.saved) return;
                            await this.plugin.updatePlayer(
                                player,
                                modal.player
                            );
                            this.plugin.app.workspace.trigger(
                                "initiative-tracker:creature-updated-in-settings",
                                player
                            );

                            this._displayPlayers(additionalContainer);
                        };
                    });
                new ExtraButtonComponent(icons.createDiv())
                    .setIcon("trash")
                    .setTooltip("Delete")
                    .onClick(async () => {
                        this.plugin.data.players =
                            this.plugin.data.players.filter((p) => p != player);

                        await this.plugin.saveSettings();
                        this._displayPlayers(additionalContainer);
                    });
            }
        }
    }
Example #13
Source File: settings.ts    From obsidian-admonition with MIT License 4 votes vote down vote up
async display(): Promise<void> {
        this.containerEl.empty();
        this.containerEl.addClass("admonition-settings");
        this.containerEl.createEl("h2", { text: t("Admonition Settings") });

        const admonitionEl = this.containerEl.createDiv(
            "admonitions-nested-settings"
        );
        if (!Platform.isMobile) {
            new Setting(admonitionEl)
                .setName("Export Custom Types as CSS")
                .setDesc("Export a CSS snippet for custom callout types.")
                .addButton((b) =>
                    b
                        .setIcon("download")
                        .onClick(() => {
                            const sheet = [
                                `/* This snippet was auto-generated by the Admonitions plugin */\n\n`
                            ];
                            const file = new Blob(
                                [
                                    this.plugin.calloutManager.generateCssString()
                                ],
                                {
                                    type: "text/css"
                                }
                            );
                            createEl("a", {
                                attr: {
                                    download: "custom_callouts.css",
                                    href: URL.createObjectURL(file)
                                }
                            }).click();
                        })
                        .setDisabled(
                            !Object.keys(this.plugin.data.userAdmonitions)
                                .length
                        )
                );
        }

        new Setting(admonitionEl)
            .setName("Use CSS Snippet for Custom Callouts")
            .setDesc(
                "Instead of managing it internally, Admonitions will maintain a CSS snippet to enable your custom types for callouts."
            )
            .addToggle((t) =>
                t.setValue(this.plugin.data.useSnippet).onChange((v) => {
                    this.plugin.data.useSnippet = v;
                    this.plugin.saveSettings();
                    this.plugin.calloutManager.setUseSnippet();
                })
            );

        new Setting(admonitionEl)
            .setName(t("Add New"))
            .setDesc(
                "Add a new Admonition type. All custom Admonitions will also be usable as callouts."
            )
            .addButton((button: ButtonComponent): ButtonComponent => {
                let b = button
                    .setTooltip(t("Add Additional"))
                    .setButtonText("+")
                    .onClick(async () => {
                        let modal = new SettingsModal(this.plugin);

                        modal.onClose = async () => {
                            if (modal.saved) {
                                const admonition = {
                                    type: modal.type,
                                    color: modal.color,
                                    icon: modal.icon,
                                    command: false,
                                    title: modal.title,
                                    injectColor: modal.injectColor,
                                    noTitle: modal.noTitle,
                                    copy: modal.copy
                                };
                                this.plugin.addAdmonition(admonition);

                                this.plugin.calloutManager.addAdmonition(
                                    admonition
                                );
                                this.display();
                            }
                        };

                        modal.open();
                    });

                return b;
            });

        this.additionalEl = admonitionEl.createDiv("additional");
        this.buildTypes();

        this.buildAdmonitions(
            this.containerEl.createEl("details", {
                cls: "admonitions-nested-settings",
                attr: {
                    ...(this.plugin.data.open.admonitions ? { open: true } : {})
                }
            })
        );
        this.buildIcons(
            this.containerEl.createEl("details", {
                cls: "admonitions-nested-settings",
                attr: {
                    ...(this.plugin.data.open.icons ? { open: true } : {})
                }
            })
        );
        this.buildOtherSyntaxes(
            this.containerEl.createEl("details", {
                cls: "admonitions-nested-settings",
                attr: {
                    ...(this.plugin.data.open.other ? { open: true } : {})
                }
            })
        );
        this.buildAdvanced(
            this.containerEl.createEl("details", {
                cls: "admonitions-nested-settings",
                attr: {
                    ...(this.plugin.data.open.advanced ? { open: true } : {})
                }
            })
        );

        const div = this.containerEl.createDiv("coffee");
        div.createEl("a", {
            href: "https://www.buymeacoffee.com/valentine195"
        }).createEl("img", {
            attr: {
                src: "https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=☕&slug=valentine195&button_colour=e3e7ef&font_colour=262626&font_family=Inter&outline_colour=262626&coffee_colour=ff0000"
            }
        });
    }
Example #14
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
private _displayParties(additionalContainer: HTMLDetailsElement) {
        additionalContainer.empty();
        additionalContainer.ontoggle = () => {
            this.plugin.data.openState.party = additionalContainer.open;
        };
        const summary = additionalContainer.createEl("summary");
        new Setting(summary).setHeading().setName("Parties");
        summary.createDiv("collapser").createDiv("handle");
        const explanation = additionalContainer.createDiv(
            "initiative-tracker-explanation"
        );
        explanation.createEl("span", {
            text: "Parties allow you to create different groups of your players. Each player can be a member of multiple parties."
        });
        explanation.createEl("br");
        explanation.createEl("br");
        explanation.createEl("span", {
            text: "You can set a default party for encounters to use, or specify the party for the encounter in the encounter block. While running an encounter in the tracker, you can change the active party, allowing you to quickly switch which players are in combat."
        });
        new Setting(additionalContainer)
            .setName("Default Party")
            .setDesc(
                "The tracker will load this party to encounters by default."
            )
            .addDropdown((d) => {
                d.addOption("none", "None");
                for (const party of this.plugin.data.parties) {
                    d.addOption(party.name, party.name);
                }
                d.setValue(this.plugin.data.defaultParty ?? "none");
                d.onChange(async (v) => {
                    this.plugin.data.defaultParty = v == "none" ? null : v;
                    this.plugin.saveSettings();
                });
            });
        new Setting(additionalContainer)
            .setName("Add New Party")
            .addButton((button: ButtonComponent): ButtonComponent => {
                let b = button
                    .setTooltip("Add Party")
                    .setButtonText("+")
                    .onClick(async () => {
                        const modal = new PartyModal(this.plugin);
                        modal.open();
                        modal.onClose = async () => {
                            if (modal.canceled) return;
                            if (!modal.party.name || !modal.party.name.length)
                                return;
                            if (
                                this.plugin.data.parties.filter(
                                    (party) => party.name == modal.party.name
                                )
                            ) {
                                const map = new Map(
                                    [...this.plugin.data.parties].map((c) => [
                                        c.name,
                                        c
                                    ])
                                );
                                map.set(modal.party.name, modal.party);
                                this.plugin.data.parties = Array.from(
                                    map.values()
                                );
                            } else {
                                this.plugin.data.parties.push(modal.party);
                            }

                            await this.plugin.saveSettings();

                            this._displayParties(additionalContainer);
                        };
                    });

                return b;
            });
        const additional = additionalContainer.createDiv("additional");
        if (!this.plugin.data.parties.length) {
            additional
                .createDiv({
                    attr: {
                        style: "display: flex; justify-content: center; padding-bottom: 18px;"
                    }
                })
                .createSpan({
                    text: "No saved parties! Create one to see it here."
                });
        } else {
            for (const party of this.plugin.data.parties) {
                new Setting(additional)
                    .setName(party.name)
                    .setDesc(party.players.join(", "))
                    .addExtraButton((b) => {
                        b.setIcon("pencil").onClick(() => {
                            const modal = new PartyModal(this.plugin, party);
                            modal.open();
                            modal.onClose = async () => {
                                if (modal.canceled) return;
                                if (
                                    !modal.party.name ||
                                    !modal.party.name.length
                                )
                                    return;

                                this.plugin.data.parties.splice(
                                    this.plugin.data.parties.indexOf(party),
                                    1,
                                    modal.party
                                );
                                if (
                                    this.plugin.data.parties.filter(
                                        (s) => s.name == modal.party.name
                                    ).length > 1
                                ) {
                                    if (
                                        this.plugin.data.parties.filter(
                                            (status) =>
                                                status.name == modal.party.name
                                        )
                                    ) {
                                        const map = new Map(
                                            this.plugin.data.parties.map(
                                                (c) => [c.name, c]
                                            )
                                        );
                                        map.set(modal.party.name, modal.party);
                                        this.plugin.data.parties = Array.from(
                                            map.values()
                                        );
                                    }
                                }

                                await this.plugin.saveSettings();

                                this._displayParties(additionalContainer);
                            };
                        });
                    })
                    .addExtraButton((b) => {
                        b.setIcon("trash").onClick(async () => {
                            this.plugin.data.parties =
                                this.plugin.data.parties.filter(
                                    (p) => p.name != party.name
                                );
                            if (this.plugin.data.defaultParty == party.name) {
                                this.plugin.data.defaultParty =
                                    this.plugin.data.parties[0]?.name ?? null;
                            }
                            await this.plugin.saveSettings();
                            this._displayParties(additionalContainer);
                        });
                    });
            }
        }
    }
Example #15
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
private _displayStatuses(additionalContainer: HTMLDetailsElement) {
        additionalContainer.empty();
        additionalContainer.ontoggle = () => {
            this.plugin.data.openState.status = additionalContainer.open;
        };
        const summary = additionalContainer.createEl("summary");
        new Setting(summary).setHeading().setName("Statuses");
        summary.createDiv("collapser").createDiv("handle");
        const add = new Setting(additionalContainer)
            .setName("Add New Status")
            .setDesc("These statuses will be available to apply to creatures.")
            .addButton((button: ButtonComponent): ButtonComponent => {
                let b = button
                    .setTooltip("Add Status")
                    .setButtonText("+")
                    .onClick(async () => {
                        const modal = new StatusModal(this.plugin);
                        modal.onClose = async () => {
                            if (modal.canceled) return;
                            if (!modal.status.name) return;
                            if (
                                this.plugin.data.statuses.filter(
                                    (status) => status.name == modal.status.name
                                )
                            ) {
                                const map = new Map(
                                    [...this.plugin.data.statuses].map((c) => [
                                        c.name,
                                        c
                                    ])
                                );
                                map.set(modal.status.name, modal.status);
                                this.plugin.data.statuses = Array.from(
                                    map.values()
                                );
                            } else {
                                this.plugin.data.statuses.push(modal.status);
                            }
                            await this.plugin.saveSettings();
                            this._displayStatuses(additionalContainer);
                        };
                        modal.open();
                    });

                return b;
            });
        if (!Conditions.every((c) => this.plugin.data.statuses.includes(c))) {
            add.addExtraButton((b) =>
                b
                    .setIcon("reset")
                    .setTooltip("Re-add Default Statuses")
                    .onClick(async () => {
                        this.plugin.data.statuses = Array.from(
                            new Map(
                                [
                                    ...this.plugin.data.statuses,
                                    ...Conditions
                                ].map((c) => [c.name, c])
                            ).values()
                        );
                        await this.plugin.saveSettings();
                        this._displayStatuses(additionalContainer);
                    })
            );
        }
        const additional = additionalContainer.createDiv("additional");
        for (const status of this.plugin.data.statuses) {
            new Setting(additional)
                .setName(status.name)
                .setDesc(status.description)
                .addExtraButton((b) =>
                    b.setIcon("pencil").onClick(() => {
                        const modal = new StatusModal(this.plugin, status);
                        modal.onClose = async () => {
                            if (modal.canceled) return;
                            if (!modal.status.name) return;
                            this.plugin.data.statuses.splice(
                                this.plugin.data.statuses.indexOf(status),
                                1,
                                modal.status
                            );
                            if (
                                this.plugin.data.statuses.filter(
                                    (s) => s.name == modal.status.name
                                ).length > 1
                            ) {
                                if (
                                    this.plugin.data.statuses.filter(
                                        (status) =>
                                            status.name == modal.status.name
                                    )
                                ) {
                                    const map = new Map(
                                        this.plugin.data.statuses.map((c) => [
                                            c.name,
                                            c
                                        ])
                                    );
                                    map.set(modal.status.name, modal.status);
                                    this.plugin.data.statuses = Array.from(
                                        map.values()
                                    );
                                }
                            }
                            await this.plugin.saveSettings();
                            this._displayStatuses(additionalContainer);
                        };
                        modal.open();
                    })
                )
                .addExtraButton((b) =>
                    b.setIcon("trash").onClick(async () => {
                        this.plugin.data.statuses =
                            this.plugin.data.statuses.filter(
                                (s) => s.name != status.name
                            );
                        await this.plugin.saveSettings();
                        this._displayStatuses(additionalContainer);
                    })
                )
                .setClass("initiative-status-item");
        }
    }
Example #16
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
private async _displayIntegrations(containerEl: HTMLDetailsElement) {
        containerEl.empty();
        containerEl.ontoggle = () => {
            this.plugin.data.openState.plugin = containerEl.open;
        };
        const summary = containerEl.createEl("summary");
        new Setting(summary).setHeading().setName("Plugin Integrations");
        summary.createDiv("collapser").createDiv("handle");
        if (!this.plugin.canUseStatBlocks) {
            this.plugin.data.sync = false;
            await this.plugin.saveSettings();
        }
        new Setting(containerEl)
            .setName("Sync Monsters from TTRPG Statblocks")
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "Homebrew creatures saved to the TTRPG Statblocks plugin will be available in the quick-add."
                    });
                    if (!this.plugin.canUseStatBlocks) {
                        e.createEl("br");
                        e.createEl("br");
                        e.createSpan({
                            text: "Install and enable the "
                        });
                        e.createEl("a", {
                            text: "TTRPG Statblocks",
                            href: "obsidian://show-plugin?id=obsidian-5e-statblocks"
                        });
                        e.createSpan({
                            text: " plugin to use homebrew creatures."
                        });
                    }
                })
            )
            .addToggle((t) => {
                t.setDisabled(!this.plugin.canUseStatBlocks).setValue(
                    this.plugin.data.sync
                );
                t.onChange(async (v) => {
                    this.plugin.data.sync = v;
                    await this.plugin.saveSettings();
                    this._displayIntegrations(containerEl);
                });
            });
        if (this.plugin.data.sync) {
            const synced = new Setting(containerEl).setDesc(
                `${this.plugin.statblock_creatures.length} creatures synced.`
            );
            synced.settingEl.addClass("initiative-synced");
            setIcon(synced.nameEl, "check-in-circle");
            synced.nameEl.appendChild(createSpan({ text: "Synced" }));
        }

        new Setting(containerEl)
            .setName("Initiative Formula")
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "Initiative formula to use when calculating initiative. Use "
                    });
                    e.createEl("code", { text: "%mod%" });
                    e.createSpan({
                        text: " for the modifier placeholder."
                    });
                    if (!this.plugin.canUseDiceRoller) {
                        e.createEl("br");
                        e.createEl("br");
                        e.createSpan({
                            attr: {
                                style: `color: var(--text-error);`
                            },
                            text: "Requires the "
                        });
                        e.createEl("a", {
                            text: "Dice Roller",
                            href: "https://github.com/valentine195/obsidian-dice-roller",
                            cls: "external-link"
                        });
                        e.createSpan({
                            attr: {
                                style: `color: var(--text-error);`
                            },
                            text: " plugin to modify."
                        });
                    }
                })
            )
            .addText((t) => {
                if (!this.plugin.canUseDiceRoller) {
                    t.setDisabled(true);
                    this.plugin.data.initiative = "1d20 + %mod%";
                }
                t.setValue(this.plugin.data.initiative);
                t.onChange((v) => {
                    this.plugin.data.initiative = v;
                });
                t.inputEl.onblur = async () => {
                    const view = this.plugin.view;
                    if (view) view.rollInitiatives();
                    await this.plugin.saveSettings();
                };
            });
        new Setting(containerEl)
            .setName("Integrate with Obsidian Leaflet")
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "Integrate with the Obsidian Leaflet plugin and display combats on a map."
                    });

                    if (!this.plugin.canUseLeaflet) {
                        e.createEl("br");
                        e.createEl("br");
                        e.createSpan({
                            attr: {
                                style: `color: var(--text-error);`
                            },
                            text: "Requires  "
                        });
                        e.createEl("a", {
                            text: "Obsidian Leaflet",
                            href: "https://github.com/valentine195/obsidian-leaflet-plugin",
                            cls: "external-link"
                        });
                        e.createSpan({
                            attr: {
                                style: `color: var(--text-error);`
                            },
                            text: " version 4.0.0 to modify."
                        });
                    }
                })
            )
            .addToggle((t) => {
                if (!this.plugin.canUseLeaflet) {
                    t.setDisabled(true);
                    this.plugin.data.leafletIntegration = false;
                }
                t.setValue(this.plugin.data.leafletIntegration);
                t.onChange(async (v) => {
                    this.plugin.data.leafletIntegration = v;
                    this.plugin.view.setMapState(v);
                    await this.plugin.saveSettings();
                    this._displayIntegrations(containerEl);
                });
            });

        if (this.plugin.canUseLeaflet && this.plugin.data.leafletIntegration) {
            new Setting(containerEl)
                .setName("Default Player Marker Type")
                .setDesc(
                    createFragment((e) => {
                        if (this.plugin.data.playerMarker) {
                            const div = e.createDiv("marker-type-display");
                            const inner = div.createDiv("marker-icon-display");

                            const marker = this.plugin.leaflet.markerIcons.find(
                                (icon) =>
                                    icon.type == this.plugin.data.playerMarker
                            );
                            if (marker) {
                                inner.innerHTML = marker.html;
                            }
                        }
                    })
                )
                .addDropdown((drop) => {
                    for (let marker of this.plugin.leaflet.markerIcons) {
                        drop.addOption(marker.type, marker.type);
                    }
                    drop.setValue(this.plugin.data.playerMarker ?? "default");
                    drop.onChange(async (v) => {
                        this.plugin.data.playerMarker = v;
                        await this.plugin.saveSettings();
                        this._displayIntegrations(containerEl);
                    });
                });
            new Setting(containerEl)
                .setName("Default Monster Marker Type")
                .setDesc(
                    createFragment((e) => {
                        if (this.plugin.data.monsterMarker) {
                            const div = e.createDiv("marker-type-display");
                            const inner = div.createDiv("marker-icon-display");

                            const marker = this.plugin.leaflet.markerIcons.find(
                                (icon) =>
                                    icon.type == this.plugin.data.monsterMarker
                            );
                            if (marker) {
                                inner.innerHTML = marker.html;
                            }
                        }
                    })
                )
                .addDropdown((drop) => {
                    for (let marker of this.plugin.leaflet.markerIcons) {
                        drop.addOption(marker.type, marker.type);
                    }
                    drop.setValue(this.plugin.data.monsterMarker);
                    drop.onChange(async (v) => {
                        this.plugin.data.monsterMarker = v;
                        await this.plugin.saveSettings();
                        this._displayIntegrations(containerEl);
                    });
                });
        }
    }
Example #17
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
private _displayHomebrew(additionalContainer: HTMLElement) {
        additionalContainer.empty();
        if (this.plugin.data.homebrew.length) {
            const additional = additionalContainer.createDiv("additional");
            new Setting(additional).setHeading().setName("Homebrew Creatures");
            const warning = additional
                .createDiv({
                    attr: {
                        style: "display: flex; justify-content: center; padding: 18px;"
                    }
                })
                .createEl("strong");
            warning.createSpan({
                text: "Homebrew creatures have moved to the "
            });
            warning.createEl("a", {
                text: "5e Statblocks",
                href: "obsidian://show-plugin?id=obsidian-5e-statblocks"
            });
            warning.createSpan({
                text: " plugin."
            });
            if (this.plugin.canUseStatBlocks) {
                new Setting(additional)
                    .setName("Migrate Hombrew")
                    .setDesc(
                        "Move all created homebrew creatures to the 5e Statblocks plugin."
                    )
                    .addButton((b) => {
                        b.setIcon("install")
                            .setTooltip("Migrate")
                            .onClick(async () => {
                                const statblocks = this.app.plugins.getPlugin(
                                    "obsidian-5e-statblocks"
                                );
                                const existing =
                                    statblocks.settings.monsters.length;
                                await statblocks.saveMonsters(
                                    this.plugin.data.homebrew
                                );
                                new Notice(
                                    `${
                                        statblocks.settings.monsters.length -
                                        existing
                                    } of ${
                                        this.plugin.data.homebrew.length
                                    } Homebrew Monsters saved.`
                                );
                            });
                    })
                    .addExtraButton((b) => {
                        b.setIcon("cross-in-box")
                            .setTooltip("Delete Homebrew")
                            .onClick(async () => {
                                if (
                                    await confirmWithModal(
                                        this.app,
                                        "Are you sure you want to delete all homebrew creatures?"
                                    )
                                ) {
                                    this.plugin.data.homebrew = [];
                                    await this.plugin.saveSettings();
                                    this._displayHomebrew(additionalContainer);
                                }
                            });
                    });
            } else {
                additional
                    .createDiv({
                        attr: {
                            style: "display: flex; justify-content: center; padding: 18px;"
                        }
                    })
                    .createEl("strong");
                warning.createSpan({
                    text: "Install the "
                });
                warning.createEl("a", {
                    text: "5e Statblocks",
                    href: "obsidian://show-plugin?id=obsidian-5e-statblocks"
                });
                warning.createSpan({
                    text: " plugin to migrate."
                });
            }
        }
    }
Example #18
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
async display(load?: boolean) {
        let { contentEl } = this;

        contentEl.addClass("initiative-tracker-add-player-modal");

        contentEl.empty();

        let error = false;

        contentEl.createEl("h2", {
            text: this.original ? "Edit Player" : "New Player"
        });

        new Setting(contentEl)
            .setName("Link to Note")
            .setDesc("Link player to a note in your vault.")
            .addText((t) => {
                t.setValue(this.player.note ?? "");
                const modal = new FileSuggestionModal(this.app, t);
                modal.onClose = async () => {
                    if (!modal.file) return;

                    const metaData = this.app.metadataCache.getFileCache(
                        modal.file
                    );

                    this.player.note = modal.file.basename;
                    this.player.path = modal.file.path;
                    this.player.name = modal.file.basename;

                    if (!metaData || !metaData.frontmatter) return;

                    const { ac, hp, modifier, level } = metaData.frontmatter;
                    this.player = {
                        ...this.player,
                        ...{ ac, hp, modifier, level }
                    };
                    this.display();
                };
            });

        let nameInput: InputValidate,
            levelInput: InputValidate,
            hpInput: InputValidate,
            acInput: InputValidate,
            modInput: InputValidate;

        new Setting(contentEl)
            .setName("Name")
            .setDesc("Player name. Must be unique!")
            .addText((t) => {
                nameInput = {
                    input: t.inputEl,
                    validate: (i: HTMLInputElement) => {
                        let error = false;
                        if (
                            (!i.value.length && !load) ||
                            (this.plugin.data.players.find(
                                (p) => p.name === i.value
                            ) &&
                                this.player.name != this.original.name)
                        ) {
                            i.addClass("has-error");
                            error = true;
                        }
                        return error;
                    }
                };
                t.setValue(this.player.name ?? "");
                t.onChange((v) => {
                    t.inputEl.removeClass("has-error");
                    this.player.name = v;
                });
            });
        new Setting(contentEl)
            .setName("Level")
            .setDesc("Player level.")
            .addText((t) => {
                levelInput = {
                    input: t.inputEl,
                    validate: (i: HTMLInputElement) => {
                        let error = false;
                        if (isNaN(Number(i.value)) || Number(i.value) <= 0) {
                            i.addClass("has-error");
                            error = true;
                        }
                        return error;
                    }
                };
                t.setValue(`${this.player.level ?? ""}`);
                t.onChange((v) => {
                    t.inputEl.removeClass("has-error");
                    this.player.level = Number(v);
                });
            });
        new Setting(contentEl).setName("Max Hit Points").addText((t) => {
            hpInput = {
                input: t.inputEl,
                validate: (i: HTMLInputElement) => {
                    let error = false;
                    if (isNaN(Number(i.value))) {
                        i.addClass("has-error");
                        error = true;
                    }
                    return error;
                }
            };
            t.setValue(`${this.player.hp ?? ""}`);
            t.onChange((v) => {
                t.inputEl.removeClass("has-error");
                this.player.hp = Number(v);
            });
        });
        new Setting(contentEl).setName("Armor Class").addText((t) => {
            acInput = {
                input: t.inputEl,
                validate: (i) => {
                    let error = false;
                    if (isNaN(Number(i.value))) {
                        t.inputEl.addClass("has-error");
                        error = true;
                    }
                    return error;
                }
            };
            t.setValue(`${this.player.ac ?? ""}`);
            t.onChange((v) => {
                t.inputEl.removeClass("has-error");
                this.player.ac = Number(v);
            });
        });
        new Setting(contentEl)
            .setName("Initiative Modifier")
            .setDesc("This will be added to randomly-rolled initiatives.")
            .addText((t) => {
                modInput = {
                    input: t.inputEl,
                    validate: (i) => {
                        let error = false;
                        if (isNaN(Number(i.value))) {
                            t.inputEl.addClass("has-error");
                            error = true;
                        }
                        return error;
                    }
                };
                t.setValue(`${this.player.modifier ?? ""}`);
                t.onChange((v) => {
                    this.player.modifier = Number(v);
                });
            });

        if (this.plugin.canUseLeaflet) {
            const markerSetting = new Setting(contentEl)
                .setName("Leaflet Marker")
                .addDropdown((drop) => {
                    for (let marker of this.plugin.leaflet.markerIcons) {
                        drop.addOption(marker.type, marker.type);
                    }
                    drop.setValue(
                        this.player.marker ??
                            this.plugin.data.playerMarker ??
                            "default"
                    );
                    drop.onChange(async (v) => {
                        this.player.marker = v;
                        this.display();
                    });
                });

            if (this.player.marker) {
                const div = createDiv("marker-type-display");
                const inner = div.createDiv("marker-icon-display");

                const marker = this.plugin.leaflet.markerIcons.find(
                    (icon) => icon.type == this.player.marker
                );
                if (marker) {
                    inner.innerHTML = marker.html;

                    markerSetting.descEl.appendChild(div);
                }
            }
        }

        let footerEl = contentEl.createDiv();
        let footerButtons = new Setting(footerEl);
        footerButtons.addButton((b) => {
            b.setTooltip("Save")
                .setIcon("checkmark")
                .onClick(async () => {
                    let error = this.validateInputs(
                        nameInput,
                        acInput,
                        hpInput,
                        modInput
                    );
                    if (error) {
                        new Notice("Fix errors before saving.");
                        return;
                    }
                    this.saved = true;
                    this.close();
                });
            return b;
        });
        footerButtons.addExtraButton((b) => {
            b.setIcon("cross")
                .setTooltip("Cancel")
                .onClick(() => {
                    this.saved = false;
                    this.close();
                });
            return b;
        });

        this.validateInputs(nameInput, acInput, hpInput, modInput);
    }
Example #19
Source File: settings.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
onOpen(): void {
        this.titleEl.setText(
            this.editing ? `Edit ${this.party.name ?? "Party"}` : "New Party"
        );

        const name = new Setting(this.contentEl)
            .setName("Name")
            .addText((t) => {
                t.setValue(this.party.name).onChange((v) => {
                    this.party.name = v;
                    if (
                        this.plugin.data.parties.find(
                            (s) => s.name == this.party.name
                        ) &&
                        !this.warned &&
                        this.original != this.party.name
                    ) {
                        this.warned = true;
                        name.setDesc(
                            createFragment((e) => {
                                const container = e.createDiv(
                                    "initiative-tracker-warning"
                                );
                                setIcon(
                                    container,
                                    "initiative-tracker-warning"
                                );
                                container.createSpan({
                                    text: "A party by this name already exists and will be overwritten."
                                });
                            })
                        );
                    } else if (this.warned) {
                        this.warned = false;
                        name.setDesc("");
                    }
                });
            });

        const playersEl = this.contentEl.createDiv(
            "initiative-tracker-additional-container"
        );
        let playerText: TextComponent;
        new Setting(playersEl)
            .setName("Add Player to Party")
            .addText((t) => {
                playerText = t;
                new PlayerSuggestionModal(this.plugin, t, this.party);
            })
            .addExtraButton((b) =>
                b.setIcon("plus-with-circle").onClick(() => {
                    if (!playerText.getValue() || !playerText.getValue().length)
                        return;
                    if (this.party.players.includes(playerText.getValue())) {
                        new Notice("That player is already in this party!");
                        return;
                    }
                    if (
                        !this.plugin.data.players.find(
                            (p) => p.name == playerText.getValue()
                        )
                    ) {
                        new Notice(
                            "That player doesn't exist! You should make them first."
                        );
                        return;
                    }
                    this.party.players.push(playerText.getValue());
                    this.displayPlayers(playersDisplayEl);
                    playerText.setValue("");
                })
            );
        const playersDisplayEl = playersEl.createDiv("additional");
        this.displayPlayers(playersDisplayEl);

        new ButtonComponent(
            this.contentEl.createDiv("initiative-tracker-cancel")
        )
            .setButtonText("Cancel")
            .onClick(() => {
                this.canceled = true;
                this.close();
            });
    }
Example #20
Source File: settings.ts    From obsidian-admonition with MIT License 4 votes vote down vote up
async display() {
        let { contentEl } = this;

        contentEl.empty();

        const settingDiv = contentEl.createDiv();
        const title = this.title ?? this.type ?? "...";

        this.admonitionPreview = this.plugin.getAdmonitionElement(
            this.type,
            title[0].toUpperCase() + title.slice(1).toLowerCase(),
            this.icon,
            this.injectColor ?? this.plugin.data.injectColor ? this.color : null
        );
        this.admonitionPreview
            .createDiv("callout-content admonition-content")
            .createEl("p", {
                text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla."
            });

        contentEl.appendChild(this.admonitionPreview);
        let typeText: TextComponent;
        const typeSetting = new Setting(settingDiv)
            .setName(t("Admonition Type"))
            .addText((text) => {
                typeText = text;
                typeText.setValue(this.type).onChange((v) => {
                    if (!v.length) {
                        SettingsModal.setValidationError(
                            text,
                            t("Admonition type cannot be empty.")
                        );
                        return;
                    }

                    if (v.includes(" ")) {
                        SettingsModal.setValidationError(
                            text,
                            t("Admonition type cannot include spaces.")
                        );
                        return;
                    }

                    if (!isSelectorValid(v)) {
                        SettingsModal.setValidationError(
                            text,
                            t("Types must be a valid CSS selector.")
                        );
                        return;
                    }

                    SettingsModal.removeValidationError(text);

                    this.type = v;
                    if (!this.title)
                        this.updateTitle(
                            this.admonitionPreview,
                            this.type?.[0].toUpperCase() +
                                this.type?.slice(1).toLowerCase()
                        );
                });
            });
        typeSetting.controlEl.addClass("admonition-type-setting");

        typeSetting.descEl.createSpan({
            text: "This is used to create the admonition (e.g.,  "
        });
        typeSetting.descEl.createEl("code", {
            text: "note"
        });
        typeSetting.descEl.createSpan({
            text: " or "
        });
        typeSetting.descEl.createEl("code", {
            text: "abstract"
        });
        typeSetting.descEl.createSpan({
            text: ")"
        });

        new Setting(settingDiv)
            .setName(t("Admonition Title"))
            .setDesc(
                t("This will be the default title for this admonition type.")
            )
            .addText((text) => {
                text.setValue(this.title).onChange((v) => {
                    if (!v.length) {
                        this.title = null;
                        this.updateTitle(
                            this.admonitionPreview,
                            this.type?.[0].toUpperCase() +
                                title.slice(1).toLowerCase()
                        );
                        return;
                    }

                    this.title = v;
                    this.updateTitle(this.admonitionPreview, this.title);
                });
            });
        new Setting(settingDiv)
            .setName(t("No Admonition Title by Default"))
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: t("The admonition will have no title unless ")
                    });
                    e.createEl("code", { text: "title" });
                    e.createSpan({ text: t(" is explicitly provided.") });
                })
            )
            .addToggle((t) => {
                t.setValue(this.noTitle).onChange((v) => (this.noTitle = v));
            });
        new Setting(settingDiv)
            .setName(t("Show Copy Button"))
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "A copy button will be added to the admonition & callout."
                    });
                })
            )
            .addToggle((t) => {
                t.setValue(this.copy).onChange((v) => (this.copy = v));
            });

        const input = createEl("input", {
            attr: {
                type: "file",
                name: "image",
                accept: "image/*"
            }
        });
        let iconText: TextComponent;
        new Setting(settingDiv)
            .setName(t("Admonition Icon"))
            .setDesc("Icon to display next to the title.")
            .addText((text) => {
                iconText = text;
                if (this.icon.type !== "image") text.setValue(this.icon.name);

                const validate = async () => {
                    const v = text.inputEl.value;
                    let ic = this.plugin.iconManager.getIconType(v);
                    if (!ic) {
                        SettingsModal.setValidationError(
                            text,
                            t("Invalid icon name.")
                        );
                        return;
                    }

                    if (v.length == 0) {
                        SettingsModal.setValidationError(
                            text,
                            t("Icon cannot be empty.")
                        );
                        return;
                    }

                    SettingsModal.removeValidationError(text);

                    this.icon = modal.icon ?? {
                        name: v as AdmonitionIconName,
                        type: ic as AdmonitionIconType
                    };

                    let iconEl = this.admonitionPreview.querySelector(
                        ".admonition-title-icon"
                    );

                    iconEl.innerHTML =
                        this.plugin.iconManager.getIconNode(this.icon)
                            ?.outerHTML ?? "";
                };

                const modal = new IconSuggestionModal(this.plugin, text);

                modal.onClose = validate;

                text.inputEl.onblur = validate;
            })
            .addButton((b) => {
                b.setButtonText(t("Upload Image")).setIcon("image-file");
                b.buttonEl.addClass("admonition-file-upload");
                b.buttonEl.appendChild(input);
                b.onClick(() => input.click());
            });

        /** Image Uploader */
        input.onchange = async () => {
            const { files } = input;

            if (!files.length) return;

            const image = files[0];
            const reader = new FileReader();
            reader.onloadend = (evt) => {
                var image = new Image();
                image.onload = () => {
                    try {
                        // Resize the image
                        const canvas = document.createElement("canvas"),
                            max_size = 24;
                        let width = image.width,
                            height = image.height;
                        if (width > height) {
                            if (width > max_size) {
                                height *= max_size / width;
                                width = max_size;
                            }
                        } else {
                            if (height > max_size) {
                                width *= max_size / height;
                                height = max_size;
                            }
                        }
                        canvas.width = width;
                        canvas.height = height;
                        canvas
                            .getContext("2d")
                            .drawImage(image, 0, 0, width, height);

                        this.icon = {
                            name: canvas.toDataURL("image/png"),
                            type: "image"
                        };
                        this.display();
                    } catch (e) {
                        new Notice("There was an error parsing the image.");
                    }
                };
                image.src = evt.target.result.toString();
            };
            reader.readAsDataURL(image);

            input.value = null;
        };

        const color = settingDiv.createDiv("admonition-color-settings");
        this.createColor(color);

        let footerEl = contentEl.createDiv();
        let footerButtons = new Setting(footerEl);
        footerButtons.addButton((b) => {
            b.setTooltip(t("Save"))
                .setIcon("checkmark")
                .onClick(async () => {
                    let error = false;
                    if (!typeText.inputEl.value.length) {
                        SettingsModal.setValidationError(
                            typeText,
                            t("Admonition type cannot be empty.")
                        );
                        error = true;
                    }

                    if (typeText.inputEl.value.includes(" ")) {
                        SettingsModal.setValidationError(
                            typeText,
                            t("Admonition type cannot include spaces.")
                        );
                        error = true;
                    }
                    if (
                        this.type != this.originalType &&
                        this.type in this.plugin.data.userAdmonitions
                    ) {
                        SettingsModal.setValidationError(
                            typeText,
                            "That Admonition type already exists."
                        );
                        error = true;
                    }

                    if (!isSelectorValid(typeText.inputEl.value)) {
                        SettingsModal.setValidationError(
                            typeText,
                            t("Types must be a valid CSS selector.")
                        );
                        error = true;
                    }

                    if (
                        !this.plugin.iconManager.getIconType(
                            iconText.inputEl.value
                        ) &&
                        this.icon.type !== "image"
                    ) {
                        SettingsModal.setValidationError(
                            iconText,
                            t("Invalid icon name.")
                        );
                        error = true;
                    }

                    if (!this.icon.name.length) {
                        SettingsModal.setValidationError(
                            iconText,
                            t("Icon cannot be empty.")
                        );
                        error = true;
                    }

                    if (error) {
                        new Notice("Fix errors before saving.");
                        return;
                    }
                    this.saved = true;
                    this.close();
                });
            return b;
        });
        footerButtons.addExtraButton((b) => {
            b.setIcon("cross")
                .setTooltip("Cancel")
                .onClick(() => {
                    this.saved = false;
                    this.close();
                });
            return b;
        });
    }
Example #21
Source File: settings.ts    From obsidian-admonition with MIT License 4 votes vote down vote up
buildTypes() {
        this.additionalEl.empty();
        for (const admonition of Object.values(
            this.plugin.data.userAdmonitions
        )) {
            let setting = new Setting(this.additionalEl);

            let admonitionElement = this.plugin.getAdmonitionElement(
                admonition.type,
                admonition.type[0].toUpperCase() +
                    admonition.type.slice(1).toLowerCase(),
                admonition.icon,
                admonition.injectColor ?? this.plugin.data.injectColor
                    ? admonition.color
                    : null
            );
            setting.infoEl.replaceWith(admonitionElement);

            if (!admonition.command) {
                setting.addExtraButton((b) => {
                    b.setIcon(ADD_COMMAND_NAME.toString())
                        .setTooltip(t("Register Commands"))
                        .onClick(async () => {
                            this.plugin.registerCommandsFor(admonition);
                            await this.plugin.saveSettings();
                            this.display();
                        });
                });
            } else {
                setting.addExtraButton((b) => {
                    b.setIcon(REMOVE_COMMAND_NAME.toString())
                        .setTooltip(t("Unregister Commands"))
                        .onClick(async () => {
                            this.plugin.unregisterCommandsFor(admonition);
                            await this.plugin.saveSettings();
                            this.display();
                        });
                });
            }

            setting
                .addExtraButton((b) => {
                    b.setIcon("pencil")
                        .setTooltip(t("Edit"))
                        .onClick(() => {
                            let modal = new SettingsModal(
                                this.plugin,
                                admonition
                            );

                            modal.onClose = async () => {
                                if (modal.saved) {
                                    const hasCommand = admonition.command;
                                    const modalAdmonition = {
                                        type: modal.type,
                                        color: modal.color,
                                        icon: modal.icon,
                                        command: hasCommand,
                                        title: modal.title,
                                        injectColor: modal.injectColor,
                                        noTitle: modal.noTitle,
                                        copy: modal.copy
                                    };

                                    if (
                                        modalAdmonition.type != admonition.type
                                    ) {
                                        this.plugin.unregisterType(admonition);

                                        const existing: [string, Admonition][] =
                                            Object.entries(
                                                this.plugin.data.userAdmonitions
                                            );

                                        this.plugin.data.userAdmonitions =
                                            Object.fromEntries(
                                                existing.map(([type, def]) => {
                                                    if (
                                                        type == admonition.type
                                                    ) {
                                                        return [
                                                            modalAdmonition.type,
                                                            modalAdmonition
                                                        ];
                                                    }
                                                    return [type, def];
                                                })
                                            );
                                    } else {
                                        this.plugin.data.userAdmonitions[
                                            modalAdmonition.type
                                        ] = modalAdmonition;
                                    }

                                    this.plugin.registerType(
                                        modalAdmonition.type
                                    );

                                    this.plugin.calloutManager.addAdmonition(
                                        modalAdmonition
                                    );

                                    this.display();
                                }
                            };

                            modal.open();
                        });
                })
                .addExtraButton((b) => {
                    b.setIcon("trash")
                        .setTooltip(t("Delete"))
                        .onClick(() => {
                            this.plugin.removeAdmonition(admonition);
                            this.display();
                        });
                });
        }
    }
Example #22
Source File: settings.ts    From obsidian-admonition with MIT License 4 votes vote down vote up
buildOtherSyntaxes(containerEl: HTMLDetailsElement) {
        containerEl.empty();
        containerEl.ontoggle = () => {
            this.plugin.data.open.other = containerEl.open;
            this.plugin.saveSettings();
        };
        const summary = containerEl.createEl("summary");
        new Setting(summary).setHeading().setName("Additional Syntaxes");
        summary.createDiv("collapser").createDiv("handle");

        containerEl.createEl("p", {
            text: "Obsidian 0.14 has introduced Callout boxes to its core functionality using the same syntax as the Microsoft Document callouts.",

            cls: "setting-item"
        });
        containerEl.createEl("p", {
            text: "This has rendered the Microsoft Document syntax for Admonitions obsolete, but Admonitions can still be used to create and manage your custom callout types.",

            cls: "setting-item"
        });
        containerEl.createEl("p", {
            text: "Your existing code block Admonitions will always work!",

            cls: "setting-item"
        });

        if (!this.plugin.data.msDocConverted) {
            new Setting(containerEl)
                .setName("Convert MSDoc Admonitions to Callouts")
                .setDesc(
                    createFragment((e) => {
                        const text = e.createDiv("admonition-convert");
                        setIcon(text.createSpan(), WARNING_ICON_NAME);
                        text.createSpan({
                            text: "This "
                        });
                        text.createEl("strong", { text: "will" });
                        text.createSpan({
                            text: " modify notes. Use at your own risk and please make backups."
                        });
                        e.createEl("p", {
                            text: "With large vaults, this could take awhile!"
                        });
                    })
                )
                .addButton((b) =>
                    b
                        .setButtonText("Convert")
                        .setCta()
                        .onClick(() => {
                            this.queue =
                                this.plugin.app.vault.getMarkdownFiles();
                            this.notice = new Notice(
                                createFragment((e) => {
                                    const container =
                                        e.createDiv("admonition-convert");
                                    container.createSpan({
                                        text: "Converting MS-doc admonitions..."
                                    });
                                    setIcon(
                                        container.createSpan(
                                            "admonition-convert-icon"
                                        ),
                                        SPIN_ICON_NAME
                                    );
                                }),
                                0
                            );
                            this.checkAndReplace();
                        })
                );
        }
        new Setting(containerEl)
            .setName("Convert Codeblock Admonitions to Callouts")
            .setDesc(
                createFragment((e) => {
                    const text = e.createDiv("admonition-convert");
                    setIcon(text.createSpan(), WARNING_ICON_NAME);
                    text.createSpan({
                        text: "This "
                    });
                    text.createEl("strong", { text: "will" });
                    text.createSpan({
                        text: " modify notes. Use at your own risk and please make backups."
                    });
                    e.createEl("p", {
                        text: "With large vaults, this could take awhile!"
                    });
                })
            )
            .addButton((b) =>
                b
                    .setButtonText("Convert")
                    .setCta()
                    .onClick(() => {
                        this.queue = this.plugin.app.vault.getMarkdownFiles();
                        /* this.queue = [
                            this.plugin.app.vault.getAbstractFileByPath(
                                "99 Plugin Testing/admonition/Admonition Codeblock.md"
                            ) as TFile
                        ]; */
                        this.notice = new Notice(
                            createFragment((e) => {
                                const container =
                                    e.createDiv("admonition-convert");
                                container.createSpan({
                                    text: "Converting Codeblock admonitions..."
                                });
                                setIcon(
                                    container.createSpan(
                                        "admonition-convert-icon"
                                    ),
                                    SPIN_ICON_NAME
                                );
                            }),
                            0
                        );
                        this.converted = 0;
                        this.checkAndReplaceCodeBlocks();
                    })
            );
    }
Example #23
Source File: settings.ts    From obsidian-admonition with MIT License 4 votes vote down vote up
buildIcons(containerEl: HTMLDetailsElement) {
        containerEl.empty();
        containerEl.ontoggle = () => {
            this.plugin.data.open.icons = containerEl.open;
            this.plugin.saveSettings();
        };
        const summary = containerEl.createEl("summary");
        new Setting(summary).setHeading().setName("Icon Packs");
        summary.createDiv("collapser").createDiv("handle");

        new Setting(containerEl)
            .setName("Use Font Awesome Icons")
            .setDesc(
                "Font Awesome Free icons will be available in the item picker. Existing Admonitions defined using Font Awesome icons will continue to work."
            )
            .addToggle((t) => {
                t.setValue(this.plugin.data.useFontAwesome).onChange((v) => {
                    this.plugin.data.useFontAwesome = v;
                    this.plugin.iconManager.setIconDefinitions();
                    this.plugin.saveSettings();
                });
            });

        let selected: DownloadableIconPack;
        const possibilities = Object.entries(DownloadableIcons).filter(
            ([icon]) => !this.plugin.data.icons.includes(icon)
        );
        new Setting(containerEl)
            .setName("Load Additional Icons")
            .setDesc(
                "Load an additional icon pack. This requires an internet connection."
            )
            .addDropdown((d) => {
                if (!possibilities.length) {
                    d.setDisabled(true);
                    return;
                }
                for (const [icon, display] of possibilities) {
                    d.addOption(icon, display);
                }
                d.onChange((v: DownloadableIconPack) => (selected = v));
                selected = d.getValue() as DownloadableIconPack;
            })
            .addExtraButton((b) => {
                b.setIcon("plus-with-circle")
                    .setTooltip("Load")
                    .onClick(async () => {
                        if (!selected || !selected.length) return;

                        await this.plugin.iconManager.downloadIcon(selected);
                        this.buildIcons(containerEl);
                    });
                if (!possibilities.length) b.setDisabled(true);
            });

        const iconsEl = containerEl.createDiv("admonitions-nested-settings");
        new Setting(iconsEl);
        for (const icon of this.plugin.data.icons) {
            new Setting(iconsEl)
                .setName(DownloadableIcons[icon])
                .addExtraButton((b) => {
                    b.setIcon("reset")
                        .setTooltip("Redownload")
                        .onClick(async () => {
                            await this.plugin.iconManager.removeIcon(icon);
                            await this.plugin.iconManager.downloadIcon(icon);
                            this.buildIcons(containerEl);
                        });
                })
                .addExtraButton((b) => {
                    b.setIcon("trash").onClick(async () => {
                        if (
                            Object.values(
                                this.plugin.data.userAdmonitions
                            ).find((admonition) => admonition.icon.type == icon)
                        ) {
                            if (
                                !(await confirmWithModal(
                                    this.plugin.app,
                                    "You have Admonitions using icons from this pack. Are you sure you want to remove it?"
                                ))
                            )
                                return;
                        }

                        await this.plugin.iconManager.removeIcon(icon);

                        this.buildIcons(containerEl);
                    });
                });
        }
    }
Example #24
Source File: main.ts    From remotely-save with Apache License 2.0 4 votes vote down vote up
async syncRun(triggerSource: SyncTriggerSourceType = "manual") {
    const t = (x: TransItemType, vars?: any) => {
      return this.i18n.t(x, vars);
    };

    const getNotice = (x: string, timeout?: number) => {
      // only show notices in manual mode
      // no notice in auto mode
      if (triggerSource === "manual" || triggerSource === "dry") {
        new Notice(x, timeout);
      }
    };
    if (this.syncStatus !== "idle") {
      // here the notice is shown regardless of triggerSource
      new Notice(
        t("syncrun_alreadyrunning", {
          pluginName: this.manifest.name,
          syncStatus: this.syncStatus,
        })
      );
      if (this.currSyncMsg !== undefined && this.currSyncMsg !== "") {
        new Notice(this.currSyncMsg);
      }
      return;
    }

    let originLabel = `${this.manifest.name}`;
    if (this.syncRibbon !== undefined) {
      originLabel = this.syncRibbon.getAttribute("aria-label");
    }

    try {
      log.info(
        `${
          this.manifest.id
        }-${Date.now()}: start sync, triggerSource=${triggerSource}`
      );

      if (this.syncRibbon !== undefined) {
        setIcon(this.syncRibbon, iconNameSyncRunning);
        this.syncRibbon.setAttribute(
          "aria-label",
          t("syncrun_syncingribbon", {
            pluginName: this.manifest.name,
            triggerSource: triggerSource,
          })
        );
      }

      const MAX_STEPS = 8;

      if (triggerSource === "dry") {
        getNotice(
          t("syncrun_step0", {
            maxSteps: `${MAX_STEPS}`,
          })
        );
      }

      //log.info(`huh ${this.settings.password}`)
      getNotice(
        t("syncrun_step1", {
          maxSteps: `${MAX_STEPS}`,
          serviceType: this.settings.serviceType,
        })
      );
      this.syncStatus = "preparing";

      getNotice(
        t("syncrun_step2", {
          maxSteps: `${MAX_STEPS}`,
        })
      );
      this.syncStatus = "getting_remote_files_list";
      const self = this;
      const client = new RemoteClient(
        this.settings.serviceType,
        this.settings.s3,
        this.settings.webdav,
        this.settings.dropbox,
        this.settings.onedrive,
        this.app.vault.getName(),
        () => self.saveSettings()
      );
      const remoteRsp = await client.listFromRemote();
      // log.debug(remoteRsp);

      getNotice(
        t("syncrun_step3", {
          maxSteps: `${MAX_STEPS}`,
        })
      );
      this.syncStatus = "checking_password";
      const passwordCheckResult = await isPasswordOk(
        remoteRsp.Contents,
        this.settings.password
      );
      if (!passwordCheckResult.ok) {
        getNotice(t("syncrun_passworderr"));
        throw Error(passwordCheckResult.reason);
      }

      getNotice(
        t("syncrun_step4", {
          maxSteps: `${MAX_STEPS}`,
        })
      );
      this.syncStatus = "getting_remote_extra_meta";
      const { remoteStates, metadataFile } = await parseRemoteItems(
        remoteRsp.Contents,
        this.db,
        this.vaultRandomID,
        client.serviceType,
        this.settings.password
      );
      const origMetadataOnRemote = await fetchMetadataFile(
        metadataFile,
        client,
        this.app.vault,
        this.settings.password
      );

      getNotice(
        t("syncrun_step5", {
          maxSteps: `${MAX_STEPS}`,
        })
      );
      this.syncStatus = "getting_local_meta";
      const local = this.app.vault.getAllLoadedFiles();
      const localHistory = await loadFileHistoryTableByVault(
        this.db,
        this.vaultRandomID
      );
      let localConfigDirContents: ObsConfigDirFileType[] = undefined;
      if (this.settings.syncConfigDir) {
        localConfigDirContents = await listFilesInObsFolder(
          this.app.vault.configDir,
          this.app.vault,
          this.manifest.id
        );
      }
      // log.info(local);
      // log.info(localHistory);

      getNotice(
        t("syncrun_step6", {
          maxSteps: `${MAX_STEPS}`,
        })
      );
      this.syncStatus = "generating_plan";
      const { plan, sortedKeys, deletions, sizesGoWrong } = await getSyncPlan(
        remoteStates,
        local,
        localConfigDirContents,
        origMetadataOnRemote.deletions,
        localHistory,
        client.serviceType,
        triggerSource,
        this.app.vault,
        this.settings.syncConfigDir,
        this.app.vault.configDir,
        this.settings.syncUnderscoreItems,
        this.settings.skipSizeLargerThan,
        this.settings.password
      );
      log.info(plan.mixedStates); // for debugging
      await insertSyncPlanRecordByVault(this.db, plan, this.vaultRandomID);

      // The operations above are almost read only and kind of safe.
      // The operations below begins to write or delete (!!!) something.

      if (triggerSource !== "dry") {
        getNotice(
          t("syncrun_step7", {
            maxSteps: `${MAX_STEPS}`,
          })
        );

        this.syncStatus = "syncing";
        await doActualSync(
          client,
          this.db,
          this.vaultRandomID,
          this.app.vault,
          plan,
          sortedKeys,
          metadataFile,
          origMetadataOnRemote,
          sizesGoWrong,
          deletions,
          (key: string) => self.trash(key),
          this.settings.password,
          this.settings.concurrency,
          (ss: FileOrFolderMixedState[]) => {
            new SizesConflictModal(
              self.app,
              self,
              this.settings.skipSizeLargerThan,
              ss,
              this.settings.password !== ""
            ).open();
          },
          (i: number, totalCount: number, pathName: string, decision: string) =>
            self.setCurrSyncMsg(i, totalCount, pathName, decision)
        );
      } else {
        this.syncStatus = "syncing";
        getNotice(
          t("syncrun_step7skip", {
            maxSteps: `${MAX_STEPS}`,
          })
        );
      }

      getNotice(
        t("syncrun_step8", {
          maxSteps: `${MAX_STEPS}`,
        })
      );
      this.syncStatus = "finish";
      this.syncStatus = "idle";

      if (this.syncRibbon !== undefined) {
        setIcon(this.syncRibbon, iconNameSyncWait);
        this.syncRibbon.setAttribute("aria-label", originLabel);
      }

      log.info(
        `${
          this.manifest.id
        }-${Date.now()}: finish sync, triggerSource=${triggerSource}`
      );
    } catch (error) {
      const msg = t("syncrun_abort", {
        manifestID: this.manifest.id,
        theDate: `${Date.now()}`,
        triggerSource: triggerSource,
        syncStatus: this.syncStatus,
      });
      log.error(msg);
      log.error(error);
      getNotice(msg, 10 * 1000);
      if (error instanceof AggregateError) {
        for (const e of error.errors) {
          getNotice(e.message, 10 * 1000);
        }
      } else {
        getNotice(error.message, 10 * 1000);
      }
      this.syncStatus = "idle";
      if (this.syncRibbon !== undefined) {
        setIcon(this.syncRibbon, iconNameSyncWait);
        this.syncRibbon.setAttribute("aria-label", originLabel);
      }
    }
  }
Example #25
Source File: settingsTab.ts    From obsidian-customizable-sidebar with MIT License 4 votes vote down vote up
display(): void {
		let { containerEl } = this;

		containerEl.empty();

		containerEl.createEl('h2', { text: 'Customizable Sidebar Settings' });

		new Setting(containerEl)
			.setName("Add Command to Sidebar")
			.setDesc("Add a new command to the left Sidebar Ribbon")
			.addButton((bt) => {
				bt.setButtonText("Add Command")
					.onClick(() => {
						new CommandSuggester(this.plugin).open();
					});
			});

		this.plugin.settings.sidebarCommands.forEach((c, index) => {
			const iconDiv = createDiv({ cls: "CS-settings-icon" });
			setIcon(iconDiv, c.icon, 20);
			const setting = new Setting(containerEl)
				.setName(c.name);

			if (index > 0) {
				setting.addExtraButton(bt => {
					bt.setIcon("up-arrow-with-tail")
						.setTooltip("Move up")
						.onClick(async () => await this.moveCommand(c, 'up'));
				})
			}
			if (index < this.plugin.settings.sidebarCommands.length - 1) {
				setting.addExtraButton(bt => {
					bt.setIcon("down-arrow-with-tail")
						.setTooltip("Move down")
						.onClick(async () => await this.moveCommand(c, 'down'));
				})
			}
			setting
				.addExtraButton(bt => {
					bt.setIcon("trash")
						.setTooltip("Remove Command")
						.onClick(async () => {
							this.plugin.settings.sidebarCommands.remove(c);
							await this.plugin.saveSettings();
							this.display();
							const ribbonButton = Array.from(this.leftRibbonPanel.children)
								.find((btn) => c.name === btn.getAttribute('aria-label'))
							this.leftRibbonPanel.removeChild(ribbonButton);
						})
				})
				.addExtraButton(bt => {
					bt.setIcon("gear")
						.setTooltip("Edit Icon")
						.onClick(() => {
							new IconPicker(this.plugin, c, true).open();
						})
				});
			setting.nameEl.prepend(iconDiv);
			setting.nameEl.addClass("CS-flex");
		});

		//@ts-ignore
		const children: HTMLCollection = this.app.workspace.leftRibbon.ribbonActionsEl.children;
		for (let i = 0; i < children.length; i++) {
			if (!this.plugin.settings.sidebarCommands.contains(this.plugin.settings.sidebarCommands.find(c => c.name === (children.item(i) as HTMLElement).getAttribute("aria-label")))) {
				new Setting(containerEl)
					.setName("Hide " + (children.item(i) as HTMLElement).getAttribute("aria-label") + "?")
					.addToggle(cb => {
						cb.setValue((children.item(i) as HTMLElement).style.display === "none")
						cb.onChange(async value => {
							if(value === true) {
								(children.item(i) as HTMLElement).style.display = "none";
								this.plugin.settings.hiddenCommands.push((children.item(i) as HTMLElement).getAttribute("aria-label"));
								await this.plugin.saveSettings();
							} else {
								(children.item(i) as HTMLElement).style.display = "flex";
								this.plugin.settings.hiddenCommands.remove((children.item(i) as HTMLElement).getAttribute("aria-label"));
								await this.plugin.saveSettings();
							}
						});
					});
			}
		}

		new Setting(containerEl)
			.setName("Desktop only: Support floating sidebars")
			.setDesc("Change the sidebar behavior to match mobile: they will open above content panes unless pinned.")
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.pinSidebar !== undefined);
				toggle.onChange(async value => {
					if ( value ) {
						// start with default pinned/open
						this.plugin.settings.pinSidebar = {
							right: true,
							left: true
						};
					} else {
						delete this.plugin.settings.pinSidebar;
					}
					this.plugin.sidebarPins();
					await this.plugin.saveSettings();
				});
			});

		new Setting(containerEl)
			.setName('Donate')
			.setDesc('If you like this plugin, consider donating to support continued development:')
			.setClass("AT-extra")
			.addButton((bt) => {
				bt.buttonEl.outerHTML = `<a href="https://www.buymeacoffee.com/phibr0"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=phibr0&button_colour=5F7FFF&font_colour=ffffff&font_family=Inter&outline_colour=000000&coffee_colour=FFDD00"></a>`;
			});

	}
Example #26
Source File: settings.ts    From obsidian-fantasy-calendar with MIT License 4 votes vote down vote up
buildEvents(containerEl: HTMLDetailsElement) {
        containerEl.empty();
        containerEl.ontoggle = () => {
            this.data.settingsToggleState.events = containerEl.open;
        };
        const summary = containerEl.createEl("summary");
        new Setting(summary).setHeading().setName("Events");

        summary.createDiv("collapser").createDiv("handle");

        new Setting(containerEl)
            .setName("Add Events to Default Calendar")
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "Add events found in notes to the default calendar if the "
                    });
                    e.createEl("code", { text: "fc-calendar" });
                    e.createSpan({ text: " frontmatter tag is not present." });
                })
            )
            .addToggle((t) => {
                t.setValue(this.data.addToDefaultIfMissing).onChange(
                    async (v) => {
                        this.data.addToDefaultIfMissing = v;
                        await this.plugin.saveSettings();
                        this.plugin.watcher.start();
                    }
                );
            });
        new Setting(containerEl)
            .setName("Display Event Previews")
            .setDesc(
                "Use the core Note Preview plugin to display event notes when hovered."
            )
            .addToggle((t) => {
                t.setValue(this.data.eventPreview).onChange((v) => {
                    this.data.eventPreview = v;
                    this.plugin.saveSettings();
                });
            });
        new Setting(containerEl)
            .setName("Write Event Data to Frontmatter")
            .setDesc(
                "Events linked to notes will write their data to the note frontmatter."
            )
            .addToggle((t) => {
                t.setValue(this.data.eventFrontmatter).onChange((v) => {
                    this.data.eventFrontmatter = v;
                    this.plugin.saveSettings();
                });
            });

        new Setting(containerEl)
            .setName("Parse Note Titles for Event Dates")
            .setDesc("The plugin will parse note titles for event dates.")
            .addToggle((t) => {
                t.setValue(this.data.parseDates).onChange(async (v) => {
                    this.data.parseDates = v;
                    await this.plugin.saveSettings();
                    this.plugin.watcher.start();
                });
            });
        new Setting(containerEl)
            .setName("Date Format")
            .setClass(this.data.dailyNotes ? "daily-notes" : "no-daily-notes")
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "Event dates will be parsed using this format."
                    });
                    e.createSpan({ text: "Only the " });
                    e.createEl("code", { text: "Y" });
                    e.createSpan({
                        text: ", "
                    });
                    e.createEl("code", { text: "M" });
                    e.createSpan({
                        text: ", and "
                    });
                    e.createEl("code", { text: "D" });
                    e.createEl("a", {
                        text: "tokens",
                        href: "https://momentjs.com/docs/#/displaying/format/",
                        cls: "external-link"
                    });
                    e.createSpan({
                        text: " are supported."
                    });
                    if (
                        ["Y", "M", "D"].some(
                            (token) => !this.data.dateFormat.includes(token)
                        )
                    ) {
                        e.createEl("br");
                        const span = e.createSpan({
                            cls: "fantasy-calendar-warning date-format"
                        });
                        setIcon(
                            span.createSpan("fantasy-calendar-warning"),
                            "fantasy-calendar-warning"
                        );
                        let missing = ["Y", "M", "D"].filter(
                            (token) => !this.data.dateFormat.includes(token)
                        );
                        span.createSpan({
                            text: ` Date format is missing: ${missing
                                .join(", ")
                                .replace(/, ([^,]*)$/, " and $1")}`
                        });
                    }
                })
            )
            .addText((t) => {
                t.setDisabled(this.data.dailyNotes)
                    .setValue(this.plugin.format)
                    .onChange((v) => {
                        this.data.dateFormat = v;
                        this.plugin.saveSettings();
                    });
                t.inputEl.onblur = () => this.buildEvents(containerEl);
            })
            .addExtraButton((b) => {
                if (!this.plugin.canUseDailyNotes) {
                    b.extraSettingsEl.detach();
                    return;
                }
                if (this.data.dailyNotes) {
                    b.setIcon("checkmark")
                        .setTooltip("Unlink from Daily Notes")
                        .onClick(() => {
                            this.data.dailyNotes = false;
                            this.buildEvents(containerEl);
                        });
                } else {
                    b.setIcon("sync")
                        .setTooltip("Link with Daily Notes")
                        .onClick(() => {
                            this.data.dailyNotes = true;
                            this.buildEvents(containerEl);
                        });
                }
            });
    }
Example #27
Source File: settings.ts    From obsidian-fantasy-calendar with MIT License 4 votes vote down vote up
buildCalendars() {
        this.calendarsEl.empty();
        this.calendarsEl.ontoggle = () => {
            this.data.settingsToggleState.calendars = this.calendarsEl.open;
        };
        const summary = this.calendarsEl.createEl("summary");
        new Setting(summary).setHeading().setName("Calendar Management");

        summary.createDiv("collapser").createDiv("handle");

        new Setting(this.calendarsEl)
            .setName("Show Intercalary Months Separately")
            .setDesc(
                "Intercalary months will appear a distinct months in the calendar."
            )
            .addToggle((t) => {
                t.setValue(this.data.showIntercalary).onChange((v) => {
                    this.data.showIntercalary = v;
                    this.plugin.saveCalendar();
                });
            });
        new Setting(this.calendarsEl)
            .setName("Default Calendar")
            .setDesc("Views will open to this calendar by default.")
            .addDropdown((d) => {
                d.addOption("none", "None");
                for (let calendar of this.data.calendars) {
                    d.addOption(calendar.id, calendar.name);
                }
                d.setValue(this.plugin.data.defaultCalendar);
                d.onChange(async (v) => {
                    if (v === "none") {
                        this.plugin.data.defaultCalendar = null;
                        this.plugin.saveSettings();
                        return;
                    }

                    this.plugin.data.defaultCalendar = v;
                    await this.plugin.saveSettings();
                    this.plugin.watcher.start();
                });
            });
        new Setting(this.calendarsEl)
            .setName("Import Calendar")
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "Import calendar from "
                    });
                    e.createEl("a", {
                        href: "https://app.fantasy-calendar.com",
                        text: "Fantasy Calendar",
                        cls: "external-link"
                    });
                })
            )
            .addButton((b) => {
                const input = createEl("input", {
                    attr: {
                        type: "file",
                        name: "merge",
                        accept: ".json",
                        multiple: true,
                        style: "display: none;"
                    }
                });
                input.onchange = async () => {
                    const { files } = input;

                    if (!files.length) return;
                    try {
                        const data = [];
                        for (let file of Array.from(files)) {
                            data.push(JSON.parse(await file.text()));
                        }
                        const calendars = Importer.import(data);
                        for (const calendar of calendars) {
                            await this.plugin.addNewCalendar(calendar);
                        }
                        this.display();
                    } catch (e) {
                        new Notice(
                            `There was an error while importing the calendar${
                                files.length == 1 ? "" : "s"
                            }.`
                        );
                        console.error(e);
                    }

                    input.value = null;
                };
                b.setButtonText("Choose Files");
                b.buttonEl.addClass("calendar-file-upload");
                b.buttonEl.appendChild(input);
                b.onClick(() => input.click());
            });

        new Setting(this.calendarsEl)
            .setName("Create New Calendar")
            .addButton((button: ButtonComponent) =>
                button
                    .setTooltip("Launch Calendar Creator")
                    .setIcon("plus-with-circle")
                    .onClick(async () => {
                        const calendar = await this.launchCalendarCreator();
                        if (calendar) {
                            await this.plugin.addNewCalendar(calendar);
                            this.display();
                        }
                    })
            );

        this.existingEl = this.calendarsEl.createDiv("existing-calendars");

        this.showCalendars();
    }
Example #28
Source File: settings.ts    From obsidian-fantasy-calendar with MIT License 4 votes vote down vote up
buildInfo(containerEl: HTMLElement) {
        containerEl.empty();

        new Setting(containerEl)
            .setName(`Reset "Don't Ask Again" Prompts`)
            .setDesc(
                `All confirmations set to "Don't Ask Again" will be reset.`
            )
            .addButton((b) => {
                b.setIcon("reset").onClick(() => {
                    this.plugin.data.exit = {
                        saving: false,
                        event: false,
                        calendar: false
                    };
                    this.plugin.saveSettings();
                });
            });

        new Setting(containerEl)
            .setName(
                createFragment((e) => {
                    const span = e.createSpan("fantasy-calendar-warning");
                    setIcon(
                        span.createSpan("fantasy-calendar-warning"),
                        "fantasy-calendar-warning"
                    );
                    span.createSpan({ text: "Default Config Directory" });
                })
            )
            .setDesc(
                createFragment((e) => {
                    e.createSpan({
                        text: "Please back up your data before changing this setting. Hidden directories must be manually entered."
                    });
                    e.createEl("br");
                    e.createSpan({
                        text: `Current directory: `
                    });
                    const configDirectory =
                        this.data.configDirectory ?? this.app.vault.configDir;
                    e.createEl("code", {
                        text: configDirectory
                    });
                })
            )
            .addText(async (text) => {
                let folders = this.app.vault
                    .getAllLoadedFiles()
                    .filter((f) => f instanceof TFolder);

                text.setPlaceholder(
                    this.data.configDirectory ?? this.app.vault.configDir
                );
                const modal = new FolderSuggestionModal(this.app, text, [
                    ...(folders as TFolder[])
                ]);

                modal.onClose = async () => {
                    if (!text.inputEl.value) {
                        this.data.configDirectory = null;
                    } else {
                        const exists = await this.app.vault.adapter.exists(
                            text.inputEl.value
                        );

                        if (!exists) {
                            this.data.configDirectory = text.inputEl.value;
                            await this.plugin.saveSettings();
                        }
                    }
                };

                text.inputEl.onblur = async () => {
                    if (!text.inputEl.value) {
                        return;
                    }
                    const exists = await this.app.vault.adapter.exists(
                        text.inputEl.value
                    );

                    this.data.configDirectory = text.inputEl.value;

                    await this.plugin.saveSettings();
                    this.display();
                };
            })
            .addExtraButton((b) => {
                b.setTooltip("Reset to Default")
                    .setIcon("reset")
                    .onClick(async () => {
                        this.data.configDirectory = null;
                        await this.plugin.saveSettings();
                        this.display();
                    });
            });
    }