Maintain scroll positions when switching tabs
This commit is contained in:
parent
45c61e7596
commit
52acec9d21
File diff suppressed because one or more lines are too long
@ -4,19 +4,24 @@ import { AutoSizer } from 'react-virtualized/dist/commonjs/AutoSizer';
|
||||
import debounce from 'lodash/debounce';
|
||||
import Message from './Message';
|
||||
import { measureScrollBarWidth } from '../util';
|
||||
import { getScrollPos, saveScrollPos } from '../util/scrollPosition';
|
||||
|
||||
const scrollBarWidth = measureScrollBarWidth();
|
||||
const listStyle = { padding: '7px 0', boxSizing: 'content-box' };
|
||||
const threshold = 100;
|
||||
|
||||
export default class MessageBox extends PureComponent {
|
||||
componentDidMount() {
|
||||
this.loadScrollPos();
|
||||
}
|
||||
|
||||
componentWillUpdate(nextProps) {
|
||||
if (nextProps.messages !== this.props.messages) {
|
||||
this.list.recomputeRowHeights();
|
||||
}
|
||||
|
||||
if (nextProps.tab !== this.props.tab) {
|
||||
this.bottom = true;
|
||||
this.saveScrollPos();
|
||||
}
|
||||
|
||||
if (nextProps.messages.get(0) !== this.props.messages.get(0)) {
|
||||
@ -34,17 +39,25 @@ export default class MessageBox extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.tab !== this.props.tab) {
|
||||
this.loadScrollPos();
|
||||
}
|
||||
|
||||
if (this.nextScrollTop > 0) {
|
||||
this.container.scrollTop = this.nextScrollTop;
|
||||
this.nextScrollTop = 0;
|
||||
} else if (this.bottom) {
|
||||
this.container.scrollTop = this.container.scrollHeight;
|
||||
this.list.scrollToRow(this.props.messages.size);
|
||||
}
|
||||
|
||||
this.updateWidth();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.saveScrollPos();
|
||||
}
|
||||
|
||||
getRowHeight = ({ index }) => {
|
||||
if (index === 0) {
|
||||
if (this.props.hasMoreMessages) {
|
||||
@ -57,8 +70,38 @@ export default class MessageBox extends PureComponent {
|
||||
|
||||
listRef = el => {
|
||||
this.list = el;
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
this.container = el.Grid._scrollingContainer;
|
||||
if (el) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
this.container = el.Grid._scrollingContainer;
|
||||
}
|
||||
};
|
||||
|
||||
updateScrollKey = () => {
|
||||
const { tab } = this.props;
|
||||
this.scrollKey = `msg:${tab.server}:${tab.name}`;
|
||||
return this.scrollKey;
|
||||
}
|
||||
|
||||
loadScrollPos = () => {
|
||||
const pos = getScrollPos(this.updateScrollKey());
|
||||
if (pos >= 0) {
|
||||
this.bottom = false;
|
||||
this.container.scrollTop = pos;
|
||||
} else {
|
||||
this.bottom = true;
|
||||
}
|
||||
};
|
||||
|
||||
saveScrollPos = () => {
|
||||
if (this.bottom) {
|
||||
saveScrollPos(this.scrollKey, -1);
|
||||
} else {
|
||||
saveScrollPos(this.scrollKey, this.container.scrollTop);
|
||||
}
|
||||
}
|
||||
|
||||
scrollDown = () => {
|
||||
this.container.scrollTop = this.container.scrollHeight - this.container.clientHeight;
|
||||
};
|
||||
|
||||
updateWidth = (width) => {
|
||||
@ -105,7 +148,7 @@ export default class MessageBox extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
this.bottom = scrollTop + clientHeight >= scrollHeight;
|
||||
this.bottom = scrollTop + clientHeight >= scrollHeight - 10;
|
||||
this.prevScrollTop = scrollTop;
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@ function updateSelected({ params, dispatch }) {
|
||||
}
|
||||
|
||||
function updateCharWidth() {
|
||||
const charWidth = stringWidth(' ', '16px Roboto Mono');
|
||||
const charWidth = stringWidth(' ', '16px Roboto Mono, monospace');
|
||||
window.messageIndent = 6 * charWidth;
|
||||
return setCharWidth(charWidth);
|
||||
}
|
||||
@ -38,9 +38,6 @@ class Chat extends PureComponent {
|
||||
const { dispatch } = this.props;
|
||||
dispatch(updateCharWidth());
|
||||
setTimeout(() => dispatch(updateCharWidth()), 1000);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
updateSelected(this.props);
|
||||
}
|
||||
|
||||
|
12
client/src/js/util/scrollPosition.js
Normal file
12
client/src/js/util/scrollPosition.js
Normal file
@ -0,0 +1,12 @@
|
||||
const positions = {};
|
||||
|
||||
export function getScrollPos(key) {
|
||||
if (key in positions) {
|
||||
return positions[key];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
export function saveScrollPos(key, pos) {
|
||||
positions[key] = pos;
|
||||
}
|
Loading…
Reference in New Issue
Block a user