@theia/core 1.62.1 → 1.63.0-next.24
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/README.md +6 -6
- package/lib/browser/secondary-window-handler.d.ts +1 -0
- package/lib/browser/secondary-window-handler.d.ts.map +1 -1
- package/lib/browser/secondary-window-handler.js +4 -1
- package/lib/browser/secondary-window-handler.js.map +1 -1
- package/lib/browser/shell/application-shell.d.ts.map +1 -1
- package/lib/browser/shell/application-shell.js +5 -1
- package/lib/browser/shell/application-shell.js.map +1 -1
- package/lib/browser/tree/tree-widget.d.ts +38 -1
- package/lib/browser/tree/tree-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-widget.js +62 -5
- package/lib/browser/tree/tree-widget.js.map +1 -1
- package/lib/browser/window/default-secondary-window-service.d.ts +1 -0
- package/lib/browser/window/default-secondary-window-service.d.ts.map +1 -1
- package/lib/browser/window/default-secondary-window-service.js +3 -0
- package/lib/browser/window/default-secondary-window-service.js.map +1 -1
- package/lib/browser/window/secondary-window-service.d.ts +1 -0
- package/lib/browser/window/secondary-window-service.d.ts.map +1 -1
- package/lib/node/logger-cli-contribution.d.ts.map +1 -1
- package/lib/node/logger-cli-contribution.js +4 -0
- package/lib/node/logger-cli-contribution.js.map +1 -1
- package/package.json +6 -6
- package/src/browser/secondary-window-handler.ts +5 -1
- package/src/browser/shell/application-shell.ts +5 -1
- package/src/browser/tree/tree-widget.tsx +85 -4
- package/src/browser/window/default-secondary-window-service.ts +4 -0
- package/src/browser/window/secondary-window-service.ts +1 -0
- package/src/node/logger-cli-contribution.ts +5 -0
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { injectable, inject, postConstruct } from 'inversify';
|
|
18
18
|
import { Message } from '@lumino/messaging';
|
|
19
|
-
import { Disposable, MenuPath, SelectionService } from '../../common';
|
|
19
|
+
import { Disposable, MenuPath, SelectionService, Event as TheiaEvent, Emitter } from '../../common';
|
|
20
20
|
import { Key, KeyCode, KeyModifier } from '../keyboard/keys';
|
|
21
21
|
import { ContextMenuRenderer } from '../context-menu-renderer';
|
|
22
22
|
import { StatefulWidget } from '../shell';
|
|
@@ -62,6 +62,27 @@ export const COMPOSITE_TREE_NODE_CLASS = 'theia-CompositeTreeNode';
|
|
|
62
62
|
export const TREE_NODE_CAPTION_CLASS = 'theia-TreeNodeCaption';
|
|
63
63
|
export const TREE_NODE_INDENT_GUIDE_CLASS = 'theia-tree-node-indent';
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Threshold in pixels to consider the view as being scrolled to the bottom
|
|
67
|
+
*/
|
|
68
|
+
export const SCROLL_BOTTOM_THRESHOLD = 30;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Tree scroll event data.
|
|
72
|
+
*/
|
|
73
|
+
export interface TreeScrollEvent {
|
|
74
|
+
readonly scrollTop: number;
|
|
75
|
+
readonly scrollLeft: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Tree scroll state data.
|
|
80
|
+
*/
|
|
81
|
+
export interface TreeScrollState {
|
|
82
|
+
readonly scrollTop: number;
|
|
83
|
+
readonly isAtBottom: boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
65
86
|
export const TreeProps = Symbol('TreeProps');
|
|
66
87
|
|
|
67
88
|
/**
|
|
@@ -165,6 +186,9 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
|
|
|
165
186
|
protected searchBox: SearchBox;
|
|
166
187
|
protected searchHighlights: Map<string, TreeDecoration.CaptionHighlight>;
|
|
167
188
|
|
|
189
|
+
protected readonly onScrollEmitter = new Emitter<TreeScrollEvent>();
|
|
190
|
+
readonly onScroll: TheiaEvent<TreeScrollEvent> = this.onScrollEmitter.event;
|
|
191
|
+
|
|
168
192
|
@inject(TreeDecoratorService)
|
|
169
193
|
protected readonly decoratorService: TreeDecoratorService;
|
|
170
194
|
@inject(TreeSearch)
|
|
@@ -258,6 +282,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
|
|
|
258
282
|
this.node.addEventListener('mouseup', this.handleMiddleClickEvent.bind(this));
|
|
259
283
|
this.node.addEventListener('auxclick', this.handleMiddleClickEvent.bind(this));
|
|
260
284
|
this.toDispose.pushAll([
|
|
285
|
+
this.onScrollEmitter,
|
|
261
286
|
this.model,
|
|
262
287
|
this.model.onChanged(() => this.updateRows()),
|
|
263
288
|
this.model.onSelectionChanged(() => this.scheduleUpdateScrollToRow({ resize: false })),
|
|
@@ -509,6 +534,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
|
|
|
509
534
|
rows={rows}
|
|
510
535
|
renderNodeRow={this.renderNodeRow}
|
|
511
536
|
scrollToRow={this.scrollToRow}
|
|
537
|
+
onScrollEmitter={this.onScrollEmitter}
|
|
512
538
|
{...this.props.viewProps}
|
|
513
539
|
/>;
|
|
514
540
|
}
|
|
@@ -1157,6 +1183,39 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
|
|
|
1157
1183
|
return this.node;
|
|
1158
1184
|
}
|
|
1159
1185
|
|
|
1186
|
+
/**
|
|
1187
|
+
* Get the current scroll state from the virtualized view.
|
|
1188
|
+
* This should be used instead of accessing the DOM scroll properties directly
|
|
1189
|
+
* when the tree is virtualized.
|
|
1190
|
+
*/
|
|
1191
|
+
protected getVirtualizedScrollState(): TreeScrollState | undefined {
|
|
1192
|
+
return this.view?.getScrollState();
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
/**
|
|
1196
|
+
* Check if the tree is scrolled to the bottom.
|
|
1197
|
+
* Works with both virtualized and non-virtualized trees.
|
|
1198
|
+
*/
|
|
1199
|
+
isScrolledToBottom(): boolean {
|
|
1200
|
+
if (this.props.virtualized !== false && this.view) {
|
|
1201
|
+
// Use virtualized scroll state
|
|
1202
|
+
const scrollState = this.getVirtualizedScrollState();
|
|
1203
|
+
return scrollState?.isAtBottom ?? true;
|
|
1204
|
+
} else {
|
|
1205
|
+
// Fallback to DOM-based calculation for non-virtualized trees
|
|
1206
|
+
const scrollContainer = this.node;
|
|
1207
|
+
const scrollHeight = scrollContainer.scrollHeight;
|
|
1208
|
+
const scrollTop = scrollContainer.scrollTop;
|
|
1209
|
+
const clientHeight = scrollContainer.clientHeight;
|
|
1210
|
+
|
|
1211
|
+
if (scrollHeight <= clientHeight) {
|
|
1212
|
+
return true;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
return scrollHeight - scrollTop - clientHeight <= SCROLL_BOTTOM_THRESHOLD;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1160
1219
|
protected override onAfterAttach(msg: Message): void {
|
|
1161
1220
|
const up = [
|
|
1162
1221
|
Key.ARROW_UP,
|
|
@@ -1577,11 +1636,17 @@ export namespace TreeWidget {
|
|
|
1577
1636
|
*/
|
|
1578
1637
|
rows: NodeRow[]
|
|
1579
1638
|
renderNodeRow: (row: NodeRow) => React.ReactNode
|
|
1639
|
+
/**
|
|
1640
|
+
* Optional scroll event emitter.
|
|
1641
|
+
*/
|
|
1642
|
+
onScrollEmitter?: Emitter<TreeScrollEvent>
|
|
1580
1643
|
}
|
|
1581
1644
|
export class View extends React.Component<ViewProps> {
|
|
1582
1645
|
list: VirtuosoHandle | undefined;
|
|
1646
|
+
private lastScrollState: TreeScrollState = { scrollTop: 0, isAtBottom: true };
|
|
1647
|
+
|
|
1583
1648
|
override render(): React.ReactNode {
|
|
1584
|
-
const { rows, width, height, scrollToRow, renderNodeRow, ...other } = this.props;
|
|
1649
|
+
const { rows, width, height, scrollToRow, renderNodeRow, onScrollEmitter, ...other } = this.props;
|
|
1585
1650
|
return <Virtuoso
|
|
1586
1651
|
ref={list => {
|
|
1587
1652
|
this.list = (list || undefined);
|
|
@@ -1592,14 +1657,30 @@ export namespace TreeWidget {
|
|
|
1592
1657
|
});
|
|
1593
1658
|
}
|
|
1594
1659
|
}}
|
|
1660
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1661
|
+
onScroll={(e: any) => {
|
|
1662
|
+
const scrollTop = e.target.scrollTop;
|
|
1663
|
+
const scrollHeight = e.target.scrollHeight;
|
|
1664
|
+
const clientHeight = e.target.clientHeight;
|
|
1665
|
+
const isAtBottom = scrollHeight - scrollTop - clientHeight <= SCROLL_BOTTOM_THRESHOLD;
|
|
1666
|
+
|
|
1667
|
+
// Store scroll state before firing the event to prevent jitter during inference and scrolling
|
|
1668
|
+
this.lastScrollState = { scrollTop, isAtBottom };
|
|
1669
|
+
onScrollEmitter?.fire({ scrollTop, scrollLeft: e.target.scrollLeft || 0 });
|
|
1670
|
+
}}
|
|
1595
1671
|
totalCount={rows.length}
|
|
1596
1672
|
itemContent={index => renderNodeRow(rows[index])}
|
|
1597
1673
|
width={width}
|
|
1598
1674
|
height={height}
|
|
1599
|
-
// This is a pixel value
|
|
1600
|
-
|
|
1675
|
+
// This is a pixel value that determines how many pixels to render outside the visible area
|
|
1676
|
+
// Higher value provides smoother scrolling experience especially during inference, but uses more memory
|
|
1677
|
+
overscan={800}
|
|
1601
1678
|
{...other}
|
|
1602
1679
|
/>;
|
|
1603
1680
|
}
|
|
1681
|
+
|
|
1682
|
+
getScrollState(): TreeScrollState {
|
|
1683
|
+
return { ...this.lastScrollState };
|
|
1684
|
+
}
|
|
1604
1685
|
}
|
|
1605
1686
|
}
|
|
@@ -189,6 +189,10 @@ export class DefaultSecondaryWindowService implements SecondaryWindowService {
|
|
|
189
189
|
return [height, width, left, top];
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
getWindows(): Window[] {
|
|
193
|
+
return this.secondaryWindows;
|
|
194
|
+
}
|
|
195
|
+
|
|
192
196
|
focus(win: Window): void {
|
|
193
197
|
win.focus();
|
|
194
198
|
}
|
|
@@ -120,6 +120,11 @@ export class LogLevelCliContribution implements CliContribution {
|
|
|
120
120
|
console.error(`Error creating log file ${filename}: ${e}`);
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
// some initial loggers have already been constructed. Fire the event to notify them.
|
|
125
|
+
if (args['log-level'] || args['log-config'] || args['log-file']) {
|
|
126
|
+
this.logConfigChangedEvent.fire();
|
|
127
|
+
}
|
|
123
128
|
}
|
|
124
129
|
|
|
125
130
|
protected async watchLogConfigFile(filename: string): Promise<void> {
|