diff --git a/app/src/assets/template/app/window.tpl b/app/src/assets/template/app/window.tpl new file mode 100644 index 000000000..e0351fd6a --- /dev/null +++ b/app/src/assets/template/app/window.tpl @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+ + diff --git a/app/src/util/onGetConfig.ts b/app/src/util/onGetConfig.ts index 3e14ffd05..762400bd8 100644 --- a/app/src/util/onGetConfig.ts +++ b/app/src/util/onGetConfig.ts @@ -20,7 +20,7 @@ import {openFileById} from "../editor/util"; import {focusByRange} from "../protyle/util/selection"; import {exitSiYuan, processSync} from "../dialog/processSystem"; import {openSetting} from "../config"; -import {getSearch} from "./functions"; +import {getSearch, isWindow} from "./functions"; import {initStatus} from "../layout/status"; import {syncGuide} from "../sync/syncGuide"; import {showMessage} from "../dialog/message"; @@ -120,7 +120,7 @@ export const onGetConfig = (isStart: boolean) => { const hasKeymap6 = hasKeymap(Constants.SIYUAN_KEYMAP.editor.table, "editor", "table"); if (!window.siyuan.config.readonly && (!matchKeymap1 || !matchKeymap2 || !matchKeymap3 || !matchKeymap4 || !matchKeymap5 || !matchKeymap6 || - !hasKeymap1 || !hasKeymap2 || !hasKeymap3 || !hasKeymap4 || !hasKeymap5 || !hasKeymap6)) { + !hasKeymap1 || !hasKeymap2 || !hasKeymap3 || !hasKeymap4 || !hasKeymap5 || !hasKeymap6)) { fetchPost("/api/setting/setKeymap", { data: window.siyuan.config.keymap }, () => { @@ -333,22 +333,27 @@ export const initWindow = () => { currentWindow.on("blur", () => { document.body.classList.add("body--blur"); }); - ipcRenderer.on(Constants.SIYUAN_OPENURL, (event, url) => { - if (!/^siyuan:\/\/blocks\/\d{14}-\w{7}/.test(url)) { - return; - } - const id = url.substr(16, 22); - fetchPost("/api/block/checkBlockExist", {id}, existResponse => { - if (existResponse.data) { - openFileById({ - id, - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT], - zoomIn: getSearch("focus", url) === "1" - }); - ipcRenderer.send(Constants.SIYUAN_SHOW, getCurrentWindow().id); + if (!isWindow()) { + ipcRenderer.on(Constants.SIYUAN_OPENURL, (event, url) => { + if (!/^siyuan:\/\/blocks\/\d{14}-\w{7}/.test(url)) { + return; } + const id = url.substr(16, 22); + fetchPost("/api/block/checkBlockExist", {id}, existResponse => { + if (existResponse.data) { + openFileById({ + id, + action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT], + zoomIn: getSearch("focus", url) === "1" + }); + ipcRenderer.send(Constants.SIYUAN_SHOW, getCurrentWindow().id); + } + }); }); - }); + ipcRenderer.on(Constants.SIYUAN_SAVE_CLOSE, (event, close) => { + winOnClose(currentWindow, close); + }); + } ipcRenderer.on(Constants.SIYUAN_LOCK_SCREEN, () => { exportLayout(false, () => { fetchPost("/api/system/logoutAuth", {}, () => { @@ -356,9 +361,6 @@ export const initWindow = () => { }); }); }); - ipcRenderer.on(Constants.SIYUAN_SAVE_CLOSE, (event, close) => { - winOnClose(currentWindow, close); - }); ipcRenderer.on(Constants.SIYUAN_EXPORT_CLOSE, () => { window.siyuan.printWin.destroy(); }); @@ -452,7 +454,7 @@ export const initWindow = () => { window.addEventListener("beforeunload", () => { currentWindow.off("focus", winOnFocus); }, false); - if ( "darwin" === window.siyuan.config.system.os) { + if ("darwin" === window.siyuan.config.system.os) { document.getElementById("drag")?.addEventListener("dblclick", () => { if (currentWindow.isMaximized()) { currentWindow.unmaximize(); diff --git a/app/src/window.ts b/app/src/window.ts new file mode 100644 index 000000000..8d7dda027 --- /dev/null +++ b/app/src/window.ts @@ -0,0 +1,147 @@ +import {Constants} from "./constants"; +import {Menus} from "./menus"; +import {Model} from "./layout/Model"; +import "./assets/scss/base.scss"; +import {initBlockPopover} from "./block/popover"; +import {addScript, addScriptSync} from "./protyle/util/addScript"; +import {genUUID} from "./util/genID"; +import {fetchGet, fetchPost} from "./util/fetch"; +import {addBaseURL, setNoteBook} from "./util/pathName"; +import {openFileById} from "./editor/util"; +import { + downloadProgress, + processSync, progressBackgroundTask, + progressLoading, + progressStatus, + setTitle, + transactionError +} from "./dialog/processSystem"; +import {promiseTransactions} from "./protyle/wysiwyg/transaction"; +import {initMessage} from "./dialog/message"; +import {getAllTabs} from "./layout/getAll"; +import {getLocalStorage} from "./protyle/util/compatibility"; +import {init} from "./window/init"; + +class App { + constructor() { + addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript"); + addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript"); + addBaseURL(); + window.siyuan = { + transactions: [], + reqIds: {}, + backStack: [], + layout: {}, + dialogs: [], + blockPanels: [], + ctrlIsPressed: false, + altIsPressed: false, + ws: new Model({ + id: genUUID(), + type: "main", + msgCallback: (data) => { + if (data) { + switch (data.cmd) { + case "progress": + progressLoading(data); + break; + case "setLocalStorageVal": + window.siyuan.storage[data.data.key] = data.data.val; + break; + case "rename": + getAllTabs().forEach((tab) => { + if (tab.headElement) { + const initTab = tab.headElement.getAttribute("data-initdata"); + if (initTab) { + const initTabData = JSON.parse(initTab); + if (initTabData.rootId === data.data.id) { + tab.updateTitle(data.data.title); + } + } + } + }); + break; + case "unmount": + getAllTabs().forEach((tab) => { + if (tab.headElement) { + const initTab = tab.headElement.getAttribute("data-initdata"); + if (initTab) { + const initTabData = JSON.parse(initTab); + if (data.data.box === initTabData.notebookId) { + tab.parent.removeTab(tab.id); + } + } + } + }); + break; + case "removeDoc": + getAllTabs().forEach((tab) => { + if (tab.headElement) { + const initTab = tab.headElement.getAttribute("data-initdata"); + if (initTab) { + const initTabData = JSON.parse(initTab); + if (data.data.ids.includes(initTabData.rootId)) { + tab.parent.removeTab(tab.id); + } + } + } + }); + break; + case "statusbar": + progressStatus(data); + break; + case "downloadProgress": + downloadProgress(data.data); + break; + case "txerr": + transactionError(data); + break; + case "syncing": + processSync(data); + break; + case "backgroundtask": + progressBackgroundTask(data.data.tasks); + break; + case "refreshtheme": + if (!window.siyuan.config.appearance.customCSS && data.data.theme.indexOf("custom.css") > -1) { + return; + } + if ((window.siyuan.config.appearance.mode === 1 && window.siyuan.config.appearance.themeDark !== "midnight") || (window.siyuan.config.appearance.mode === 0 && window.siyuan.config.appearance.themeLight !== "daylight")) { + (document.getElementById("themeStyle") as HTMLLinkElement).href = data.data.theme; + } else { + (document.getElementById("themeDefaultStyle") as HTMLLinkElement).href = data.data.theme; + } + break; + case "createdailynote": + openFileById({id: data.data.id, action: [Constants.CB_GET_FOCUS]}); + break; + case "openFileById": + openFileById({id: data.data.id, action: [Constants.CB_GET_FOCUS]}); + break; + } + } + } + }), + menus: new Menus() + }; + fetchPost("/api/system/getConf", {}, response => { + window.siyuan.config = response.data.conf; + getLocalStorage(() => { + fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => { + window.siyuan.languages = lauguages; + fetchPost("/api/setting/getCloudUser", {}, userResponse => { + window.siyuan.user = userResponse.data; + init(); + setTitle(window.siyuan.languages.siyuanNote); + initMessage(); + }); + }); + }); + }); + setNoteBook(); + initBlockPopover(); + promiseTransactions(); + } +} + +new App(); diff --git a/app/src/window/init.ts b/app/src/window/init.ts new file mode 100644 index 000000000..603311c79 --- /dev/null +++ b/app/src/window/init.ts @@ -0,0 +1,57 @@ +import {Constants} from "../constants"; +import {webFrame} from "electron"; +import {globalShortcut} from "../util/globalShortcut"; +import {fetchPost} from "../util/fetch"; +import {JSONToCenter, resizeTabs} from "../layout/util"; +import {initStatus} from "../layout/status"; +import {appearance} from "../config/appearance"; +import {initAssets, setInlineStyle} from "../util/assets"; +import {renderSnippet} from "../config/util/snippets"; +import {getSearch} from "../util/functions"; +import {Layout} from "../layout"; +import {initWindow} from "../util/onGetConfig"; + +export const init = () => { + webFrame.setZoomFactor(window.siyuan.storage[Constants.LOCAL_ZOOM]); + globalShortcut(); + fetchPost("/api/system/getEmojiConf", {}, response => { + window.siyuan.emojis = response.data as IEmoji[]; + const id = getSearch("id"); + JSONToCenter({ + "direction": "lr", + "resize": "lr", + "size": "auto", + "type": "center", + "instance": "Layout", + "children": [{ + "instance": "Wnd", + "children": [{ + "instance": "Tab", + active: true, + docIcon: "1f389", + title: "请从这里开始", + "children": [{ + rootId: id, + blockId: id, + instance: "Editor", + mode: "wysiwyg" + }] + }] + }] + }); + window.siyuan.layout.centerLayout = window.siyuan.layout.layout; + }); + initStatus(true); + initWindow(); + appearance.onSetappearance(window.siyuan.config.appearance); + initAssets(); + renderSnippet(); + setInlineStyle(); + let resizeTimeout = 0; + window.addEventListener("resize", () => { + window.clearTimeout(resizeTimeout); + resizeTimeout = window.setTimeout(() => { + resizeTabs(); + }, 200); + }); +} diff --git a/app/src/window/setHeader.ts b/app/src/window/setHeader.ts new file mode 100644 index 000000000..c954b7e88 --- /dev/null +++ b/app/src/window/setHeader.ts @@ -0,0 +1,48 @@ +import {isWindow} from "../util/functions"; +import {Wnd} from "../layout/Wnd"; +import {Layout} from "../layout"; +import {getCurrentWindow} from "@electron/remote"; + +const getAllWnds = (layout: Layout, wnds: Wnd[]) => { + for (let i = 0; i < layout.children.length; i++) { + const item = layout.children[i]; + if (item instanceof Wnd) { + wnds.push(item); + } else if (item instanceof Layout) { + getAllWnds(item, wnds); + } + } +} +export const setTabPosition = () => { + if (!isWindow()) { + return; + } + const wndsTemp: Wnd[] = [] + getAllWnds(window.siyuan.layout.layout, wndsTemp); + wndsTemp.forEach(item => { + const headerElement = item.headersElement.parentElement; + const rect = headerElement.getBoundingClientRect() + const dragElement = headerElement.querySelector('.item--readonly .fn__flex-1') as HTMLElement + if (rect.top === 0) { + dragElement.style.height = dragElement.parentElement.clientHeight + "px" + // @ts-ignore + dragElement.style.WebkitAppRegion = "drag"; + } else { + // @ts-ignore + dragElement.style.WebkitAppRegion = ""; + } + if ("darwin" === window.siyuan.config.system.os) { + if (rect.top <= 0 && rect.left <= 0 && !getCurrentWindow().isFullScreen()) { + item.headersElement.style.paddingLeft = "69px"; + } else { + item.headersElement.style.paddingLeft = ""; + } + } else { + if (rect.top <= 0 && rect.right >= window.innerWidth) { + (headerElement.lastElementChild as HTMLElement).style.paddingRight = (42 * 3) + "px"; + } else { + (headerElement.lastElementChild as HTMLElement).style.paddingRight = ""; + } + } + }) +}