Fix blinking avatars in chat, replies footer
This commit is contained in:
parent
56b1421137
commit
cc92edeb26
@ -4,7 +4,7 @@ import rootScope from "../lib/rootScope";
|
||||
import { attachClickEvent, cancelEvent } from "../helpers/dom";
|
||||
import AppMediaViewer, { AppMediaViewerAvatar } from "./appMediaViewer";
|
||||
import { Photo } from "../layer";
|
||||
import type { LazyLoadQueueIntersector } from "./lazyLoadQueue";
|
||||
//import type { LazyLoadQueueIntersector } from "./lazyLoadQueue";
|
||||
|
||||
rootScope.on('avatar_update', (e) => {
|
||||
let peerId = e;
|
||||
@ -20,8 +20,9 @@ export default class AvatarElement extends HTMLElement {
|
||||
private peerId: number;
|
||||
private isDialog = false;
|
||||
public peerTitle: string;
|
||||
public lazyLoadQueue: LazyLoadQueueIntersector;
|
||||
private addedToQueue = false;
|
||||
public loadPromises: Promise<any>[];
|
||||
//public lazyLoadQueue: LazyLoadQueueIntersector;
|
||||
//private addedToQueue = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -105,13 +106,13 @@ export default class AvatarElement extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
/* disconnectedCallback() {
|
||||
// браузер вызывает этот метод при удалении элемента из документа
|
||||
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
|
||||
if(this.lazyLoadQueue) {
|
||||
this.lazyLoadQueue.unobserve(this);
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
static get observedAttributes(): string[] {
|
||||
return ['peer', 'dialog', 'peer-title'/* массив имён атрибутов для отслеживания их изменений */];
|
||||
@ -120,22 +121,22 @@ export default class AvatarElement extends HTMLElement {
|
||||
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
|
||||
//console.log('avatar changed attribute:', name, oldValue, newValue);
|
||||
// вызывается при изменении одного из перечисленных выше атрибутов
|
||||
if(name == 'peer') {
|
||||
if(this.peerId == +newValue) {
|
||||
if(name === 'peer') {
|
||||
if(this.peerId === +newValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.peerId = +newValue;
|
||||
this.update();
|
||||
} else if(name == 'peer-title') {
|
||||
} else if(name === 'peer-title') {
|
||||
this.peerTitle = newValue;
|
||||
} else if(name == 'dialog') {
|
||||
} else if(name === 'dialog') {
|
||||
this.isDialog = !!+newValue;
|
||||
}
|
||||
}
|
||||
|
||||
public update() {
|
||||
if(this.lazyLoadQueue) {
|
||||
/* if(this.lazyLoadQueue) {
|
||||
if(this.addedToQueue) return;
|
||||
this.lazyLoadQueue.push({
|
||||
div: this,
|
||||
@ -146,9 +147,15 @@ export default class AvatarElement extends HTMLElement {
|
||||
}
|
||||
});
|
||||
this.addedToQueue = true;
|
||||
} else {
|
||||
appProfileManager.putPhoto(this, this.peerId, this.isDialog, this.peerTitle);
|
||||
}
|
||||
} else { */
|
||||
const res = appProfileManager.putPhoto(this, this.peerId, this.isDialog, this.peerTitle);
|
||||
if(this.loadPromises && res && res.cached) {
|
||||
this.loadPromises.push(res.loadPromise);
|
||||
res.loadPromise.finally(() => {
|
||||
this.loadPromises = undefined;
|
||||
});
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2256,13 +2256,14 @@ export default class ChatBubbles {
|
||||
let avatarElem = new AvatarElement();
|
||||
//avatarElem.lazyLoadQueue = this.lazyLoadQueue;
|
||||
avatarElem.classList.add('user-avatar', 'avatar-40');
|
||||
avatarElem.loadPromises = loadPromises;
|
||||
|
||||
if(!message.fwdFromId && message.fwd_from && message.fwd_from.from_name) {
|
||||
avatarElem.setAttribute('peer-title', /* '🔥 FF 🔥' */message.fwd_from.from_name);
|
||||
}
|
||||
|
||||
avatarElem.setAttribute('peer', '' + (((message.fwd_from && (this.peerId === rootScope.myId || this.peerId === REPLIES_PEER_ID)) || isForwardFromChannel ? message.fwdFromId : message.fromId) || 0));
|
||||
avatarElem.update();
|
||||
//avatarElem.update();
|
||||
|
||||
//this.log('exec loadDialogPhoto', message);
|
||||
|
||||
@ -2305,7 +2306,8 @@ export default class ChatBubbles {
|
||||
bubble,
|
||||
bubbleContainer,
|
||||
message: messageWithReplies,
|
||||
messageDiv
|
||||
messageDiv,
|
||||
loadPromises
|
||||
});
|
||||
|
||||
if(isFooter) {
|
||||
|
@ -58,16 +58,19 @@ export namespace MessageRender {
|
||||
return timeSpan;
|
||||
};
|
||||
|
||||
export const renderReplies = ({bubble, bubbleContainer, message, messageDiv}: {
|
||||
export const renderReplies = ({bubble, bubbleContainer, message, messageDiv, loadPromises}: {
|
||||
bubble: HTMLElement,
|
||||
bubbleContainer: HTMLElement,
|
||||
message: any,
|
||||
messageDiv: HTMLElement
|
||||
messageDiv: HTMLElement,
|
||||
loadPromises?: Promise<any>[]
|
||||
}) => {
|
||||
const isFooter = !bubble.classList.contains('sticker') && !bubble.classList.contains('emoji-big') && !bubble.classList.contains('round');
|
||||
const repliesFooter = new RepliesElement();
|
||||
repliesFooter.message = message;
|
||||
repliesFooter.type = isFooter ? 'footer' : 'beside';
|
||||
repliesFooter.loadPromises = loadPromises;
|
||||
repliesFooter.init();
|
||||
bubbleContainer.prepend(repliesFooter);
|
||||
return isFooter;
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||
import rootScope from "../../lib/rootScope";
|
||||
import { ripple } from "../ripple";
|
||||
import AvatarElement from "../avatar";
|
||||
|
||||
const TAG_NAME = 'replies-element';
|
||||
|
||||
@ -18,6 +19,7 @@ rootScope.on('replies_updated', (e) => {
|
||||
export default class RepliesElement extends HTMLElement {
|
||||
public message: Message.message;
|
||||
public type: 'footer' | 'beside';
|
||||
public loadPromises: Promise<any>[];
|
||||
|
||||
private updated = false;
|
||||
|
||||
@ -25,7 +27,7 @@ export default class RepliesElement extends HTMLElement {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
public init() {
|
||||
this.render();
|
||||
this.dataset.postKey = this.message.peerId + '_' + this.message.mid;
|
||||
this.classList.add('replies', 'replies-' + this.type);
|
||||
@ -34,17 +36,62 @@ export default class RepliesElement extends HTMLElement {
|
||||
public render() {
|
||||
const replies = this.message.replies;
|
||||
|
||||
/* if(this.firstChild) {
|
||||
this.innerHTML = '';
|
||||
} */
|
||||
|
||||
if(this.type === 'footer') {
|
||||
let leftHTML = '';
|
||||
let leftPart: HTMLElement;
|
||||
if(this.firstElementChild) {
|
||||
leftPart = this.firstElementChild as HTMLElement;
|
||||
}
|
||||
|
||||
if(replies?.recent_repliers) {
|
||||
leftHTML += '<div class="replies-footer-avatars">'
|
||||
let l: string[] = [];
|
||||
replies.recent_repliers/* .slice().reverse() */.forEach((peer) => {
|
||||
l.push(`<avatar-element class="avatar-34" dialog="0" peer="${appPeersManager.getPeerId(peer)}"></avatar-element>`);
|
||||
if(leftPart && !leftPart.classList.contains('replies-footer-avatars')) {
|
||||
leftPart.remove();
|
||||
leftPart = null;
|
||||
}
|
||||
|
||||
if(!leftPart) {
|
||||
leftPart = document.createElement('div');
|
||||
leftPart.classList.add('replies-footer-avatars');
|
||||
}
|
||||
|
||||
replies.recent_repliers.slice().reverse().forEach((peer, idx) => {
|
||||
let avatarElem = leftPart.children[idx] as AvatarElement;
|
||||
if(!avatarElem) {
|
||||
avatarElem = new AvatarElement();
|
||||
avatarElem.setAttribute('dialog', '0');
|
||||
avatarElem.classList.add('avatar-34');
|
||||
|
||||
if(this.loadPromises) {
|
||||
avatarElem.loadPromises = this.loadPromises;
|
||||
}
|
||||
}
|
||||
|
||||
avatarElem.setAttribute('peer', '' + appPeersManager.getPeerId(peer));
|
||||
|
||||
if(!avatarElem.parentNode) {
|
||||
leftPart.append(avatarElem);
|
||||
}
|
||||
});
|
||||
leftHTML += l.reverse().join('') + '</div>';
|
||||
|
||||
// if were 3 and became 2
|
||||
(Array.from(leftPart.children) as HTMLElement[]).slice(replies.recent_repliers.length).forEach(el => el.remove());
|
||||
} else {
|
||||
leftHTML = '<span class="tgico-comments"></span>';
|
||||
if(leftPart && !leftPart.classList.contains('tgico-comments')) {
|
||||
leftPart.remove();
|
||||
leftPart = null;
|
||||
}
|
||||
|
||||
if(!leftPart) {
|
||||
leftPart = document.createElement('span');
|
||||
leftPart.classList.add('tgico-comments');
|
||||
}
|
||||
}
|
||||
|
||||
if(!leftPart.parentElement) {
|
||||
this.append(leftPart);
|
||||
}
|
||||
|
||||
let text: string;
|
||||
@ -63,11 +110,21 @@ export default class RepliesElement extends HTMLElement {
|
||||
this.classList.toggle('is-unread', replies.read_max_id < replies.max_id && (!historyStorage.readMaxId || historyStorage.readMaxId < replies.max_id));
|
||||
}
|
||||
|
||||
this.innerHTML = `${leftHTML}<span class="replies-footer-text">${text}</span><span class="tgico-next"></span>`;
|
||||
let textSpan = this.children[1] as HTMLElement;
|
||||
if(!textSpan) {
|
||||
textSpan = document.createElement('span');
|
||||
textSpan.classList.add('replies-footer-text');
|
||||
|
||||
const rippleContainer = document.createElement('div');
|
||||
this.append(rippleContainer);
|
||||
ripple(rippleContainer);
|
||||
const iconSpan = document.createElement('span');
|
||||
iconSpan.classList.add('tgico-next');
|
||||
|
||||
const rippleContainer = document.createElement('div');
|
||||
ripple(rippleContainer);
|
||||
|
||||
this.append(textSpan, iconSpan, rippleContainer);
|
||||
}
|
||||
|
||||
textSpan.innerHTML = text;
|
||||
} else {
|
||||
this.classList.add('bubble-beside-button');
|
||||
this.innerHTML = `<span class="tgico-commentssticker"></span><span class="replies-beside-text">${replies?.replies ? formatNumber(replies.replies, 0) : ''}</span>`;
|
||||
@ -78,6 +135,10 @@ export default class RepliesElement extends HTMLElement {
|
||||
appMessagesManager.updateMessage(this.message.peerId, this.message.mid, 'replies_updated');
|
||||
this.updated = true;
|
||||
}
|
||||
|
||||
if(this.loadPromises) {
|
||||
this.loadPromises = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,6 @@ avatar-element {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
user-select: none;
|
||||
|
||||
&.fade-in {
|
||||
animation: fade-in-opacity .2s ease forwards;
|
||||
|
Loading…
x
Reference in New Issue
Block a user