Skip to content

Commit 457a82b

Browse files
Fix follow property and the ScrollFollow component. (issue #14) (#31)
* Updated dependencies * Added onScroll callback to LazyLog component * Fixed scroll following logic * Fixed ScrollFollow logic * Fixed the startFollowing property
1 parent 58cd4d9 commit 457a82b

File tree

3 files changed

+97
-65
lines changed

3 files changed

+97
-65
lines changed

package-lock.json

Lines changed: 56 additions & 56 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/LazyLog/index.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,17 @@ export interface LazyLogProps {
192192
* @param {React.MouseEvent<HTMLElement>} event - Browser event.
193193
*/
194194
onLineContentClick?(event: React.MouseEvent<HTMLSpanElement>): void;
195+
196+
/**
197+
* Callback to invoke on user scroll. Args matches the ScrollFollow onScroll callback.
198+
* @param args
199+
*/
200+
onScroll?(args: {
201+
scrollTop: number;
202+
scrollHeight: number;
203+
clientHeight: number;
204+
}): void;
205+
195206
/**
196207
* Number of rows to render above/below the visible bounds of the list.
197208
* This can help reduce flickering during scrolling on
@@ -405,6 +416,12 @@ export default class LazyLog extends Component<LazyLogProps, LazyLogState> {
405416
update();
406417
}
407418

419+
// If follow is activated, and we're not currently searching, scroll to offset
420+
if (this.props.follow && !this.state.isSearching) {
421+
this.state.listRef?.current?.scrollToItem(this.state.scrollToIndex, "auto");
422+
this.state.listRef?.current?.forceUpdate();
423+
}
424+
408425
if (
409426
!this.state.loaded &&
410427
prevState.loaded !== this.state.loaded &&
@@ -1116,6 +1133,18 @@ export default class LazyLog extends Component<LazyLogProps, LazyLogState> {
11161133
this.setState({
11171134
scrollOffset: options.scrollOffset,
11181135
});
1136+
// If there is an onScroll callback, call it.
1137+
if(this.props.onScroll) {
1138+
const args = {
1139+
scrollTop: options.scrollOffset,
1140+
scrollHeight: this.getItemSize(0) * (rowCount === 0
1141+
? rowCount
1142+
: rowCount +
1143+
(this.props.extraLines || 0)),
1144+
clientHeight: this.calculateListHeight(height) as number
1145+
}
1146+
this.props.onScroll(args);
1147+
}
11191148
}}
11201149
>
11211150
{/*

src/components/ScrollFollow/index.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,22 @@ export default class ScrollFollow extends Component<
5757
startFollowing: false,
5858
};
5959

60-
static getDerivedStateFromProps(nextProps: { startFollowing: boolean }) {
61-
return {
62-
follow: nextProps.startFollowing,
63-
};
64-
}
65-
60+
// Initial state is the startFollowing prop.
6661
state: ScrollFollowState = {
67-
follow: false,
62+
follow: this.props.startFollowing ?? false,
6863
};
6964

7065
handleScroll = ({ scrollTop, scrollHeight, clientHeight }: any) => {
71-
if (this.state.follow && scrollHeight - scrollTop !== clientHeight) {
72-
this.setState({ follow: false });
66+
// Only update the state if the content exceeds the available space
67+
// otherwise the follow will be disabled before the screen is filled.
68+
if(scrollHeight > clientHeight) {
69+
if (this.state.follow && scrollHeight - scrollTop !== clientHeight) {
70+
// Disable follow, if we're currently following and have manually scrolled away from the bottom.
71+
this.setState({follow: false});
72+
} else if (!this.state.follow && scrollHeight - scrollTop === clientHeight) {
73+
// Enable follow if we are not currently following and have scrolled to the bottom.
74+
this.setState({follow: true});
75+
}
7376
}
7477
};
7578

0 commit comments

Comments
 (0)