A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {isMobile} from "../util/functions";
2import {Dialog} from "../dialog";
3
4export class Setting {
5 private items: IPluginSettingOption[] = [];
6 private confirmCallback: () => void;
7 private destroyCallback: () => void;
8 private width: string;
9 private height: string;
10 public dialog:Dialog;
11
12 constructor(options: {
13 height?: string,
14 width?: string,
15 destroyCallback?: () => void
16 confirmCallback?: () => void
17 }) {
18 this.confirmCallback = options.confirmCallback;
19 this.destroyCallback = options.destroyCallback;
20 this.width = options.width || (isMobile() ? "92vw" : "768px");
21 this.height = options.height || "80vh";
22 }
23
24 public addItem(options: IPluginSettingOption) {
25 this.items.push(options);
26 }
27
28 public open(name: string) {
29 const dialog = new Dialog({
30 title: name,
31 content: `<div class="b3-dialog__content">
32</div>
33<div class="b3-dialog__action${this.confirmCallback ? "" : " fn__none"}">
34 <button class="b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button>
35 <div class="fn__space${this.confirmCallback ? "" : " fn__none"}"></div>
36 <button class="b3-button b3-button--text${this.confirmCallback ? "" : " fn__none"}">${window.siyuan.languages.save}</button>
37</div>`,
38 width: this.width,
39 height: this.height,
40 destroyCallback: () => {
41 if (this.destroyCallback) {
42 this.destroyCallback();
43 }
44 }
45 });
46 const contentElement = dialog.element.querySelector(".b3-dialog__content");
47 this.items.forEach((item) => {
48 let html = "";
49 let actionElement = item.actionElement;
50 if (!item.actionElement && item.createActionElement) {
51 actionElement = item.createActionElement();
52 }
53 const tagName = actionElement?.classList.contains("b3-switch") ? "label" : "div";
54 if (typeof item.direction === "undefined") {
55 item.direction = (!actionElement || "TEXTAREA" === actionElement.tagName) ? "row" : "column";
56 }
57 if (item.direction === "row") {
58 html = `<${tagName} class="b3-label">
59 <div class="fn__block">
60 ${item.title}
61 ${item.description ? `<div class="b3-label__text">${item.description}</div>` : ""}
62 <div class="fn__hr"></div>
63 </div>
64</${tagName}>`;
65 } else {
66 html = `<${tagName} class="fn__flex b3-label config__item">
67 <div class="fn__flex-1">
68 ${item.title}
69 ${item.description ? `<div class="b3-label__text">${item.description}</div>` : ""}
70 </div>
71 <span class="fn__space${actionElement ? "" : " fn__none"}"></span>
72</${tagName}>`;
73 }
74 contentElement.insertAdjacentHTML("beforeend", html);
75 if (actionElement) {
76 if (["INPUT", "TEXTAREA"].includes(actionElement.tagName)) {
77 dialog.bindInput(actionElement as HTMLInputElement, () => {
78 btnsElement[1].dispatchEvent(new CustomEvent("click"));
79 }, actionElement.tagName === "INPUT");
80 }
81 if (item.direction === "row") {
82 contentElement.lastElementChild.lastElementChild.insertAdjacentElement("beforeend", actionElement);
83 actionElement.classList.add("fn__block");
84 } else {
85 actionElement.classList.remove("fn__block");
86 actionElement.classList.add("fn__flex-center", "fn__size200");
87 contentElement.lastElementChild.insertAdjacentElement("beforeend", actionElement);
88 }
89 }
90 });
91 (contentElement.querySelector("input, textarea") as HTMLElement)?.focus();
92 const btnsElement = dialog.element.querySelectorAll(".b3-dialog__action .b3-button");
93 btnsElement[0].addEventListener("click", () => {
94 dialog.destroy();
95 });
96 btnsElement[1].addEventListener("click", () => {
97 if (this.confirmCallback) {
98 this.confirmCallback();
99 }
100 dialog.destroy();
101 });
102 this.dialog = dialog;
103 }
104}