ChatWindow: fix unread and gaps in scrollback

This commit is contained in:
Liam Fitzgerald 2021-03-12 11:26:02 +10:00
parent f20da46745
commit 0fe7a2c985
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
2 changed files with 18 additions and 26 deletions

View File

@ -60,9 +60,6 @@ class ChatWindow extends Component<
private virtualList: VirtualScroller | null; private virtualList: VirtualScroller | null;
private unreadMarkerRef: React.RefObject<HTMLDivElement>; private unreadMarkerRef: React.RefObject<HTMLDivElement>;
private prevSize = 0; private prevSize = 0;
private loadedNewest = false;
private loadedOldest = false;
private fetchPending = false;
INITIALIZATION_MAX_TIME = 100; INITIALIZATION_MAX_TIME = 100;
@ -126,8 +123,11 @@ class ChatWindow extends Component<
componentDidUpdate(prevProps: ChatWindowProps, prevState) { componentDidUpdate(prevProps: ChatWindowProps, prevState) {
const { history, graph, unreadCount, station } = this.props; const { history, graph, unreadCount, station } = this.props;
if (graph.size !== prevProps.graph.size && this.fetchPending) { if (graph.size !== this.prevSize) {
this.fetchPending = false; this.prevSize = graph.size;
if(!this.state.unreadIndex && this.virtualList?.loaded.top) {
this.calculateUnreadIndex();
}
} }
if (unreadCount > prevProps.unreadCount) { if (unreadCount > prevProps.unreadCount) {
@ -171,30 +171,28 @@ class ChatWindow extends Component<
fetchMessages = async (newer: boolean): Promise<boolean> => { fetchMessages = async (newer: boolean): Promise<boolean> => {
const { api, station, graph } = this.props; const { api, station, graph } = this.props;
if(this.fetchPending) { const pageSize = 100;
return false;
}
this.fetchPending = true;
const [, , ship, name] = station.split('/'); const [, , ship, name] = station.split('/');
const currSize = graph.size; const expectedSize = graph.size + pageSize;
if (newer) { if (newer) {
const [index] = graph.peekLargest()!; const [index] = graph.peekLargest()!;
await api.graph.getYoungerSiblings( await api.graph.getYoungerSiblings(
ship, ship,
name, name,
100, pageSize,
`/${index.toString()}` `/${index.toString()}`
); );
return expectedSize !== graph.size;
} else { } else {
const [index] = graph.peekSmallest()!; const [index] = graph.peekSmallest()!;
await api.graph.getOlderSiblings(ship, name, 100, `/${index.toString()}`); await api.graph.getOlderSiblings(ship, name, pageSize, `/${index.toString()}`);
this.calculateUnreadIndex(); const done = expectedSize !== graph.size;
if(done) {
this.calculateUnreadIndex();
}
return done;
} }
this.fetchPending = false;
return currSize === graph.size;
} }
onScroll = ({ scrollTop, scrollHeight, windowHeight }) => { onScroll = ({ scrollTop, scrollHeight, windowHeight }) => {
@ -289,8 +287,7 @@ class ChatWindow extends Component<
api, api,
associations associations
}; };
const unreadIndex = graph.keys()[this.props.unreadCount]; const unreadMsg = graph.get(this.state.unreadIndex);
const unreadMsg = unreadIndex && graph.get(unreadIndex);
return ( return (
<Col height='100%' overflow='hidden' position='relative'> <Col height='100%' overflow='hidden' position='relative'>

View File

@ -153,14 +153,10 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
} }
componentDidMount() { componentDidMount() {
if(this.props.size < 100) {
this.loaded.top = true;
this.loaded.bottom = true;
}
this.updateVisible(0); this.updateVisible(0);
this.resetScroll(); this.resetScroll();
this.loadRows(false); this.loadRows(false);
this.loadRows(true);
} }
// manipulate scrollbar manually, to dodge change detection // manipulate scrollbar manually, to dodge change detection
@ -485,7 +481,6 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
const transform = isTop ? 'scale3d(1, 1, 1)' : 'scale3d(1, -1, 1)'; const transform = isTop ? 'scale3d(1, 1, 1)' : 'scale3d(1, -1, 1)';
const atStart = (this.props.data.peekLargest()?.[0] ?? bigInt.zero).eq(visibleItems.peekLargest()?.[0] || bigInt.zero); const atStart = (this.props.data.peekLargest()?.[0] ?? bigInt.zero).eq(visibleItems.peekLargest()?.[0] || bigInt.zero);
const atEnd = this.loaded.top; const atEnd = this.loaded.top;