A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 104 lines 4.3 kB view raw
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}