Refine BIM comment panel interactions

This commit is contained in:
CODEX 2026-06-20 19:40:32 +03:00
parent b7fa6b5fbd
commit 7d65070f59
3 changed files with 61 additions and 17 deletions

View File

@ -612,14 +612,24 @@ header {
.comment-list-item:hover,
.comment-list-item.active {
border-color: color-mix(in srgb, var(--comment-target-active) 55%, var(--modal-border));
background: color-mix(in srgb, var(--comment-target-active) 16%, var(--modal-focus));
border-color: transparent;
background: var(--toolbar-bg-active, var(--comment-target-active));
color: var(--toolbar-bg-active-contrast, #15170f);
}
.comment-list-item:active {
transform: translateY(1px);
}
.comment-list-item:hover .comment-list-title,
.comment-list-item:hover .comment-list-body,
.comment-list-item:hover .comment-list-meta,
.comment-list-item.active .comment-list-title,
.comment-list-item.active .comment-list-body,
.comment-list-item.active .comment-list-meta {
color: inherit;
}
.comment-list-title {
min-width: 0;
overflow: hidden;
@ -726,7 +736,7 @@ header {
.nodedc-dropdown-surface {
position: fixed;
z-index: 30041;
z-index: 50000;
padding: 0.65rem;
border: 0;
border-radius: 1.25rem;
@ -1225,7 +1235,7 @@ header {
}
.nodedc-dropdown-surface.nodedc-select__menu {
z-index: 30060;
z-index: 50010;
display: grid;
gap: 2px;
max-height: 232px;
@ -1843,7 +1853,7 @@ header {
}
.bim-subitem-menu {
z-index: 30070;
z-index: 50020;
display: grid;
gap: 0.18rem;
min-width: 17.25rem;

View File

@ -554,7 +554,7 @@ const setCommentModalError = (message = "") => {
const bringFloatingWindowToFront = (id) => {
if (!id) return;
floatingWindowOrder = [...floatingWindowOrder.filter((item) => item !== id), id];
const zBase = 21000;
const zBase = 30080;
floatingWindowOrder.forEach((item, index) => {
const element = floatingWindowElements.get(item);
if (element) element.style.zIndex = `${zBase + index * 10}`;
@ -566,7 +566,7 @@ const registerFloatingWindowElement = (id, element) => {
floatingWindowElements.set(id, element);
if (!floatingWindowOrder.includes(id)) floatingWindowOrder.push(id);
element.addEventListener("pointerdown", (event) => {
if (event.button !== 0) return;
if (event.pointerType === "mouse" && event.button !== 0) return;
bringFloatingWindowToFront(id);
}, true);
bringFloatingWindowToFront(id);
@ -666,6 +666,14 @@ const getCommentDisplayBody = (comment) => {
return lastMessage?.body || "";
};
const syncCommentListActiveState = () => {
if (!commentsList) return;
commentsList.querySelectorAll(".comment-list-item").forEach((item) => {
const commentId = item.dataset.commentId;
item.classList.toggle("active", activeCommentId === commentId || hoverCommentId === commentId);
});
};
const renderCommentsPanel = () => {
if (!commentsList) return;
commentsList.replaceChildren();
@ -697,12 +705,12 @@ const renderCommentsPanel = () => {
item.append(title, body, meta);
item.addEventListener("mouseenter", () => {
hoverCommentId = comment.id;
renderCommentsPanel();
syncCommentListActiveState();
renderCommentTargets();
});
item.addEventListener("mouseleave", () => {
if (hoverCommentId === comment.id) hoverCommentId = null;
renderCommentsPanel();
syncCommentListActiveState();
renderCommentTargets();
});
item.addEventListener("click", () => openCommentModalForComment(comment.id));
@ -770,6 +778,17 @@ const stopCommentTargetLoop = () => {
}
};
const syncCommentTargetActiveState = () => {
if (!commentTargetsLayer) return;
commentTargetsLayer.querySelectorAll(".comment-target").forEach((targetEl) => {
const commentId = targetEl.dataset.commentId;
targetEl.classList.toggle(
"active",
commentId === "__draft_comment__" || activeCommentId === commentId || hoverCommentId === commentId
);
});
};
const renderCommentTargets = () => {
if (!commentTargetsLayer) return;
commentTargetsLayer.replaceChildren();
@ -790,13 +809,13 @@ const renderCommentTargets = () => {
btn.innerHTML = COMMENT_TARGET_ICON;
btn.addEventListener("mouseenter", () => {
if (!comment.draft) hoverCommentId = comment.id;
renderCommentTargets();
renderCommentsPanel();
syncCommentTargetActiveState();
syncCommentListActiveState();
});
btn.addEventListener("mouseleave", () => {
if (hoverCommentId === comment.id) hoverCommentId = null;
renderCommentTargets();
renderCommentsPanel();
syncCommentTargetActiveState();
syncCommentListActiveState();
});
btn.addEventListener("click", (event) => {
event.stopPropagation();
@ -1227,7 +1246,7 @@ const openCommentModalForTarget = () => {
renderCommentThread(null);
commentModalBackdrop?.classList.remove("hidden");
commentModal.classList.remove("hidden");
bringFloatingWindowToFront("comments");
bringFloatingWindowToFront("commentModal");
updateCommentsVisibility();
commentTitleInput?.focus();
};
@ -1258,6 +1277,11 @@ const openCommentModalForComment = (commentId) => {
renderCommentThread(comment);
commentModalBackdrop?.classList.remove("hidden");
commentModal.classList.remove("hidden");
commentsModeActive = true;
commentsCollapsed = false;
bringFloatingWindowToFront("commentModal");
updateCommentsVisibility();
commentTitleInput?.focus();
renderCommentsPanel();
renderCommentTargets();
};
@ -1968,12 +1992,14 @@ const closeTemplatesPanel = () => {
const openSettingsPanel = () => {
closeTemplatesPanel();
settingsMenu?.show();
bringFloatingWindowToFront("settings");
setToolbarButtonActive(settingsButton, true);
};
const openTemplatesPanel = () => {
closeSettingsPanel();
templatesMenu?.show();
bringFloatingWindowToFront("templates");
setToolbarButtonActive(templatesButton, true);
};
@ -5164,6 +5190,7 @@ const loadProjectSnapshot = async (project) => {
fetchProjects: () => loadProjectsList(),
openProject: (projectId) => loadProjectFromServer(projectId),
onShow: () => {
bringFloatingWindowToFront("templates");
setToolbarButtonActive(templatesButton, true);
setToolbarButtonActive(settingsButton, false);
},
@ -5197,6 +5224,7 @@ const loadProjectSnapshot = async (project) => {
focusCanvasAndControls();
},
onShow: () => {
bringFloatingWindowToFront("settings");
setToolbarButtonActive(settingsButton, true);
setToolbarButtonActive(templatesButton, false);
closeTemplatesPanel();
@ -5269,9 +5297,15 @@ const loadProjectSnapshot = async (project) => {
zoomSpeedControl.replaceChildren(zoomSpeedSlider);
}
inspectorCollapseButton?.addEventListener("click", () => setInspectorCollapsed(true));
inspectorRestoreButton?.addEventListener("click", () => setInspectorCollapsed(false));
inspectorRestoreButton?.addEventListener("click", () => {
setInspectorCollapsed(false);
bringFloatingWindowToFront("inspector");
});
registerFloatingWindowElement("inspector", sidePanelEl);
registerFloatingWindowElement("comments", commentsPanel);
registerFloatingWindowElement("settings", settingsPanel);
registerFloatingWindowElement("templates", templatesPanel);
registerFloatingWindowElement("commentModal", commentModal);
setupDraggableFixedWindow(commentsPanel, commentsPanelHeader);
setupDraggableFixedWindow(commentModal, commentModalHeader);
commentsCollapseButton?.addEventListener("click", () => setCommentsCollapsed(true));

View File

@ -134,7 +134,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./dcViewer.css?v=26">
<link rel="stylesheet" href="./dcViewer.css?v=27">
</head>
<body>
<header>
@ -570,6 +570,6 @@
<input id="fileInput" class="hidden" type="file"
accept=".xkt,.glb,.gltf,.bim,.las,.laz,.obj,.stl">
<script type="module" src="./dcViewer.js?v=37"></script>
<script type="module" src="./dcViewer.js?v=40"></script>
</body>
</html>