dsh-neotui 0.0.12 → 0.0.14
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/package.json +1 -1
- package/src/views.js +25 -17
package/package.json
CHANGED
package/src/views.js
CHANGED
|
@@ -849,23 +849,31 @@ export class ChatView extends Widget {
|
|
|
849
849
|
}
|
|
850
850
|
const node = this.nodes[info.nodeIdx];
|
|
851
851
|
// Expand/collapse changes the line count ABOVE the viewport, which would
|
|
852
|
-
// leave scrollY pointing at unrelated content
|
|
853
|
-
//
|
|
854
|
-
//
|
|
855
|
-
//
|
|
856
|
-
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
|
|
852
|
+
// leave scrollY pointing at unrelated content. Anchor: remember the
|
|
853
|
+
// viewport-top line's identity AND its offset within that block, then
|
|
854
|
+
// restore the same position after the rebuild — the view does not move
|
|
855
|
+
// at all when the top line survives (e.g. clicking a block header), and
|
|
856
|
+
// lands on the fold's last line when the top line itself was collapsed.
|
|
857
|
+
const lineKey = (m) => (m ? `${m.nodeIdx}:${m.blockIdx ?? "n"}` : null);
|
|
858
|
+
const topKey = lineKey(this.lineMap[this.view.scrollY]);
|
|
859
|
+
let topFirst = -1;
|
|
860
|
+
if (topKey !== null) {
|
|
860
861
|
for (let i = 0; i < this.lineMap.length; i++) {
|
|
861
|
-
if (
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
862
|
+
if (lineKey(this.lineMap[i]) === topKey) { topFirst = i; break; }
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
const topOffset = topFirst >= 0 ? this.view.scrollY - topFirst : 0;
|
|
866
|
+
const reanchor = () => {
|
|
867
|
+
if (topKey === null || topFirst < 0) return;
|
|
868
|
+
let first = -1, last = -1;
|
|
869
|
+
for (let i = 0; i < this.lineMap.length; i++) {
|
|
870
|
+
if (lineKey(this.lineMap[i]) !== topKey) continue;
|
|
871
|
+
if (first < 0) first = i;
|
|
872
|
+
last = i;
|
|
867
873
|
}
|
|
868
|
-
if (
|
|
874
|
+
if (first < 0) return;
|
|
875
|
+
const target = Math.min(first + topOffset, last);
|
|
876
|
+
this.view.scrollY = Math.max(0, Math.min(target, this.view.maxScroll()));
|
|
869
877
|
};
|
|
870
878
|
if (node?.kind === "assistant" && info.blockIdx !== null) {
|
|
871
879
|
const b = node.blocks[info.blockIdx];
|
|
@@ -881,7 +889,7 @@ export class ChatView extends Widget {
|
|
|
881
889
|
else this.collapsedBlocks.add(key);
|
|
882
890
|
}
|
|
883
891
|
this.#rebuild();
|
|
884
|
-
reanchor(
|
|
892
|
+
reanchor();
|
|
885
893
|
return true;
|
|
886
894
|
}
|
|
887
895
|
}
|
|
@@ -889,7 +897,7 @@ export class ChatView extends Widget {
|
|
|
889
897
|
if (this.expanded.has(info.nodeIdx)) this.expanded.delete(info.nodeIdx);
|
|
890
898
|
else this.expanded.add(info.nodeIdx);
|
|
891
899
|
this.#rebuild();
|
|
892
|
-
reanchor(
|
|
900
|
+
reanchor();
|
|
893
901
|
return true;
|
|
894
902
|
}
|
|
895
903
|
}
|