Browse Source

Batch reactions update

master
Eduard Kuzmenko 3 years ago
parent
commit
dfa112d455
  1. 26
      src/components/chat/bubbles.ts
  2. 24
      src/helpers/scrollSaver.ts

26
src/components/chat/bubbles.ts

@ -207,6 +207,8 @@ export default class ChatBubbles {
private hoverBubble: HTMLElement; private hoverBubble: HTMLElement;
private hoverReaction: HTMLElement; private hoverReaction: HTMLElement;
private onUpdateScrollSaver: ScrollSaver;
// private reactions: Map<number, ReactionsElement>; // private reactions: Map<number, ReactionsElement>;
constructor( constructor(
@ -428,10 +430,8 @@ export default class ChatBubbles {
const updatePosition = this.chat.type === 'scheduled'; const updatePosition = this.chat.type === 'scheduled';
const scrollSaver = new ScrollSaver(this.scrollable, true); this.saveOnUpdateScroll();
scrollSaver.save();
this.safeRenderMessage(mounted.message, true, false, mounted.bubble, updatePosition); this.safeRenderMessage(mounted.message, true, false, mounted.bubble, updatePosition);
scrollSaver.restore();
if(updatePosition) { if(updatePosition) {
(this.messagesQueuePromise || Promise.resolve()).then(() => { (this.messagesQueuePromise || Promise.resolve()).then(() => {
@ -465,13 +465,12 @@ export default class ChatBubbles {
return; return;
} }
const scrollSaver = new ScrollSaver(this.scrollable, true);
const bubble = this.getBubbleByMessage(message); const bubble = this.getBubbleByMessage(message);
if(!bubble) { if(!bubble) {
return; return;
} }
scrollSaver.save(); this.saveOnUpdateScroll();
const key = message.peerId + '_' + message.mid; const key = message.peerId + '_' + message.mid;
const set = REACTIONS_ELEMENTS.get(key); const set = REACTIONS_ELEMENTS.get(key);
@ -482,8 +481,6 @@ export default class ChatBubbles {
} else { } else {
rootScope.dispatchEvent('missed_reactions_element', {message, changedResults}); rootScope.dispatchEvent('missed_reactions_element', {message, changedResults});
} }
scrollSaver.restore();
}); });
} }
@ -775,6 +772,7 @@ export default class ChatBubbles {
let different = false; let different = false;
postViewsElements.forEach(postViews => { postViewsElements.forEach(postViews => {
if(different || postViews.innerHTML !== str) { if(different || postViews.innerHTML !== str) {
this.saveOnUpdateScroll();
different = true; different = true;
postViews.innerHTML = str; postViews.innerHTML = str;
} }
@ -922,6 +920,18 @@ export default class ChatBubbles {
} }
} }
private saveOnUpdateScroll() {
if(!this.onUpdateScrollSaver) {
this.onUpdateScrollSaver = new ScrollSaver(this.scrollable, true);
setTimeout(() => {
this.onUpdateScrollSaver.restore();
this.onUpdateScrollSaver = undefined;
}, 0);
this.onUpdateScrollSaver.save();
}
}
private onBubblesMouseMove = (e: MouseEvent) => { private onBubblesMouseMove = (e: MouseEvent) => {
const content = findUpClassName(e.target, 'bubble-content'); const content = findUpClassName(e.target, 'bubble-content');
if(content && !this.chat.selection.isSelecting) { if(content && !this.chat.selection.isSelecting) {
@ -3904,7 +3914,7 @@ export default class ChatBubbles {
} }
if(scrollSaver) { if(scrollSaver) {
scrollSaver.restore(); scrollSaver.restore(history.length === 1 && !reverse ? false : true);
} }
return true; return true;

24
src/helpers/scrollSaver.ts

@ -9,6 +9,7 @@ import { IS_SAFARI } from "../environment/userAgent";
import reflowScrollableElement from "./dom/reflowScrollableElement"; import reflowScrollableElement from "./dom/reflowScrollableElement";
export default class ScrollSaver { export default class ScrollSaver {
private previousScrollHeight: number;
private previousScrollHeightMinusTop: number/* , previousScrollHeight: number */; private previousScrollHeightMinusTop: number/* , previousScrollHeight: number */;
/** /**
@ -16,7 +17,10 @@ export default class ScrollSaver {
* @param scrollable to reset scroll position and direction * @param scrollable to reset scroll position and direction
* @param reverse true means top * @param reverse true means top
*/ */
constructor(private scrollable: Scrollable, private reverse: boolean) { constructor(
private scrollable: Scrollable,
private reverse: boolean
) {
} }
@ -29,6 +33,7 @@ export default class ScrollSaver {
//previousScrollHeight = scrollHeight; //previousScrollHeight = scrollHeight;
//previousScrollHeight = scrollHeight + padding; //previousScrollHeight = scrollHeight + padding;
this.previousScrollHeight = scrollHeight;
this.previousScrollHeightMinusTop = this.reverse ? scrollHeight - scrollTop : scrollTop; this.previousScrollHeightMinusTop = this.reverse ? scrollHeight - scrollTop : scrollTop;
//this.chatInner.style.paddingTop = padding + 'px'; //this.chatInner.style.paddingTop = padding + 'px';
@ -43,14 +48,19 @@ export default class ScrollSaver {
} */ } */
} }
public restore() { public restore(useReflow?: boolean) {
const {container, previousScrollHeightMinusTop, scrollable} = this; const {container, previousScrollHeightMinusTop, scrollable} = this;
if(previousScrollHeightMinusTop !== undefined) { if(previousScrollHeightMinusTop !== undefined) {
const scrollHeight = container.scrollHeight;
if(scrollHeight === this.previousScrollHeight) {
return;
}
/* const scrollHeight = container.scrollHeight; /* const scrollHeight = container.scrollHeight;
const addedHeight = scrollHeight - previousScrollHeight; const addedHeight = scrollHeight - previousScrollHeight;
this.chatInner.style.paddingTop = (10000 - addedHeight) + 'px'; */ this.chatInner.style.paddingTop = (10000 - addedHeight) + 'px'; */
/* const scrollHeight = container.scrollHeight; /* const scrollHeight = scrollHeight;
const addedHeight = scrollHeight - previousScrollHeight; const addedHeight = scrollHeight - previousScrollHeight;
this.chatInner.style.paddingTop = (padding - addedHeight) + 'px'; this.chatInner.style.paddingTop = (padding - addedHeight) + 'px';
@ -58,10 +68,10 @@ export default class ScrollSaver {
//const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop; //const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
const newScrollTop = reverse ? scrollHeight - addedHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop; const newScrollTop = reverse ? scrollHeight - addedHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
this.log('performHistoryResult: will set scrollTop', this.log('performHistoryResult: will set scrollTop',
previousScrollHeightMinusTop, container.scrollHeight, previousScrollHeightMinusTop, scrollHeight,
newScrollTop, container.container.clientHeight); */ newScrollTop, container.container.clientHeight); */
//const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop; //const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
const newScrollTop = this.reverse ? container.scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop; const newScrollTop = this.reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
/* if(DEBUG) { /* if(DEBUG) {
this.log('performHistoryResult: will set up scrollTop:', newScrollTop, this.isHeavyAnimationInProgress); this.log('performHistoryResult: will set up scrollTop:', newScrollTop, this.isHeavyAnimationInProgress);
@ -70,13 +80,13 @@ export default class ScrollSaver {
// touchSupport for safari iOS // touchSupport for safari iOS
//isTouchSupported && isApple && (container.container.style.overflow = 'hidden'); //isTouchSupported && isApple && (container.container.style.overflow = 'hidden');
container.scrollTop = newScrollTop; container.scrollTop = newScrollTop;
//container.scrollTop = container.scrollHeight; //container.scrollTop = scrollHeight;
//isTouchSupported && isApple && (container.container.style.overflow = ''); //isTouchSupported && isApple && (container.container.style.overflow = '');
scrollable.lastScrollPosition = newScrollTop; scrollable.lastScrollPosition = newScrollTop;
// scrollable.lastScrollDirection = 0; // scrollable.lastScrollDirection = 0;
if(IS_SAFARI/* && !isAppleMobile */) { // * fix blinking and jumping if(IS_SAFARI && useReflow/* && !isAppleMobile */) { // * fix blinking and jumping
reflowScrollableElement(container); reflowScrollableElement(container);
} }

Loading…
Cancel
Save