Right sidebar changes:
Search and forward are tabs now Fix history navigation
This commit is contained in:
parent
730e442a7f
commit
d4e93c819e
@ -2,8 +2,8 @@ import appChatsManager from "../../lib/appManagers/appChatsManager";
|
||||
import appImManager from "../../lib/appManagers/appImManager";
|
||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||
import appSidebarRight from "../../lib/appManagers/appSidebarRight";
|
||||
import { findUpClassName, $rootScope } from "../../lib/utils";
|
||||
import appForward from "../appForward";
|
||||
import { parseMenuButtonsTo, attachContextMenuListener, positionMenu, openBtnMenu } from "../misc";
|
||||
import { PopupButton, PopupPeer } from "../popup";
|
||||
|
||||
@ -149,7 +149,7 @@ export class ChatContextMenu {
|
||||
});
|
||||
|
||||
this.buttons.forward.addEventListener('click', () => {
|
||||
appForward.init([this.msgID]);
|
||||
appSidebarRight.forwardTab.open([this.msgID]);
|
||||
});
|
||||
|
||||
this.buttons.edit.addEventListener('click', () => {
|
||||
|
@ -1,25 +1,11 @@
|
||||
import { findUpTag, whichChild } from "../lib/utils";
|
||||
|
||||
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {
|
||||
/* if(toRight) {
|
||||
//prevTabContent.style.filter = `brightness(80%)`;
|
||||
prevTabContent.style.transform = `translateX(-25%)`;
|
||||
tabContent.style.transform = `translateX(20%)`;
|
||||
} else {
|
||||
//tabContent.style.filter = `brightness(80%)`;
|
||||
tabContent.style.transform = `translateX(-25%)`;
|
||||
prevTabContent.style.transform = `translateX(20%)`;
|
||||
} */
|
||||
const width = prevTabContent.getBoundingClientRect().width;
|
||||
if(toRight) {
|
||||
prevTabContent.style.filter = `brightness(80%)`;
|
||||
prevTabContent.style.transform = `translate3d(${-width * .25}px, 0, 0)`;
|
||||
tabContent.style.transform = `translate3d(${width}px, 0, 0)`;
|
||||
} else {
|
||||
tabContent.style.filter = `brightness(80%)`;
|
||||
tabContent.style.transform = `translate3d(${-width * .25}px, 0, 0)`;
|
||||
prevTabContent.style.transform = `translate3d(${width}px, 0, 0)`;
|
||||
}
|
||||
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
|
||||
const elements = [tabContent, prevTabContent];
|
||||
if(toRight) elements.reverse();
|
||||
elements[0].style.filter = `brightness(80%)`;
|
||||
elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;
|
||||
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
||||
|
||||
tabContent.classList.add('active');
|
||||
void tabContent.offsetWidth; // reflow
|
||||
@ -28,15 +14,11 @@ function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, t
|
||||
tabContent.style.filter = '';
|
||||
}
|
||||
|
||||
function slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {
|
||||
const width = prevTabContent.getBoundingClientRect().width;
|
||||
if(toRight) {
|
||||
tabContent.style.transform = `translate3d(${width}px, 0, 0)`;
|
||||
prevTabContent.style.transform = `translate3d(${-width}px, 0, 0)`;
|
||||
} else {
|
||||
tabContent.style.transform = `translate3d(${-width}px, 0, 0)`;
|
||||
prevTabContent.style.transform = `translate3d(${width}px, 0, 0)`;
|
||||
}
|
||||
function slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
|
||||
const elements = [tabContent, prevTabContent];
|
||||
if(toRight) elements.reverse();
|
||||
elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;
|
||||
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
||||
|
||||
tabContent.classList.add('active');
|
||||
void tabContent.offsetWidth; // reflow
|
||||
@ -72,11 +54,15 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?
|
||||
}
|
||||
|
||||
const toRight = prevId < id;
|
||||
if(prevId != -1) {
|
||||
if(!tabContent) {
|
||||
//prevTabContent.classList.remove('active');
|
||||
} else if(prevId != -1) {
|
||||
const width = prevTabContent.getBoundingClientRect().width;
|
||||
|
||||
if(tabs || content.dataset.slider == 'tabs') {
|
||||
slideTabs(tabContent, prevTabContent, toRight);
|
||||
slideTabs(tabContent, prevTabContent, width, toRight);
|
||||
} else {
|
||||
slideNavigation(tabContent, prevTabContent, toRight);
|
||||
slideNavigation(tabContent, prevTabContent, width, toRight);
|
||||
}
|
||||
} else {
|
||||
tabContent.classList.add('active');
|
||||
|
@ -1,20 +1,32 @@
|
||||
import appSidebarRight from "../lib/appManagers/appSidebarRight";
|
||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||
import { putPreloader } from "./misc";
|
||||
import { AppSelectPeers } from "./appSelectPeers";
|
||||
import appSidebarRight, { AppSidebarRight } from "../../lib/appManagers/appSidebarRight";
|
||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||
import { putPreloader } from "../misc";
|
||||
import { AppSelectPeers } from "../appSelectPeers";
|
||||
import { SliderTab } from "../slider";
|
||||
|
||||
class AppForward {
|
||||
public container = document.getElementById('forward-container') as HTMLDivElement;
|
||||
private closeBtn = this.container.querySelector('.sidebar-close-button') as HTMLButtonElement;
|
||||
private sendBtn = this.container.querySelector('.btn-circle') as HTMLButtonElement;
|
||||
export default class AppForwardTab implements SliderTab {
|
||||
public container: HTMLElement;
|
||||
public closeBtn: HTMLElement;
|
||||
private sendBtn: HTMLButtonElement;
|
||||
|
||||
private selector: AppSelectPeers;
|
||||
private msgIDs: number[] = [];
|
||||
|
||||
private sidebarWasActive: boolean;
|
||||
onCloseAfterTimeout() {
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.closeBtn.addEventListener('click', this.close.bind(this));
|
||||
public cleanup() {
|
||||
if(this.selector) {
|
||||
this.selector.container.remove();
|
||||
this.selector = null;
|
||||
}
|
||||
}
|
||||
|
||||
public init() {
|
||||
this.container = document.getElementById('forward-container') as HTMLDivElement;
|
||||
this.closeBtn = this.container.querySelector('.sidebar-close-button') as HTMLButtonElement;
|
||||
this.sendBtn = this.container.querySelector('.btn-circle') as HTMLButtonElement;
|
||||
|
||||
this.sendBtn.addEventListener('click', () => {
|
||||
let peerIDs = this.selector.getSelected();
|
||||
@ -44,25 +56,15 @@ class AppForward {
|
||||
});
|
||||
}
|
||||
|
||||
public close() {
|
||||
(this.sidebarWasActive ? Promise.resolve() : appSidebarRight.toggleSidebar(false)).then(() => {
|
||||
this.cleanup();
|
||||
this.container.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
public cleanup() {
|
||||
if(this.selector) {
|
||||
this.selector.container.remove();
|
||||
this.selector = null;
|
||||
public open(ids: number[]) {
|
||||
if(this.init) {
|
||||
this.init();
|
||||
this.init = null;
|
||||
}
|
||||
}
|
||||
|
||||
public init(ids: number[]) {
|
||||
this.cleanup();
|
||||
this.msgIDs = ids;
|
||||
|
||||
this.container.classList.add('active');
|
||||
this.sendBtn.innerHTML = '';
|
||||
this.sendBtn.classList.add('tgico-send');
|
||||
this.sendBtn.disabled = false;
|
||||
@ -75,10 +77,8 @@ class AppForward {
|
||||
}
|
||||
}, ['dialogs', 'contacts'], () => {
|
||||
//console.log('forward rendered:', this.container.querySelector('.selector ul').childElementCount);
|
||||
this.sidebarWasActive = appSidebarRight.sidebarEl.classList.contains('active');
|
||||
appSidebarRight.selectTab(AppSidebarRight.SLIDERITEMSIDS.forward);
|
||||
appSidebarRight.toggleSidebar(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new AppForward();
|
50
src/components/sidebarRight/search.ts
Normal file
50
src/components/sidebarRight/search.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import appSidebarRight, { AppSidebarRight } from "../../lib/appManagers/appSidebarRight";
|
||||
import AppSearch, { SearchGroup } from "../appSearch";
|
||||
import SearchInput from "../searchInput";
|
||||
import { SliderTab } from "../slider";
|
||||
|
||||
export default class AppPrivateSearchTab implements SliderTab {
|
||||
public container: HTMLElement;
|
||||
public closeBtn: HTMLElement;
|
||||
|
||||
private searchInput: SearchInput;
|
||||
private appSearch: AppSearch;
|
||||
|
||||
private peerID = 0;
|
||||
|
||||
onOpenAfterTimeout() {
|
||||
this.appSearch.beginSearch(this.peerID);
|
||||
}
|
||||
|
||||
onCloseAfterTimeout() {
|
||||
this.peerID = 0;
|
||||
this.appSearch.reset();
|
||||
}
|
||||
|
||||
public init() {
|
||||
this.container = document.getElementById('search-private-container');
|
||||
this.closeBtn = this.container.querySelector('.sidebar-close-button');
|
||||
this.searchInput = new SearchInput('Search');
|
||||
this.closeBtn.parentElement.append(this.searchInput.container);
|
||||
this.appSearch = new AppSearch(this.container.querySelector('.chats-container'), this.searchInput, {
|
||||
messages: new SearchGroup('Private Search', 'messages')
|
||||
});
|
||||
}
|
||||
|
||||
open(peerID: number) {
|
||||
if(this.init) {
|
||||
this.init();
|
||||
this.init = null;
|
||||
}
|
||||
|
||||
if(this.peerID != 0) {
|
||||
this.appSearch.beginSearch(this.peerID);
|
||||
return;
|
||||
}
|
||||
|
||||
this.peerID = peerID;
|
||||
|
||||
appSidebarRight.selectTab(AppSidebarRight.SLIDERITEMSIDS.search);
|
||||
appSidebarRight.toggleSidebar(true);
|
||||
}
|
||||
}
|
793
src/components/sidebarRight/sharedMedia.ts
Normal file
793
src/components/sidebarRight/sharedMedia.ts
Normal file
@ -0,0 +1,793 @@
|
||||
import appImManager from "../../lib/appManagers/appImManager";
|
||||
import appMediaViewer from "../../lib/appManagers/appMediaViewer";
|
||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||
import appPhotosManager from "../../lib/appManagers/appPhotosManager";
|
||||
import appProfileManager from "../../lib/appManagers/appProfileManager";
|
||||
import appUsersManager from "../../lib/appManagers/appUsersManager";
|
||||
import { logger, LogLevels } from "../../lib/logger";
|
||||
import { RichTextProcessor } from "../../lib/richtextprocessor";
|
||||
import { $rootScope } from "../../lib/utils";
|
||||
import AvatarElement from "../avatar";
|
||||
import { horizontalMenu } from "../horizontalMenu";
|
||||
import LazyLoadQueue from "../lazyLoadQueue";
|
||||
import { renderImageFromUrl, putPreloader } from "../misc";
|
||||
import Scrollable from "../scrollable_new";
|
||||
import { SliderTab } from "../slider";
|
||||
import { wrapDocument, wrapAudio } from "../wrappers";
|
||||
|
||||
const testScroll = false;
|
||||
|
||||
let setText = (text: string, el: HTMLDivElement) => {
|
||||
window.requestAnimationFrame(() => {
|
||||
if(el.childElementCount > 1) {
|
||||
el.firstElementChild.remove();
|
||||
}
|
||||
|
||||
let p = document.createElement('p');
|
||||
p.innerHTML = text;
|
||||
el.prepend(p);
|
||||
|
||||
el.style.display = '';
|
||||
});
|
||||
};
|
||||
|
||||
type ContentType = 'contentMembers' | 'contentMedia' | 'contentDocuments' | 'contentLinks' | 'contentAudio';
|
||||
type SharedMediaType = 'inputMessagesFilterContacts' | 'inputMessagesFilterPhotoVideo' | 'inputMessagesFilterDocument' | 'inputMessagesFilterUrl' | 'inputMessagesFilterMusic';
|
||||
|
||||
const contentToSharedMap: {[contentType in ContentType]: SharedMediaType} = {
|
||||
contentMembers: 'inputMessagesFilterContacts',
|
||||
contentMedia: 'inputMessagesFilterPhotoVideo',
|
||||
contentDocuments: 'inputMessagesFilterDocument',
|
||||
contentLinks: 'inputMessagesFilterUrl',
|
||||
contentAudio: 'inputMessagesFilterMusic'
|
||||
};
|
||||
|
||||
// TODO: отправленное сообщение с картинкой, или же новое полученное апдейтом сообщение не отобразится в медии
|
||||
// TODO: по-хорошему, нужно просто сделать апдейты для всего сайдбара
|
||||
|
||||
export default class AppSharedMediaTab implements SliderTab {
|
||||
public container: HTMLElement;
|
||||
public closeBtn: HTMLElement;
|
||||
|
||||
private peerID = 0;
|
||||
|
||||
public profileContentEl: HTMLDivElement;
|
||||
public contentContainer: HTMLDivElement;
|
||||
public profileElements: {
|
||||
avatar: AvatarElement,
|
||||
name: HTMLDivElement,
|
||||
subtitle: HTMLDivElement,
|
||||
bio: HTMLDivElement,
|
||||
username: HTMLDivElement,
|
||||
phone: HTMLDivElement,
|
||||
notificationsRow: HTMLDivElement,
|
||||
notificationsCheckbox: HTMLInputElement,
|
||||
notificationsStatus: HTMLParagraphElement
|
||||
} = {} as any;
|
||||
public sharedMedia: {
|
||||
[t in ContentType]: HTMLDivElement
|
||||
} = {} as any;
|
||||
|
||||
private loadSidebarMediaPromises: {[type: string]: Promise<void>} = {};
|
||||
private loadedAllMedia: {[type: string]: boolean} = {};
|
||||
|
||||
public sharedMediaTypes: SharedMediaType[] = [
|
||||
//'members',
|
||||
'inputMessagesFilterContacts',
|
||||
'inputMessagesFilterPhotoVideo',
|
||||
'inputMessagesFilterDocument',
|
||||
'inputMessagesFilterUrl',
|
||||
'inputMessagesFilterMusic'
|
||||
];
|
||||
public sharedMediaType: SharedMediaType = 'inputMessagesFilterPhotoVideo';
|
||||
private sharedMediaSelected: HTMLDivElement = null;
|
||||
|
||||
private lazyLoadQueue = new LazyLoadQueue();
|
||||
|
||||
public historiesStorage: {
|
||||
[peerID: number]: Partial<{
|
||||
[type in SharedMediaType]: number[]
|
||||
}>
|
||||
} = {};
|
||||
public usedFromHistory: Partial<{
|
||||
[type in SharedMediaType]: number
|
||||
}> = {};
|
||||
|
||||
public scroll: Scrollable = null;
|
||||
|
||||
private profileTabs: HTMLUListElement;
|
||||
private prevTabID = -1;
|
||||
|
||||
private mediaDivsByIDs: {
|
||||
[mid: number]: HTMLDivElement
|
||||
} = {};
|
||||
|
||||
public urlsToRevoke: string[] = [];
|
||||
|
||||
private loadMutex: Promise<any> = Promise.resolve();
|
||||
|
||||
private log = logger('SM', LogLevels.error);
|
||||
|
||||
public init() {
|
||||
this.container = document.getElementById('shared-media-container');
|
||||
this.closeBtn = this.container.querySelector('.sidebar-close-button');
|
||||
|
||||
this.profileContentEl = this.container.querySelector('.profile-content');
|
||||
this.contentContainer = this.container.querySelector('.content-container');
|
||||
this.profileElements = {
|
||||
avatar: this.profileContentEl.querySelector('.profile-avatar'),
|
||||
name: this.profileContentEl.querySelector('.profile-name'),
|
||||
subtitle: this.profileContentEl.querySelector('.profile-subtitle'),
|
||||
bio: this.profileContentEl.querySelector('.profile-row-bio'),
|
||||
username: this.profileContentEl.querySelector('.profile-row-username'),
|
||||
phone: this.profileContentEl.querySelector('.profile-row-phone'),
|
||||
notificationsRow: this.profileContentEl.querySelector('.profile-row-notifications'),
|
||||
notificationsCheckbox: this.profileContentEl.querySelector('#profile-notifications'),
|
||||
notificationsStatus: this.profileContentEl.querySelector('.profile-row-notifications > p')
|
||||
};
|
||||
|
||||
this.sharedMedia = {
|
||||
contentMembers: this.profileContentEl.querySelector('#content-members'),
|
||||
contentMedia: this.profileContentEl.querySelector('#content-media'),
|
||||
contentDocuments: this.profileContentEl.querySelector('#content-docs'),
|
||||
contentLinks: this.profileContentEl.querySelector('#content-links'),
|
||||
contentAudio: this.profileContentEl.querySelector('#content-audio'),
|
||||
};
|
||||
|
||||
let container = this.profileContentEl.querySelector('.content-container .tabs-container') as HTMLDivElement;
|
||||
this.profileTabs = this.profileContentEl.querySelector('.profile-tabs');
|
||||
|
||||
this.scroll = new Scrollable(this.container, 'SR', undefined, 400);
|
||||
this.scroll.onScrolledBottom = () => {
|
||||
if(this.sharedMediaSelected && this.sharedMediaSelected.childElementCount/* && false */) {
|
||||
this.log('onScrolledBottom will load media');
|
||||
this.loadSidebarMedia(true);
|
||||
}
|
||||
};
|
||||
//this.scroll.attachSentinels(undefined, 400);
|
||||
|
||||
horizontalMenu(this.profileTabs, container, (id, tabContent) => {
|
||||
if(this.prevTabID == id) return;
|
||||
|
||||
if(this.prevTabID != -1) {
|
||||
this.onTransitionStart();
|
||||
}
|
||||
|
||||
this.sharedMediaType = this.sharedMediaTypes[id];
|
||||
this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement;
|
||||
|
||||
if(this.prevTabID != -1 && this.profileTabs.offsetTop) {
|
||||
this.scroll.scrollTop -= this.profileTabs.offsetTop;
|
||||
}
|
||||
|
||||
/* this.log('setVirtualContainer', id, this.sharedMediaSelected, this.sharedMediaSelected.childElementCount);
|
||||
this.scroll.setVirtualContainer(this.sharedMediaSelected); */
|
||||
|
||||
if(this.prevTabID != -1 && !this.sharedMediaSelected.childElementCount) { // quick brown fix
|
||||
//this.contentContainer.classList.remove('loaded');
|
||||
this.loadSidebarMedia(true);
|
||||
}
|
||||
|
||||
this.prevTabID = id;
|
||||
}, () => {
|
||||
this.scroll.onScroll();
|
||||
this.onTransitionEnd();
|
||||
});
|
||||
|
||||
this.sharedMedia.contentMedia.addEventListener('click', (e) => {
|
||||
const target = e.target as HTMLDivElement;
|
||||
|
||||
const messageID = +target.dataset.mid;
|
||||
if(!messageID) {
|
||||
this.log.warn('no messageID by click on target:', target);
|
||||
return;
|
||||
}
|
||||
|
||||
const message = appMessagesManager.getMessage(messageID);
|
||||
|
||||
const ids = Object.keys(this.mediaDivsByIDs).map(k => +k).sort((a, b) => a - b);
|
||||
const idx = ids.findIndex(i => i == messageID);
|
||||
|
||||
const targets = ids.map(id => {
|
||||
const element = this.mediaDivsByIDs[id] as HTMLElement;
|
||||
//element = element.querySelector('img') || element;
|
||||
return {element, mid: id};
|
||||
});
|
||||
|
||||
appMediaViewer.openMedia(message, target, false, this.container, targets.slice(idx + 1).reverse(), targets.slice(0, idx).reverse(), true);
|
||||
});
|
||||
|
||||
this.profileElements.notificationsCheckbox.addEventListener('change', () => {
|
||||
//let checked = this.profileElements.notificationsCheckbox.checked;
|
||||
appImManager.mutePeer(this.peerID);
|
||||
});
|
||||
|
||||
/* this.closeBtn.addEventListener('click', () => {
|
||||
this.toggleSidebar(false);
|
||||
}); */
|
||||
}
|
||||
|
||||
private onTransitionStart = () => {
|
||||
// Jolly Cobra's // Workaround for scrollable content flickering during animation.
|
||||
const container = this.scroll.container;
|
||||
if(container.style.overflowY !== 'hidden') {
|
||||
const scrollBarWidth = container.offsetWidth - container.clientWidth;
|
||||
container.style.overflowY = 'hidden';
|
||||
container.style.paddingRight = `${scrollBarWidth}px`;
|
||||
}
|
||||
};
|
||||
|
||||
private onTransitionEnd = () => {
|
||||
// Jolly Cobra's // Workaround for scrollable content flickering during animation.
|
||||
const container = this.scroll.container;
|
||||
container.style.overflowY = '';
|
||||
container.style.paddingRight = '0';
|
||||
};
|
||||
|
||||
public filterMessagesByType(ids: number[], type: string) {
|
||||
let messages: any[] = [];
|
||||
for(let mid of ids) {
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
if(message.media) messages.push(message);
|
||||
}
|
||||
|
||||
let filtered: any[] = [];
|
||||
|
||||
switch(type) {
|
||||
case 'inputMessagesFilterPhotoVideo': {
|
||||
for(let message of messages) {
|
||||
let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
|
||||
if(!media) {
|
||||
//this.log('no media!', message);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) {
|
||||
//this.log('broken video', media);
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterDocument': {
|
||||
for(let message of messages) {
|
||||
if(!message.media.document || message.media.document.type == 'voice' || message.media.document.type == 'audio') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let doc = message.media.document;
|
||||
if(doc.attributes) {
|
||||
if(doc.attributes.find((a: any) => a._ == "documentAttributeSticker")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterUrl': {
|
||||
for(let message of messages) {
|
||||
if(!message.media.webpage || message.media.webpage._ == 'webPageEmpty') {
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterMusic': {
|
||||
for(let message of messages) {
|
||||
if(!message.media.document || message.media.document.type != 'audio') {
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
public async performSearchResult(messages: any[], type: SharedMediaType) {
|
||||
const peerID = this.peerID;
|
||||
const elemsToAppend: HTMLElement[] = [];
|
||||
const promises: Promise<any>[] = [];
|
||||
let sharedMediaDiv: HTMLDivElement;
|
||||
|
||||
/* for(let contentType in contentToSharedMap) {
|
||||
if(contentToSharedMap[contentType as ContentType] == type) {
|
||||
sharedMediaDiv = this.sharedMedia[contentType as ContentType];
|
||||
}
|
||||
} */
|
||||
|
||||
// https://core.telegram.org/type/MessagesFilter
|
||||
switch(type) {
|
||||
case 'inputMessagesFilterPhotoVideo': {
|
||||
sharedMediaDiv = this.sharedMedia.contentMedia;
|
||||
|
||||
for(const message of messages) {
|
||||
const media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('media-item');
|
||||
//console.log(message, photo);
|
||||
|
||||
const isPhoto = media._ == 'photo';
|
||||
|
||||
const photo = isPhoto ? appPhotosManager.getPhoto(media.id) : null;
|
||||
let isDownloaded: boolean;
|
||||
if(photo) {
|
||||
isDownloaded = photo.downloaded > 0;
|
||||
} else {
|
||||
const cachedThumb = appPhotosManager.getDocumentCachedThumb(media.id);
|
||||
isDownloaded = cachedThumb?.downloaded > 0;
|
||||
}
|
||||
|
||||
//this.log('inputMessagesFilterPhotoVideo', message, media);
|
||||
|
||||
if(!isPhoto) {
|
||||
const span = document.createElement('span');
|
||||
span.classList.add('video-time');
|
||||
div.append(span);
|
||||
|
||||
if(media.type != 'gif') {
|
||||
span.innerText = (media.duration + '').toHHMMSS(false);
|
||||
|
||||
/* const spanPlay = document.createElement('span');
|
||||
spanPlay.classList.add('video-play', 'tgico-largeplay', 'btn-circle', 'position-center');
|
||||
div.append(spanPlay); */
|
||||
} else {
|
||||
span.innerText = 'GIF';
|
||||
}
|
||||
}
|
||||
|
||||
const load = () => appPhotosManager.preloadPhoto(isPhoto ? media.id : media, appPhotosManager.choosePhotoSize(media, 200, 200))
|
||||
.then(() => {
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
const url = (photo && photo.url) || appPhotosManager.getDocumentCachedThumb(media.id).url;
|
||||
if(url) {
|
||||
//if(needBlur) return;
|
||||
|
||||
const needBlurCallback = needBlur ? () => {
|
||||
//void img.offsetLeft; // reflow
|
||||
img.style.opacity = '';
|
||||
|
||||
if(thumb) {
|
||||
window.setTimeout(() => {
|
||||
thumb.remove();
|
||||
}, 200);
|
||||
}
|
||||
} : undefined;
|
||||
renderImageFromUrl(img, url, needBlurCallback);
|
||||
}
|
||||
});
|
||||
|
||||
let thumb: HTMLImageElement;
|
||||
const sizes = media.sizes || media.thumbs;
|
||||
|
||||
const willHaveThumb = !isDownloaded && sizes && sizes[0].bytes;
|
||||
if(willHaveThumb) {
|
||||
thumb = new Image();
|
||||
thumb.classList.add('media-image', 'thumbnail');
|
||||
thumb.dataset.mid = '' + message.mid;
|
||||
appPhotosManager.setAttachmentPreview(sizes[0].bytes, thumb, false, false);
|
||||
div.append(thumb);
|
||||
}
|
||||
|
||||
const needBlur = !isDownloaded || !willHaveThumb;
|
||||
const img = new Image();
|
||||
img.dataset.mid = '' + message.mid;
|
||||
img.classList.add('media-image');
|
||||
if(needBlur) img.style.opacity = '0';
|
||||
div.append(img);
|
||||
|
||||
if(isDownloaded || willHaveThumb) {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
(thumb || img).addEventListener('load', () => {
|
||||
clearTimeout(timeout);
|
||||
resolve();
|
||||
});
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
this.log('didn\'t load', thumb, media, isDownloaded, sizes);
|
||||
reject();
|
||||
}, 1e3);
|
||||
});
|
||||
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
if(sizes?.length) {
|
||||
if(isDownloaded) load();
|
||||
else this.lazyLoadQueue.push({div, load});
|
||||
}
|
||||
|
||||
elemsToAppend.push(div);
|
||||
this.mediaDivsByIDs[message.mid] = div;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterDocument': {
|
||||
sharedMediaDiv = this.sharedMedia.contentDocuments;
|
||||
|
||||
for(let message of messages) {
|
||||
let div = wrapDocument(message.media.document, true, false, message.mid);
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterUrl': {
|
||||
sharedMediaDiv = this.sharedMedia.contentLinks;
|
||||
|
||||
for(let message of messages) {
|
||||
let webpage = message.media.webpage;
|
||||
let div = document.createElement('div');
|
||||
|
||||
let previewDiv = document.createElement('div');
|
||||
previewDiv.classList.add('preview');
|
||||
|
||||
//this.log('wrapping webpage', webpage);
|
||||
|
||||
previewDiv.innerText = (webpage.title || webpage.description || webpage.url || webpage.display_url).slice(0, 1);
|
||||
previewDiv.classList.add('empty');
|
||||
if(webpage.photo) {
|
||||
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 60, 60))
|
||||
.then(() => {
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
previewDiv.classList.remove('empty');
|
||||
|
||||
previewDiv.innerText = '';
|
||||
renderImageFromUrl(previewDiv, webpage.photo.url);
|
||||
});
|
||||
|
||||
this.lazyLoadQueue.push({div: previewDiv, load});
|
||||
}
|
||||
|
||||
let title = webpage.rTitle || '';
|
||||
let subtitle = webpage.rDescription || '';
|
||||
let url = RichTextProcessor.wrapRichText(webpage.url || '');
|
||||
|
||||
if(!title) {
|
||||
//title = new URL(webpage.url).hostname;
|
||||
title = webpage.display_url.split('/', 1)[0];
|
||||
}
|
||||
|
||||
div.append(previewDiv);
|
||||
div.insertAdjacentHTML('beforeend', `
|
||||
<div class="title">${title}</button>
|
||||
<div class="subtitle">${subtitle}</div>
|
||||
<div class="url">${url}</div>
|
||||
`);
|
||||
|
||||
if(div.innerText.trim().length) {
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterMusic': {
|
||||
sharedMediaDiv = this.sharedMedia.contentAudio;
|
||||
|
||||
for(let message of messages) {
|
||||
let div = wrapAudio(message.media.document, true, message.mid);
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
console.warn('death is my friend', messages);
|
||||
break;
|
||||
}
|
||||
|
||||
if(this.loadMutex) {
|
||||
promises.push(this.loadMutex);
|
||||
}
|
||||
|
||||
if(promises.length) {
|
||||
await Promise.all(promises);
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(elemsToAppend.length) {
|
||||
sharedMediaDiv.append(...elemsToAppend);
|
||||
}
|
||||
|
||||
if(sharedMediaDiv) {
|
||||
const parent = sharedMediaDiv.parentElement;
|
||||
Array.from(parent.children).slice(1).forEach(child => {
|
||||
child.remove();
|
||||
});
|
||||
|
||||
//this.contentContainer.classList.add('loaded');
|
||||
|
||||
if(!messages.length && !sharedMediaDiv.childElementCount) {
|
||||
const div = document.createElement('div');
|
||||
div.innerText = 'Nothing interesting here yet...';
|
||||
div.classList.add('position-center', 'text-center', 'content-empty', 'no-select');
|
||||
|
||||
parent.append(div);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public loadSidebarMedia(single = false) {
|
||||
if(testScroll/* || 1 == 1 */) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.log('loadSidebarMedia', single, this.peerID, this.loadSidebarMediaPromises);
|
||||
|
||||
const peerID = this.peerID;
|
||||
|
||||
let typesToLoad = single ? [this.sharedMediaType] : this.sharedMediaTypes;
|
||||
typesToLoad = typesToLoad.filter(type => !this.loadedAllMedia[type]);
|
||||
if(!typesToLoad.length) return;
|
||||
|
||||
const loadCount = (appPhotosManager.windowH / 130 | 0) * 3; // that's good for all types
|
||||
|
||||
const historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {});
|
||||
|
||||
const promises = typesToLoad.map(type => {
|
||||
if(this.loadSidebarMediaPromises[type]) return this.loadSidebarMediaPromises[type];
|
||||
|
||||
const history = historyStorage[type] ?? (historyStorage[type] = []);
|
||||
|
||||
// render from cache
|
||||
if(history.length && this.usedFromHistory[type] < history.length) {
|
||||
let messages: any[] = [];
|
||||
let used = this.usedFromHistory[type];
|
||||
|
||||
do {
|
||||
let ids = history.slice(used, used + loadCount);
|
||||
this.log('loadSidebarMedia: will render from cache', used, history, ids, loadCount);
|
||||
used += ids.length;
|
||||
|
||||
messages.push(...this.filterMessagesByType(ids, type));
|
||||
} while(messages.length < loadCount && used < history.length);
|
||||
|
||||
// если перебор
|
||||
if(messages.length > loadCount) {
|
||||
let diff = messages.length - loadCount;
|
||||
messages = messages.slice(0, messages.length - diff);
|
||||
used -= diff;
|
||||
}
|
||||
|
||||
this.usedFromHistory[type] = used;
|
||||
//if(messages.length) {
|
||||
return this.performSearchResult(messages, type);
|
||||
//}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// заливать новую картинку сюда только после полной отправки!
|
||||
let maxID = history[history.length - 1] || 0;
|
||||
|
||||
let ids = !maxID && appMessagesManager.historiesStorage[peerID]
|
||||
? appMessagesManager.historiesStorage[peerID].history.slice() : [];
|
||||
|
||||
maxID = !maxID && ids.length ? ids[ids.length - 1] : maxID;
|
||||
this.log('loadSidebarMedia: search house of glass pre', type, ids, maxID);
|
||||
|
||||
//let loadCount = history.length ? 50 : 15;
|
||||
return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, loadCount)
|
||||
.then(value => {
|
||||
ids = ids.concat(value.history);
|
||||
history.push(...ids);
|
||||
|
||||
this.log('loadSidebarMedia: search house of glass', type, value, ids);
|
||||
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
if(value.history.length < loadCount) {
|
||||
this.loadedAllMedia[type] = true;
|
||||
}
|
||||
|
||||
this.usedFromHistory[type] = history.length;
|
||||
|
||||
//if(ids.length) {
|
||||
return this.performSearchResult(this.filterMessagesByType(ids, type), type);
|
||||
//}
|
||||
}, (err) => {
|
||||
this.log.error('load error:', err);
|
||||
}).then(() => {
|
||||
this.loadSidebarMediaPromises[type] = null;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
public cleanup() {
|
||||
this.loadSidebarMediaPromises = {};
|
||||
this.loadedAllMedia = {};
|
||||
|
||||
this.prevTabID = -1;
|
||||
this.mediaDivsByIDs = {};
|
||||
this.lazyLoadQueue.clear();
|
||||
|
||||
this.sharedMediaTypes.forEach(type => {
|
||||
this.usedFromHistory[type] = 0;
|
||||
});
|
||||
|
||||
this.sharedMediaType = 'inputMessagesFilterPhotoVideo';
|
||||
}
|
||||
|
||||
public cleanupHTML() {
|
||||
//this.contentContainer.classList.remove('loaded');
|
||||
|
||||
//this.profileContentEl.parentElement.scrollTop = 0;
|
||||
this.profileElements.bio.style.display = 'none';
|
||||
this.profileElements.phone.style.display = 'none';
|
||||
this.profileElements.username.style.display = 'none';
|
||||
this.profileElements.notificationsRow.style.display = '';
|
||||
this.profileElements.notificationsCheckbox.checked = true;
|
||||
this.profileElements.notificationsStatus.innerText = 'Enabled';
|
||||
|
||||
if(this.urlsToRevoke.length) {
|
||||
this.urlsToRevoke.forEach(url => {
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
this.urlsToRevoke.length = 0;
|
||||
}
|
||||
|
||||
(Object.keys(this.sharedMedia) as ContentType[]).forEach(key => {
|
||||
this.sharedMedia[key].innerHTML = '';
|
||||
|
||||
const inputFilter = contentToSharedMap[key];
|
||||
if(!this.historiesStorage[this.peerID] || !this.historiesStorage[this.peerID][inputFilter]) {
|
||||
const parent = this.sharedMedia[key].parentElement;
|
||||
if(!testScroll) {
|
||||
if(!parent.querySelector('.preloader')) {
|
||||
putPreloader(parent, true);
|
||||
}
|
||||
}
|
||||
|
||||
const empty = parent.querySelector('.content-empty');
|
||||
if(empty) {
|
||||
empty.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(testScroll) {
|
||||
for(let i = 0; i < 1500; ++i) {
|
||||
let div = document.createElement('div');
|
||||
div.insertAdjacentHTML('beforeend', `<img class="media-image" src="assets/img/camomile.jpg">`);
|
||||
div.classList.add('media-item');
|
||||
div.dataset.id = '' + (i / 3 | 0);
|
||||
//div.innerText = '' + (i / 3 | 0);
|
||||
this.sharedMedia.contentMedia.append(div);
|
||||
}
|
||||
}
|
||||
|
||||
(this.profileTabs.firstElementChild.children[1] as HTMLLIElement).click(); // set media
|
||||
}
|
||||
|
||||
public setLoadMutex(promise: Promise<any>) {
|
||||
this.loadMutex = promise;
|
||||
}
|
||||
|
||||
public setPeer(peerID: number) {
|
||||
if(this.init) {
|
||||
this.init();
|
||||
this.init = null;
|
||||
}
|
||||
|
||||
this.peerID = peerID;
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
public fillProfileElements() {
|
||||
let peerID = this.peerID = $rootScope.selectedPeerID;
|
||||
|
||||
this.cleanupHTML();
|
||||
|
||||
this.profileElements.avatar.setAttribute('peer', '' + peerID);
|
||||
|
||||
// username
|
||||
if(peerID != $rootScope.myID) {
|
||||
let username = appPeersManager.getPeerUsername(peerID);
|
||||
if(username) {
|
||||
setText(appPeersManager.getPeerUsername(peerID), this.profileElements.username);
|
||||
}
|
||||
|
||||
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
|
||||
if(dialog) {
|
||||
let muted = false;
|
||||
if(dialog.notify_settings && dialog.notify_settings.mute_until) {
|
||||
muted = new Date(dialog.notify_settings.mute_until * 1000) > new Date();
|
||||
}
|
||||
|
||||
appImManager.setMutedState(muted);
|
||||
}
|
||||
} else {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.profileElements.notificationsRow.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
//let membersLi = this.profileTabs.firstElementChild.children[0] as HTMLLIElement;
|
||||
if(peerID > 0) {
|
||||
//membersLi.style.display = 'none';
|
||||
|
||||
let user = appUsersManager.getUser(peerID);
|
||||
if(user.phone && peerID != $rootScope.myID) {
|
||||
setText(user.rPhone, this.profileElements.phone);
|
||||
}
|
||||
|
||||
appProfileManager.getProfile(peerID, true).then(userFull => {
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
if(userFull.rAbout && peerID != $rootScope.myID) {
|
||||
setText(userFull.rAbout, this.profileElements.bio);
|
||||
}
|
||||
|
||||
//this.log('userFull', userFull);
|
||||
});
|
||||
} else {
|
||||
//membersLi.style.display = appPeersManager.isBroadcast(peerID) ? 'none' : '';
|
||||
let chat = appPeersManager.getPeer(peerID);
|
||||
|
||||
appProfileManager.getChatFull(chat.id).then((chatFull: any) => {
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
//this.log('chatInfo res 2:', chatFull);
|
||||
|
||||
if(chatFull.about) {
|
||||
setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* onOpen() {
|
||||
this.scroll.onScroll();
|
||||
} */
|
||||
|
||||
onOpenAfterTimeout() {
|
||||
this.scroll.onScroll();
|
||||
}
|
||||
}
|
@ -7,21 +7,23 @@ export interface SliderTab {
|
||||
onCloseAfterTimeout?: () => void
|
||||
}
|
||||
|
||||
const TRANSITIONTIME = 250;
|
||||
const TRANSITION_TIME = 250;
|
||||
|
||||
export default class SidebarSlider {
|
||||
protected _selectTab: (id: number) => void;
|
||||
public historyTabIDs: number[] = [];
|
||||
|
||||
constructor(public sidebarEl: HTMLElement, public tabs: {[id: number]: SliderTab}) {
|
||||
this._selectTab = horizontalMenu(null, this.sidebarEl.querySelector('.sidebar-slider') as HTMLDivElement, null, null, TRANSITIONTIME);
|
||||
this._selectTab(0);
|
||||
constructor(public sidebarEl: HTMLElement, public tabs: {[id: number]: SliderTab}, canHideFirst = false) {
|
||||
this._selectTab = horizontalMenu(null, this.sidebarEl.querySelector('.sidebar-slider') as HTMLDivElement, null, null, TRANSITION_TIME);
|
||||
if(!canHideFirst) {
|
||||
this._selectTab(0);
|
||||
}
|
||||
|
||||
let onCloseBtnClick = () => {
|
||||
//console.log('sidebar-close-button click:', this.historyTabIDs);
|
||||
let closingID = this.historyTabIDs.pop(); // pop current
|
||||
this.onCloseTab(closingID);
|
||||
this._selectTab(this.historyTabIDs[this.historyTabIDs.length - 1] || 0);
|
||||
this._selectTab(this.historyTabIDs[this.historyTabIDs.length - 1] ?? (canHideFirst ? -1 : 0));
|
||||
};
|
||||
Array.from(this.sidebarEl.querySelectorAll('.sidebar-close-button') as any as HTMLElement[]).forEach(el => {
|
||||
el.addEventListener('click', onCloseBtnClick);
|
||||
@ -30,7 +32,7 @@ export default class SidebarSlider {
|
||||
|
||||
public selectTab(id: number) {
|
||||
if(this.historyTabIDs[this.historyTabIDs.length - 1] == id) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
const tab = this.tabs[id];
|
||||
@ -42,13 +44,13 @@ export default class SidebarSlider {
|
||||
if(tab.onOpenAfterTimeout) {
|
||||
setTimeout(() => {
|
||||
tab.onOpenAfterTimeout();
|
||||
}, TRANSITIONTIME);
|
||||
}, TRANSITION_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.historyTabIDs.push(id);
|
||||
this._selectTab(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public removeTabFromHistory(id: number) {
|
||||
@ -66,7 +68,7 @@ export default class SidebarSlider {
|
||||
if(tab.onCloseAfterTimeout) {
|
||||
setTimeout(() => {
|
||||
tab.onCloseAfterTimeout();
|
||||
}, TRANSITIONTIME);
|
||||
}, TRANSITION_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -588,14 +588,14 @@
|
||||
</div>
|
||||
<div class="sidebar sidebar-right main-column" id="column-right">
|
||||
<div class="sidebar-content sidebar-slider tabs-container">
|
||||
<div class="sidebar-slider-item profile-container">
|
||||
<div class="sidebar-slider-item profile-container" id="shared-media-container">
|
||||
<div class="sidebar-header">
|
||||
<button class="btn-icon tgico sidebar-close-button"></button>
|
||||
<div class="sidebar-header__title">Info</div>
|
||||
|
||||
<!-- <button class="btn-icon rp tgico-edit sidebar-edit-button"></button> -->
|
||||
|
||||
<div class="btn-icon tgico-more rp"></div>
|
||||
<div class="btn-icon tgico-more"></div>
|
||||
<!-- <div class="btn-icon tgico-more rp btn-menu-toggle">
|
||||
<div class="btn-menu bottom-left"> -->
|
||||
<!-- <div class="btn-menu-item menu-mute rp">Mute</div>
|
||||
@ -649,20 +649,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-slider-item sidebar-search chats-container" id="search-private-container">
|
||||
<div class="sidebar-slider-item chats-container" id="search-private-container">
|
||||
<div class="sidebar-header">
|
||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||
</div>
|
||||
<div class="chats-container"></div>
|
||||
</div>
|
||||
<div class="sidebar-slider-item sidebar-search" id="forward-container">
|
||||
<div class="sidebar-slider-item" id="forward-container">
|
||||
<div class="sidebar-header">
|
||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||
<div class="sidebar-header__title">Forward</div>
|
||||
</div>
|
||||
<button class="btn-primary btn-circle btn-icon rp btn-corner tgico-send"></button>
|
||||
</div>
|
||||
<div class="sidebar-slider-item sidebar-search chats-container" id="stickers-container">
|
||||
<div class="sidebar-slider-item chats-container" id="stickers-container">
|
||||
<div class="sidebar-header">
|
||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||
</div>
|
||||
@ -675,7 +675,7 @@
|
||||
</div>
|
||||
<div class="sidebar-content"><div class="poll-results"></div></div>
|
||||
</div>
|
||||
<div class="sidebar-slider-item sidebar-search chats-container" id="search-gifs-container">
|
||||
<div class="sidebar-slider-item chats-container" id="search-gifs-container">
|
||||
<div class="sidebar-header">
|
||||
<button class="btn-icon tgico-close sidebar-close-button"></button>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@ import appProfileManager from "./appProfileManager";
|
||||
import appDialogsManager from "./appDialogsManager";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
import appPhotosManager from "./appPhotosManager";
|
||||
import appSidebarRight from './appSidebarRight';
|
||||
import appSidebarRight, { AppSidebarRight } from './appSidebarRight';
|
||||
|
||||
import { logger, LogLevels } from "../logger";
|
||||
import appMediaViewer from "./appMediaViewer";
|
||||
@ -23,7 +23,6 @@ import Scrollable from '../../components/scrollable_new';
|
||||
import BubbleGroups from '../../components/bubbleGroups';
|
||||
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
||||
import appDocsManager from './appDocsManager';
|
||||
import appForward from '../../components/appForward';
|
||||
import appStickersManager from './appStickersManager';
|
||||
import AvatarElement from '../../components/avatar';
|
||||
import appInlineBotsManager from './AppInlineBotsManager';
|
||||
@ -511,7 +510,7 @@ export class AppImManager {
|
||||
return;
|
||||
} else if(target.classList.contains('forward')) {
|
||||
const mid = +bubble.dataset.mid;
|
||||
appForward.init([mid]);
|
||||
appSidebarRight.forwardTab.open([mid]);
|
||||
return;
|
||||
} else if(target.classList.contains('name')) {
|
||||
let peerID = +target.dataset.peerID;
|
||||
@ -560,7 +559,7 @@ export class AppImManager {
|
||||
this.searchBtn.addEventListener('click', (e) => {
|
||||
cancelEvent(e);
|
||||
if(this.peerID) {
|
||||
appSidebarRight.beginSearch();
|
||||
appSidebarRight.searchTab.open(this.peerID);
|
||||
}
|
||||
});
|
||||
|
||||
@ -610,8 +609,8 @@ export class AppImManager {
|
||||
if(e.key == 'Escape') {
|
||||
if(appMediaViewer.wholeDiv.classList.contains('active')) {
|
||||
appMediaViewer.buttons.close.click();
|
||||
} else if(appForward.container.classList.contains('active')) {
|
||||
appForward.close();
|
||||
} else if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) {
|
||||
appSidebarRight.forwardTab.closeBtn.click();
|
||||
} else if(this.chatInputC.replyElements.container.classList.contains('active')) {
|
||||
this.chatInputC.replyElements.cancelBtn.click();
|
||||
} else if(this.peerID != 0) { // hide current dialog
|
||||
@ -885,16 +884,18 @@ export class AppImManager {
|
||||
public setPeerStatus(needClear = false) {
|
||||
if(!this.myID) return;
|
||||
|
||||
const profileElements = appSidebarRight.sharedMediaTab.profileElements;
|
||||
|
||||
if(this.peerID < 0) { // not human
|
||||
let chat = appPeersManager.getPeer(this.peerID);
|
||||
let isChannel = appPeersManager.isChannel(this.peerID) && !appPeersManager.isMegagroup(this.peerID);
|
||||
|
||||
this.subtitleEl.classList.remove('online');
|
||||
appSidebarRight.profileElements.subtitle.classList.remove('online');
|
||||
profileElements.subtitle.classList.remove('online');
|
||||
///////this.log('setPeerStatus', chat);
|
||||
|
||||
if(needClear) {
|
||||
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = '';
|
||||
this.subtitleEl.innerText = profileElements.subtitle.innerText = '';
|
||||
}
|
||||
|
||||
appProfileManager.getChatFull(chat.id).then((chatInfo: any) => {
|
||||
@ -904,7 +905,7 @@ export class AppImManager {
|
||||
if(participants_count) {
|
||||
let subtitle = numberWithCommas(participants_count) + ' ' + (isChannel ? 'followers' : 'members');
|
||||
|
||||
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = subtitle;
|
||||
this.subtitleEl.innerText = profileElements.subtitle.innerText = subtitle;
|
||||
|
||||
if(participants_count < 2) return;
|
||||
appChatsManager.getOnlines(chat.id).then(onlines => {
|
||||
@ -912,7 +913,7 @@ export class AppImManager {
|
||||
subtitle += ', ' + numberWithCommas(onlines) + ' online';
|
||||
}
|
||||
|
||||
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = subtitle;
|
||||
this.subtitleEl.innerText = profileElements.subtitle.innerText = subtitle;
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -920,16 +921,16 @@ export class AppImManager {
|
||||
let user = appUsersManager.getUser(this.peerID);
|
||||
|
||||
if(this.myID == this.peerID) {
|
||||
this.subtitleEl.innerText = appSidebarRight.profileElements.subtitle.innerText = '';
|
||||
this.subtitleEl.innerText = profileElements.subtitle.innerText = '';
|
||||
} else if(user && user.status) {
|
||||
let subtitle = appUsersManager.getUserStatusString(user.id);
|
||||
|
||||
if(subtitle == 'online') {
|
||||
this.subtitleEl.classList.add('online');
|
||||
appSidebarRight.profileElements.subtitle.classList.add('online');
|
||||
profileElements.subtitle.classList.add('online');
|
||||
}
|
||||
|
||||
appSidebarRight.profileElements.subtitle.innerText = subtitle;
|
||||
profileElements.subtitle.innerText = subtitle;
|
||||
|
||||
if(this.typingUsers[this.peerID] == this.peerID) {
|
||||
this.subtitleEl.innerText = 'typing...';
|
||||
@ -939,13 +940,13 @@ export class AppImManager {
|
||||
|
||||
if(subtitle != 'online') {
|
||||
this.subtitleEl.classList.remove('online');
|
||||
appSidebarRight.profileElements.subtitle.classList.remove('online');
|
||||
profileElements.subtitle.classList.remove('online');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.subtitleEl.innerText = 'bot';
|
||||
appSidebarRight.profileElements.subtitle.innerText = 'bot';
|
||||
profileElements.subtitle.innerText = 'bot';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,8 +1051,8 @@ export class AppImManager {
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
appSidebarRight.searchCloseBtn.click();
|
||||
} else if(appSidebarRight.historyTabIDs[appSidebarRight.historyTabIDs.length - 1] == AppSidebarRight.SLIDERITEMSIDS.search) {
|
||||
appSidebarRight.searchTab.closeBtn?.click();
|
||||
}
|
||||
|
||||
// set new
|
||||
@ -1088,7 +1089,7 @@ export class AppImManager {
|
||||
const {promise, cached} = this.getHistory(lastMsgID, true, isJump, additionMsgID);
|
||||
|
||||
if(!samePeer) {
|
||||
appSidebarRight.setPeer(this.peerID);
|
||||
appSidebarRight.sharedMediaTab.setPeer(this.peerID);
|
||||
} else {
|
||||
this.peerChanged = true;
|
||||
}
|
||||
@ -1207,8 +1208,8 @@ export class AppImManager {
|
||||
//appSidebarRight.setLoadMutex(this.setPeerPromise);
|
||||
//}
|
||||
|
||||
appSidebarRight.setLoadMutex(this.setPeerPromise);
|
||||
appSidebarRight.loadSidebarMedia(true);
|
||||
appSidebarRight.sharedMediaTab.setLoadMutex(this.setPeerPromise);
|
||||
appSidebarRight.sharedMediaTab.loadSidebarMedia(true);
|
||||
|
||||
return this.setPeerPromise;
|
||||
}
|
||||
@ -1252,14 +1253,14 @@ export class AppImManager {
|
||||
let title = '';
|
||||
if(this.peerID == this.myID) title = 'Saved Messages';
|
||||
else title = appPeersManager.getPeerTitle(this.peerID);
|
||||
this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = title;
|
||||
this.titleEl.innerHTML = appSidebarRight.sharedMediaTab.profileElements.name.innerHTML = title;
|
||||
|
||||
this.goDownBtn.classList.remove('hide');
|
||||
|
||||
this.setPeerStatus(true);
|
||||
});
|
||||
|
||||
appSidebarRight.fillProfileElements();
|
||||
appSidebarRight.sharedMediaTab.fillProfileElements();
|
||||
|
||||
$rootScope.$broadcast('peer_changed', this.peerID);
|
||||
}
|
||||
@ -2536,8 +2537,8 @@ export class AppImManager {
|
||||
}
|
||||
|
||||
public setMutedState(muted = false) {
|
||||
appSidebarRight.profileElements.notificationsCheckbox.checked = !muted;
|
||||
appSidebarRight.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
|
||||
appSidebarRight.sharedMediaTab.profileElements.notificationsCheckbox.checked = !muted;
|
||||
appSidebarRight.sharedMediaTab.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
|
||||
|
||||
if(appPeersManager.isBroadcast(this.peerID)) { // not human
|
||||
this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
|
||||
|
@ -10,12 +10,12 @@ import VideoPlayer from "../mediaPlayer";
|
||||
import { renderImageFromUrl, parseMenuButtonsTo } from "../../components/misc";
|
||||
import AvatarElement from "../../components/avatar";
|
||||
import { LazyLoadQueueBase } from "../../components/lazyLoadQueue";
|
||||
import appForward from "../../components/appForward";
|
||||
import { touchSupport } from "../config";
|
||||
import appMediaPlaybackController from "../../components/appMediaPlaybackController";
|
||||
import { deferredPromise } from "../../helpers/cancellablePromise";
|
||||
import mediaSizes from "../../helpers/mediaSizes";
|
||||
import { isSafari } from "../../helpers/userAgent";
|
||||
import appSidebarRight, { AppSidebarRight } from "./appSidebarRight";
|
||||
|
||||
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
|
||||
// TODO: картинки "обрезаются" если возвращаются или появляются с места, где есть их перекрытие (топбар, поле ввода)
|
||||
@ -155,9 +155,9 @@ export class AppMediaViewer {
|
||||
this.loadMediaPromiseUp = this.loadMediaPromiseDown = null;
|
||||
this.setMoverPromise = null;
|
||||
|
||||
if(appForward.container.classList.contains('active')) {
|
||||
if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) {
|
||||
setTimeout(() => {
|
||||
appForward.close();
|
||||
appSidebarRight.forwardTab.closeBtn.click();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ export class AppMediaViewer {
|
||||
});
|
||||
|
||||
const forward = (e: MouseEvent) => {
|
||||
appForward.init([this.currentMessageID]);
|
||||
appSidebarRight.forwardTab.open([this.currentMessageID]);
|
||||
};
|
||||
|
||||
[this.buttons.forward, this.buttons["menu-forward"]].forEach(el => {
|
||||
@ -853,8 +853,8 @@ export class AppMediaViewer {
|
||||
this.needLoadMore = needLoadMore;
|
||||
//this.loadMore = loadMore;
|
||||
|
||||
if(appForward.container.classList.contains('active')) {
|
||||
appForward.close();
|
||||
if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) {
|
||||
appSidebarRight.forwardTab.closeBtn.click();
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +114,8 @@ export class AppSidebarLeft extends SidebarSlider {
|
||||
[AppSidebarLeft.SLIDERITEMSIDS.includedChats]: includedChatsTab,
|
||||
});
|
||||
|
||||
//this._selectTab(0); // make first tab as default
|
||||
|
||||
this.searchInput = new SearchInput('Telegram Search');
|
||||
this.sidebarEl.querySelector('.item-main .sidebar-header').append(this.searchInput.container);
|
||||
|
||||
|
@ -1,68 +1,25 @@
|
||||
import { putPreloader, renderImageFromUrl } from "../../components/misc";
|
||||
//import Scrollable from '../../components/scrollable';
|
||||
import Scrollable from '../../components/scrollable_new';
|
||||
import { $rootScope } from "../utils";
|
||||
import appMessagesManager from "./appMessagesManager";
|
||||
import appPhotosManager from "./appPhotosManager";
|
||||
import appPeersManager from "./appPeersManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
import appProfileManager from "./appProfileManager";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
import { logger, LogLevels } from "../logger";
|
||||
import appImManager from "./appImManager";
|
||||
import appMediaViewer from "./appMediaViewer";
|
||||
import LazyLoadQueue from "../../components/lazyLoadQueue";
|
||||
import { wrapDocument, wrapAudio } from "../../components/wrappers";
|
||||
import AppSearch, { SearchGroup } from "../../components/appSearch";
|
||||
import AvatarElement from "../../components/avatar";
|
||||
import appForward from "../../components/appForward";
|
||||
import SidebarSlider from "../../components/slider";
|
||||
import SearchInput from "../../components/searchInput";
|
||||
import { horizontalMenu } from "../../components/horizontalMenu";
|
||||
import AppStickersTab from "../../components/sidebarRight/stickers";
|
||||
import AppPollResultsTab from "../../components/sidebarRight/pollResults";
|
||||
import AppGifsTab from "../../components/sidebarRight/gifs";
|
||||
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
|
||||
import { isSafari } from "../../helpers/userAgent";
|
||||
|
||||
const testScroll = false;
|
||||
import AppPrivateSearchTab from "../../components/sidebarRight/search";
|
||||
import AppSharedMediaTab from "../../components/sidebarRight/sharedMedia";
|
||||
import AppForwardTab from "../../components/sidebarRight/forward";
|
||||
|
||||
const COLUMN_ACTIVE_CLASSNAME = 'is-right-column-shown';
|
||||
|
||||
let setText = (text: string, el: HTMLDivElement) => {
|
||||
window.requestAnimationFrame(() => {
|
||||
if(el.childElementCount > 1) {
|
||||
el.firstElementChild.remove();
|
||||
}
|
||||
|
||||
let p = document.createElement('p');
|
||||
p.innerHTML = text;
|
||||
el.prepend(p);
|
||||
|
||||
el.style.display = '';
|
||||
});
|
||||
};
|
||||
|
||||
const sharedMediaTab = new AppSharedMediaTab();
|
||||
const searchTab = new AppPrivateSearchTab();
|
||||
const forwardTab = new AppForwardTab();
|
||||
const stickersTab = new AppStickersTab();
|
||||
const pollResultsTab = new AppPollResultsTab();
|
||||
const gifsTab = new AppGifsTab();
|
||||
|
||||
type ContentType = 'contentMembers' | 'contentMedia' | 'contentDocuments' | 'contentLinks' | 'contentAudio';
|
||||
type SharedMediaType = 'inputMessagesFilterContacts' | 'inputMessagesFilterPhotoVideo' | 'inputMessagesFilterDocument' | 'inputMessagesFilterUrl' | 'inputMessagesFilterMusic';
|
||||
|
||||
const contentToSharedMap: {[contentType in ContentType]: SharedMediaType} = {
|
||||
contentMembers: 'inputMessagesFilterContacts',
|
||||
contentMedia: 'inputMessagesFilterPhotoVideo',
|
||||
contentDocuments: 'inputMessagesFilterDocument',
|
||||
contentLinks: 'inputMessagesFilterUrl',
|
||||
contentAudio: 'inputMessagesFilterMusic'
|
||||
};
|
||||
|
||||
// TODO: отправленное сообщение с картинкой, или же новое полученное апдейтом сообщение не отобразится в медии
|
||||
// TODO: по-хорошему, нужно просто сделать апдейты для всего сайдбара
|
||||
|
||||
export class AppSidebarRight extends SidebarSlider {
|
||||
public static SLIDERITEMSIDS = {
|
||||
sharedMedia: 0,
|
||||
search: 1,
|
||||
forward: 2,
|
||||
stickers: 3,
|
||||
@ -70,197 +27,32 @@ export class AppSidebarRight extends SidebarSlider {
|
||||
gifs: 5,
|
||||
};
|
||||
|
||||
public profileContainer: HTMLDivElement;
|
||||
public profileContentEl: HTMLDivElement;
|
||||
public contentContainer: HTMLDivElement;
|
||||
public profileElements: {
|
||||
avatar: AvatarElement,
|
||||
name: HTMLDivElement,
|
||||
subtitle: HTMLDivElement,
|
||||
bio: HTMLDivElement,
|
||||
username: HTMLDivElement,
|
||||
phone: HTMLDivElement,
|
||||
notificationsRow: HTMLDivElement,
|
||||
notificationsCheckbox: HTMLInputElement,
|
||||
notificationsStatus: HTMLParagraphElement
|
||||
} = {} as any;
|
||||
public sharedMedia: {
|
||||
[t in ContentType]: HTMLDivElement
|
||||
} = {} as any;
|
||||
|
||||
private loadSidebarMediaPromises: {[type: string]: Promise<void>} = {};
|
||||
private loadedAllMedia: {[type: string]: boolean} = {};
|
||||
|
||||
public sharedMediaTypes: SharedMediaType[] = [
|
||||
//'members',
|
||||
'inputMessagesFilterContacts',
|
||||
'inputMessagesFilterPhotoVideo',
|
||||
'inputMessagesFilterDocument',
|
||||
'inputMessagesFilterUrl',
|
||||
'inputMessagesFilterMusic'
|
||||
];
|
||||
public sharedMediaType: SharedMediaType = 'inputMessagesFilterPhotoVideo';
|
||||
private sharedMediaSelected: HTMLDivElement = null;
|
||||
|
||||
private lazyLoadQueue = new LazyLoadQueue();
|
||||
|
||||
public historiesStorage: {
|
||||
[peerID: number]: Partial<{
|
||||
[type in SharedMediaType]: number[]
|
||||
}>
|
||||
} = {};
|
||||
public usedFromHistory: Partial<{
|
||||
[type in SharedMediaType]: number
|
||||
}> = {};
|
||||
|
||||
private log = logger('SR', LogLevels.error);
|
||||
|
||||
private peerID = 0;
|
||||
|
||||
public scroll: Scrollable = null;
|
||||
|
||||
private profileTabs: HTMLUListElement;
|
||||
private prevTabID = -1;
|
||||
|
||||
private mediaDivsByIDs: {
|
||||
[mid: number]: HTMLDivElement
|
||||
} = {};
|
||||
|
||||
public urlsToRevoke: string[] = [];
|
||||
|
||||
private searchContainer: HTMLDivElement;;
|
||||
public searchCloseBtn: HTMLButtonElement;
|
||||
private searchInput: SearchInput;
|
||||
public privateSearch: AppSearch;
|
||||
|
||||
private loadMutex: Promise<any> = Promise.resolve();
|
||||
|
||||
public sharedMediaTab: AppSharedMediaTab;
|
||||
public searchTab: AppPrivateSearchTab;
|
||||
public forwardTab: AppForwardTab;
|
||||
public stickersTab: AppStickersTab;
|
||||
public pollResultsTab: AppPollResultsTab;
|
||||
public gifsTab: AppGifsTab;
|
||||
|
||||
constructor() {
|
||||
super(document.getElementById('column-right') as HTMLElement, {
|
||||
[AppSidebarRight.SLIDERITEMSIDS.sharedMedia]: sharedMediaTab,
|
||||
[AppSidebarRight.SLIDERITEMSIDS.search]: searchTab,
|
||||
[AppSidebarRight.SLIDERITEMSIDS.forward]: forwardTab,
|
||||
[AppSidebarRight.SLIDERITEMSIDS.stickers]: stickersTab,
|
||||
[AppSidebarRight.SLIDERITEMSIDS.pollResults]: pollResultsTab,
|
||||
[AppSidebarRight.SLIDERITEMSIDS.gifs]: gifsTab
|
||||
});
|
||||
}, true);
|
||||
|
||||
//this._selectTab(3);
|
||||
|
||||
this.sharedMediaTab = sharedMediaTab;
|
||||
this.searchTab = searchTab;
|
||||
this.forwardTab = forwardTab;
|
||||
this.stickersTab = stickersTab;
|
||||
this.pollResultsTab = pollResultsTab;
|
||||
this.gifsTab = gifsTab;
|
||||
|
||||
this.profileContainer = this.sidebarEl.querySelector('.profile-container');
|
||||
this.profileContentEl = this.sidebarEl.querySelector('.profile-content');
|
||||
this.contentContainer = this.sidebarEl.querySelector('.content-container');
|
||||
this.profileElements = {
|
||||
avatar: this.profileContentEl.querySelector('.profile-avatar'),
|
||||
name: this.profileContentEl.querySelector('.profile-name'),
|
||||
subtitle: this.profileContentEl.querySelector('.profile-subtitle'),
|
||||
bio: this.profileContentEl.querySelector('.profile-row-bio'),
|
||||
username: this.profileContentEl.querySelector('.profile-row-username'),
|
||||
phone: this.profileContentEl.querySelector('.profile-row-phone'),
|
||||
notificationsRow: this.profileContentEl.querySelector('.profile-row-notifications'),
|
||||
notificationsCheckbox: this.profileContentEl.querySelector('#profile-notifications'),
|
||||
notificationsStatus: this.profileContentEl.querySelector('.profile-row-notifications > p')
|
||||
};
|
||||
|
||||
this.sharedMedia = {
|
||||
contentMembers: this.profileContentEl.querySelector('#content-members'),
|
||||
contentMedia: this.profileContentEl.querySelector('#content-media'),
|
||||
contentDocuments: this.profileContentEl.querySelector('#content-docs'),
|
||||
contentLinks: this.profileContentEl.querySelector('#content-links'),
|
||||
contentAudio: this.profileContentEl.querySelector('#content-audio'),
|
||||
};
|
||||
|
||||
this.searchContainer = this.sidebarEl.querySelector('#search-private-container');
|
||||
this.searchCloseBtn = this.searchContainer.querySelector('.sidebar-close-button');
|
||||
this.searchInput = new SearchInput('Search');
|
||||
this.searchCloseBtn.parentElement.append(this.searchInput.container);
|
||||
this.privateSearch = new AppSearch(this.searchContainer.querySelector('.chats-container'), this.searchInput, {
|
||||
messages: new SearchGroup('Private Search', 'messages')
|
||||
});
|
||||
|
||||
let container = this.profileContentEl.querySelector('.content-container .tabs-container') as HTMLDivElement;
|
||||
this.profileTabs = this.profileContentEl.querySelector('.profile-tabs');
|
||||
|
||||
this.scroll = new Scrollable(this.profileContainer, 'SR', undefined, 400);
|
||||
this.scroll.onScrolledBottom = () => {
|
||||
if(this.sharedMediaSelected && this.sharedMediaSelected.childElementCount/* && false */) {
|
||||
this.log('onScrolledBottom will load media');
|
||||
this.loadSidebarMedia(true);
|
||||
}
|
||||
};
|
||||
//this.scroll.attachSentinels(undefined, 400);
|
||||
|
||||
horizontalMenu(this.profileTabs, container, (id, tabContent) => {
|
||||
if(this.prevTabID == id) return;
|
||||
|
||||
if(this.prevTabID != -1) {
|
||||
this.onTransitionStart();
|
||||
}
|
||||
|
||||
this.sharedMediaType = this.sharedMediaTypes[id];
|
||||
this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement;
|
||||
|
||||
if(this.prevTabID != -1 && this.profileTabs.offsetTop) {
|
||||
this.scroll.scrollTop -= this.profileTabs.offsetTop;
|
||||
}
|
||||
|
||||
/* this.log('setVirtualContainer', id, this.sharedMediaSelected, this.sharedMediaSelected.childElementCount);
|
||||
this.scroll.setVirtualContainer(this.sharedMediaSelected); */
|
||||
|
||||
if(this.prevTabID != -1 && !this.sharedMediaSelected.childElementCount) { // quick brown fix
|
||||
//this.contentContainer.classList.remove('loaded');
|
||||
this.loadSidebarMedia(true);
|
||||
}
|
||||
|
||||
this.prevTabID = id;
|
||||
}, () => {
|
||||
this.scroll.onScroll();
|
||||
this.onTransitionEnd();
|
||||
});
|
||||
|
||||
let sidebarCloseBtn = this.sidebarEl.querySelector('.sidebar-close-button') as HTMLButtonElement;
|
||||
sidebarCloseBtn.addEventListener('click', () => {
|
||||
this.toggleSidebar(false);
|
||||
});
|
||||
|
||||
this.searchCloseBtn.addEventListener('click', () => {
|
||||
this.searchContainer.classList.remove('active');
|
||||
this.privateSearch.reset();
|
||||
});
|
||||
|
||||
this.sharedMedia.contentMedia.addEventListener('click', (e) => {
|
||||
const target = e.target as HTMLDivElement;
|
||||
|
||||
const messageID = +target.dataset.mid;
|
||||
if(!messageID) {
|
||||
this.log.warn('no messageID by click on target:', target);
|
||||
return;
|
||||
}
|
||||
|
||||
const message = appMessagesManager.getMessage(messageID);
|
||||
|
||||
const ids = Object.keys(this.mediaDivsByIDs).map(k => +k).sort((a, b) => a - b);
|
||||
const idx = ids.findIndex(i => i == messageID);
|
||||
|
||||
const targets = ids.map(id => {
|
||||
const element = this.mediaDivsByIDs[id] as HTMLElement;
|
||||
//element = element.querySelector('img') || element;
|
||||
return {element, mid: id};
|
||||
});
|
||||
|
||||
appMediaViewer.openMedia(message, target, false, this.sidebarEl, targets.slice(idx + 1).reverse(), targets.slice(0, idx).reverse(), true);
|
||||
});
|
||||
|
||||
this.profileElements.notificationsCheckbox.addEventListener('change', () => {
|
||||
//let checked = this.profileElements.notificationsCheckbox.checked;
|
||||
appImManager.mutePeer(this.peerID);
|
||||
});
|
||||
|
||||
mediaSizes.addListener('changeScreen', (from, to) => {
|
||||
if(from !== undefined && to == ScreenSize.medium) {
|
||||
this.toggleSidebar(false);
|
||||
@ -268,29 +60,24 @@ export class AppSidebarRight extends SidebarSlider {
|
||||
});
|
||||
}
|
||||
|
||||
private onTransitionStart = () => {
|
||||
// Jolly Cobra's // Workaround for scrollable content flickering during animation.
|
||||
const container = this.scroll.container;
|
||||
if(container.style.overflowY !== 'hidden') {
|
||||
const scrollBarWidth = container.offsetWidth - container.clientWidth;
|
||||
container.style.overflowY = 'hidden';
|
||||
container.style.paddingRight = `${scrollBarWidth}px`;
|
||||
public onCloseTab(id: number) {
|
||||
if(!this.historyTabIDs.length) {
|
||||
this.toggleSidebar(false);
|
||||
}
|
||||
};
|
||||
|
||||
private onTransitionEnd = () => {
|
||||
// Jolly Cobra's // Workaround for scrollable content flickering during animation.
|
||||
const container = this.scroll.container;
|
||||
container.style.overflowY = '';
|
||||
container.style.paddingRight = '0';
|
||||
};
|
||||
|
||||
public beginSearch() {
|
||||
this.toggleSidebar(true);
|
||||
this.searchContainer.classList.add('active');
|
||||
this.privateSearch.beginSearch(this.peerID);
|
||||
super.onCloseTab(id);
|
||||
}
|
||||
|
||||
/* public selectTab(id: number) {
|
||||
const res = super.selectTab(id);
|
||||
|
||||
if(id !== -1) {
|
||||
this.toggleSidebar(true);
|
||||
}
|
||||
|
||||
return res;
|
||||
} */
|
||||
|
||||
public toggleSidebar(enable?: boolean) {
|
||||
/////this.log('sidebarEl', this.sidebarEl, enable, isElementInViewport(this.sidebarEl));
|
||||
|
||||
@ -310,6 +97,10 @@ export class AppSidebarRight extends SidebarSlider {
|
||||
|
||||
if(!willChange) return Promise.resolve();
|
||||
|
||||
if(!active && !this.historyTabIDs.length) {
|
||||
this.selectTab(AppSidebarRight.SLIDERITEMSIDS.sharedMedia);
|
||||
}
|
||||
|
||||
//console.log('sidebar selectTab', enable, willChange);
|
||||
if(mediaSizes.isMobile) {
|
||||
appImManager.selectTab(active ? 1 : 2);
|
||||
@ -354,10 +145,10 @@ export class AppSidebarRight extends SidebarSlider {
|
||||
(item.element.firstElementChild as HTMLElement).style.display = '';
|
||||
}
|
||||
|
||||
if(active) {
|
||||
/* if(active) {
|
||||
appForward.close();
|
||||
this.searchCloseBtn.click();
|
||||
}
|
||||
} */
|
||||
|
||||
resolve();
|
||||
}, 200);
|
||||
@ -374,559 +165,6 @@ export class AppSidebarRight extends SidebarSlider {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public filterMessagesByType(ids: number[], type: string) {
|
||||
let messages: any[] = [];
|
||||
for(let mid of ids) {
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
if(message.media) messages.push(message);
|
||||
}
|
||||
|
||||
let filtered: any[] = [];
|
||||
|
||||
switch(type) {
|
||||
case 'inputMessagesFilterPhotoVideo': {
|
||||
for(let message of messages) {
|
||||
let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
|
||||
if(!media) {
|
||||
//this.log('no media!', message);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) {
|
||||
//this.log('broken video', media);
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterDocument': {
|
||||
for(let message of messages) {
|
||||
if(!message.media.document || message.media.document.type == 'voice' || message.media.document.type == 'audio') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let doc = message.media.document;
|
||||
if(doc.attributes) {
|
||||
if(doc.attributes.find((a: any) => a._ == "documentAttributeSticker")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterUrl': {
|
||||
for(let message of messages) {
|
||||
if(!message.media.webpage || message.media.webpage._ == 'webPageEmpty') {
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterMusic': {
|
||||
for(let message of messages) {
|
||||
if(!message.media.document || message.media.document.type != 'audio') {
|
||||
continue;
|
||||
}
|
||||
|
||||
filtered.push(message);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
public async performSearchResult(messages: any[], type: SharedMediaType) {
|
||||
const peerID = this.peerID;
|
||||
const elemsToAppend: HTMLElement[] = [];
|
||||
const promises: Promise<any>[] = [];
|
||||
let sharedMediaDiv: HTMLDivElement;
|
||||
|
||||
/* for(let contentType in contentToSharedMap) {
|
||||
if(contentToSharedMap[contentType as ContentType] == type) {
|
||||
sharedMediaDiv = this.sharedMedia[contentType as ContentType];
|
||||
}
|
||||
} */
|
||||
|
||||
// https://core.telegram.org/type/MessagesFilter
|
||||
switch(type) {
|
||||
case 'inputMessagesFilterPhotoVideo': {
|
||||
sharedMediaDiv = this.sharedMedia.contentMedia;
|
||||
|
||||
for(const message of messages) {
|
||||
const media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('media-item');
|
||||
//console.log(message, photo);
|
||||
|
||||
const isPhoto = media._ == 'photo';
|
||||
|
||||
const photo = isPhoto ? appPhotosManager.getPhoto(media.id) : null;
|
||||
let isDownloaded: boolean;
|
||||
if(photo) {
|
||||
isDownloaded = photo.downloaded > 0;
|
||||
} else {
|
||||
const cachedThumb = appPhotosManager.getDocumentCachedThumb(media.id);
|
||||
isDownloaded = cachedThumb?.downloaded > 0;
|
||||
}
|
||||
|
||||
//this.log('inputMessagesFilterPhotoVideo', message, media);
|
||||
|
||||
if(!isPhoto) {
|
||||
const span = document.createElement('span');
|
||||
span.classList.add('video-time');
|
||||
div.append(span);
|
||||
|
||||
if(media.type != 'gif') {
|
||||
span.innerText = (media.duration + '').toHHMMSS(false);
|
||||
|
||||
/* const spanPlay = document.createElement('span');
|
||||
spanPlay.classList.add('video-play', 'tgico-largeplay', 'btn-circle', 'position-center');
|
||||
div.append(spanPlay); */
|
||||
} else {
|
||||
span.innerText = 'GIF';
|
||||
}
|
||||
}
|
||||
|
||||
const load = () => appPhotosManager.preloadPhoto(isPhoto ? media.id : media, appPhotosManager.choosePhotoSize(media, 200, 200))
|
||||
.then(() => {
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
const url = (photo && photo.url) || appPhotosManager.getDocumentCachedThumb(media.id).url;
|
||||
if(url) {
|
||||
//if(needBlur) return;
|
||||
|
||||
const needBlurCallback = needBlur ? () => {
|
||||
//void img.offsetLeft; // reflow
|
||||
img.style.opacity = '';
|
||||
|
||||
if(thumb) {
|
||||
window.setTimeout(() => {
|
||||
thumb.remove();
|
||||
}, 200);
|
||||
}
|
||||
} : undefined;
|
||||
renderImageFromUrl(img, url, needBlurCallback);
|
||||
}
|
||||
});
|
||||
|
||||
let thumb: HTMLImageElement;
|
||||
const sizes = media.sizes || media.thumbs;
|
||||
|
||||
const willHaveThumb = !isDownloaded && sizes && sizes[0].bytes;
|
||||
if(willHaveThumb) {
|
||||
thumb = new Image();
|
||||
thumb.classList.add('media-image', 'thumbnail');
|
||||
thumb.dataset.mid = '' + message.mid;
|
||||
appPhotosManager.setAttachmentPreview(sizes[0].bytes, thumb, false, false);
|
||||
div.append(thumb);
|
||||
}
|
||||
|
||||
const needBlur = !isDownloaded || !willHaveThumb;
|
||||
const img = new Image();
|
||||
img.dataset.mid = '' + message.mid;
|
||||
img.classList.add('media-image');
|
||||
if(needBlur) img.style.opacity = '0';
|
||||
div.append(img);
|
||||
|
||||
if(isDownloaded || willHaveThumb) {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
(thumb || img).addEventListener('load', () => {
|
||||
clearTimeout(timeout);
|
||||
resolve();
|
||||
});
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
this.log('didn\'t load', thumb, media, isDownloaded, sizes);
|
||||
reject();
|
||||
}, 1e3);
|
||||
});
|
||||
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
if(sizes?.length) {
|
||||
if(isDownloaded) load();
|
||||
else this.lazyLoadQueue.push({div, load});
|
||||
}
|
||||
|
||||
elemsToAppend.push(div);
|
||||
this.mediaDivsByIDs[message.mid] = div;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterDocument': {
|
||||
sharedMediaDiv = this.sharedMedia.contentDocuments;
|
||||
|
||||
for(let message of messages) {
|
||||
let div = wrapDocument(message.media.document, true, false, message.mid);
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterUrl': {
|
||||
sharedMediaDiv = this.sharedMedia.contentLinks;
|
||||
|
||||
for(let message of messages) {
|
||||
let webpage = message.media.webpage;
|
||||
let div = document.createElement('div');
|
||||
|
||||
let previewDiv = document.createElement('div');
|
||||
previewDiv.classList.add('preview');
|
||||
|
||||
//this.log('wrapping webpage', webpage);
|
||||
|
||||
previewDiv.innerText = (webpage.title || webpage.description || webpage.url || webpage.display_url).slice(0, 1);
|
||||
previewDiv.classList.add('empty');
|
||||
if(webpage.photo) {
|
||||
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 60, 60))
|
||||
.then(() => {
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
previewDiv.classList.remove('empty');
|
||||
|
||||
previewDiv.innerText = '';
|
||||
renderImageFromUrl(previewDiv, webpage.photo.url);
|
||||
});
|
||||
|
||||
this.lazyLoadQueue.push({div: previewDiv, load});
|
||||
}
|
||||
|
||||
let title = webpage.rTitle || '';
|
||||
let subtitle = webpage.rDescription || '';
|
||||
let url = RichTextProcessor.wrapRichText(webpage.url || '');
|
||||
|
||||
if(!title) {
|
||||
//title = new URL(webpage.url).hostname;
|
||||
title = webpage.display_url.split('/', 1)[0];
|
||||
}
|
||||
|
||||
div.append(previewDiv);
|
||||
div.insertAdjacentHTML('beforeend', `
|
||||
<div class="title">${title}</button>
|
||||
<div class="subtitle">${subtitle}</div>
|
||||
<div class="url">${url}</div>
|
||||
`);
|
||||
|
||||
if(div.innerText.trim().length) {
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterMusic': {
|
||||
sharedMediaDiv = this.sharedMedia.contentAudio;
|
||||
|
||||
for(let message of messages) {
|
||||
let div = wrapAudio(message.media.document, true, message.mid);
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
console.warn('death is my friend', messages);
|
||||
break;
|
||||
}
|
||||
|
||||
if(this.loadMutex) {
|
||||
promises.push(this.loadMutex);
|
||||
}
|
||||
|
||||
if(promises.length) {
|
||||
await Promise.all(promises);
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(elemsToAppend.length) {
|
||||
sharedMediaDiv.append(...elemsToAppend);
|
||||
}
|
||||
|
||||
if(sharedMediaDiv) {
|
||||
const parent = sharedMediaDiv.parentElement;
|
||||
Array.from(parent.children).slice(1).forEach(child => {
|
||||
child.remove();
|
||||
});
|
||||
|
||||
//this.contentContainer.classList.add('loaded');
|
||||
|
||||
if(!messages.length && !sharedMediaDiv.childElementCount) {
|
||||
const div = document.createElement('div');
|
||||
div.innerText = 'Nothing interesting here yet...';
|
||||
div.classList.add('position-center', 'text-center', 'content-empty', 'no-select');
|
||||
|
||||
parent.append(div);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public loadSidebarMedia(single = false) {
|
||||
if(testScroll/* || 1 == 1 */) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.log('loadSidebarMedia', single, this.peerID, this.loadSidebarMediaPromises);
|
||||
|
||||
const peerID = this.peerID;
|
||||
|
||||
let typesToLoad = single ? [this.sharedMediaType] : this.sharedMediaTypes;
|
||||
typesToLoad = typesToLoad.filter(type => !this.loadedAllMedia[type]);
|
||||
if(!typesToLoad.length) return;
|
||||
|
||||
const loadCount = (appPhotosManager.windowH / 130 | 0) * 3; // that's good for all types
|
||||
|
||||
const historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {});
|
||||
|
||||
const promises = typesToLoad.map(type => {
|
||||
if(this.loadSidebarMediaPromises[type]) return this.loadSidebarMediaPromises[type];
|
||||
|
||||
const history = historyStorage[type] ?? (historyStorage[type] = []);
|
||||
|
||||
// render from cache
|
||||
if(history.length && this.usedFromHistory[type] < history.length) {
|
||||
let messages: any[] = [];
|
||||
let used = this.usedFromHistory[type];
|
||||
|
||||
do {
|
||||
let ids = history.slice(used, used + loadCount);
|
||||
this.log('loadSidebarMedia: will render from cache', used, history, ids, loadCount);
|
||||
used += ids.length;
|
||||
|
||||
messages.push(...this.filterMessagesByType(ids, type));
|
||||
} while(messages.length < loadCount && used < history.length);
|
||||
|
||||
// если перебор
|
||||
if(messages.length > loadCount) {
|
||||
let diff = messages.length - loadCount;
|
||||
messages = messages.slice(0, messages.length - diff);
|
||||
used -= diff;
|
||||
}
|
||||
|
||||
this.usedFromHistory[type] = used;
|
||||
//if(messages.length) {
|
||||
return this.performSearchResult(messages, type);
|
||||
//}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// заливать новую картинку сюда только после полной отправки!
|
||||
let maxID = history[history.length - 1] || 0;
|
||||
|
||||
let ids = !maxID && appMessagesManager.historiesStorage[peerID]
|
||||
? appMessagesManager.historiesStorage[peerID].history.slice() : [];
|
||||
|
||||
maxID = !maxID && ids.length ? ids[ids.length - 1] : maxID;
|
||||
this.log('loadSidebarMedia: search house of glass pre', type, ids, maxID);
|
||||
|
||||
//let loadCount = history.length ? 50 : 15;
|
||||
return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, loadCount)
|
||||
.then(value => {
|
||||
ids = ids.concat(value.history);
|
||||
history.push(...ids);
|
||||
|
||||
this.log('loadSidebarMedia: search house of glass', type, value, ids);
|
||||
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
if(value.history.length < loadCount) {
|
||||
this.loadedAllMedia[type] = true;
|
||||
}
|
||||
|
||||
this.usedFromHistory[type] = history.length;
|
||||
|
||||
//if(ids.length) {
|
||||
return this.performSearchResult(this.filterMessagesByType(ids, type), type);
|
||||
//}
|
||||
}, (err) => {
|
||||
this.log.error('load error:', err);
|
||||
}).then(() => {
|
||||
this.loadSidebarMediaPromises[type] = null;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
public cleanup() {
|
||||
this.loadSidebarMediaPromises = {};
|
||||
this.loadedAllMedia = {};
|
||||
|
||||
this.prevTabID = -1;
|
||||
this.mediaDivsByIDs = {};
|
||||
this.lazyLoadQueue.clear();
|
||||
|
||||
this.sharedMediaTypes.forEach(type => {
|
||||
this.usedFromHistory[type] = 0;
|
||||
});
|
||||
|
||||
this.sharedMediaType = 'inputMessagesFilterPhotoVideo';
|
||||
}
|
||||
|
||||
public cleanupHTML() {
|
||||
//this.contentContainer.classList.remove('loaded');
|
||||
|
||||
//this.profileContentEl.parentElement.scrollTop = 0;
|
||||
this.profileElements.bio.style.display = 'none';
|
||||
this.profileElements.phone.style.display = 'none';
|
||||
this.profileElements.username.style.display = 'none';
|
||||
this.profileElements.notificationsRow.style.display = '';
|
||||
this.profileElements.notificationsCheckbox.checked = true;
|
||||
this.profileElements.notificationsStatus.innerText = 'Enabled';
|
||||
|
||||
if(this.urlsToRevoke.length) {
|
||||
this.urlsToRevoke.forEach(url => {
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
this.urlsToRevoke.length = 0;
|
||||
}
|
||||
|
||||
(Object.keys(this.sharedMedia) as ContentType[]).forEach(key => {
|
||||
this.sharedMedia[key].innerHTML = '';
|
||||
|
||||
const inputFilter = contentToSharedMap[key];
|
||||
if(!this.historiesStorage[this.peerID] || !this.historiesStorage[this.peerID][inputFilter]) {
|
||||
const parent = this.sharedMedia[key].parentElement;
|
||||
if(!testScroll) {
|
||||
if(!parent.querySelector('.preloader')) {
|
||||
putPreloader(parent, true);
|
||||
}
|
||||
}
|
||||
|
||||
const empty = parent.querySelector('.content-empty');
|
||||
if(empty) {
|
||||
empty.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(testScroll) {
|
||||
for(let i = 0; i < 1500; ++i) {
|
||||
let div = document.createElement('div');
|
||||
div.insertAdjacentHTML('beforeend', `<img class="media-image" src="assets/img/camomile.jpg">`);
|
||||
div.classList.add('media-item');
|
||||
div.dataset.id = '' + (i / 3 | 0);
|
||||
//div.innerText = '' + (i / 3 | 0);
|
||||
this.sharedMedia.contentMedia.append(div);
|
||||
}
|
||||
}
|
||||
|
||||
(this.profileTabs.firstElementChild.children[1] as HTMLLIElement).click(); // set media
|
||||
}
|
||||
|
||||
public setLoadMutex(promise: Promise<any>) {
|
||||
this.loadMutex = promise;
|
||||
}
|
||||
|
||||
public setPeer(peerID: number) {
|
||||
this.peerID = peerID;
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
public fillProfileElements() {
|
||||
let peerID = this.peerID = $rootScope.selectedPeerID;
|
||||
|
||||
this.cleanupHTML();
|
||||
|
||||
this.profileElements.avatar.setAttribute('peer', '' + peerID);
|
||||
|
||||
// username
|
||||
if(peerID != $rootScope.myID) {
|
||||
let username = appPeersManager.getPeerUsername(peerID);
|
||||
if(username) {
|
||||
setText(appPeersManager.getPeerUsername(peerID), this.profileElements.username);
|
||||
}
|
||||
|
||||
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
|
||||
if(dialog) {
|
||||
let muted = false;
|
||||
if(dialog.notify_settings && dialog.notify_settings.mute_until) {
|
||||
muted = new Date(dialog.notify_settings.mute_until * 1000) > new Date();
|
||||
}
|
||||
|
||||
appImManager.setMutedState(muted);
|
||||
}
|
||||
} else {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.profileElements.notificationsRow.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
//let membersLi = this.profileTabs.firstElementChild.children[0] as HTMLLIElement;
|
||||
if(peerID > 0) {
|
||||
//membersLi.style.display = 'none';
|
||||
|
||||
let user = appUsersManager.getUser(peerID);
|
||||
if(user.phone && peerID != $rootScope.myID) {
|
||||
setText(user.rPhone, this.profileElements.phone);
|
||||
}
|
||||
|
||||
appProfileManager.getProfile(peerID, true).then(userFull => {
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
if(userFull.rAbout && peerID != $rootScope.myID) {
|
||||
setText(userFull.rAbout, this.profileElements.bio);
|
||||
}
|
||||
|
||||
//this.log('userFull', userFull);
|
||||
});
|
||||
} else {
|
||||
//membersLi.style.display = appPeersManager.isBroadcast(peerID) ? 'none' : '';
|
||||
let chat = appPeersManager.getPeer(peerID);
|
||||
|
||||
appProfileManager.getChatFull(chat.id).then((chatFull: any) => {
|
||||
if(this.peerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
//this.log('chatInfo res 2:', chatFull);
|
||||
|
||||
if(chatFull.about) {
|
||||
setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const appSidebarRight = new AppSidebarRight();
|
||||
|
@ -16,7 +16,7 @@ export function dT () {
|
||||
return '[' + ((Date.now() - _logTimer) / 1000).toFixed(3) + ']';
|
||||
}
|
||||
|
||||
export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
|
||||
/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
|
||||
if(!element) {
|
||||
return false;
|
||||
}
|
||||
@ -26,6 +26,9 @@ export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
|
||||
return true;
|
||||
}
|
||||
return isInDOM(element.parentNode as HTMLElement, parentNode);
|
||||
} */
|
||||
export function isInDOM(element: Element): boolean {
|
||||
return element?.isConnected;
|
||||
}
|
||||
|
||||
export function checkDragEvent(e: any) {
|
||||
|
@ -51,6 +51,10 @@
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
overflow: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
#forward-container {
|
||||
|
Loading…
x
Reference in New Issue
Block a user