@ashx-j/lunr-tui 0.2.8 → 0.2.9
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/dist/tui.d.ts +11 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +94 -7
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -104,6 +104,20 @@ export class Container {
|
|
|
104
104
|
}
|
|
105
105
|
return lines;
|
|
106
106
|
}
|
|
107
|
+
handleClick(localY, width) {
|
|
108
|
+
let y = 0;
|
|
109
|
+
for (const child of this.children) {
|
|
110
|
+
const h = child.render(width).length;
|
|
111
|
+
if (localY >= y && localY < y + h) {
|
|
112
|
+
if (typeof child.handleClick === "function") {
|
|
113
|
+
return child.handleClick(localY - y, width);
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
y += h;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
107
121
|
}
|
|
108
122
|
/**
|
|
109
123
|
* TUI - Main class for managing terminal UI with differential rendering
|
|
@@ -157,6 +171,9 @@ export class TUI extends Container {
|
|
|
157
171
|
static WHEEL_LINES = 3;
|
|
158
172
|
chatScrollbar;
|
|
159
173
|
scrollbarDrag;
|
|
174
|
+
pendingClick;
|
|
175
|
+
lastChatStart = 0;
|
|
176
|
+
lastChatSliceHeight = 0;
|
|
160
177
|
constructor(terminal, showHardwareCursor) {
|
|
161
178
|
super();
|
|
162
179
|
this.terminal = terminal;
|
|
@@ -386,27 +403,29 @@ export class TUI extends Container {
|
|
|
386
403
|
return -1;
|
|
387
404
|
return this.children.indexOf(this.pinComponent);
|
|
388
405
|
}
|
|
389
|
-
collectChildLines(from, to, width) {
|
|
406
|
+
collectChildLines(from, to, width, ranges) {
|
|
390
407
|
const lines = [];
|
|
391
408
|
for (let i = from; i < to; i++) {
|
|
392
409
|
const child = this.children[i];
|
|
393
410
|
if (!child)
|
|
394
411
|
continue;
|
|
395
|
-
this.appendRenderedChild(lines, child, width);
|
|
412
|
+
this.appendRenderedChild(lines, child, width, ranges);
|
|
396
413
|
}
|
|
397
414
|
return lines;
|
|
398
415
|
}
|
|
399
|
-
appendRenderedChild(lines, child, width) {
|
|
416
|
+
appendRenderedChild(lines, child, width, ranges) {
|
|
400
417
|
const nested = "children" in child && Array.isArray(child.children);
|
|
401
418
|
if (nested && child.children.length > 0 && child.render === Container.prototype.render) {
|
|
402
419
|
for (const nestedChild of child.children) {
|
|
403
|
-
this.appendRenderedChild(lines, nestedChild, width);
|
|
420
|
+
this.appendRenderedChild(lines, nestedChild, width, ranges);
|
|
404
421
|
}
|
|
405
422
|
return;
|
|
406
423
|
}
|
|
424
|
+
const start = lines.length;
|
|
407
425
|
for (const line of child.render(width)) {
|
|
408
426
|
lines.push(line);
|
|
409
427
|
}
|
|
428
|
+
ranges?.push({ component: child, start, end: lines.length });
|
|
410
429
|
}
|
|
411
430
|
snapStartToKittyImageHeader(lines, start) {
|
|
412
431
|
if (start <= 0 || start >= lines.length)
|
|
@@ -448,27 +467,32 @@ export class TUI extends Container {
|
|
|
448
467
|
this.chatLaidOut = true;
|
|
449
468
|
let chatWidth = this.chatUsesGutter ? Math.max(1, width - 1) : width;
|
|
450
469
|
let scrollLines;
|
|
470
|
+
let ranges;
|
|
451
471
|
let fromCache = false;
|
|
452
472
|
const cache = this.chatLayoutCache;
|
|
453
473
|
if (cache && cache.epoch === this.contentEpoch && cache.chatWidth === chatWidth) {
|
|
454
474
|
scrollLines = cache.scrollLines;
|
|
475
|
+
ranges = cache.ranges;
|
|
455
476
|
fromCache = true;
|
|
456
477
|
}
|
|
457
478
|
else {
|
|
458
|
-
|
|
479
|
+
ranges = [];
|
|
480
|
+
scrollLines = this.collectChildLines(0, pinIndex, chatWidth, ranges);
|
|
459
481
|
}
|
|
460
482
|
if (this.chatUsesGutter) {
|
|
461
483
|
if (scrollLines.length <= viewH) {
|
|
462
484
|
this.chatUsesGutter = false;
|
|
463
485
|
chatWidth = width;
|
|
464
|
-
|
|
486
|
+
ranges = [];
|
|
487
|
+
scrollLines = this.collectChildLines(0, pinIndex, chatWidth, ranges);
|
|
465
488
|
fromCache = false;
|
|
466
489
|
}
|
|
467
490
|
}
|
|
468
491
|
else if (scrollLines.length > viewH) {
|
|
469
492
|
this.chatUsesGutter = true;
|
|
470
493
|
chatWidth = Math.max(1, width - 1);
|
|
471
|
-
|
|
494
|
+
ranges = [];
|
|
495
|
+
scrollLines = this.collectChildLines(0, pinIndex, chatWidth, ranges);
|
|
472
496
|
fromCache = false;
|
|
473
497
|
}
|
|
474
498
|
if (!fromCache) {
|
|
@@ -476,6 +500,7 @@ export class TUI extends Container {
|
|
|
476
500
|
epoch: this.contentEpoch,
|
|
477
501
|
chatWidth,
|
|
478
502
|
scrollLines,
|
|
503
|
+
ranges,
|
|
479
504
|
};
|
|
480
505
|
}
|
|
481
506
|
let chatSlice;
|
|
@@ -487,6 +512,7 @@ export class TUI extends Container {
|
|
|
487
512
|
this.chatScrollbar = undefined;
|
|
488
513
|
this.scrollbarDrag = undefined;
|
|
489
514
|
chatSlice = scrollLines.slice();
|
|
515
|
+
this.lastChatStart = 0;
|
|
490
516
|
}
|
|
491
517
|
else {
|
|
492
518
|
this.lastChatScrollMax = scrollLines.length - viewH;
|
|
@@ -494,6 +520,7 @@ export class TUI extends Container {
|
|
|
494
520
|
start = scrollLines.length - viewH - this.chatScrollOffset;
|
|
495
521
|
start = this.snapStartToKittyImageHeader(scrollLines, start);
|
|
496
522
|
start = Math.max(0, start);
|
|
523
|
+
this.lastChatStart = start;
|
|
497
524
|
chatSlice = scrollLines.slice(start, start + viewH);
|
|
498
525
|
while (chatSlice.length < viewH) {
|
|
499
526
|
chatSlice.push("");
|
|
@@ -521,6 +548,7 @@ export class TUI extends Container {
|
|
|
521
548
|
chatSlice[i] = `${padToWidth(chatSlice[i] ?? "", chatWidth)}${glyph}`;
|
|
522
549
|
}
|
|
523
550
|
}
|
|
551
|
+
this.lastChatSliceHeight = chatSlice.length;
|
|
524
552
|
return [...chatSlice, ...dockLines];
|
|
525
553
|
}
|
|
526
554
|
/**
|
|
@@ -860,8 +888,67 @@ export class TUI extends Container {
|
|
|
860
888
|
this.setChatScroll(Math.round((1 - rel) * sb.scrollMax));
|
|
861
889
|
}
|
|
862
890
|
this.scrollbarDrag = { grabY: y, startOffset: this.chatScrollOffset };
|
|
891
|
+
this.pendingClick = undefined;
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
if (mouse.kind === "button" && mouse.button === 0 && !mouse.release) {
|
|
895
|
+
this.pendingClick = { x: mouse.x, y: mouse.y };
|
|
863
896
|
return;
|
|
864
897
|
}
|
|
898
|
+
if (mouse.kind === "move" && this.pendingClick) {
|
|
899
|
+
const dx = Math.abs(mouse.x - this.pendingClick.x);
|
|
900
|
+
const dy = Math.abs(mouse.y - this.pendingClick.y);
|
|
901
|
+
if (dx + dy > 1) {
|
|
902
|
+
this.pendingClick = undefined;
|
|
903
|
+
}
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
if (mouse.kind === "button" && mouse.button === 0 && mouse.release) {
|
|
907
|
+
const pending = this.pendingClick;
|
|
908
|
+
this.pendingClick = undefined;
|
|
909
|
+
if (!pending)
|
|
910
|
+
return;
|
|
911
|
+
if (this.dispatchChatClick(pending.y) || this.dispatchDockClick(pending.y)) {
|
|
912
|
+
this.requestRender();
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
dispatchChatClick(mouseY) {
|
|
917
|
+
const cache = this.chatLayoutCache;
|
|
918
|
+
if (!cache || mouseY < 1 || mouseY > this.lastChatSliceHeight)
|
|
919
|
+
return false;
|
|
920
|
+
const lineIndex = this.lastChatStart + (mouseY - 1);
|
|
921
|
+
const hit = cache.ranges.find((range) => lineIndex >= range.start && lineIndex < range.end);
|
|
922
|
+
if (!hit || typeof hit.component.handleClick !== "function")
|
|
923
|
+
return false;
|
|
924
|
+
return hit.component.handleClick(lineIndex - hit.start, cache.chatWidth) === true;
|
|
925
|
+
}
|
|
926
|
+
dispatchDockClick(mouseY) {
|
|
927
|
+
if (mouseY <= this.lastChatSliceHeight)
|
|
928
|
+
return false;
|
|
929
|
+
const pin = this.getPinIndex();
|
|
930
|
+
if (pin < 0)
|
|
931
|
+
return false;
|
|
932
|
+
const width = this.terminal.columns;
|
|
933
|
+
let y = this.lastChatSliceHeight;
|
|
934
|
+
const local = mouseY - 1;
|
|
935
|
+
for (let i = pin; i < this.children.length; i++) {
|
|
936
|
+
const child = this.children[i];
|
|
937
|
+
if (!child)
|
|
938
|
+
continue;
|
|
939
|
+
const h = child.render(width).length;
|
|
940
|
+
if (local >= y && local < y + h) {
|
|
941
|
+
if (typeof child.handleClick === "function") {
|
|
942
|
+
return child.handleClick(local - y, width);
|
|
943
|
+
}
|
|
944
|
+
if (child instanceof Container) {
|
|
945
|
+
return child.handleClick(local - y, width);
|
|
946
|
+
}
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
y += h;
|
|
950
|
+
}
|
|
951
|
+
return false;
|
|
865
952
|
}
|
|
866
953
|
dragScrollbarTo(mouseY) {
|
|
867
954
|
if (!this.scrollbarDrag || !this.chatScrollbar)
|