dsh-conversation-navigator 0.1.21 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +46 -9
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -92,6 +92,7 @@ window.__ModuleLoader__.load({
|
|
|
92
92
|
transition: opacity .18s ease, transform .18s ease;
|
|
93
93
|
}
|
|
94
94
|
.cnvnav-panel-hidden { opacity: 0; transform: translateY(-6px) scale(.985); pointer-events: none; }
|
|
95
|
+
.cnvnav-panel-unplaced { visibility: hidden; }
|
|
95
96
|
.cnvnav-head {
|
|
96
97
|
display: flex; align-items: center; gap: 8px;
|
|
97
98
|
padding: 10px 12px;
|
|
@@ -571,23 +572,59 @@ window.__ModuleLoader__.load({
|
|
|
571
572
|
|
|
572
573
|
React.useEffect(() => {
|
|
573
574
|
if (!snap.open) return;
|
|
575
|
+
let lastKey = null;
|
|
576
|
+
let stableTicks = 0;
|
|
577
|
+
let misses = 0;
|
|
574
578
|
function place() {
|
|
575
579
|
const panel = panelEl;
|
|
576
|
-
if (panel === null) return;
|
|
580
|
+
if (panel === null) return false;
|
|
577
581
|
const vw = document.documentElement.clientWidth || 1000;
|
|
578
582
|
const vh = document.documentElement.clientHeight || 800;
|
|
579
583
|
const sp = document.querySelector("[data-conversation-scroll]");
|
|
580
|
-
const rect = sp !== null ? sp.getBoundingClientRect() : { top: 60, height: vh - 90 };
|
|
581
584
|
const width = 288;
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
585
|
+
if (sp === null) {
|
|
586
|
+
/* 会话视图可能尚未挂载(刷新/重启/切会话时面板先就位);
|
|
587
|
+
非会话页(设置页等)则永远没有该容器。
|
|
588
|
+
连续 15 次(约 6s)仍未出现才回退到视口定位, 否则保持隐藏等待校准。 */
|
|
589
|
+
misses += 1;
|
|
590
|
+
if (misses >= 15) {
|
|
591
|
+
panel.style.left = Math.max(8, vw - width - 12) + "px";
|
|
592
|
+
panel.style.top = Math.max(8, 60) + "px";
|
|
593
|
+
panel.style.maxHeight = Math.round(vh - 90) + "px";
|
|
594
|
+
panel.classList.remove("cnvnav-panel-unplaced");
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
const r = sp.getBoundingClientRect();
|
|
600
|
+
const key = [Math.round(r.top), Math.round(r.height), Math.round(vw), Math.round(vh)].join("|");
|
|
601
|
+
if (key !== lastKey) {
|
|
602
|
+
lastKey = key;
|
|
603
|
+
panel.style.left = Math.max(8, vw - width - 12) + "px";
|
|
604
|
+
panel.style.top = Math.max(8, Math.round(r.top + 8)) + "px";
|
|
605
|
+
panel.style.maxHeight = Math.round(Math.min(r.height - 24, vh - 40)) + "px";
|
|
606
|
+
}
|
|
607
|
+
panel.classList.remove("cnvnav-panel-unplaced");
|
|
608
|
+
return true;
|
|
586
609
|
}
|
|
587
610
|
place();
|
|
611
|
+
/* 每 400ms 复查: 容器出现即校准; 布局连续 3 次无变化后停止 */
|
|
612
|
+
let id = setInterval(() => {
|
|
613
|
+
const before = lastKey;
|
|
614
|
+
if (!place()) return;
|
|
615
|
+
if (lastKey !== null && lastKey === before) {
|
|
616
|
+
stableTicks += 1;
|
|
617
|
+
if (stableTicks >= 3) clearInterval(id);
|
|
618
|
+
} else {
|
|
619
|
+
stableTicks = 0;
|
|
620
|
+
}
|
|
621
|
+
}, 400);
|
|
588
622
|
window.addEventListener("resize", place);
|
|
589
|
-
return () =>
|
|
590
|
-
|
|
623
|
+
return () => {
|
|
624
|
+
clearInterval(id);
|
|
625
|
+
window.removeEventListener("resize", place);
|
|
626
|
+
};
|
|
627
|
+
}, [snap.open, snap.sessionId]);
|
|
591
628
|
|
|
592
629
|
React.useEffect(() => {
|
|
593
630
|
if (!snap.open) return;
|
|
@@ -821,7 +858,7 @@ window.__ModuleLoader__.load({
|
|
|
821
858
|
|
|
822
859
|
return React.createElement("div", {
|
|
823
860
|
ref: (el) => { panelEl = el; },
|
|
824
|
-
className: "cnvnav-panel" + (snap.open ? "" : " cnvnav-panel-hidden"),
|
|
861
|
+
className: "cnvnav-panel cnvnav-panel-unplaced" + (snap.open ? "" : " cnvnav-panel-hidden"),
|
|
825
862
|
role: "complementary",
|
|
826
863
|
"aria-label": "会话导航",
|
|
827
864
|
"aria-hidden": !snap.open,
|