mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-22 02:41:23 +01:00
updating selectedline will now scroll the window
This commit is contained in:
parent
d04f94d481
commit
82819bbe94
112
src/main.tsx
112
src/main.tsx
@ -1636,12 +1636,11 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
rszObs : any;
|
||||
linesRef : React.RefObject<any>;
|
||||
staticRender : OV<boolean> = mobx.observable.box(true);
|
||||
anchorLine : number = 0;
|
||||
anchorOffset : number = 0;
|
||||
lastOffsetHeight : number = 0;
|
||||
lastOffsetWidth : number = 0;
|
||||
ignoreNextScroll : boolean = false;
|
||||
visibleMap : Map<string, OV<boolean>>; // lineid => OV<vis>
|
||||
lastSelectedLine : number = 0;
|
||||
|
||||
computeAnchorLine_throttled : () => void;
|
||||
computeVisibleMap_debounced : () => void;
|
||||
@ -1649,8 +1648,6 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.linesRef = React.createRef();
|
||||
this.anchorLine = props.lines[props.lines.length-1].linenum;
|
||||
this.anchorOffset = 0;
|
||||
this.computeAnchorLine_throttled = throttle(100, this.computeAnchorLine.bind(this), {noLeading: true, noTrailing: false});
|
||||
this.visibleMap = new Map();
|
||||
this.computeVisibleMap_debounced = debounce(1000, this.computeVisibleMap.bind(this));
|
||||
@ -1668,16 +1665,17 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
}
|
||||
|
||||
computeAnchorLine() : void {
|
||||
let {sw} = this.props;
|
||||
let linesElem = this.linesRef.current;
|
||||
if (linesElem == null) {
|
||||
this.anchorLine = null;
|
||||
this.anchorOffset = 0;
|
||||
sw.anchorLine = null;
|
||||
sw.anchorOffset = 0;
|
||||
return;
|
||||
}
|
||||
let lineElemArr = linesElem.querySelectorAll(".line");
|
||||
if (lineElemArr == null) {
|
||||
this.anchorLine = null;
|
||||
this.anchorOffset = 0;
|
||||
sw.anchorLine = null;
|
||||
sw.anchorOffset = 0;
|
||||
return;
|
||||
}
|
||||
let scrollTop = linesElem.scrollTop;
|
||||
@ -1694,8 +1692,8 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
if (anchorElem == null) {
|
||||
anchorElem = lineElemArr[0];
|
||||
}
|
||||
this.anchorLine = parseInt(anchorElem.dataset.linenum);
|
||||
this.anchorOffset = containerBottom - (anchorElem.offsetTop + anchorElem.offsetHeight);
|
||||
sw.anchorLine = parseInt(anchorElem.dataset.linenum);
|
||||
sw.anchorOffset = containerBottom - (anchorElem.offsetTop + anchorElem.offsetHeight);
|
||||
// console.log("anchor", this.anchorLine, this.anchorOffset);
|
||||
}
|
||||
|
||||
@ -1710,7 +1708,6 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
}
|
||||
let containerTop = linesElem.scrollTop - LinesVisiblePadding;
|
||||
let containerBot = linesElem.scrollTop + linesElem.clientHeight + LinesVisiblePadding;
|
||||
console.log("container", containerTop, containerBot);
|
||||
let newMap = new Map<string, boolean>();
|
||||
for (let i=0; i<lineElemArr.length; i++) {
|
||||
let lineElem = lineElemArr[i];
|
||||
@ -1740,14 +1737,15 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
}
|
||||
|
||||
restoreAnchorOffset(reason : string) : void {
|
||||
let {sw} = this.props;
|
||||
let linesElem = this.linesRef.current;
|
||||
if (linesElem == null) {
|
||||
return;
|
||||
}
|
||||
if (this.anchorLine == null || this.anchorLine == 0) {
|
||||
if (sw.anchorLine == null || sw.anchorLine == 0) {
|
||||
return;
|
||||
}
|
||||
let anchorElem = linesElem.querySelector(sprintf(".line[data-linenum=\"%d\"]", this.anchorLine));
|
||||
let anchorElem = linesElem.querySelector(sprintf(".line[data-linenum=\"%d\"]", sw.anchorLine));
|
||||
if (anchorElem == null) {
|
||||
return;
|
||||
}
|
||||
@ -1755,8 +1753,8 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
let height = linesElem.clientHeight;
|
||||
let containerBottom = scrollTop + height;
|
||||
let curAnchorOffset = containerBottom - (anchorElem.offsetTop + anchorElem.offsetHeight);
|
||||
if (curAnchorOffset != this.anchorOffset) {
|
||||
let offsetDiff = curAnchorOffset - this.anchorOffset;
|
||||
if (curAnchorOffset != sw.anchorOffset) {
|
||||
let offsetDiff = curAnchorOffset - sw.anchorOffset;
|
||||
let newScrollTop = scrollTop - offsetDiff;
|
||||
// console.log("update scrolltop", reason, -offsetDiff, linesElem.scrollTop, "=>", newScrollTop);
|
||||
linesElem.scrollTop = newScrollTop;
|
||||
@ -1765,7 +1763,14 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
}
|
||||
|
||||
componentDidMount() : void {
|
||||
this.computeAnchorLine();
|
||||
let {sw} = this.props;
|
||||
if (sw.anchorLine == null) {
|
||||
this.computeAnchorLine();
|
||||
}
|
||||
else {
|
||||
this.restoreAnchorOffset("re-mount");
|
||||
}
|
||||
this.lastSelectedLine = sw.selectedLine.get();
|
||||
|
||||
let linesElem = this.linesRef.current;
|
||||
if (linesElem != null) {
|
||||
@ -1781,6 +1786,80 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
})();
|
||||
}
|
||||
|
||||
getLineElem(lineNum : number) : HTMLElement {
|
||||
let linesElem = this.linesRef.current;
|
||||
if (linesElem == null) {
|
||||
return null;
|
||||
}
|
||||
let elem = linesElem.querySelector(sprintf(".line[data-linenum=\"%d\"]", lineNum));
|
||||
return elem;
|
||||
}
|
||||
|
||||
getLineViewInfo(lineNum : number) : {height: number, topOffset: number, botOffset: number} {
|
||||
let linesElem = this.linesRef.current;
|
||||
if (linesElem == null) {
|
||||
return null;
|
||||
}
|
||||
let lineElem = this.getLineElem(lineNum);
|
||||
if (lineElem == null) {
|
||||
return null;
|
||||
}
|
||||
let rtn = {
|
||||
height: lineElem.offsetHeight,
|
||||
topOffset: 0,
|
||||
botOffset: 0,
|
||||
};
|
||||
let containerTop = linesElem.scrollTop;
|
||||
let containerBot = linesElem.scrollTop + linesElem.clientHeight;
|
||||
let lineTop = lineElem.offsetTop;
|
||||
let lineBot = lineElem.offsetTop + lineElem.offsetHeight;
|
||||
if (lineTop < containerTop) {
|
||||
rtn.topOffset = lineTop - containerTop;
|
||||
}
|
||||
else if (lineTop > containerBot) {
|
||||
rtn.topOffset = lineTop - containerBot;
|
||||
}
|
||||
if (lineBot < containerTop) {
|
||||
rtn.botOffset = lineBot - containerTop;
|
||||
}
|
||||
else if (lineBot > containerBot) {
|
||||
rtn.botOffset = lineBot - containerBot;
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
updateSelectedLine() : void {
|
||||
let {sw, lines} = this.props;
|
||||
let linesElem = this.linesRef.current;
|
||||
if (linesElem == null) {
|
||||
return null;
|
||||
}
|
||||
let newLine = sw.selectedLine.get();
|
||||
if (newLine == sw.anchorLine) {
|
||||
return;
|
||||
}
|
||||
let viewInfo = this.getLineViewInfo(newLine);
|
||||
if (viewInfo == null) {
|
||||
return;
|
||||
}
|
||||
let isFirst = (newLine == lines[0].linenum);
|
||||
let isLast = (newLine == lines[lines.length-1].linenum);
|
||||
if (viewInfo.botOffset > 0) {
|
||||
linesElem.scrollTop = linesElem.scrollTop + viewInfo.botOffset + (isLast ? 10 : 0);
|
||||
}
|
||||
else if (viewInfo.topOffset < 0) {
|
||||
linesElem.scrollTop = linesElem.scrollTop + viewInfo.topOffset + (isFirst ? -10 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) : void {
|
||||
let {sw} = this.props;
|
||||
if (sw.selectedLine.get() != this.lastSelectedLine) {
|
||||
this.updateSelectedLine();
|
||||
this.lastSelectedLine = sw.selectedLine.get();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() : void {
|
||||
if (this.rszObs != null) {
|
||||
this.rszObs.disconnect();
|
||||
@ -1813,6 +1892,7 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line
|
||||
|
||||
render() {
|
||||
let {sw, width, lines} = this.props;
|
||||
let selectedLine = sw.selectedLine.get(); // for re-rendering
|
||||
let line : LineType = null;
|
||||
let idx : number = 0;
|
||||
for (let i=0; i<lines.length; i++) {
|
||||
|
@ -266,6 +266,8 @@ class ScreenWindow {
|
||||
scrollTop : OV<number>;
|
||||
shouldFollow : OV<boolean> = mobx.observable.box(true);
|
||||
focusType : OV<"input"|"lines"> = mobx.observable.box("input");
|
||||
anchorLine : number = null;
|
||||
anchorOffset : number = 0;
|
||||
|
||||
// cmdid => TermWrap
|
||||
terms : Record<string, TermWrap> = {};
|
||||
@ -281,6 +283,10 @@ class ScreenWindow {
|
||||
this.selectedLine = mobx.observable.box(swdata.selectedline == 0 ? null : swdata.selectedline);
|
||||
this.scrollTop = mobx.observable.box(swdata.scrolltop);
|
||||
this.setScrollTop_debounced = debounce(1000, this.setScrollTop.bind(this));
|
||||
if (swdata.selectedline != 0) {
|
||||
this.anchorLine = swdata.selectedline;
|
||||
this.anchorOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
updateSelf(swdata : ScreenWindowType) {
|
||||
|
@ -641,9 +641,7 @@ body .xterm .xterm-viewport {
|
||||
flex-direction: column;
|
||||
height: 80vh;
|
||||
overflow-y: scroll;
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
padding-right: 0px;
|
||||
padding: 10px 0 10px 0;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
|
||||
|
@ -15,10 +15,11 @@ let jbmFontNormal = new FontFace("JetBrains Mono", "url('static/fonts/jetbrains-
|
||||
let jbmFont200 = new FontFace("JetBrains Mono", "url('static/fonts/jetbrains-mono-v13-latin-200.woff2')", {style: "normal", weight: "200"});
|
||||
let jbmFont700 = new FontFace("JetBrains Mono", "url('static/fonts/jetbrains-mono-v13-latin-700.woff2')", {style: "normal", weight: "700"});
|
||||
let faFont = new FontFace("FontAwesome", "url(static/fonts/fontawesome-webfont-4.7.woff2)", {style: "normal", weight: "normal"});
|
||||
document.fonts.add(jbmFontNormal);
|
||||
document.fonts.add(jbmFont200);
|
||||
document.fonts.add(jbmFont700);
|
||||
document.fonts.add(faFont);
|
||||
let docFonts : any = document.fonts; // work around ts typing issue
|
||||
docFonts.add(jbmFontNormal);
|
||||
docFonts.add(jbmFont200);
|
||||
docFonts.add(jbmFont700);
|
||||
docFonts.add(faFont);
|
||||
jbmFontNormal.load();
|
||||
jbmFont200.load();
|
||||
jbmFont700.load();
|
||||
|
Loading…
Reference in New Issue
Block a user