Refine BIM comment panel interactions
This commit is contained in:
parent
b7fa6b5fbd
commit
7d65070f59
|
|
@ -612,14 +612,24 @@ header {
|
||||||
|
|
||||||
.comment-list-item:hover,
|
.comment-list-item:hover,
|
||||||
.comment-list-item.active {
|
.comment-list-item.active {
|
||||||
border-color: color-mix(in srgb, var(--comment-target-active) 55%, var(--modal-border));
|
border-color: transparent;
|
||||||
background: color-mix(in srgb, var(--comment-target-active) 16%, var(--modal-focus));
|
background: var(--toolbar-bg-active, var(--comment-target-active));
|
||||||
|
color: var(--toolbar-bg-active-contrast, #15170f);
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-list-item:active {
|
.comment-list-item:active {
|
||||||
transform: translateY(1px);
|
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 {
|
.comment-list-title {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -726,7 +736,7 @@ header {
|
||||||
|
|
||||||
.nodedc-dropdown-surface {
|
.nodedc-dropdown-surface {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 30041;
|
z-index: 50000;
|
||||||
padding: 0.65rem;
|
padding: 0.65rem;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: 1.25rem;
|
border-radius: 1.25rem;
|
||||||
|
|
@ -1225,7 +1235,7 @@ header {
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodedc-dropdown-surface.nodedc-select__menu {
|
.nodedc-dropdown-surface.nodedc-select__menu {
|
||||||
z-index: 30060;
|
z-index: 50010;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
max-height: 232px;
|
max-height: 232px;
|
||||||
|
|
@ -1843,7 +1853,7 @@ header {
|
||||||
}
|
}
|
||||||
|
|
||||||
.bim-subitem-menu {
|
.bim-subitem-menu {
|
||||||
z-index: 30070;
|
z-index: 50020;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.18rem;
|
gap: 0.18rem;
|
||||||
min-width: 17.25rem;
|
min-width: 17.25rem;
|
||||||
|
|
|
||||||
|
|
@ -554,7 +554,7 @@ const setCommentModalError = (message = "") => {
|
||||||
const bringFloatingWindowToFront = (id) => {
|
const bringFloatingWindowToFront = (id) => {
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
floatingWindowOrder = [...floatingWindowOrder.filter((item) => item !== id), id];
|
floatingWindowOrder = [...floatingWindowOrder.filter((item) => item !== id), id];
|
||||||
const zBase = 21000;
|
const zBase = 30080;
|
||||||
floatingWindowOrder.forEach((item, index) => {
|
floatingWindowOrder.forEach((item, index) => {
|
||||||
const element = floatingWindowElements.get(item);
|
const element = floatingWindowElements.get(item);
|
||||||
if (element) element.style.zIndex = `${zBase + index * 10}`;
|
if (element) element.style.zIndex = `${zBase + index * 10}`;
|
||||||
|
|
@ -566,7 +566,7 @@ const registerFloatingWindowElement = (id, element) => {
|
||||||
floatingWindowElements.set(id, element);
|
floatingWindowElements.set(id, element);
|
||||||
if (!floatingWindowOrder.includes(id)) floatingWindowOrder.push(id);
|
if (!floatingWindowOrder.includes(id)) floatingWindowOrder.push(id);
|
||||||
element.addEventListener("pointerdown", (event) => {
|
element.addEventListener("pointerdown", (event) => {
|
||||||
if (event.button !== 0) return;
|
if (event.pointerType === "mouse" && event.button !== 0) return;
|
||||||
bringFloatingWindowToFront(id);
|
bringFloatingWindowToFront(id);
|
||||||
}, true);
|
}, true);
|
||||||
bringFloatingWindowToFront(id);
|
bringFloatingWindowToFront(id);
|
||||||
|
|
@ -666,6 +666,14 @@ const getCommentDisplayBody = (comment) => {
|
||||||
return lastMessage?.body || "";
|
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 = () => {
|
const renderCommentsPanel = () => {
|
||||||
if (!commentsList) return;
|
if (!commentsList) return;
|
||||||
commentsList.replaceChildren();
|
commentsList.replaceChildren();
|
||||||
|
|
@ -697,12 +705,12 @@ const renderCommentsPanel = () => {
|
||||||
item.append(title, body, meta);
|
item.append(title, body, meta);
|
||||||
item.addEventListener("mouseenter", () => {
|
item.addEventListener("mouseenter", () => {
|
||||||
hoverCommentId = comment.id;
|
hoverCommentId = comment.id;
|
||||||
renderCommentsPanel();
|
syncCommentListActiveState();
|
||||||
renderCommentTargets();
|
renderCommentTargets();
|
||||||
});
|
});
|
||||||
item.addEventListener("mouseleave", () => {
|
item.addEventListener("mouseleave", () => {
|
||||||
if (hoverCommentId === comment.id) hoverCommentId = null;
|
if (hoverCommentId === comment.id) hoverCommentId = null;
|
||||||
renderCommentsPanel();
|
syncCommentListActiveState();
|
||||||
renderCommentTargets();
|
renderCommentTargets();
|
||||||
});
|
});
|
||||||
item.addEventListener("click", () => openCommentModalForComment(comment.id));
|
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 = () => {
|
const renderCommentTargets = () => {
|
||||||
if (!commentTargetsLayer) return;
|
if (!commentTargetsLayer) return;
|
||||||
commentTargetsLayer.replaceChildren();
|
commentTargetsLayer.replaceChildren();
|
||||||
|
|
@ -790,13 +809,13 @@ const renderCommentTargets = () => {
|
||||||
btn.innerHTML = COMMENT_TARGET_ICON;
|
btn.innerHTML = COMMENT_TARGET_ICON;
|
||||||
btn.addEventListener("mouseenter", () => {
|
btn.addEventListener("mouseenter", () => {
|
||||||
if (!comment.draft) hoverCommentId = comment.id;
|
if (!comment.draft) hoverCommentId = comment.id;
|
||||||
renderCommentTargets();
|
syncCommentTargetActiveState();
|
||||||
renderCommentsPanel();
|
syncCommentListActiveState();
|
||||||
});
|
});
|
||||||
btn.addEventListener("mouseleave", () => {
|
btn.addEventListener("mouseleave", () => {
|
||||||
if (hoverCommentId === comment.id) hoverCommentId = null;
|
if (hoverCommentId === comment.id) hoverCommentId = null;
|
||||||
renderCommentTargets();
|
syncCommentTargetActiveState();
|
||||||
renderCommentsPanel();
|
syncCommentListActiveState();
|
||||||
});
|
});
|
||||||
btn.addEventListener("click", (event) => {
|
btn.addEventListener("click", (event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
@ -1227,7 +1246,7 @@ const openCommentModalForTarget = () => {
|
||||||
renderCommentThread(null);
|
renderCommentThread(null);
|
||||||
commentModalBackdrop?.classList.remove("hidden");
|
commentModalBackdrop?.classList.remove("hidden");
|
||||||
commentModal.classList.remove("hidden");
|
commentModal.classList.remove("hidden");
|
||||||
bringFloatingWindowToFront("comments");
|
bringFloatingWindowToFront("commentModal");
|
||||||
updateCommentsVisibility();
|
updateCommentsVisibility();
|
||||||
commentTitleInput?.focus();
|
commentTitleInput?.focus();
|
||||||
};
|
};
|
||||||
|
|
@ -1258,6 +1277,11 @@ const openCommentModalForComment = (commentId) => {
|
||||||
renderCommentThread(comment);
|
renderCommentThread(comment);
|
||||||
commentModalBackdrop?.classList.remove("hidden");
|
commentModalBackdrop?.classList.remove("hidden");
|
||||||
commentModal.classList.remove("hidden");
|
commentModal.classList.remove("hidden");
|
||||||
|
commentsModeActive = true;
|
||||||
|
commentsCollapsed = false;
|
||||||
|
bringFloatingWindowToFront("commentModal");
|
||||||
|
updateCommentsVisibility();
|
||||||
|
commentTitleInput?.focus();
|
||||||
renderCommentsPanel();
|
renderCommentsPanel();
|
||||||
renderCommentTargets();
|
renderCommentTargets();
|
||||||
};
|
};
|
||||||
|
|
@ -1968,12 +1992,14 @@ const closeTemplatesPanel = () => {
|
||||||
const openSettingsPanel = () => {
|
const openSettingsPanel = () => {
|
||||||
closeTemplatesPanel();
|
closeTemplatesPanel();
|
||||||
settingsMenu?.show();
|
settingsMenu?.show();
|
||||||
|
bringFloatingWindowToFront("settings");
|
||||||
setToolbarButtonActive(settingsButton, true);
|
setToolbarButtonActive(settingsButton, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openTemplatesPanel = () => {
|
const openTemplatesPanel = () => {
|
||||||
closeSettingsPanel();
|
closeSettingsPanel();
|
||||||
templatesMenu?.show();
|
templatesMenu?.show();
|
||||||
|
bringFloatingWindowToFront("templates");
|
||||||
setToolbarButtonActive(templatesButton, true);
|
setToolbarButtonActive(templatesButton, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -5164,6 +5190,7 @@ const loadProjectSnapshot = async (project) => {
|
||||||
fetchProjects: () => loadProjectsList(),
|
fetchProjects: () => loadProjectsList(),
|
||||||
openProject: (projectId) => loadProjectFromServer(projectId),
|
openProject: (projectId) => loadProjectFromServer(projectId),
|
||||||
onShow: () => {
|
onShow: () => {
|
||||||
|
bringFloatingWindowToFront("templates");
|
||||||
setToolbarButtonActive(templatesButton, true);
|
setToolbarButtonActive(templatesButton, true);
|
||||||
setToolbarButtonActive(settingsButton, false);
|
setToolbarButtonActive(settingsButton, false);
|
||||||
},
|
},
|
||||||
|
|
@ -5197,6 +5224,7 @@ const loadProjectSnapshot = async (project) => {
|
||||||
focusCanvasAndControls();
|
focusCanvasAndControls();
|
||||||
},
|
},
|
||||||
onShow: () => {
|
onShow: () => {
|
||||||
|
bringFloatingWindowToFront("settings");
|
||||||
setToolbarButtonActive(settingsButton, true);
|
setToolbarButtonActive(settingsButton, true);
|
||||||
setToolbarButtonActive(templatesButton, false);
|
setToolbarButtonActive(templatesButton, false);
|
||||||
closeTemplatesPanel();
|
closeTemplatesPanel();
|
||||||
|
|
@ -5269,9 +5297,15 @@ const loadProjectSnapshot = async (project) => {
|
||||||
zoomSpeedControl.replaceChildren(zoomSpeedSlider);
|
zoomSpeedControl.replaceChildren(zoomSpeedSlider);
|
||||||
}
|
}
|
||||||
inspectorCollapseButton?.addEventListener("click", () => setInspectorCollapsed(true));
|
inspectorCollapseButton?.addEventListener("click", () => setInspectorCollapsed(true));
|
||||||
inspectorRestoreButton?.addEventListener("click", () => setInspectorCollapsed(false));
|
inspectorRestoreButton?.addEventListener("click", () => {
|
||||||
|
setInspectorCollapsed(false);
|
||||||
|
bringFloatingWindowToFront("inspector");
|
||||||
|
});
|
||||||
registerFloatingWindowElement("inspector", sidePanelEl);
|
registerFloatingWindowElement("inspector", sidePanelEl);
|
||||||
registerFloatingWindowElement("comments", commentsPanel);
|
registerFloatingWindowElement("comments", commentsPanel);
|
||||||
|
registerFloatingWindowElement("settings", settingsPanel);
|
||||||
|
registerFloatingWindowElement("templates", templatesPanel);
|
||||||
|
registerFloatingWindowElement("commentModal", commentModal);
|
||||||
setupDraggableFixedWindow(commentsPanel, commentsPanelHeader);
|
setupDraggableFixedWindow(commentsPanel, commentsPanelHeader);
|
||||||
setupDraggableFixedWindow(commentModal, commentModalHeader);
|
setupDraggableFixedWindow(commentModal, commentModalHeader);
|
||||||
commentsCollapseButton?.addEventListener("click", () => setCommentsCollapsed(true));
|
commentsCollapseButton?.addEventListener("click", () => setCommentsCollapsed(true));
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<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 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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
|
@ -570,6 +570,6 @@
|
||||||
<input id="fileInput" class="hidden" type="file"
|
<input id="fileInput" class="hidden" type="file"
|
||||||
accept=".xkt,.glb,.gltf,.bim,.las,.laz,.obj,.stl">
|
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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue