import { LazyLoadQueue, horizontalMenu, wrapDocument, formatPhoneNumber } from "../../components/misc"; import { isElementInViewport, $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 } from "../polyfill"; import appImManager from "./appImManager"; import appMediaViewer from "./appMediaViewer"; class AppSidebarRight { public sidebarEl = document.querySelector('.profile-container') as HTMLDivElement; public profileContentEl = document.querySelector('.profile-content') as HTMLDivElement; public profileElements = { avatar: this.profileContentEl.querySelector('.profile-avatar') as HTMLDivElement, name: this.profileContentEl.querySelector('.profile-name') as HTMLDivElement, subtitle: this.profileContentEl.querySelector('.profile-subtitle') as HTMLDivElement, bio: this.profileContentEl.querySelector('.profile-row-bio') as HTMLDivElement, username: this.profileContentEl.querySelector('.profile-row-username') as HTMLDivElement, phone: this.profileContentEl.querySelector('.profile-row-phone') as HTMLDivElement, notificationsCheckbox: this.profileContentEl.querySelector('#profile-notifications') as HTMLInputElement, notificationsStatus: this.profileContentEl.querySelector('.profile-row-notifications > p') as HTMLParagraphElement }; public sharedMedia: { [type: string]: HTMLDivElement } = { contentMembers: this.profileContentEl.querySelector('#content-members') as HTMLDivElement, contentMedia: this.profileContentEl.querySelector('#content-media') as HTMLDivElement, contentDocuments: this.profileContentEl.querySelector('#content-docs') as HTMLDivElement, contentLinks: this.profileContentEl.querySelector('#content-links') as HTMLDivElement, contentAudio: this.profileContentEl.querySelector('#content-audio') as HTMLDivElement, }; public sidebarScroll: HTMLDivElement = null; private loadSidebarMediaPromises: { [type: string]: Promise } = {}; public sharedMediaTypes = [ 'inputMessagesFilterContacts', 'inputMessagesFilterPhotoVideo', 'inputMessagesFilterDocument', 'inputMessagesFilterUrl', 'inputMessagesFilterVoice' ]; public sharedMediaType: string = ''; private sharedMediaSelected: HTMLDivElement = null; private lazyLoadQueueSidebar = new LazyLoadQueue(); /* public minMediaID: { [type: string]: number } = {}; */ public cleared: { [type: string]: boolean } = {}; public historiesStorage: { [peerID: number]: { [type: string]: number[] } } = {}; private log = logger('SR'); constructor() { let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement; let tabs = this.profileContentEl.querySelector('.profile-tabs') as HTMLUListElement; horizontalMenu(tabs, container, (id, tabContent) => { this.sharedMediaType = this.sharedMediaTypes[id]; this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement; }, this.onSidebarScroll.bind(this)); (tabs.children[1] as HTMLLIElement).click(); // set media let sidebarCloseBtn = this.sidebarEl.querySelector('.sidebar-close-button') as HTMLButtonElement; sidebarCloseBtn.addEventListener('click', () => { this.toggleSidebar(false); }); this.sharedMedia.contentMedia.addEventListener('click', (e) => { let target = e.target as HTMLDivElement; let messageID = +target.getAttribute('message-id'); if(!messageID) { this.log.warn('no messageID by click on target:', target); return; } let message = appMessagesManager.getMessage(messageID); appMediaViewer.openMedia(message, false); }); window.addEventListener('resize', () => { setTimeout(() => this.onSidebarScroll(), 0); }); } public onSidebarScroll() { this.lazyLoadQueueSidebar.check(); if(this.sharedMediaSelected) { let media = Array.from(this.sharedMediaSelected.childNodes).slice(-15); for(let div of media) { if(isElementInViewport(div)) { this.log('Will load more media'); this.loadSidebarMedia(true); break; } } } } public setScroll(scroll: HTMLDivElement) { this.sidebarScroll = scroll; this.sidebarScroll.addEventListener('scroll', this.onSidebarScroll.bind(this)); /* this.sidebarScroll.options({ callbacks: { onScroll: this.onSidebarScroll.bind(this) } }); */ } public toggleSidebar(enable?: boolean) { this.log('sidebarEl', this.sidebarEl, enable, isElementInViewport(this.sidebarEl)); /* if(enable !== undefined) { this.sidebarEl.style.display = enable ? 'block' : 'none'; return; } this.sidebarEl.style.display = isElementInViewport(this.sidebarEl) ? 'none' : 'block'; */ if(enable !== undefined) { this.sidebarEl.style.width = enable ? '25%' : '0%'; return; } this.sidebarEl.style.width = isElementInViewport(this.sidebarEl) ? '0%' : '25%'; } public loadSidebarMedia(single = false) { let peerID = $rootScope.selectedPeerID; let typesToLoad = single ? [this.sharedMediaType] : this.sharedMediaTypes; if(!this.historiesStorage[peerID]) this.historiesStorage[peerID] = {}; let historyStorage = this.historiesStorage[peerID]; let promises = typesToLoad.map(type => { if(this.loadSidebarMediaPromises[type]) return this.loadSidebarMediaPromises[type]; if(!historyStorage[type]) historyStorage[type] = []; let history = historyStorage[type]; // заливать новую картинку сюда только после полной отправки! //let maxID = this.minMediaID[type] || 0; 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('search house of glass pre', type, ids, maxID); return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, 50) .then(value => { ids = ids.concat(value.history); history.push(...ids); this.log('search house of glass', type, value, ids, this.cleared); if($rootScope.selectedPeerID != peerID) { this.log.warn('peer changed'); return; } if(this.cleared[type]) { ids = history; delete this.cleared[type]; } ids.forEach(mid => { //this.minMediaID[type] = mid; let message = appMessagesManager.getMessage(mid); if(!message.media) return; /* 'inputMessagesFilterContacts', 'inputMessagesFilterPhotoVideo', 'inputMessagesFilterDocument', 'inputMessagesFilterUrl', 'inputMessagesFilterVoice'*/ switch(type) { case 'inputMessagesFilterPhotoVideo': { /* if(!(message.media.photo || message.media.document || message.media.webpage.document)) { this.log.error('no media!', message); break; } */ let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document); if(!media) { this.log('no media!', message); break; } if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) { this.log('broken video', media); break; } let div = document.createElement('div'); //console.log(message, photo); let sizes = media.sizes || media.thumbs; if(sizes && sizes[0].bytes) { appPhotosManager.setAttachmentPreview(sizes[0].bytes, div, false, true); } /* else { this.log('no stripped size', message, media); } */ //this.log('inputMessagesFilterPhotoVideo', message, media); let load = () => appPhotosManager.preloadPhoto(media, appPhotosManager.choosePhotoSize(media, 380, 0)) .then((blob) => { if($rootScope.selectedPeerID != peerID) { this.log.warn('peer changed'); return; } div.style.backgroundImage = 'url(' + URL.createObjectURL(blob) + ')'; }); div.setAttribute('message-id', '' + mid); this.lazyLoadQueueSidebar.push({div, load}); this.sharedMedia.contentMedia.append(div); break; } case 'inputMessagesFilterDocument': { if(!message.media.document) { break; } let doc = message.media.document; if(doc.attributes) { if(doc.attributes.find((a: any) => a._ == "documentAttributeSticker")) { break; } } //console.log('come back down to my knees', message); let div = wrapDocument(message.media.document, true); this.sharedMedia.contentDocuments.append(div); break; } default: //console.warn('death is my friend', message); break; } }); this.onSidebarScroll(); }).then(() => { this.loadSidebarMediaPromises[type] = null; }, (err) => { this.log.error('load error:', err); this.loadSidebarMediaPromises[type] = null; }); }); return promises; } public fillProfileElements() { let peerID = $rootScope.selectedPeerID; 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.notificationsCheckbox.setAttribute('checked', 'checked'); this.profileElements.notificationsStatus.innerText = 'Enabled'; Object.keys(this.sharedMedia).forEach(key => { this.sharedMedia[key].innerHTML = ''; }); this.sharedMediaTypes.forEach(type => { //this.minMediaID[type] = 0; this.cleared[type] = true; }); let setText = (text: string, el: HTMLDivElement) => { el.style.display = ''; if(el.childElementCount > 1) { el.firstElementChild.remove(); } let p = document.createElement('p'); p.innerHTML = text; el.prepend(p); }; // username let username = appPeersManager.getPeerUsername($rootScope.selectedPeerID); if(username) { setText(appPeersManager.getPeerUsername($rootScope.selectedPeerID), this.profileElements.username); } if($rootScope.selectedPeerID > 0) { let user = appUsersManager.getUser($rootScope.selectedPeerID); if(user.phone) { setText('+' + formatPhoneNumber(user.phone).formatted, this.profileElements.phone); } appProfileManager.getProfile($rootScope.selectedPeerID, true).then(userFull => { if($rootScope.selectedPeerID != peerID) { this.log.warn('peer changed'); return; } if(userFull.rAbout) { setText(userFull.rAbout, this.profileElements.bio); } this.log('userFull', userFull); if(userFull.pinned_msg_id) { // request pinned message appImManager.pinnedMsgID = userFull.pinned_msg_id; appMessagesManager.wrapSingleMessage(userFull.pinned_msg_id); } }); } else { let chat = appPeersManager.getPeer($rootScope.selectedPeerID); appProfileManager.getChatFull(chat.id).then((chatFull: any) => { if($rootScope.selectedPeerID != peerID) { this.log.warn('peer changed'); return; } this.log('chatInfo res 2:', chatFull); if(chatFull.about) { setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio); } }); } let dialog: any = appMessagesManager.getDialogByPeerID($rootScope.selectedPeerID); if(dialog.length) { dialog = dialog[0]; let muted = false; if(dialog.notify_settings && dialog.notify_settings.mute_until) { muted = new Date(dialog.notify_settings.mute_until * 1000) > new Date(); if(muted) { this.profileElements.notificationsCheckbox.removeAttribute('checked'); this.profileElements.notificationsStatus.innerText = 'Disabled'; } } if($rootScope.selectedPeerID < 0) { // not human let isChannel = appPeersManager.isChannel($rootScope.selectedPeerID) && !appPeersManager.isMegagroup($rootScope.selectedPeerID); if(isChannel) { appImManager.btnMute.classList.remove('tgico-mute', 'tgico-unmute'); appImManager.btnMute.classList.add(muted ? 'tgico-unmute' : 'tgico-mute'); appImManager.btnMute.style.display = ''; } else { appImManager.btnMute.style.display = 'none'; } } else { appImManager.btnMute.style.display = 'none'; } } //this.loadSidebarMedia(); } } export default new AppSidebarRight();