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 = "";
+ }
+ }
+ })
+}