tweb/src/components/avatar.ts

171 lines
5.8 KiB
TypeScript

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import appMessagesManager from "../lib/appManagers/appMessagesManager";
import appProfileManager from "../lib/appManagers/appProfileManager";
import rootScope from "../lib/rootScope";
import { attachClickEvent, cancelEvent } from "../helpers/dom";
import AppMediaViewer, { AppMediaViewerAvatar } from "./appMediaViewer";
import { Photo } from "../layer";
import appPeersManager from "../lib/appManagers/appPeersManager";
//import type { LazyLoadQueueIntersector } from "./lazyLoadQueue";
const onAvatarUpdate = (peerId: number) => {
appProfileManager.removeFromAvatarsCache(peerId);
(Array.from(document.querySelectorAll('avatar-element[peer="' + peerId + '"]')) as AvatarElement[]).forEach(elem => {
//console.log('updating avatar:', elem);
elem.update();
});
};
rootScope.on('avatar_update', onAvatarUpdate);
rootScope.on('peer_title_edit', onAvatarUpdate);
export default class AvatarElement extends HTMLElement {
private peerId: number;
private isDialog = false;
public peerTitle: string;
public loadPromises: Promise<any>[];
//public lazyLoadQueue: LazyLoadQueueIntersector;
//private addedToQueue = false;
constructor() {
super();
// элемент создан
}
connectedCallback() {
// браузер вызывает этот метод при добавлении элемента в документ
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
this.isDialog = !!this.getAttribute('dialog');
if(this.getAttribute('clickable') === '') {
this.setAttribute('clickable', 'set');
let loading = false;
attachClickEvent(this, async(e) => {
cancelEvent(e);
if(loading) return;
//console.log('avatar clicked');
const peerId = this.peerId;
loading = true;
const photo = await appProfileManager.getFullPhoto(this.peerId);
if(this.peerId !== peerId || !photo) {
loading = false;
return;
}
if(peerId < 0) {
const maxId = Number.MAX_SAFE_INTEGER;
const inputFilter = 'inputMessagesFilterChatPhotos';
let message: any = await appMessagesManager.getSearch({
peerId,
inputFilter: {_: inputFilter},
maxId,
limit: 2,
backLimit: 1
}).then(value => {
//console.log(lol);
// ! by descend
return value.history[0];
});
if(message) {
// ! гений в деле, костылируем (но это гениально)
const messagePhoto = message.action.photo;
if(messagePhoto.id !== photo.id) {
message = {
_: 'message',
mid: maxId,
media: {
_: 'messageMediaPhoto',
photo: photo
},
peerId,
date: (photo as Photo.photo).date,
fromId: peerId
};
appMessagesManager.getMessagesStorage(peerId)[maxId] = message;
}
const good = Array.from(this.querySelectorAll('img')).find(img => !img.classList.contains('emoji'));
new AppMediaViewer()
.setSearchContext({
peerId,
inputFilter,
})
.openMedia(message, good ? this : null);
loading = false;
return;
}
}
if(photo) {
const good = Array.from(this.querySelectorAll('img')).find(img => !img.classList.contains('emoji'));
new AppMediaViewerAvatar(peerId).openMedia(photo.id, good ? this : null);
}
loading = false;
});
}
}
/* disconnectedCallback() {
// браузер вызывает этот метод при удалении элемента из документа
// (может вызываться много раз, если элемент многократно добавляется/удаляется)
if(this.lazyLoadQueue) {
this.lazyLoadQueue.unobserve(this);
}
} */
static get observedAttributes(): string[] {
return ['peer', 'dialog', 'peer-title'/* массив имён атрибутов для отслеживания их изменений */];
}
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
//console.log('avatar changed attribute:', name, oldValue, newValue);
// вызывается при изменении одного из перечисленных выше атрибутов
if(name === 'peer') {
if(this.peerId === +newValue) {
return;
}
this.peerId = appPeersManager.getPeerMigratedTo(+newValue) || +newValue;
this.update();
} else if(name === 'peer-title') {
this.peerTitle = newValue;
} else if(name === 'dialog') {
this.isDialog = !!+newValue;
}
}
public update() {
/* if(this.lazyLoadQueue) {
if(this.addedToQueue) return;
this.lazyLoadQueue.push({
div: this,
load: () => {
return appProfileManager.putPhoto(this, this.peerId, this.isDialog, this.peerTitle).finally(() => {
this.addedToQueue = false;
});
}
});
this.addedToQueue = true;
} 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;
});
}
//}
}
}
customElements.define("avatar-element", AvatarElement);