diff --git a/app/src/config/bazaar.ts b/app/src/config/bazaar.ts index c8e834d67..8e6a55729 100644 --- a/app/src/config/bazaar.ts +++ b/app/src/config/bazaar.ts @@ -302,7 +302,7 @@ export const bazaar = { app.plugins.find((item: Plugin) => { if (item.name === dataObj.name) { // @ts-ignore - hasSetting = item.__proto__.hasOwnProperty("openSetting"); + hasSetting = item.setting || item.__proto__.hasOwnProperty("openSetting"); return true; } }); diff --git a/app/src/plugin/API.ts b/app/src/plugin/API.ts index 461b1d5e9..199d54c8a 100644 --- a/app/src/plugin/API.ts +++ b/app/src/plugin/API.ts @@ -13,6 +13,7 @@ import {newCardModel} from "../card/newCardTab"; import {App} from "../index"; import {Constants} from "../constants"; import {Model} from "../layout/Model"; +import {Setting} from "./Setting"; export class Menu { private menu: SiyuanMenu; @@ -208,4 +209,5 @@ export const API = { Plugin, Dialog, Menu, + Setting }; diff --git a/app/src/plugin/Setting.ts b/app/src/plugin/Setting.ts new file mode 100644 index 000000000..e91a69cab --- /dev/null +++ b/app/src/plugin/Setting.ts @@ -0,0 +1,94 @@ +import {isMobile} from "../util/functions"; +import {Dialog} from "../dialog"; + +export class Setting { + private items: IPluginSettingOption[] = []; + private confirmCallback: () => void; + private destroyCallback: () => void; + private width: string; + private height: string; + + constructor(options: { + height?: string, + width?: string, + destroyCallback?: () => void + confirmCallback?: () => void + }) { + this.confirmCallback = options.confirmCallback; + this.width = options.width || (isMobile() ? "92vw" : "768px"); + this.height = options.height || "80vh"; + } + + public addItem(options: IPluginSettingOption) { + this.items.push(options); + } + + public open(name: string) { + const dialog = new Dialog({ + title: name, + content: `
+
+
+ +
+ +
`, + width: this.width, + height: this.height, + destroyCallback: () => { + if (this.destroyCallback) { + this.destroyCallback(); + } + } + }); + const contentElement = dialog.element.querySelector(".b3-dialog__content"); + this.items.forEach((item) => { + let html = "" + let actionElement = item.actionElement; + if (!item.actionElement && item.createActionElement) { + actionElement = item.createActionElement(); + } + if (actionElement && actionElement.tagName === "TEXTAREA") { + html = `` + } else { + html = `` + } + contentElement.insertAdjacentHTML("beforeend", html); + if (actionElement) { + if (["INPUT", "TEXTAREA"].includes(actionElement.tagName)) { + dialog.bindInput(actionElement as HTMLInputElement, () => { + (btnsElement[1] as HTMLButtonElement).click(); + }); + } + if (actionElement.tagName === "TEXTAREA") { + contentElement.lastElementChild.lastElementChild.insertAdjacentElement("beforeend", actionElement); + } else { + contentElement.lastElementChild.insertAdjacentElement("beforeend", actionElement); + } + } + }) + contentElement.querySelector("input")?.focus(); + const btnsElement = dialog.element.querySelectorAll(".b3-dialog__action .b3-button"); + btnsElement[0].addEventListener("click", () => { + dialog.destroy(); + }); + btnsElement[1].addEventListener("click", () => { + if (this.confirmCallback) { + this.confirmCallback(); + } + dialog.destroy(); + }); + } +} diff --git a/app/src/plugin/index.ts b/app/src/plugin/index.ts index 2695e8d36..64bb891ce 100644 --- a/app/src/plugin/index.ts +++ b/app/src/plugin/index.ts @@ -10,6 +10,7 @@ import {getDockByType, setPanelFocus} from "../layout/util"; import {hasClosestByAttribute} from "../protyle/util/hasClosest"; import {BlockPanel} from "../block/Panel"; import {genUUID} from "../util/genID"; +import {Setting} from "./Setting"; export class Plugin { private app: App; @@ -18,6 +19,7 @@ export class Plugin { public data: any = {}; public name: string; public topBarIcons: Element[] = []; + public setting: Setting; public statusBarIcons: Element[] = []; public commands: ICommand[] = []; public models: { @@ -103,7 +105,10 @@ export class Plugin { } public openSetting() { - // 打开设置 + if (!this.setting) { + return; + } + this.setting.open(this.name); } public loadData(storageName: string) { diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 5ddd63ae0..7dc97fea2 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -83,6 +83,14 @@ interface ICard { nextDues: IObject } +interface IPluginSettingOption { + title: string + description?: string + actionElement?: HTMLElement + + createActionElement?(): HTMLElement +} + interface ISearchOption { page: number removed?: boolean // 移除后需记录搜索内容 https://github.com/siyuan-note/siyuan/issues/7745