diff --git a/app/src/assets/scss/component/_list.scss b/app/src/assets/scss/component/_list.scss index 2923482c1..d9508f757 100644 --- a/app/src/assets/scss/component/_list.scss +++ b/app/src/assets/scss/component/_list.scss @@ -7,7 +7,7 @@ &--background .b3-list-item { border-radius: var(--b3-border-radius); - &:hover:not(.b3-list-item--focus), + &:hover:not(.b3-list-item--focus):not(.dragover):not(.dragover__top):not(.dragover__bottom), &--focus:not(.dragover) { background-color: var(--b3-list-hover); } diff --git a/app/src/layout/dock/Outline.ts b/app/src/layout/dock/Outline.ts index 0bb8c243a..108062f0b 100644 --- a/app/src/layout/dock/Outline.ts +++ b/app/src/layout/dock/Outline.ts @@ -99,7 +99,7 @@ export class Outline extends Model {
-`; +`; this.element = options.tab.panelElement.lastElementChild as HTMLElement; this.headerElement = options.tab.panelElement.firstElementChild as HTMLElement; this.tree = new Tree({ @@ -233,18 +233,35 @@ export class Outline extends Model { return; } const documentSelf = document; + item.style.opacity = "0.38"; const ghostElement = item.cloneNode(true) as HTMLElement; document.body.append(ghostElement); ghostElement.firstElementChild.setAttribute("style", "padding-left:4px"); - ghostElement.setAttribute("style", `opacity:.38;position: fixed; top: ${event.clientY}px; left: ${event.clientX}px; z-index:999997;`); + ghostElement.setAttribute("style", `border-radius: var(--b3-border-radius);background-color: var(--b3-list-hover);position: fixed; top: ${event.clientY}px; left: ${event.clientX}px; z-index:999997;`); documentSelf.ondragstart = () => false; + let selectItem: HTMLElement; documentSelf.onmousemove = (moveEvent: MouseEvent) => { moveEvent.preventDefault(); moveEvent.stopPropagation(); ghostElement.style.top = moveEvent.clientY + "px"; ghostElement.style.left = moveEvent.clientX + "px"; + selectItem = hasClosestByClassName(moveEvent.target as HTMLElement, "b3-list-item") as HTMLElement; + if (!selectItem || selectItem.tagName !== "LI" || selectItem.isSameNode(item) || selectItem.style.position === "fixed" || !this.element.contains(selectItem)) { + return; + } + this.element.querySelectorAll(".dragover__top, .dragover__bottom, .dragover").forEach(item => { + item.classList.remove("dragover__top", "dragover__bottom", "dragover"); + }); + const selectRect = selectItem.getBoundingClientRect(); + if (moveEvent.clientY > selectRect.bottom - 10) { + selectItem.classList.add("dragover__bottom"); + } else if (moveEvent.clientY < selectRect.top + 10) { + selectItem.classList.add("dragover__top"); + } else { + selectItem.classList.add("dragover"); + } }; documentSelf.onmouseup = () => { @@ -254,26 +271,29 @@ export class Outline extends Model { documentSelf.onselectstart = null; documentSelf.onselect = null; ghostElement.remove(); - const selectItem = hasClosestByClassName(event.target as HTMLElement, "b3-list-item"); - if (!selectItem || selectItem.tagName !== "LI") { + item.style.opacity = ""; + this.element.querySelectorAll(".dragover__top, .dragover__bottom, .dragover").forEach(item => { + item.classList.remove("dragover__top", "dragover__bottom", "dragover"); + }); + if (!selectItem) { return; } getAllModels().editor.find(editItem => { if (editItem.editor.protyle.block.rootID === this.blockId) { transaction(editItem.editor.protyle, [{ action: "moveOutlineHeading", - id: item.dataset.blockId, + id: item.dataset.nodeId, previousID: selectItem.previousElementSibling?.getAttribute("data-node-id"), parentID: selectItem.parentElement.previousElementSibling?.getAttribute("data-node-id"), }], [{ action: "moveOutlineHeading", - id: item.dataset.blockId, + id: item.dataset.nodeId, previousID: item.previousElementSibling?.getAttribute("data-node-id"), parentID: item.parentElement.previousElementSibling?.getAttribute("data-node-id"), }]); return true; } - }) + }); }; }); } diff --git a/app/src/util/Tree.ts b/app/src/util/Tree.ts index c6fa75da2..f13d496dd 100644 --- a/app/src/util/Tree.ts +++ b/app/src/util/Tree.ts @@ -87,6 +87,7 @@ export class Tree { html += `