Fix saving scroll once again
Fix detecting pinned messages position
This commit is contained in:
parent
fc5a653759
commit
045199cccc
@ -80,6 +80,10 @@ class BubbleGroup {
|
||||
return this.firstItem.timestamp;
|
||||
}
|
||||
|
||||
get firstMid() {
|
||||
return this.firstItem.mid;
|
||||
}
|
||||
|
||||
get firstItem() {
|
||||
return this.items[this.items.length - 1];
|
||||
}
|
||||
@ -145,7 +149,7 @@ class BubbleGroup {
|
||||
}
|
||||
|
||||
if(items.length === 1) {
|
||||
insertInDescendSortedArray(this.groups.groups, this, 'firstTimestamp');
|
||||
insertInDescendSortedArray(this.groups.groups, this, 'firstMid');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -944,7 +944,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
private createScrollSaver(reverse = true) {
|
||||
const scrollSaver = new ScrollSaver(this.scrollable, '.bubbles-group .bubble', reverse);
|
||||
const scrollSaver = new ScrollSaver(this.scrollable, '.bubble:not(.is-date)', reverse);
|
||||
return scrollSaver;
|
||||
}
|
||||
|
||||
@ -2745,6 +2745,10 @@ export default class ChatBubbles {
|
||||
this.attachPlaceholderOnRender();
|
||||
}
|
||||
|
||||
if(!isTarget && this.chat.type === 'chat') {
|
||||
this.chat.topbar.pinnedMessage.setCorrectIndex(0);
|
||||
}
|
||||
|
||||
this.container.classList.toggle('has-groups', !!Object.keys(this.dateMessages).length);
|
||||
|
||||
log.warn('mounted chat', this.chatInner === chatInner, this.chatInner.parentElement, performance.now() - perf);
|
||||
|
@ -422,7 +422,7 @@ export default class Chat extends EventListenerBase<{
|
||||
this.selection.cleanup(); // TODO: REFACTOR !!!!!!
|
||||
}
|
||||
|
||||
public async setPeer(peerId: PeerId, lastMsgId?: number, startParam?: string) {
|
||||
public setPeer(peerId: PeerId, lastMsgId?: number, startParam?: string) {
|
||||
if(!peerId) {
|
||||
this.inited = undefined;
|
||||
} else if(!this.inited) {
|
||||
|
@ -1386,6 +1386,7 @@ export default class ChatInput {
|
||||
}
|
||||
|
||||
private filterAttachMenuButtons() {
|
||||
if(!this.attachMenuButtons) return;
|
||||
const {peerId, threadId} = this.chat;
|
||||
return filterAsync(this.attachMenuButtons, (button) => {
|
||||
return button.verify(peerId, threadId);
|
||||
@ -1406,7 +1407,7 @@ export default class ChatInput {
|
||||
|
||||
this.updateMessageInputPlaceholder(placeholderKey);
|
||||
|
||||
this.attachMenuButtons.forEach((button) => {
|
||||
this.attachMenuButtons && this.attachMenuButtons.forEach((button) => {
|
||||
button.element.classList.toggle('hide', !visible.includes(button));
|
||||
});
|
||||
|
||||
@ -1421,8 +1422,11 @@ export default class ChatInput {
|
||||
}
|
||||
}
|
||||
|
||||
attachMenu.toggleAttribute('disabled', !visible.length);
|
||||
attachMenu.classList.toggle('btn-disabled', !visible.length);
|
||||
if(attachMenu) {
|
||||
attachMenu.toggleAttribute('disabled', !visible.length);
|
||||
attachMenu.classList.toggle('btn-disabled', !visible.length);
|
||||
}
|
||||
|
||||
this.updateSendBtn();
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManager";
|
||||
import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
|
||||
import type ChatTopbar from "./topbar";
|
||||
import PopupPinMessage from "../popups/unpinMessage";
|
||||
import PinnedContainer from "./pinnedContainer";
|
||||
@ -24,6 +22,7 @@ import debounce from "../../helpers/schedulers/debounce";
|
||||
import throttle from "../../helpers/schedulers/throttle";
|
||||
import { AppManagers } from "../../lib/appManagers/managers";
|
||||
import { Message } from "../../layer";
|
||||
import { logger } from "../../lib/logger";
|
||||
|
||||
class AnimatedSuper {
|
||||
static DURATION = 200;
|
||||
@ -253,14 +252,19 @@ export default class ChatPinnedMessage {
|
||||
|
||||
private setPinnedMessage: () => void;
|
||||
|
||||
private isStatic = false;
|
||||
private isStatic: boolean;
|
||||
|
||||
private debug = false;
|
||||
private debug: boolean;
|
||||
|
||||
public setCorrectIndexThrottled: (lastScrollDirection?: number) => void;
|
||||
|
||||
private log: ReturnType<typeof logger>;
|
||||
|
||||
constructor(private topbar: ChatTopbar, private chat: Chat, private managers: AppManagers) {
|
||||
this.listenerSetter = new ListenerSetter();
|
||||
this.log = logger('PM');
|
||||
this.debug = true;
|
||||
this.isStatic = false;
|
||||
|
||||
const dAC = new ReplyContainer('pinned-message');
|
||||
this.pinnedMessageContainer = new PinnedContainer({
|
||||
@ -361,14 +365,14 @@ export default class ChatPinnedMessage {
|
||||
|
||||
//const perf = performance.now();
|
||||
let el = this.chat.bubbles.getBubbleByPoint('bottom');
|
||||
//this.chat.log('[PM]: setCorrectIndex: get last element perf:', performance.now() - perf, el);
|
||||
//this.log('setCorrectIndex: get last element perf:', performance.now() - perf, el);
|
||||
if(!el) return;
|
||||
|
||||
//return;
|
||||
|
||||
const mid = el.dataset.mid;
|
||||
if(el && mid !== undefined) {
|
||||
//this.chat.log('[PM]: setCorrectIndex will test mid:', mid);
|
||||
//this.log('setCorrectIndex will test mid:', mid);
|
||||
this.testMid(+mid, lastScrollDirection);
|
||||
}
|
||||
}
|
||||
@ -379,7 +383,7 @@ export default class ChatPinnedMessage {
|
||||
//if(lastScrollDirection !== undefined) return;
|
||||
if(this.hidden) return;
|
||||
|
||||
//this.chat.log('[PM]: testMid', mid);
|
||||
//this.log('testMid', mid);
|
||||
|
||||
let currentIndex: number = this.mids.findIndex((_mid) => _mid <= mid);
|
||||
if(currentIndex !== -1 && !this.isNeededMore(currentIndex)) {
|
||||
@ -401,7 +405,7 @@ export default class ChatPinnedMessage {
|
||||
currentIndex = 0;
|
||||
} */
|
||||
|
||||
//this.chat.log('[PM]: testMid: pinned currentIndex', currentIndex, mid);
|
||||
//this.log('testMid: pinned currentIndex', currentIndex, mid);
|
||||
|
||||
const changed = this.pinnedIndex !== currentIndex;
|
||||
if(changed) {
|
||||
@ -431,6 +435,9 @@ export default class ChatPinnedMessage {
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
const log = this.debug ? this.log.bindPrefix('getCurrentIndex') : undefined;
|
||||
log && log('start', mid, correctAfter);
|
||||
|
||||
let gotRest = false;
|
||||
const promises = [
|
||||
this.managers.appMessagesManager.getSearch({
|
||||
@ -484,9 +491,9 @@ export default class ChatPinnedMessage {
|
||||
this.loadedTop = (this.offsetIndex + this.mids.length) === this.count;
|
||||
this.loadedBottom = !this.offsetIndex;
|
||||
|
||||
this.debug && this.chat.log('[PM]: getCurrentIndex result:', mid, result, backLimited, this.offsetIndex, this.loadedTop, this.loadedBottom);
|
||||
log && log('result', mid, result, backLimited, this.offsetIndex, this.loadedTop, this.loadedBottom);
|
||||
} catch(err) {
|
||||
this.chat.log.error('[PM]: getCurrentIndex error', err);
|
||||
this.log.error('getCurrentIndex error', err);
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
@ -528,7 +535,7 @@ export default class ChatPinnedMessage {
|
||||
public async handleFollowingPinnedMessage() {
|
||||
this.locked = true;
|
||||
|
||||
this.debug && this.chat.log('[PM]: handleFollowingPinnedMessage');
|
||||
this.debug && this.log('handleFollowingPinnedMessage');
|
||||
try {
|
||||
this.setScrollDownListener();
|
||||
|
||||
@ -544,16 +551,16 @@ export default class ChatPinnedMessage {
|
||||
await this.getCurrentIndexPromise;
|
||||
}
|
||||
|
||||
this.debug && this.chat.log('[PM]: handleFollowingPinnedMessage: unlock');
|
||||
this.debug && this.log('handleFollowingPinnedMessage: unlock');
|
||||
this.locked = false;
|
||||
|
||||
/* // подождём, пока скролл остановится
|
||||
setTimeout(() => {
|
||||
this.chat.log('[PM]: handleFollowingPinnedMessage: unlock');
|
||||
this.log('handleFollowingPinnedMessage: unlock');
|
||||
this.locked = false;
|
||||
}, 50); */
|
||||
} catch(err) {
|
||||
this.chat.log.error('[PM]: handleFollowingPinnedMessage error:', err);
|
||||
this.log.error('handleFollowingPinnedMessage error:', err);
|
||||
|
||||
this.locked = false;
|
||||
this.waitForScrollBottom = false;
|
||||
@ -603,7 +610,7 @@ export default class ChatPinnedMessage {
|
||||
|
||||
const fromTop = pinnedIndex > this.wasPinnedIndex;
|
||||
|
||||
this.debug && this.chat.log('[PM]: setPinnedMessage: fromTop', fromTop, pinnedIndex, this.wasPinnedIndex);
|
||||
this.debug && this.log('setPinnedMessage: fromTop', fromTop, pinnedIndex, this.wasPinnedIndex);
|
||||
|
||||
const writeTo = this.animatedSubtitle.getRow(pinnedIndex);
|
||||
const writeMediaTo = this.animatedMedia.getRow(pinnedIndex);
|
||||
|
@ -697,13 +697,14 @@ export default class ChatTopbar {
|
||||
newAvatar = this.constructAvatar();
|
||||
}
|
||||
|
||||
const [isBroadcast, isAnyChat, chat, _, setTitleCallback, setStatusCallback] = await Promise.all([
|
||||
const [isBroadcast, isAnyChat, chat, _, setTitleCallback, setStatusCallback, state] = await Promise.all([
|
||||
this.managers.appPeersManager.isBroadcast(peerId),
|
||||
this.managers.appPeersManager.isAnyChat(peerId),
|
||||
peerId.isAnyChat() ? this.managers.appChatsManager.getChat(peerId.toChatId()) : undefined,
|
||||
newAvatar ? newAvatar.updateWithOptions({peerId}) : undefined,
|
||||
this.setTitleManual(),
|
||||
this.setPeerStatusManual(true),
|
||||
apiManagerProxy.getState()
|
||||
]);
|
||||
|
||||
return () => {
|
||||
@ -726,7 +727,6 @@ export default class ChatTopbar {
|
||||
|
||||
this.verifyButtons();
|
||||
|
||||
const middleware = this.chat.bubbles.getMiddleware();
|
||||
if(this.pinnedMessage) { // * replace with new one
|
||||
if(this.chat.type === 'chat') {
|
||||
if(this.chat.wasAlreadyUsed) { // * change
|
||||
@ -737,15 +737,7 @@ export default class ChatTopbar {
|
||||
this.pinnedMessage = newPinnedMessage;
|
||||
}
|
||||
|
||||
apiManagerProxy.getState().then((state) => {
|
||||
if(!middleware()) return;
|
||||
|
||||
this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[peerId];
|
||||
|
||||
if(!isTarget) {
|
||||
this.pinnedMessage.setCorrectIndex(0);
|
||||
}
|
||||
});
|
||||
this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[peerId];
|
||||
} else if(this.chat.type === 'discussion') {
|
||||
this.pinnedMessage.pinnedMid = this.chat.threadId;
|
||||
this.pinnedMessage.count = 1;
|
||||
@ -756,9 +748,7 @@ export default class ChatTopbar {
|
||||
|
||||
setTitleCallback();
|
||||
setStatusCallback && setStatusCallback();
|
||||
fastRaf(() => {
|
||||
this.setMutedState();
|
||||
});
|
||||
this.setMutedState();
|
||||
|
||||
this.container.classList.remove('hide');
|
||||
};
|
||||
|
@ -12,7 +12,7 @@ import reflowScrollableElement from "./dom/reflowScrollableElement";
|
||||
|
||||
export default class ScrollSaver {
|
||||
private scrollHeight: number;
|
||||
// private scrollHeightMinusTop: number;
|
||||
private scrollHeightMinusTop: number;
|
||||
private scrollTop: number;
|
||||
private clientHeight: number;
|
||||
private anchor: HTMLElement;
|
||||
@ -60,6 +60,14 @@ export default class ScrollSaver {
|
||||
}
|
||||
}
|
||||
|
||||
if(!rect) {
|
||||
const bubble = bubbles[0];
|
||||
if(bubble) {
|
||||
rect = bubble.getBoundingClientRect();
|
||||
anchor = bubble;
|
||||
}
|
||||
}
|
||||
|
||||
return {rect, anchor};
|
||||
}
|
||||
|
||||
@ -83,7 +91,7 @@ export default class ScrollSaver {
|
||||
this.scrollHeight = scrollHeight;
|
||||
this.scrollTop = scrollTop;
|
||||
this.clientHeight = clientHeight;
|
||||
// this.scrollHeightMinusTop = this.reverse ? scrollHeight - scrollTop : scrollTop;
|
||||
this.scrollHeightMinusTop = this.reverse ? scrollHeight - scrollTop : scrollTop;
|
||||
|
||||
//this.chatInner.style.paddingTop = padding + 'px';
|
||||
/* if(reverse) {
|
||||
@ -113,13 +121,13 @@ export default class ScrollSaver {
|
||||
const {scrollTop, scrollHeight} = this.scrollable;
|
||||
this.scrollHeight = scrollHeight;
|
||||
|
||||
// if(!this.anchor.parentElement) { // fallback to old method if element has disappeared (e.g. edited)
|
||||
// this._restore(useReflow);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if(!this.anchor.parentElement) { // try to find new anchor
|
||||
if(!this.anchor?.parentElement) { // try to find new anchor
|
||||
this.findAndSetAnchor();
|
||||
|
||||
if(!this.anchor) { // fallback to old method if smth is really strange
|
||||
this._restore(useReflow);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const rect = this.rect;
|
||||
@ -129,47 +137,47 @@ export default class ScrollSaver {
|
||||
// console.warn('scroll restore', rect, diff, newRect);
|
||||
}
|
||||
|
||||
// public _restore(useReflow?: boolean) {
|
||||
// const {scrollHeightMinusTop: previousScrollHeightMinusTop, scrollable} = this;
|
||||
// // if(previousScrollHeightMinusTop === undefined) {
|
||||
// // throw new Error('scroll was not saved');
|
||||
// // }
|
||||
public _restore(useReflow?: boolean) {
|
||||
const {scrollHeightMinusTop: previousScrollHeightMinusTop, scrollable} = this;
|
||||
// if(previousScrollHeightMinusTop === undefined) {
|
||||
// throw new Error('scroll was not saved');
|
||||
// }
|
||||
|
||||
// // const scrollHeight = container.scrollHeight;
|
||||
// const scrollHeight = this.scrollHeight;
|
||||
// // if(scrollHeight === this.scrollHeight) {
|
||||
// // return;
|
||||
// // }
|
||||
// const scrollHeight = container.scrollHeight;
|
||||
const scrollHeight = this.scrollHeight;
|
||||
// if(scrollHeight === this.scrollHeight) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // this.scrollHeight = scrollHeight;
|
||||
// this.scrollHeight = scrollHeight;
|
||||
|
||||
// /* const scrollHeight = container.scrollHeight;
|
||||
// const addedHeight = scrollHeight - previousScrollHeight;
|
||||
/* const scrollHeight = container.scrollHeight;
|
||||
const addedHeight = scrollHeight - previousScrollHeight;
|
||||
|
||||
// this.chatInner.style.paddingTop = (10000 - addedHeight) + 'px'; */
|
||||
// /* const scrollHeight = scrollHeight;
|
||||
// const addedHeight = scrollHeight - previousScrollHeight;
|
||||
this.chatInner.style.paddingTop = (10000 - addedHeight) + 'px'; */
|
||||
/* const scrollHeight = scrollHeight;
|
||||
const addedHeight = scrollHeight - previousScrollHeight;
|
||||
|
||||
// this.chatInner.style.paddingTop = (padding - addedHeight) + 'px';
|
||||
this.chatInner.style.paddingTop = (padding - addedHeight) + 'px';
|
||||
|
||||
// //const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
// const newScrollTop = reverse ? scrollHeight - addedHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
// this.log('performHistoryResult: will set scrollTop',
|
||||
// previousScrollHeightMinusTop, scrollHeight,
|
||||
// newScrollTop, container.container.clientHeight); */
|
||||
// //const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
// const newScrollTop = this.reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
//const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
const newScrollTop = reverse ? scrollHeight - addedHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
this.log('performHistoryResult: will set scrollTop',
|
||||
previousScrollHeightMinusTop, scrollHeight,
|
||||
newScrollTop, container.container.clientHeight); */
|
||||
//const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
const newScrollTop = this.reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;
|
||||
|
||||
// /* if(DEBUG) {
|
||||
// this.log('performHistoryResult: will set up scrollTop:', newScrollTop, this.isHeavyAnimationInProgress);
|
||||
// } */
|
||||
/* if(DEBUG) {
|
||||
this.log('performHistoryResult: will set up scrollTop:', newScrollTop, this.isHeavyAnimationInProgress);
|
||||
} */
|
||||
|
||||
// this.setScrollTop(newScrollTop, useReflow);
|
||||
this.setScrollTop(newScrollTop, useReflow);
|
||||
|
||||
// /* if(DEBUG) {
|
||||
// this.log('performHistoryResult: have set up scrollTop:', newScrollTop, container.scrollTop, container.scrollHeight, this.isHeavyAnimationInProgress);
|
||||
// } */
|
||||
// }
|
||||
/* if(DEBUG) {
|
||||
this.log('performHistoryResult: have set up scrollTop:', newScrollTop, container.scrollTop, container.scrollHeight, this.isHeavyAnimationInProgress);
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.ScrollSaver = ScrollSaver);
|
||||
|
Loading…
x
Reference in New Issue
Block a user