1
0
mirror of https://github.com/matrix-org/matrix-react-sdk.git synced 2025-12-11 17:57:29 +03:00

Fix timeline jumping issues related to bubble layout (#7529)

This commit is contained in:
Michael Telatynski
2022-01-18 09:31:21 +00:00
committed by GitHub
parent 8ced6e6117
commit 4b5ca1d7a9
4 changed files with 57 additions and 34 deletions

View File

@@ -89,7 +89,7 @@ interface IProps {
* The promise should resolve to true if there is more data to be
* retrieved in this direction (in which case onFillRequest may be
* called again immediately), or false if there is no more data in this
* directon (at this time) - which will stop the pagination cycle until
* direction (at this time) - which will stop the pagination cycle until
* the user scrolls again.
*/
onFillRequest?(backwards: boolean): Promise<boolean>;
@@ -683,7 +683,7 @@ export default class ScrollPanel extends React.Component<IProps> {
return;
}
const scrollToken = node.dataset.scrollTokens.split(',')[0];
debuglog("saving anchored scroll state to message", node && node.innerText, scrollToken);
debuglog("saving anchored scroll state to message", node.innerText, scrollToken);
const bottomOffset = this.topFromBottom(node);
this.scrollState = {
stuckAtBottom: false,
@@ -791,17 +791,16 @@ export default class ScrollPanel extends React.Component<IProps> {
const scrollState = this.scrollState;
const trackedNode = scrollState.trackedNode;
if (!trackedNode || !trackedNode.parentElement) {
let node;
if (!trackedNode?.parentElement) {
let node: HTMLElement;
const messages = this.itemlist.current.children;
const scrollToken = scrollState.trackedScrollToken;
for (let i = messages.length-1; i >= 0; --i) {
for (let i = messages.length - 1; i >= 0; --i) {
const m = messages[i] as HTMLElement;
// 'data-scroll-tokens' is a DOMString of comma-separated scroll tokens
// There might only be one scroll token
if (m.dataset.scrollTokens &&
m.dataset.scrollTokens.split(',').indexOf(scrollToken) !== -1) {
if (m.dataset.scrollTokens?.split(',').includes(scrollToken)) {
node = m;
break;
}

View File

@@ -63,7 +63,7 @@ const DEBUG = false;
let debuglog = function(...s: any[]) {};
if (DEBUG) {
// using bind means that we get to keep useful line numbers in the console
debuglog = logger.log.bind(console);
debuglog = logger.log.bind(console, "TimelinePanel debuglog:");
}
interface IProps {
@@ -240,7 +240,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
constructor(props, context) {
super(props, context);
debuglog("TimelinePanel: mounting");
debuglog("mounting");
// XXX: we could track RM per TimelineSet rather than per Room.
// but for now we just do it per room for simplicity.
@@ -369,7 +369,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
private onMessageListUnfillRequest = (backwards: boolean, scrollToken: string): void => {
// If backwards, unpaginate from the back (i.e. the start of the timeline)
const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
debuglog("TimelinePanel: unpaginating events in direction", dir);
debuglog("unpaginating events in direction", dir);
// All tiles are inserted by MessagePanel to have a scrollToken === eventId, and
// this particular event should be the first or last to be unpaginated.
@@ -384,7 +384,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
const count = backwards ? marker + 1 : this.state.events.length - marker;
if (count > 0) {
debuglog("TimelinePanel: Unpaginating", count, "in direction", dir);
debuglog("Unpaginating", count, "in direction", dir);
this.timelineWindow.unpaginate(count, backwards);
const { events, liveEvents, firstVisibleEventIndex } = this.getEvents();
@@ -425,28 +425,28 @@ class TimelinePanel extends React.Component<IProps, IState> {
const paginatingKey = backwards ? 'backPaginating' : 'forwardPaginating';
if (!this.state[canPaginateKey]) {
debuglog("TimelinePanel: have given up", dir, "paginating this timeline");
debuglog("have given up", dir, "paginating this timeline");
return Promise.resolve(false);
}
if (!this.timelineWindow.canPaginate(dir)) {
debuglog("TimelinePanel: can't", dir, "paginate any further");
debuglog("can't", dir, "paginate any further");
this.setState<null>({ [canPaginateKey]: false });
return Promise.resolve(false);
}
if (backwards && this.state.firstVisibleEventIndex !== 0) {
debuglog("TimelinePanel: won't", dir, "paginate past first visible event");
debuglog("won't", dir, "paginate past first visible event");
return Promise.resolve(false);
}
debuglog("TimelinePanel: Initiating paginate; backwards:"+backwards);
debuglog("Initiating paginate; backwards:"+backwards);
this.setState<null>({ [paginatingKey]: true });
return this.onPaginationRequest(this.timelineWindow, dir, PAGINATE_SIZE).then((r) => {
if (this.unmounted) { return; }
debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r);
debuglog("paginate complete backwards:"+backwards+"; success:"+r);
const { events, liveEvents, firstVisibleEventIndex } = this.getEvents();
const newState: Partial<IState> = {
@@ -463,7 +463,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
const canPaginateOtherWayKey = backwards ? 'canForwardPaginate' : 'canBackPaginate';
if (!this.state[canPaginateOtherWayKey] &&
this.timelineWindow.canPaginate(otherDirection)) {
debuglog('TimelinePanel: can now', otherDirection, 'paginate again');
debuglog('can now', otherDirection, 'paginate again');
newState[canPaginateOtherWayKey] = true;
}
@@ -833,7 +833,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
const roomId = this.props.timelineSet.room.roomId;
const hiddenRR = SettingsStore.getValue("feature_hidden_read_receipts", roomId);
debuglog('TimelinePanel: Sending Read Markers for ',
debuglog('Sending Read Markers for ',
this.props.timelineSet.room.roomId,
'rm', this.state.readMarkerEventId,
lastReadEvent ? 'rr ' + lastReadEvent.getId() : '',