fix very long processing time in scroll handler

This commit is contained in:
or-else
2023-05-11 15:43:31 -07:00
parent f969c04c47
commit fd08d19939
9 changed files with 28 additions and 10 deletions
+10 -2
View File
@@ -185,14 +185,20 @@ class MessagesView extends React.Component {
getVisibleMessageRange(holderRect) { getVisibleMessageRange(holderRect) {
let min = Number.MAX_SAFE_INTEGER, max = -1; let min = Number.MAX_SAFE_INTEGER, max = -1;
this.chatMessageRefs.forEach((ref, seq) => { let visibilityStatus = false;
this.chatMessageRefs.every((ref, seq) => {
if (ref.current) { if (ref.current) {
const { top, bottom, height } = ref.current.getBoundingClientRect(); const { top, bottom, height } = ref.current.getBoundingClientRect();
const visible = top <= holderRect.top ? holderRect.top - top <= height : bottom - holderRect.bottom <= height; const visible = top <= holderRect.top ? holderRect.top - top <= height : bottom - holderRect.bottom <= height;
if (visible) { if (visible) {
visibilityStatus = true;
min = Math.min(min, seq); min = Math.min(min, seq);
max = Math.max(max, seq); max = Math.max(max, seq);
} else if (visibilityStatus) {
// The remaining elements are no longer visible, no need to iterate them.
return false;
} }
return true;
} }
}); });
return max >= min ? {min: min, max: max} : {min: 0, max: 0}; return max >= min ? {min: min, max: max} : {min: 0, max: 0};
@@ -577,13 +583,14 @@ class MessagesView extends React.Component {
showGoToLastButton: (pos > SHOW_GO_TO_LAST_DIST) && (pos < this.state.scrollPosition), showGoToLastButton: (pos > SHOW_GO_TO_LAST_DIST) && (pos < this.state.scrollPosition),
}); });
if (this.state.fetchingMessages) { if (this.state.fetchingMessages || this.processingScrollEvent) {
return; return;
} }
if (event.target.scrollTop <= FETCH_PAGE_TRIGGER) { if (event.target.scrollTop <= FETCH_PAGE_TRIGGER) {
const topic = this.props.tinode.getTopic(this.state.topic); const topic = this.props.tinode.getTopic(this.state.topic);
if (topic && topic.isSubscribed()) { if (topic && topic.isSubscribed()) {
this.processingScrollEvent = true;
const {min, max} = this.getVisibleMessageRange(event.target.getBoundingClientRect()); const {min, max} = this.getVisibleMessageRange(event.target.getBoundingClientRect());
const gaps = topic.msgHasMoreMessages(min, max, false); const gaps = topic.msgHasMoreMessages(min, max, false);
if (gaps.length > 0) { if (gaps.length > 0) {
@@ -595,6 +602,7 @@ class MessagesView extends React.Component {
} }
} }
} }
this.processingScrollEvent = false;
} }
/* Mount drag and drop events */ /* Mount drag and drop events */
+9 -2
View File
@@ -5250,7 +5250,8 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
getVisibleMessageRange(holderRect) { getVisibleMessageRange(holderRect) {
let min = Number.MAX_SAFE_INTEGER, let min = Number.MAX_SAFE_INTEGER,
max = -1; max = -1;
this.chatMessageRefs.forEach((ref, seq) => { let visibilityStatus = false;
this.chatMessageRefs.every((ref, seq) => {
if (ref.current) { if (ref.current) {
const { const {
top, top,
@@ -5259,9 +5260,13 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
} = ref.current.getBoundingClientRect(); } = ref.current.getBoundingClientRect();
const visible = top <= holderRect.top ? holderRect.top - top <= height : bottom - holderRect.bottom <= height; const visible = top <= holderRect.top ? holderRect.top - top <= height : bottom - holderRect.bottom <= height;
if (visible) { if (visible) {
visibilityStatus = true;
min = Math.min(min, seq); min = Math.min(min, seq);
max = Math.max(max, seq); max = Math.max(max, seq);
} else if (visibilityStatus) {
return false;
} }
return true;
} }
}); });
return max >= min ? { return max >= min ? {
@@ -5588,12 +5593,13 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
scrollPosition: pos, scrollPosition: pos,
showGoToLastButton: pos > SHOW_GO_TO_LAST_DIST && pos < this.state.scrollPosition showGoToLastButton: pos > SHOW_GO_TO_LAST_DIST && pos < this.state.scrollPosition
}); });
if (this.state.fetchingMessages) { if (this.state.fetchingMessages || this.processingScrollEvent) {
return; return;
} }
if (event.target.scrollTop <= FETCH_PAGE_TRIGGER) { if (event.target.scrollTop <= FETCH_PAGE_TRIGGER) {
const topic = this.props.tinode.getTopic(this.state.topic); const topic = this.props.tinode.getTopic(this.state.topic);
if (topic && topic.isSubscribed()) { if (topic && topic.isSubscribed()) {
this.processingScrollEvent = true;
const { const {
min, min,
max max
@@ -5610,6 +5616,7 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
} }
} }
} }
this.processingScrollEvent = false;
} }
mountDnDEvents(dnd) { mountDnDEvents(dnd) {
if (dnd) { if (dnd) {
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3
View File
@@ -4461,6 +4461,9 @@ class Topic {
} }
msgHasMoreMessages(min, max, newer) { msgHasMoreMessages(min, max, newer) {
const gaps = []; const gaps = [];
if (min >= max) {
return gaps;
}
let maxSeq = 0; let maxSeq = 0;
let gap; let gap;
this._messages.forEach((msg, prev) => { this._messages.forEach((msg, prev) => {
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long