diff --git a/app/src/assets/scss/_layout.scss b/app/src/assets/scss/_layout.scss index 0233c37da..f92ceaad7 100644 --- a/app/src/assets/scss/_layout.scss +++ b/app/src/assets/scss/_layout.scss @@ -13,9 +13,9 @@ &--float { position: fixed; - z-index: 2; + z-index: 3; min-height: auto; - transition: left .15s cubic-bezier(0, 0.88, 0.42, 0.74) 0ms, opacity .15s cubic-bezier(0, 0.88, 0.42, 0.74) 0ms; + transition: var(--b3-transition); } &__tab--active { diff --git a/app/src/config/appearance.ts b/app/src/config/appearance.ts index eb857be72..4fcaaa8d6 100644 --- a/app/src/config/appearance.ts +++ b/app/src/config/appearance.ts @@ -10,6 +10,7 @@ import {genOptions} from "../util/genOptions"; import {openSnippets} from "./util/snippets"; import {openColorPicker} from "./util/colorPicker"; import {loadAssets} from "../util/assets"; +import {resetFloatDockSize} from "../layout/dock/util"; export const appearance = { element: undefined as Element, @@ -211,6 +212,7 @@ export const appearance = { } else { document.getElementById("status").classList.remove("fn__none"); } + resetFloatDockSize(); }); }, bindEvent: () => { diff --git a/app/src/layout/dock/index.ts b/app/src/layout/dock/index.ts index 94f56398d..1ad603157 100644 --- a/app/src/layout/dock/index.ts +++ b/app/src/layout/dock/index.ts @@ -13,6 +13,7 @@ import {getDockByType, resizeTabs, setPanelFocus} from "../util"; import {Inbox} from "./Inbox"; import {Protyle} from "../../protyle"; import {Backlink} from "./Backlink"; +import {resetFloatDockSize} from "./util"; export class Dock { public element: HTMLElement; @@ -48,6 +49,9 @@ export class Dock { this.pin = options.data.pin this.data = {}; if (options.data.data.length === 0) { + this.element.firstElementChild.innerHTML = ` + +`; this.element.classList.add("fn__none"); } else { this.genButton(options.data.data[0], 0); @@ -83,8 +87,14 @@ export class Dock { } else if (target.classList.contains("dock__item")) { this.pin = !target.classList.contains("dock__item--pin"); if (!this.pin) { - const layoutRect = this.layout.element.getBoundingClientRect(); - this.layout.element.setAttribute("style", `left:${layoutRect.left}px; top: ${layoutRect.top}px; bottom: ${window.innerHeight - layoutRect.bottom}px; width: ${layoutRect.width}px;`); + if (this.position === "Left" || this.position === "Right") { + this.layout.element.setAttribute("style", `width:${this.layout.element.clientWidth}px;${this.position === "Right" ? "right" : "left"}:${this.layout.element.clientWidth}px; top: ${1 + document.getElementById("toolbar").clientHeight + document.getElementById("dockTop").clientHeight}px; bottom: ${document.getElementById("status").clientHeight + document.getElementById("dockBottom").clientHeight + 1}px;`); + } else { + this.layout.element.setAttribute("style", `height:${this.layout.element.clientHeight}px;left:0;right:0;${this.position === "Top" ? ("top:" + (1 + this.element.clientHeight + document.getElementById("toolbar").clientHeight) + "px") : ("bottom:" + (this.element.clientHeight + document.getElementById("status").clientHeight) + "px")};`); + } + target.setAttribute("aria-label", window.siyuan.languages.pin) + } else { + target.setAttribute("aria-label", window.siyuan.languages.unpin) } target.classList.toggle("dock__item--pin"); this.layout.element.classList.toggle("layout--float"); @@ -102,6 +112,15 @@ export class Dock { if (this.position === "Left" && event.clientX < 43) { return; } + if (this.position === "Right" && event.clientX > window.innerWidth - 41) { + return; + } + if (this.position === "Top" && event.clientY < 75) { + return; + } + if (this.position === "Bottom" && event.clientY > window.innerHeight - 73) { + return; + } this.hideDock() }) if (window.siyuan.config.uiLayout.hideDock) { @@ -109,18 +128,30 @@ export class Dock { } if (!this.pin) { setTimeout(() => { - const layoutRect = this.layout.element.getBoundingClientRect(); - this.layout.element.setAttribute("style", `width:${layoutRect.width}px;opacity:0px;left:-${layoutRect.width}px; top: ${layoutRect.top}px; bottom: ${window.innerHeight - layoutRect.bottom}px;`); + if (this.position === "Left" || this.position === "Right") { + this.layout.element.setAttribute("style", `opacity:0px;width:${this.layout.element.clientWidth}px;${this.position === "Right" ? "right" : "left"}:-${this.layout.element.clientWidth}px; top: ${1 + document.getElementById("toolbar").clientHeight + document.getElementById("dockTop").clientHeight}px; bottom: ${document.getElementById("status").clientHeight + document.getElementById("dockBottom").clientHeight + 1}px;`); + } else { + this.layout.element.setAttribute("style", `opacity:0px;height:${this.layout.element.clientHeight}px;left:0;right:0;${this.position === "Top" ? "top" : "bottom"}:-${this.layout.element.clientHeight}px;`) + } this.layout.element.classList.add("layout--float"); this.resizeElement.classList.add("fn__none"); - }, 1000); + }); // 需等待所有 Dock 初始化完成后才有稳定布局,才可进行定位 } } public hideDock() { - if (this.layout.element.style.opacity === "1") { + if (this.layout.element.style.opacity === "0") { + return + } + this.layout.element.style.opacity = "0"; + if (this.position === "Left") { this.layout.element.style.left = -this.layout.element.clientWidth + "px"; - this.layout.element.style.opacity = "0"; + } else if (this.position === "Right") { + this.layout.element.style.right = -this.layout.element.clientWidth + "px"; + } else if (this.position === "Top") { + this.layout.element.style.top = -this.layout.element.clientHeight + "px"; + } else if (this.position === "Bottom") { + this.layout.element.style.bottom = -this.layout.element.clientHeight + "px"; } } @@ -344,7 +375,7 @@ export class Dock { sourceElement.setAttribute("data-width", ""); const type = sourceElement.getAttribute("data-type") as TDockType; const sourceDock = getDockByType(type); - if (sourceDock.element.querySelectorAll(".dock__item").length === 1) { + if (sourceDock.element.querySelectorAll(".dock__item").length === 2) { sourceDock.element.classList.add("fn__none"); } const sourceWnd = sourceDock.layout.children[parseInt(sourceElement.getAttribute("data-index"))] as Wnd; @@ -364,11 +395,12 @@ export class Dock { sourceElement.classList.add(`b3-tooltips__${this.getClassDirect(index)}`); sourceElement.setAttribute("data-index", index.toString()); if (index === 0) { - this.element.firstElementChild.insertAdjacentElement("afterbegin", sourceElement); + this.element.firstElementChild.insertAdjacentElement("beforeend", sourceElement); } else { - this.element.lastElementChild.insertAdjacentElement("afterbegin", sourceElement); + this.element.lastElementChild.insertAdjacentElement("beforeend", sourceElement); } this.element.classList.remove("fn__none"); + resetFloatDockSize(); this.data[type] = true; if (hasActive) { this.toggleModel(type, true); @@ -433,7 +465,7 @@ export class Dock { } private genButton(data: IDockTab[], index: number) { - let html = index ? "" : ` + let html = index ? "" : ` `; data.forEach(item => { diff --git a/app/src/layout/dock/util.ts b/app/src/layout/dock/util.ts index 5e2e2e937..b0c1f6cc7 100644 --- a/app/src/layout/dock/util.ts +++ b/app/src/layout/dock/util.ts @@ -85,3 +85,26 @@ export const openOutline = (protyle: IProtyle) => { newWnd.element.style.width = "200px"; switchWnd(newWnd, protyle.model.parent.parent); }; + +export const resetFloatDockSize = () => { + if (!window.siyuan.layout.leftDock.pin) { + window.siyuan.layout.leftDock.layout.element.style.top = (1 + document.getElementById("toolbar").clientHeight + document.getElementById("dockTop").clientHeight) + "px"; + window.siyuan.layout.leftDock.layout.element.style.bottom = (document.getElementById("status").clientHeight + document.getElementById("dockBottom").clientHeight + 1) + "px"; + if (window.siyuan.layout.leftDock.layout.element.style.opacity === "1") { + window.siyuan.layout.leftDock.layout.element.style.left = (window.siyuan.layout.leftDock.element.clientWidth + .5) + "px" + } + } + if (!window.siyuan.layout.rightDock.pin) { + window.siyuan.layout.rightDock.layout.element.style.top = (1 + document.getElementById("toolbar").clientHeight + document.getElementById("dockTop").clientHeight) + "px"; + window.siyuan.layout.rightDock.layout.element.style.bottom = (document.getElementById("status").clientHeight + document.getElementById("dockBottom").clientHeight + 1) + "px"; + if (window.siyuan.layout.rightDock.layout.element.style.opacity === "1") { + window.siyuan.layout.rightDock.layout.element.style.right = (window.siyuan.layout.rightDock.element.clientWidth + .5) + "px" + } + } + if (!window.siyuan.layout.topDock.pin && window.siyuan.layout.topDock.layout.element.style.opacity === "1") { + window.siyuan.layout.topDock.layout.element.style.top = (document.getElementById("dockTop").clientHeight + document.getElementById("toolbar").clientHeight + 1) + "px" + } + if (!window.siyuan.layout.bottomDock.pin && window.siyuan.layout.bottomDock.layout.element.style.opacity === "1") { + window.siyuan.layout.bottomDock.layout.element.style.bottom = (document.getElementById("dockBottom").clientHeight + document.getElementById("status").clientHeight + 1) + "px" + } +} diff --git a/app/src/layout/status.ts b/app/src/layout/status.ts index 73f979156..0528787bd 100644 --- a/app/src/layout/status.ts +++ b/app/src/layout/status.ts @@ -11,6 +11,7 @@ import {getCurrentWindow} from "@electron/remote"; /// #endif import {MenuItem} from "../menus/Menu"; import {Constants} from "../constants"; +import {resetFloatDockSize} from "./dock/util"; export const initStatus = (isWindow = false) => { /// #if !MOBILE @@ -65,6 +66,7 @@ export const initStatus = (isWindow = false) => { }); resizeTabs(); target.querySelector(".b3-menu").classList.add("fn__none"); + resetFloatDockSize(); event.stopPropagation(); break; } else if (target.classList.contains("status__backgroundtask")) { diff --git a/app/src/menus/index.ts b/app/src/menus/index.ts index 681bd6aaf..f66efd8a9 100644 --- a/app/src/menus/index.ts +++ b/app/src/menus/index.ts @@ -59,7 +59,7 @@ export class Menus { break; } - if (target.classList.contains("dock__item")) { + if (target.classList.contains("dock__item") && target.getAttribute("data-type")) { initDockMenu(target).popup({x: event.clientX, y: event.clientY}); event.stopPropagation(); break; diff --git a/app/src/util/globalShortcut.ts b/app/src/util/globalShortcut.ts index 1afe2fda5..4560584be 100644 --- a/app/src/util/globalShortcut.ts +++ b/app/src/util/globalShortcut.ts @@ -98,11 +98,10 @@ export const globalShortcut = () => { if (event.clientX < 43) { if (!window.siyuan.layout.leftDock.pin) { - if (event.clientY > 32 && - (window.siyuan.config.appearance.hideStatusBar || - (!window.siyuan.config.appearance.hideStatusBar && event.clientY < window.innerHeight - 32)) - ) { + if (event.clientY > document.getElementById("toolbar").clientHeight + document.getElementById("dockTop").clientHeight && + event.clientY < window.innerHeight - document.getElementById("status").clientHeight - document.getElementById("dockBottom").clientHeight) { if (!hasClosestByClassName(event.target as HTMLElement, "b3-menu") && + !hasClosestByClassName(event.target as HTMLElement, "layout--float") && window.siyuan.layout.leftDock.layout.element.style.opacity !== "1") { window.siyuan.layout.leftDock.layout.element.style.left = (window.siyuan.layout.leftDock.element.clientWidth + .5) + "px" window.siyuan.layout.leftDock.layout.element.style.opacity = "1" @@ -111,6 +110,30 @@ export const globalShortcut = () => { window.siyuan.layout.leftDock.hideDock(); } } + } else if (event.clientX > window.innerWidth - 41) { + if (!window.siyuan.layout.rightDock.pin) { + if (event.clientY > document.getElementById("toolbar").clientHeight + document.getElementById("dockTop").clientHeight && + event.clientY < window.innerHeight - document.getElementById("status").clientHeight - document.getElementById("dockBottom").clientHeight) { + if (!hasClosestByClassName(event.target as HTMLElement, "layout--float") && window.siyuan.layout.rightDock.layout.element.style.opacity !== "1") { + window.siyuan.layout.rightDock.layout.element.style.right = (window.siyuan.layout.rightDock.element.clientWidth + .5) + "px" + window.siyuan.layout.rightDock.layout.element.style.opacity = "1" + } + } else { + window.siyuan.layout.rightDock.hideDock(); + } + } + } + + if (event.clientY < 75) { + if (!window.siyuan.layout.topDock.pin && window.siyuan.layout.topDock.layout.element.style.opacity !== "1") { + window.siyuan.layout.topDock.layout.element.style.top = (document.getElementById("dockTop").clientHeight + document.getElementById("toolbar").clientHeight + 1) + "px" + window.siyuan.layout.topDock.layout.element.style.opacity = "1" + } + } else if (event.clientY > window.innerHeight - 73) { + if (!window.siyuan.layout.bottomDock.pin && window.siyuan.layout.bottomDock.layout.element.style.opacity !== "1") { + window.siyuan.layout.bottomDock.layout.element.style.bottom = (document.getElementById("dockBottom").clientHeight + document.getElementById("status").clientHeight + 1) + "px" + window.siyuan.layout.bottomDock.layout.element.style.opacity = "1" + } } const eventPath0 = event.composedPath()[0] as HTMLElement;