From 2222d97a9973310ad96a13afa2f96affa10d077f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristijan=20Ribari=C4=87?= Date: Thu, 24 Oct 2024 20:26:32 +0200 Subject: [PATCH] fix: Add functionality to move workspace to the end This commit adds the ability to move a workspace to the end of the workspace list by dragging it to a designated drop target. The changes include: - Creation of a new "last position drop target" element that allows dragging a workspace to the end. - Event listeners for dragover, dragenter, dragleave, and drop events on the drop target element. - Implementation of `moveWorkspaceToEnd` function to update the workspace positions in storage when a workspace is moved to the end. - Reorder mode is exited if the panel is closed. - Updates to the workspace list to include the last position drop target. --- src/ZenWorkspaces.mjs | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/ZenWorkspaces.mjs b/src/ZenWorkspaces.mjs index 5080069..b5a3e0b 100644 --- a/src/ZenWorkspaces.mjs +++ b/src/ZenWorkspaces.mjs @@ -480,6 +480,59 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { }).bind(browser.ZenWorkspaces); return element; }; + + const createLastPositionDropTarget = () => { + const element = browser.document.createXULElement('div'); + element.className = 'zen-workspace-last-place-drop-target'; + + element.addEventListener( + 'dragover', + function (event) { + if (this.isReorderModeOn(browser) && this.draggedElement) { + event.preventDefault(); + event.dataTransfer.dropEffect = 'move'; + } + }.bind(browser.ZenWorkspaces) + ); + + element.addEventListener( + 'dragenter', + function (event) { + if (this.isReorderModeOn(browser) && this.draggedElement) { + element.classList.add('dragover'); + } + }.bind(browser.ZenWorkspaces) + ); + + element.addEventListener( + 'dragleave', + function (event) { + element.classList.remove('dragover'); + }.bind(browser.ZenWorkspaces) + ); + + element.addEventListener( + 'drop', + async function (event) { + event.preventDefault(); + element.classList.remove('dragover'); + + if (this.isReorderModeOn(browser)) { + const draggedWorkspaceId = event.dataTransfer.getData('text/plain'); + await this.moveWorkspaceToEnd(draggedWorkspaceId); + await this._propagateWorkspaceData(); + + if (this.draggedElement) { + this.draggedElement.classList.remove('dragging'); + this.draggedElement = null; + } + } + }.bind(browser.ZenWorkspaces) + ); + + return element; + }; + browser.ZenWorkspaces._workspaceCache = null; let workspaces = await browser.ZenWorkspaces._workspaces(); workspaceList.innerHTML = ''; @@ -495,12 +548,32 @@ var ZenWorkspaces = new (class extends ZenMultiWindowFeature { let workspaceElement = createWorkspaceElement(workspace); workspaceList.appendChild(workspaceElement); } + + workspaceList.appendChild(createLastPositionDropTarget()); + if (!ignoreStrip) { await browser.ZenWorkspaces._expandWorkspacesStrip(browser); } }); } + handlePanelHidden() { + const workspacesList = document.getElementById('PanelUI-zen-workspaces-list'); + const reorderModeButton = document.getElementById('PanelUI-zen-workspaces-reorder-mode'); + + workspacesList?.removeAttribute('reorder-mode'); + reorderModeButton?.removeAttribute('active'); + } + + async moveWorkspaceToEnd(draggedWorkspaceId) { + const workspaces = (await this._workspaces()).workspaces; + const draggedIndex = workspaces.findIndex((w) => w.uuid === draggedWorkspaceId); + const draggedWorkspace = workspaces.splice(draggedIndex, 1)[0]; + workspaces.push(draggedWorkspace); + + await ZenWorkspacesStorage.updateWorkspacePositions(workspaces); + } + isReorderModeOn(browser) { return browser.document.getElementById('PanelUI-zen-workspaces-list').getAttribute('reorder-mode') === 'true'; }