/// #if !BROWSER import {ipcRenderer, shell} from "electron"; import * as path from "path"; /// #endif import {Constants} from "../constants"; import {exportLayout} from "../layout/util"; import * as Pickr from "@simonwep/pickr"; import {isBrowser} from "../util/functions"; import {fetchPost} from "../util/fetch"; import {loadAssets, renderSnippet} from "../util/assets"; import {genOptions} from "../util/genOptions"; import {hasClosestByClassName} from "../protyle/util/hasClosest"; export const appearance = { element: undefined as Element, genHTML: () => { return `
${window.siyuan.languages.theme}
${window.siyuan.languages.appearance9}
${window.siyuan.languages.appearance1}
`; }, onGetcustomcss: (data: Record>) => { let customHTML = '
'; Object.keys(data).forEach((item) => { customHTML += `
${window.siyuan.languages[item]}
`; Object.keys(data[item]).forEach(subItem => { customHTML += `
${window.siyuan.languages[subItem]}
`; }); }); appearance.element.querySelector("#appearanceCustomPanel").innerHTML = customHTML; const pickrs: Record> = {}; appearance.element.querySelectorAll("#appearanceCustomPanel .colorPicker").forEach((item: HTMLInputElement) => { // @ts-ignore const pickr = Pickr.create({ container: "#appearanceCustomPanel", el: item, theme: "nano", default: item.getAttribute("data-value"), comparison: false, components: { preview: true, opacity: true, hue: true, interaction: { input: true, } } }); pickr.on("hide", () => { appearance._sendCustomcss(pickrs); }); pickr.on("changestop", () => { appearance._sendCustomcss(pickrs); }); const key = item.getAttribute("data-key"); if (!pickrs[key]) { pickrs[key] = {}; } pickrs[key][item.getAttribute("data-subkey")] = pickr; }); }, _sendCustomcss: (pickrs: Record>) => { const css: Record> = {}; Object.keys(pickrs).forEach((item) => { css[item] = {}; Object.keys(pickrs[item]).forEach(subItem => { css[item][subItem] = pickrs[item][subItem].getColor().toRGBA().toString(0); }); }); fetchPost("/api/setting/setCustomCSS", { theme: appearance.element.querySelector("#appearanceCustomName").textContent, css }); }, _send: () => { const themeLight = (appearance.element.querySelector("#themeLight") as HTMLSelectElement).value; const themeDark = (appearance.element.querySelector("#themeDark") as HTMLSelectElement).value; const modeElementValue = parseInt((appearance.element.querySelector("#mode") as HTMLSelectElement).value); fetchPost("/api/setting/setAppearance", { icon: (appearance.element.querySelector("#icon") as HTMLSelectElement).value, mode: modeElementValue === 2 ? window.siyuan.config.appearance.mode : modeElementValue, modeOS: modeElementValue === 2, codeBlockThemeDark: (appearance.element.querySelector("#codeBlockThemeDark") as HTMLSelectElement).value, codeBlockThemeLight: (appearance.element.querySelector("#codeBlockThemeLight") as HTMLSelectElement).value, themeDark, themeLight, darkThemes: window.siyuan.config.appearance.darkThemes, lightThemes: window.siyuan.config.appearance.lightThemes, icons: window.siyuan.config.appearance.icons, lang: (appearance.element.querySelector("#lang") as HTMLSelectElement).value, customCSS: window.siyuan.config.appearance.customCSS, closeButtonBehavior: (appearance.element.querySelector("#closeButtonBehavior") as HTMLInputElement).checked ? 1 : 0, nativeEmoji: (appearance.element.querySelector("#nativeEmoji") as HTMLInputElement).checked, hideStatusBar: (appearance.element.querySelector("#hideStatusBar") as HTMLInputElement).checked, }, response => { if (( window.siyuan.config.appearance.themeJS && !response.data.modeOS && ( response.data.mode !== window.siyuan.config.appearance.mode || window.siyuan.config.appearance.themeLight !== response.data.themeLight || window.siyuan.config.appearance.themeDark !== response.data.themeDark ) ) || (response.data.modeOS && !window.siyuan.config.appearance.modeOS) ) { exportLayout(true); return; } appearance.onSetappearance(response.data); if (response.data.hideStatusBar) { document.getElementById("status").classList.add("fn__none"); } else { document.getElementById("status").classList.remove("fn__none"); } }); }, _bindSnippet: (element: HTMLElement) => { const itemContentElement = hasClosestByClassName(element, "b3-label"); if (!itemContentElement) { return } fetchPost("/api/snippet/setSnippet", { id: itemContentElement.getAttribute("data-id"), name: itemContentElement.querySelector("input").value, type: itemContentElement.querySelector(".b3-chip").textContent, content: itemContentElement.querySelector("textarea").value, enabled: (itemContentElement.querySelector(".b3-switch") as HTMLInputElement).checked }, (response) => { itemContentElement.setAttribute("data-id", response.data.id) renderSnippet(); }) }, _genSnippet: (options: ISnippet) => { return `
${options.type}
` }, bindEvent: () => { if (window.siyuan.config.appearance.customCSS) { fetchPost("/api/setting/getCustomCSS", { theme: appearance.element.querySelector("#appearanceCustomName").textContent }, response => { appearance.onGetcustomcss(response.data); }); } const codeSnippetPanelElement = appearance.element.querySelector("#codeSnippetPanel"); const codeSnippetElement = appearance.element.querySelector("#codeSnippet"); codeSnippetElement.addEventListener("click", () => { if (codeSnippetPanelElement.innerHTML) { codeSnippetPanelElement.innerHTML = ""; return; } fetchPost("/api/snippet/getSnippet", {type: "all", enabled: 2}, (response) => { let html = `
`; response.data.snippets.forEach((item: ISnippet) => { html += appearance._genSnippet(item); }); codeSnippetPanelElement.innerHTML = html; response.data.snippets.forEach((item: ISnippet) => { const nameElement = (codeSnippetPanelElement.querySelector(`[data-id="${item.id}"] input`) as HTMLInputElement) nameElement.value = item.name; const contentElement = codeSnippetPanelElement.querySelector(`[data-id="${item.id}"] textarea`) as HTMLTextAreaElement; contentElement.textContent = item.content; nameElement.addEventListener("blur", (event) => { appearance._bindSnippet(nameElement); }) contentElement.addEventListener("blur", (event) => { appearance._bindSnippet(contentElement); }) codeSnippetPanelElement.querySelector(`[data-id="${item.id}"] .b3-switch`).addEventListener("change", (event) => { appearance._bindSnippet(contentElement); }) }); }); }); codeSnippetPanelElement.addEventListener("click", (event) => { const target = event.target as HTMLElement; if (target.id === "addCodeSnippetCSS" || target.id === "addCodeSnippetJS") { target.parentElement.insertAdjacentHTML("afterend", appearance._genSnippet({ type: target.id === "addCodeSnippetCSS" ? "css" : "js", name: "", content: "", enabled: false })) codeSnippetPanelElement.querySelector(".b3-text-field").addEventListener("blur", (event) => { appearance._bindSnippet(event.target as HTMLElement); }) codeSnippetPanelElement.querySelector("textarea.b3-text-field").addEventListener("blur", (event) => { appearance._bindSnippet(event.target as HTMLElement); }) codeSnippetPanelElement.querySelector('.b3-switch').addEventListener("change", (event) => { appearance._bindSnippet(event.target as HTMLElement); }) return; } const removeElement = hasClosestByClassName(target, "b3-tooltips") if (removeElement) { const id = removeElement.parentElement.parentElement.getAttribute("data-id"); removeElement.parentElement.parentElement.remove(); if (!id) { return; } fetchPost("/api/snippet/removeSnippet", { id }, (response) => { const exitElement = document.getElementById(`snippet${response.data.type === "css" ? "CSS" : "JS"}${response.data.id}`) as HTMLScriptElement; if (exitElement) { exitElement.remove(); } }) } }) const appearanceCustomElement = appearance.element.querySelector("#appearanceCustom"); appearanceCustomElement.addEventListener("click", () => { if (window.siyuan.config.appearance.customCSS) { window.siyuan.config.appearance.customCSS = false; appearanceCustomElement.textContent = window.siyuan.languages.open; appearance.element.querySelector("#appearanceCustomPanel").innerHTML = ""; } else { window.siyuan.config.appearance.customCSS = true; fetchPost("/api/setting/getCustomCSS", { theme: appearance.element.querySelector("#appearanceCustomName").textContent }, response => { appearance.onGetcustomcss(response.data); }); appearanceCustomElement.textContent = window.siyuan.languages.close; } appearance._send(); }); appearance.element.querySelector("#resetLayout").addEventListener("click", () => { fetchPost("/api/system/setUILayout", {layout: {}}, () => { window.location.reload(); }); }); /// #if !BROWSER appearance.element.querySelector("#appearanceOpenIcon").addEventListener("click", () => { shell.openPath(path.join(window.siyuan.config.system.confDir, "appearance", "icons")); }); appearance.element.querySelector("#appearanceOpenTheme").addEventListener("click", () => { shell.openPath(path.join(window.siyuan.config.system.confDir, "appearance", "themes")); }); appearance.element.querySelector("#appearanceOpenEmoji").addEventListener("click", () => { shell.openPath(path.join(window.siyuan.config.system.dataDir, "emojis")); }); appearance.element.querySelector("#appearanceRefresh").addEventListener("click", () => { exportLayout(true); }); /// #endif appearance.element.querySelectorAll("select").forEach(item => { item.addEventListener("change", () => { appearance._send(); }); }); appearance.element.querySelectorAll(".b3-switch").forEach((item) => { item.addEventListener("change", () => { appearance._send(); }); }); }, onSetappearance(data: IAppearance, needLoadAsset = true) { if (data.lang !== window.siyuan.config.appearance.lang || data.nativeEmoji !== window.siyuan.config.appearance.nativeEmoji) { exportLayout(true); return; } window.siyuan.config.appearance = data; if (appearance.element) { const theme = data.mode === 0 ? data.themeLight : data.themeDark; const modeElement = appearance.element.querySelector("#mode") as HTMLSelectElement; if (modeElement) { if (data.modeOS) { modeElement.value = "2"; } else { modeElement.value = data.mode === 0 ? "0" : "1"; } appearance.element.querySelector("#appearanceCustomName").textContent = theme; } const themeLightElement = appearance.element.querySelector("#themeLight") as HTMLSelectElement; if (themeLightElement) { themeLightElement.innerHTML = genOptions(window.siyuan.config.appearance.lightThemes, window.siyuan.config.appearance.themeLight); } const themeDarkElement = appearance.element.querySelector("#themeDark") as HTMLSelectElement; if (themeDarkElement) { themeDarkElement.innerHTML = genOptions(window.siyuan.config.appearance.darkThemes, window.siyuan.config.appearance.themeDark); } const iconElement = appearance.element.querySelector("#icon") as HTMLSelectElement; if (iconElement) { iconElement.innerHTML = genOptions(window.siyuan.config.appearance.icons, window.siyuan.config.appearance.icon); } if (data.customCSS) { fetchPost("/api/setting/getCustomCSS", { theme }, response => { appearance.onGetcustomcss(response.data); }); } } /// #if !BROWSER ipcRenderer.send(Constants.SIYUAN_CONFIG_THEME, data.modeOS ? "system" : (data.mode === 1 ? "dark" : "light")); ipcRenderer.send(Constants.SIYUAN_CONFIG_CLOSE, data.closeButtonBehavior); /// #endif if (needLoadAsset) { loadAssets(data); } document.querySelector("#barMode use").setAttribute("xlink:href", `#icon${window.siyuan.config.appearance.modeOS ? "Mode" : (window.siyuan.config.appearance.mode === 0 ? "Light" : "Dark")}`); } };